Merge "Remove unused variable in VolumeControlAction"
diff --git a/Android.bp b/Android.bp
index bbaeea5..73bc382 100644
--- a/Android.bp
+++ b/Android.bp
@@ -620,6 +620,7 @@
"av-types-aidl-java",
"mediatranscoding_aidl_interface-java",
"soundtrigger_middleware-aidl-java",
+ "modules-utils-os",
],
}
@@ -1093,6 +1094,14 @@
path: "core/java",
}
+filegroup {
+ name: "activity_manager_procstate_aidl",
+ srcs: [
+ "core/java/android/app/ProcessStateEnum.aidl",
+ ],
+ path: "core/java",
+}
+
aidl_interface {
name: "libincremental_aidl",
unstable: true,
@@ -1251,7 +1260,6 @@
filegroup {
name: "framework-telephony-common-shared-srcs",
srcs: [
- "core/java/android/os/BasicShellCommandHandler.java",
"core/java/android/os/RegistrantList.java",
"core/java/android/os/Registrant.java",
"core/java/android/util/IndentingPrintWriter.java",
@@ -1334,7 +1342,6 @@
name: "framework-wifi-service-shared-srcs",
srcs: [
"core/java/android/net/InterfaceConfiguration.java",
- "core/java/android/os/BasicShellCommandHandler.java",
"core/java/android/util/BackupUtils.java",
"core/java/android/util/Rational.java",
"core/java/com/android/internal/util/FastXmlSerializer.java",
diff --git a/apct-tests/perftests/core/src/android/util/CharsetUtilsPerfTest.java b/apct-tests/perftests/core/src/android/util/CharsetUtilsPerfTest.java
new file mode 100644
index 0000000..2a538b2
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/util/CharsetUtilsPerfTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2020 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.util;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+
+import androidx.test.filters.LargeTest;
+
+import dalvik.system.VMRuntime;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Collection;
+
+@LargeTest
+@RunWith(Parameterized.class)
+public class CharsetUtilsPerfTest {
+ @Rule
+ public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @Parameterized.Parameter(0)
+ public String mName;
+ @Parameterized.Parameter(1)
+ public String mValue;
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Collection<Object[]> getParameters() {
+ return Arrays.asList(new Object[][] {
+ { "simple", "com.example.typical_package_name" },
+ { "complex", "從不喜歡孤單一個 - 蘇永康/吳雨霏" },
+ });
+ }
+
+ @Test
+ public void timeUpstream() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mValue.getBytes(StandardCharsets.UTF_8);
+ }
+ }
+
+ /**
+ * Measure performance of writing into a small buffer where bounds checking
+ * requires careful measurement of encoded size.
+ */
+ @Test
+ public void timeLocal_SmallBuffer() {
+ final byte[] dest = (byte[]) VMRuntime.getRuntime().newNonMovableArray(byte.class, 64);
+ final long destPtr = VMRuntime.getRuntime().addressOf(dest);
+
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ CharsetUtils.toUtf8Bytes(mValue, destPtr, 0, dest.length);
+ }
+ }
+
+ /**
+ * Measure performance of writing into a large buffer where bounds checking
+ * only needs a simple worst-case 4-bytes-per-char check.
+ */
+ @Test
+ public void timeLocal_LargeBuffer() {
+ final byte[] dest = (byte[]) VMRuntime.getRuntime().newNonMovableArray(byte.class, 1024);
+ final long destPtr = VMRuntime.getRuntime().addressOf(dest);
+
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ CharsetUtils.toUtf8Bytes(mValue, destPtr, 0, dest.length);
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/util/XmlPerfTest.java b/apct-tests/perftests/core/src/android/util/XmlPerfTest.java
new file mode 100644
index 0000000..e05bd2a
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/util/XmlPerfTest.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2020 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.util;
+
+import static org.junit.Assert.assertEquals;
+
+import android.os.Bundle;
+import android.os.Debug;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.util.HexDump;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.function.Supplier;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class XmlPerfTest {
+ /**
+ * Since allocation measurement adds overhead, it's disabled by default for
+ * performance runs. It can be manually enabled to compare GC behavior.
+ */
+ private static final boolean MEASURE_ALLOC = false;
+
+ @Rule
+ public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @Test
+ public void timeWrite_Fast() throws Exception {
+ doWrite(() -> Xml.newFastSerializer());
+ }
+
+ @Test
+ public void timeWrite_Binary() throws Exception {
+ doWrite(() -> Xml.newBinarySerializer());
+ }
+
+ private void doWrite(Supplier<TypedXmlSerializer> outFactory) throws Exception {
+ if (MEASURE_ALLOC) {
+ Debug.startAllocCounting();
+ }
+
+ int iterations = 0;
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ iterations++;
+ try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+ final TypedXmlSerializer out = outFactory.get();
+ out.setOutput(os, StandardCharsets.UTF_8.name());
+ write(out);
+ }
+ }
+
+ if (MEASURE_ALLOC) {
+ Debug.stopAllocCounting();
+ final Bundle results = new Bundle();
+ results.putLong("threadAllocCount_mean", Debug.getThreadAllocCount() / iterations);
+ results.putLong("threadAllocSize_mean", Debug.getThreadAllocSize() / iterations);
+ InstrumentationRegistry.getInstrumentation().sendStatus(0, results);
+ }
+ }
+
+ @Test
+ public void timeRead_Fast() throws Exception {
+ doRead(() -> Xml.newFastSerializer(), () -> Xml.newFastPullParser());
+ }
+
+ @Test
+ public void timeRead_Binary() throws Exception {
+ doRead(() -> Xml.newBinarySerializer(), () -> Xml.newBinaryPullParser());
+ }
+
+ private void doRead(Supplier<TypedXmlSerializer> outFactory,
+ Supplier<TypedXmlPullParser> inFactory) throws Exception {
+ final byte[] raw;
+ try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+ TypedXmlSerializer out = outFactory.get();
+ out.setOutput(os, StandardCharsets.UTF_8.name());
+ write(out);
+ raw = os.toByteArray();
+ }
+
+ if (MEASURE_ALLOC) {
+ Debug.startAllocCounting();
+ }
+
+ int iterations = 0;
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ iterations++;
+ try (ByteArrayInputStream is = new ByteArrayInputStream(raw)) {
+ TypedXmlPullParser xml = inFactory.get();
+ xml.setInput(is, StandardCharsets.UTF_8.name());
+ read(xml);
+ }
+ }
+
+ if (MEASURE_ALLOC) {
+ Debug.stopAllocCounting();
+ final Bundle results = new Bundle();
+ results.putLong("sizeBytes", raw.length);
+ results.putLong("threadAllocCount_mean", Debug.getThreadAllocCount() / iterations);
+ results.putLong("threadAllocSize_mean", Debug.getThreadAllocSize() / iterations);
+ InstrumentationRegistry.getInstrumentation().sendStatus(0, results);
+ } else {
+ final Bundle results = new Bundle();
+ results.putLong("sizeBytes", raw.length);
+ InstrumentationRegistry.getInstrumentation().sendStatus(0, results);
+ }
+ }
+
+ /**
+ * Not even joking, this is a typical public key blob stored in
+ * {@code packages.xml}.
+ */
+ private static final byte[] KEY_BLOB = HexDump.hexStringToByteArray(""
+ + "308204a830820390a003020102020900a1573d0f45bea193300d06092a864886f70d010105050030819"
+ + "4310b3009060355040613025553311330110603550408130a43616c69666f726e696131163014060355"
+ + "0407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e06035"
+ + "5040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d"
+ + "0109011613616e64726f696440616e64726f69642e636f6d301e170d3131303931393138343232355a1"
+ + "70d3339303230343138343232355a308194310b3009060355040613025553311330110603550408130a"
+ + "43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e0603550"
+ + "40a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e"
+ + "64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d3"
+ + "0820120300d06092a864886f70d01010105000382010d00308201080282010100de1b51336afc909d8b"
+ + "cca5920fcdc8940578ec5c253898930e985481cfdea75ba6fc54b1f7bb492a03d98db471ab4200103a8"
+ + "314e60ee25fef6c8b83bc1b2b45b084874cffef148fa2001bb25c672b6beba50b7ac026b546da762ea2"
+ + "23829a22b80ef286131f059d2c9b4ca71d54e515a8a3fd6bf5f12a2493dfc2619b337b032a7cf8bbd34"
+ + "b833f2b93aeab3d325549a93272093943bb59dfc0197ae4861ff514e019b73f5cf10023ad1a032adb4b"
+ + "9bbaeb4debecb4941d6a02381f1165e1ac884c1fca9525c5854dce2ad8ec839b8ce78442c16367efc07"
+ + "778a337d3ca2cdf9792ac722b95d67c345f1c00976ec372f02bfcbef0262cc512a6845e71cfea0d0201"
+ + "03a381fc3081f9301d0603551d0e0416041478a0fc4517fb70ff52210df33c8d32290a44b2bb3081c90"
+ + "603551d230481c13081be801478a0fc4517fb70ff52210df33c8d32290a44b2bba1819aa48197308194"
+ + "310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550"
+ + "407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355"
+ + "040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0"
+ + "109011613616e64726f696440616e64726f69642e636f6d820900a1573d0f45bea193300c0603551d13"
+ + "040530030101ff300d06092a864886f70d01010505000382010100977302dfbf668d7c61841c9c78d25"
+ + "63bcda1b199e95e6275a799939981416909722713531157f3cdcfea94eea7bb79ca3ca972bd8058a36a"
+ + "d1919291df42d7190678d4ea47a4b9552c9dfb260e6d0d9129b44615cd641c1080580e8a990dd768c6a"
+ + "b500c3b964e185874e4105109d94c5bd8c405deb3cf0f7960a563bfab58169a956372167a7e2674a04c"
+ + "4f80015d8f7869a7a4139aecbbdca2abc294144ee01e4109f0e47a518363cf6e9bf41f7560e94bdd4a5"
+ + "d085234796b05c7a1389adfd489feec2a107955129d7991daa49afb3d327dc0dc4fe959789372b093a8"
+ + "9c8dbfa41554f771c18015a6cb242a17e04d19d55d3b4664eae12caf2a11cd2b836e");
+
+ /**
+ * Typical list of permissions referenced in {@code packages.xml}.
+ */
+ private static final String[] PERMS = new String[] {
+ "android.permission.ACCESS_CACHE_FILESYSTEM",
+ "android.permission.WRITE_SETTINGS",
+ "android.permission.MANAGE_EXTERNAL_STORAGE",
+ "android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS",
+ "android.permission.FOREGROUND_SERVICE",
+ "android.permission.RECEIVE_BOOT_COMPLETED",
+ "android.permission.WRITE_MEDIA_STORAGE",
+ "android.permission.INTERNET",
+ "android.permission.UPDATE_DEVICE_STATS",
+ "android.permission.RECEIVE_DEVICE_CUSTOMIZATION_READY",
+ "android.permission.MANAGE_USB",
+ "android.permission.ACCESS_ALL_DOWNLOADS",
+ "android.permission.ACCESS_DOWNLOAD_MANAGER",
+ "android.permission.MANAGE_USERS",
+ "android.permission.ACCESS_NETWORK_STATE",
+ "android.permission.ACCESS_MTP",
+ "android.permission.INTERACT_ACROSS_USERS",
+ "android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS",
+ "android.permission.CLEAR_APP_CACHE",
+ "android.permission.CONNECTIVITY_INTERNAL",
+ "android.permission.START_ACTIVITIES_FROM_BACKGROUND",
+ "android.permission.QUERY_ALL_PACKAGES",
+ "android.permission.WAKE_LOCK",
+ "android.permission.UPDATE_APP_OPS_STATS",
+ };
+
+ /**
+ * Write a typical {@code packages.xml} file containing 100 applications,
+ * each of which defines signing key and permission information.
+ */
+ private static void write(TypedXmlSerializer out) throws IOException {
+ out.startDocument(null, true);
+ out.startTag(null, "packages");
+ for (int i = 0; i < 100; i++) {
+ out.startTag(null, "package");
+ out.attribute(null, "name", "com.android.providers.media");
+ out.attribute(null, "codePath", "/system/priv-app/MediaProviderLegacy");
+ out.attribute(null, "nativeLibraryPath", "/system/priv-app/MediaProviderLegacy/lib");
+ out.attributeLong(null, "publicFlags", 944258629L);
+ out.attributeLong(null, "privateFlags", -1946152952L);
+ out.attributeLong(null, "ft", 1603899064000L);
+ out.attributeLong(null, "it", 1603899064000L);
+ out.attributeLong(null, "ut", 1603899064000L);
+ out.attributeInt(null, "version", 1024);
+ out.attributeInt(null, "sharedUserId", 10100);
+ out.attributeBoolean(null, "isOrphaned", true);
+
+ out.startTag(null, "sigs");
+ out.startTag(null, "cert");
+ out.attributeInt(null, "index", 10);
+ out.attributeBytesHex(null, "key", KEY_BLOB);
+ out.endTag(null, "cert");
+ out.endTag(null, "sigs");
+
+ out.startTag(null, "perms");
+ for (String perm : PERMS) {
+ out.startTag(null, "item");
+ out.attributeInterned(null, "name", perm);
+ out.attributeBoolean(null, "granted", true);
+ out.attributeInt(null, "flags", 0);
+ out.endTag(null, "item");
+ }
+ out.endTag(null, "perms");
+
+ out.endTag(null, "package");
+ }
+ out.endTag(null, "packages");
+ out.endDocument();
+ }
+
+ /**
+ * Read a typical {@code packages.xml} file containing 100 applications, and
+ * verify that data passes smell test.
+ */
+ private static void read(TypedXmlPullParser xml) throws Exception {
+ int type;
+ int packages = 0;
+ int certs = 0;
+ int perms = 0;
+ while ((type = xml.next()) != XmlPullParser.END_DOCUMENT) {
+ final String tag = xml.getName();
+ if (type == XmlPullParser.START_TAG) {
+ if ("package".equals(tag)) {
+ xml.getAttributeValue(null, "name");
+ xml.getAttributeValue(null, "codePath");
+ xml.getAttributeValue(null, "nativeLibraryPath");
+ xml.getAttributeLong(null, "publicFlags");
+ assertEquals(-1946152952L, xml.getAttributeLong(null, "privateFlags"));
+ xml.getAttributeLong(null, "ft");
+ xml.getAttributeLong(null, "it");
+ xml.getAttributeLong(null, "ut");
+ xml.getAttributeInt(null, "version");
+ xml.getAttributeInt(null, "sharedUserId");
+ xml.getAttributeBoolean(null, "isOrphaned");
+ packages++;
+ } else if ("cert".equals(tag)) {
+ xml.getAttributeInt(null, "index");
+ xml.getAttributeBytesHex(null, "key");
+ certs++;
+ } else if ("item".equals(tag)) {
+ xml.getAttributeValue(null, "name");
+ xml.getAttributeBoolean(null, "granted");
+ xml.getAttributeInt(null, "flags");
+ perms++;
+ }
+ } else if (type == XmlPullParser.TEXT) {
+ xml.getText();
+ }
+ }
+
+ assertEquals(100, packages);
+ assertEquals(packages * 1, certs);
+ assertEquals(packages * PERMS.length, perms);
+ }
+}
diff --git a/apct-tests/perftests/core/src/com/android/internal/util/FastDataPerfTest.java b/apct-tests/perftests/core/src/com/android/internal/util/FastDataPerfTest.java
new file mode 100644
index 0000000..2700fff
--- /dev/null
+++ b/apct-tests/perftests/core/src/com/android/internal/util/FastDataPerfTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2020 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.internal.util;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class FastDataPerfTest {
+ @Rule
+ public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ private static final int OUTPUT_SIZE = 64000;
+ private static final int BUFFER_SIZE = 4096;
+
+ @Test
+ public void timeWrite_Upstream() throws IOException {
+ final ByteArrayOutputStream os = new ByteArrayOutputStream(OUTPUT_SIZE);
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ os.reset();
+ final BufferedOutputStream bos = new BufferedOutputStream(os, BUFFER_SIZE);
+ final DataOutput out = new DataOutputStream(bos);
+ doWrite(out);
+ bos.flush();
+ }
+ }
+
+ @Test
+ public void timeWrite_Local() throws IOException {
+ final ByteArrayOutputStream os = new ByteArrayOutputStream(OUTPUT_SIZE);
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ os.reset();
+ final FastDataOutput out = new FastDataOutput(os, BUFFER_SIZE);
+ doWrite(out);
+ out.flush();
+ }
+ }
+
+ @Test
+ public void timeRead_Upstream() throws Exception {
+ final ByteArrayInputStream is = new ByteArrayInputStream(doWrite());
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ is.reset();
+ final BufferedInputStream bis = new BufferedInputStream(is, BUFFER_SIZE);
+ final DataInput in = new DataInputStream(bis);
+ doRead(in);
+ }
+ }
+
+ @Test
+ public void timeRead_Local() throws Exception {
+ final ByteArrayInputStream is = new ByteArrayInputStream(doWrite());
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ is.reset();
+ final DataInput in = new FastDataInput(is, BUFFER_SIZE);
+ doRead(in);
+ }
+ }
+
+ /**
+ * Since each iteration is around 64 bytes, we need to iterate many times to
+ * exercise the buffer logic.
+ */
+ private static final int REPEATS = 1000;
+
+ private static byte[] doWrite() throws IOException {
+ final ByteArrayOutputStream os = new ByteArrayOutputStream(OUTPUT_SIZE);
+ final DataOutput out = new DataOutputStream(os);
+ doWrite(out);
+ return os.toByteArray();
+ }
+
+ private static void doWrite(DataOutput out) throws IOException {
+ for (int i = 0; i < REPEATS; i++) {
+ out.writeByte(Byte.MAX_VALUE);
+ out.writeShort(Short.MAX_VALUE);
+ out.writeInt(Integer.MAX_VALUE);
+ out.writeLong(Long.MAX_VALUE);
+ out.writeFloat(Float.MAX_VALUE);
+ out.writeDouble(Double.MAX_VALUE);
+ out.writeUTF("com.example.typical_package_name");
+ }
+ }
+
+ private static void doRead(DataInput in) throws IOException {
+ for (int i = 0; i < REPEATS; i++) {
+ in.readByte();
+ in.readShort();
+ in.readInt();
+ in.readLong();
+ in.readFloat();
+ in.readDouble();
+ in.readUTF();
+ }
+ }
+}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
index 1e72062..cc20213 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
@@ -20,10 +20,11 @@
import android.app.AppGlobals;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
-import android.os.BasicShellCommandHandler;
import android.os.Binder;
import android.os.UserHandle;
+import com.android.modules.utils.BasicShellCommandHandler;
+
import java.io.PrintWriter;
public final class JobSchedulerShellCommand extends BasicShellCommandHandler {
diff --git a/api/current.txt b/api/current.txt
index 344e93b..2ebb75d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -7403,6 +7403,12 @@
field public static final int ERROR_UNKNOWN = 1; // 0x1
}
+ public final class UnsafeStateException extends java.lang.IllegalStateException implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.UnsafeStateException> CREATOR;
+ }
+
}
package android.app.assist {
@@ -43126,10 +43132,11 @@
method public String getKeystoreAlias();
method public int getOrigin();
method public int getPurposes();
+ method public int getSecurityLevel();
method @NonNull public String[] getSignaturePaddings();
method public int getUserAuthenticationType();
method public int getUserAuthenticationValidityDurationSeconds();
- method public boolean isInsideSecureHardware();
+ method @Deprecated public boolean isInsideSecureHardware();
method public boolean isInvalidatedByBiometricEnrollment();
method public boolean isTrustedUserPresenceRequired();
method public boolean isUserAuthenticationRequired();
diff --git a/api/system-current.txt b/api/system-current.txt
index 6e16770..73602ae 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -802,12 +802,17 @@
method @RequiresPermission(android.Manifest.permission.ENTER_CAR_MODE_PRIORITIZED) public void enableCarMode(@IntRange(from=0) int, int);
method @RequiresPermission(android.Manifest.permission.READ_PROJECTION_STATE) public int getActiveProjectionTypes();
method @NonNull @RequiresPermission(android.Manifest.permission.READ_PROJECTION_STATE) public java.util.Set<java.lang.String> getProjectingPackages(int);
+ method @RequiresPermission(value=android.Manifest.permission.TOGGLE_AUTOMOTIVE_PROJECTION, conditional=true) public boolean releaseProjection(int);
method @RequiresPermission(android.Manifest.permission.READ_PROJECTION_STATE) public void removeOnProjectionStateChangeListener(@NonNull android.app.UiModeManager.OnProjectionStateChangeListener);
+ method @RequiresPermission(value=android.Manifest.permission.TOGGLE_AUTOMOTIVE_PROJECTION, conditional=true) public boolean requestProjection(int);
field public static final String ACTION_ENTER_CAR_MODE_PRIORITIZED = "android.app.action.ENTER_CAR_MODE_PRIORITIZED";
field public static final String ACTION_EXIT_CAR_MODE_PRIORITIZED = "android.app.action.EXIT_CAR_MODE_PRIORITIZED";
field public static final int DEFAULT_PRIORITY = 0; // 0x0
field public static final String EXTRA_CALLING_PACKAGE = "android.app.extra.CALLING_PACKAGE";
field public static final String EXTRA_PRIORITY = "android.app.extra.PRIORITY";
+ field public static final int PROJECTION_TYPE_ALL = 65535; // 0xffff
+ field public static final int PROJECTION_TYPE_AUTOMOTIVE = 1; // 0x1
+ field public static final int PROJECTION_TYPE_NONE = 0; // 0x0
}
public static interface UiModeManager.OnProjectionStateChangeListener {
@@ -4185,6 +4190,7 @@
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, @NonNull android.os.UserHandle);
method @Deprecated @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean setProviderEnabledForUser(@NonNull String, boolean, @NonNull android.os.UserHandle);
method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean unregisterGnssBatchedLocationCallback(@NonNull android.location.BatchedLocationCallback);
+ field public static final String FUSED_PROVIDER = "fused";
}
public final class LocationRequest implements android.os.Parcelable {
@@ -5086,6 +5092,7 @@
method public long getAvSyncTime(int);
method @Nullable public android.media.tv.tuner.DemuxCapabilities getDemuxCapabilities();
method @Nullable public android.media.tv.tuner.frontend.FrontendInfo getFrontendInfo();
+ method @Nullable public java.util.List<android.media.tv.tuner.frontend.FrontendInfo> getFrontendInfoList();
method @Nullable public android.media.tv.tuner.frontend.FrontendStatus getFrontendStatus(@NonNull int[]);
method public int linkFrontendToCiCam(int);
method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_TV_DESCRAMBLER) public android.media.tv.tuner.Descrambler openDescrambler();
@@ -5302,6 +5309,7 @@
public class Filter implements java.lang.AutoCloseable {
method public void close();
method public int configure(@NonNull android.media.tv.tuner.filter.FilterConfiguration);
+ method public int configureScramblingStatusEvent(int);
method public int flush();
method public int getId();
method public long getId64Bit();
@@ -5309,6 +5317,9 @@
method public int setDataSource(@Nullable android.media.tv.tuner.filter.Filter);
method public int start();
method public int stop();
+ field public static final int SCRAMBLING_STATUS_NOT_SCRAMBLED = 2; // 0x2
+ field public static final int SCRAMBLING_STATUS_SCRAMBLED = 4; // 0x4
+ field public static final int SCRAMBLING_STATUS_UNKNOWN = 1; // 0x1
field public static final int STATUS_DATA_READY = 1; // 0x1
field public static final int STATUS_HIGH_WATER = 4; // 0x4
field public static final int STATUS_LOW_WATER = 2; // 0x2
@@ -5409,7 +5420,7 @@
public class MmtpRecordEvent extends android.media.tv.tuner.filter.FilterEvent {
method public long getDataLength();
- method public int getFirstMbInSlice();
+ method public int getFirstMacroblockInSlice();
method public int getMpuSequenceNumber();
method public long getPts();
method public int getScHevcIndexMask();
@@ -5487,6 +5498,10 @@
method @NonNull public android.media.tv.tuner.filter.RecordSettings.Builder setTsIndexMask(int);
}
+ public final class ScramblingStatusEvent extends android.media.tv.tuner.filter.FilterEvent {
+ method public int getScramblingStatus();
+ }
+
public class SectionEvent extends android.media.tv.tuner.filter.FilterEvent {
method public int getDataLength();
method public int getSectionNumber();
@@ -5585,7 +5600,7 @@
public class TsRecordEvent extends android.media.tv.tuner.filter.FilterEvent {
method public long getDataLength();
- method public int getFirstMbInSlice();
+ method public int getFirstMacroblockInSlice();
method public int getPacketId();
method public long getPts();
method public int getScIndexMask();
@@ -9914,8 +9929,13 @@
ctor public DeviceIdAttestationException(@Nullable String, @Nullable Throwable);
}
+ public final class KeyGenParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+ method public int getNamespace();
+ }
+
public static final class KeyGenParameterSpec.Builder {
- method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUid(int);
+ method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setNamespace(int);
+ method @Deprecated @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUid(int);
}
}
@@ -11197,6 +11217,17 @@
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallQuality> CREATOR;
}
+ public final class CarrierBandwidth implements android.os.Parcelable {
+ ctor public CarrierBandwidth(int, int, int, int);
+ method public int describeContents();
+ method public int getPrimaryDownlinkCapacityKbps();
+ method public int getPrimaryUplinkCapacityKbps();
+ method public int getSecondaryDownlinkCapacityKbps();
+ method public int getSecondaryUplinkCapacityKbps();
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CarrierBandwidth> CREATOR;
+ field public static final int INVALID = -1; // 0xffffffff
+ }
+
public class CarrierConfigManager {
method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDefaultCarrierServicePackageName();
method @NonNull public static android.os.PersistableBundle getDefaultConfig();
@@ -11494,6 +11525,18 @@
field public static final int PHYSICAL_CELL_ID_UNKNOWN = -1; // 0xffffffff
}
+ public final class PinResult implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getAttemptsRemaining();
+ method public int getResult();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PinResult> CREATOR;
+ field public static final int PIN_RESULT_TYPE_ABORTED = 3; // 0x3
+ field public static final int PIN_RESULT_TYPE_FAILURE = 2; // 0x2
+ field public static final int PIN_RESULT_TYPE_INCORRECT = 1; // 0x1
+ field public static final int PIN_RESULT_TYPE_SUCCESS = 0; // 0x0
+ }
+
public final class PreciseCallState implements android.os.Parcelable {
ctor public PreciseCallState(int, int, int, int, int);
method public int describeContents();
@@ -11837,6 +11880,7 @@
public class TelephonyManager {
method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void call(String, String);
+ method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult changeIccLockPin(@NonNull String, @NonNull String);
method public int checkCarrierPrivilegesForPackage(String);
method public int checkCarrierPrivilegesForPackageAnyPhone(String);
method public void dial(String);
@@ -11850,6 +11894,7 @@
method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getAndUpdateDefaultRespondViaMessageApplication();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getCallForwarding(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CallForwardingInfoCallback);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getCallWaitingStatus(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+ method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CarrierBandwidth getCarrierBandwidth();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
@@ -11941,6 +11986,7 @@
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int);
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(int, boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataRoamingEnabled(boolean);
+ method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult setIccLockEnabled(boolean, @NonNull String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMobileDataPolicyEnabledStatus(int, boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean);
method public int setNrDualConnectivityState(int);
@@ -11956,10 +12002,12 @@
method @Deprecated public void setVisualVoicemailEnabled(android.telecom.PhoneAccountHandle, boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoiceActivationState(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void shutdownAllRadios();
+ method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult supplyIccLockPin(@NonNull String);
+ method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult supplyIccLockPuk(@NonNull String, @NonNull String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPin(String);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPinReportResult(String);
+ method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPinReportResult(String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPuk(String, String);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPukReportResult(String, String);
+ method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPukReportResult(String, String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean switchSlots(int[]);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void toggleRadioOnOff();
method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void updateOtaEmergencyNumberDbFilePath(@NonNull android.os.ParcelFileDescriptor);
diff --git a/cmds/abx/Android.bp b/cmds/abx/Android.bp
new file mode 100644
index 0000000..333aced
--- /dev/null
+++ b/cmds/abx/Android.bp
@@ -0,0 +1,20 @@
+
+java_binary {
+ name: "abx",
+ wrapper: "abx",
+ srcs: ["**/*.java"],
+ required: [
+ "abx2xml",
+ "xml2abx",
+ ],
+}
+
+sh_binary {
+ name: "abx2xml",
+ src: "abx2xml",
+}
+
+sh_binary {
+ name: "xml2abx",
+ src: "xml2abx",
+}
diff --git a/cmds/abx/MODULE_LICENSE_APACHE2 b/cmds/abx/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmds/abx/MODULE_LICENSE_APACHE2
diff --git a/cmds/abx/NOTICE b/cmds/abx/NOTICE
new file mode 100644
index 0000000..50e9e9b
--- /dev/null
+++ b/cmds/abx/NOTICE
@@ -0,0 +1,189 @@
+
+ Copyright (c) 2005-2020, 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.
+
+ 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.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/cmds/abx/abx b/cmds/abx/abx
new file mode 100755
index 0000000..0a9362d
--- /dev/null
+++ b/cmds/abx/abx
@@ -0,0 +1,3 @@
+#!/system/bin/sh
+export CLASSPATH=/system/framework/abx.jar
+exec app_process /system/bin com.android.commands.abx.Abx "$0" "$@"
diff --git a/cmds/abx/abx2xml b/cmds/abx/abx2xml
new file mode 100755
index 0000000..0a9362d
--- /dev/null
+++ b/cmds/abx/abx2xml
@@ -0,0 +1,3 @@
+#!/system/bin/sh
+export CLASSPATH=/system/framework/abx.jar
+exec app_process /system/bin com.android.commands.abx.Abx "$0" "$@"
diff --git a/cmds/abx/src/com/android/commands/abx/Abx.java b/cmds/abx/src/com/android/commands/abx/Abx.java
new file mode 100644
index 0000000..8f1a4cf
--- /dev/null
+++ b/cmds/abx/src/com/android/commands/abx/Abx.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2020 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.commands.abx;
+
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * Utility that offers to convert between human-readable XML and a custom binary
+ * XML protocol.
+ *
+ * @see Xml#newSerializer()
+ * @see Xml#newBinarySerializer()
+ */
+public class Abx {
+ private static final String USAGE = "" +
+ "usage: abx2xml [-i] input [output]\n" +
+ "usage: xml2abx [-i] input [output]\n\n" +
+ "Converts between human-readable XML and Android Binary XML.\n\n" +
+ "When invoked with the '-i' argument, the output of a successful conversion\n" +
+ "will overwrite the original input file. Input can be '-' to use stdin, and\n" +
+ "output can be '-' to use stdout.\n";
+
+ private static InputStream openInput(String arg) throws IOException {
+ if ("-".equals(arg)) {
+ return System.in;
+ } else {
+ return new FileInputStream(arg);
+ }
+ }
+
+ private static OutputStream openOutput(String arg) throws IOException {
+ if ("-".equals(arg)) {
+ return System.out;
+ } else {
+ return new FileOutputStream(arg);
+ }
+ }
+
+ private static void mainInternal(String[] args) {
+ if (args.length < 2) {
+ throw new IllegalArgumentException("Missing arguments");
+ }
+
+ final XmlPullParser in;
+ final XmlSerializer out;
+ if (args[0].endsWith("abx2xml")) {
+ in = Xml.newBinaryPullParser();
+ out = Xml.newSerializer();
+ } else if (args[0].endsWith("xml2abx")) {
+ in = Xml.newPullParser();
+ out = Xml.newBinarySerializer();
+ } else {
+ throw new IllegalArgumentException("Unsupported conversion");
+ }
+
+ final boolean inPlace = "-i".equals(args[1]);
+ final String inputArg = inPlace ? args[2] : args[1];
+ final String outputArg = inPlace ? args[2] + ".tmp" : args[2];
+
+ try (InputStream is = openInput(inputArg);
+ OutputStream os = openOutput(outputArg)) {
+ in.setInput(is, StandardCharsets.UTF_8.name());
+ out.setOutput(os, StandardCharsets.UTF_8.name());
+ out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+ Xml.copy(in, out);
+ out.flush();
+ } catch (Exception e) {
+ // Clean up failed output before throwing
+ if (inPlace) {
+ new File(outputArg).delete();
+ }
+ throw new IllegalStateException(e);
+ }
+
+ // Successful in-place conversion of a file requires a rename
+ if (inPlace) {
+ if (!new File(outputArg).renameTo(new File(inputArg))) {
+ throw new IllegalStateException("Failed rename");
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ try {
+ mainInternal(args);
+ System.exit(0);
+ } catch (Exception e) {
+ System.err.println(e.toString());
+ System.err.println();
+ System.err.println(USAGE);
+ System.exit(1);
+ }
+ }
+}
diff --git a/cmds/abx/xml2abx b/cmds/abx/xml2abx
new file mode 100755
index 0000000..0a9362d
--- /dev/null
+++ b/cmds/abx/xml2abx
@@ -0,0 +1,3 @@
+#!/system/bin/sh
+export CLASSPATH=/system/framework/abx.jar
+exec app_process /system/bin com.android.commands.abx.Abx "$0" "$@"
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 012450d..d225f966 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -294,6 +294,7 @@
"tests/e2e/Anomaly_duration_sum_e2e_test.cpp",
"tests/e2e/Attribution_e2e_test.cpp",
"tests/e2e/ConfigTtl_e2e_test.cpp",
+ "tests/e2e/ConfigUpdate_e2e_test.cpp",
"tests/e2e/CountMetric_e2e_test.cpp",
"tests/e2e/DurationMetric_e2e_test.cpp",
"tests/e2e/GaugeMetric_e2e_pull_test.cpp",
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 7bee4e2..ae1ef21 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -520,10 +520,10 @@
}
void StatsLogProcessor::OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
- const StatsdConfig& config) {
+ const StatsdConfig& config, bool modularUpdate) {
std::lock_guard<std::mutex> lock(mMetricsMutex);
WriteDataToDiskLocked(key, timestampNs, CONFIG_UPDATED, NO_TIME_CONSTRAINTS);
- OnConfigUpdatedLocked(timestampNs, key, config);
+ OnConfigUpdatedLocked(timestampNs, key, config, modularUpdate);
}
void StatsLogProcessor::OnConfigUpdatedLocked(const int64_t timestampNs, const ConfigKey& key,
@@ -720,7 +720,8 @@
for (const auto& key : configs) {
StatsdConfig config;
if (StorageManager::readConfigFromDisk(key, &config)) {
- OnConfigUpdatedLocked(timestampNs, key, config);
+ // Force a full update when resetting a config.
+ OnConfigUpdatedLocked(timestampNs, key, config, /*modularUpdate=*/false);
StatsdStats::getInstance().noteConfigReset(key);
} else {
ALOGE("Failed to read backup config from disk for : %s", key.ToString().c_str());
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index 383dbd9..2af277a 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -48,7 +48,7 @@
void OnLogEvent(LogEvent* event);
void OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
- const StatsdConfig& config);
+ const StatsdConfig& config, bool modularUpdate = false);
void OnConfigRemoved(const ConfigKey& key);
size_t GetMetricsSize(const ConfigKey& key) const;
@@ -188,7 +188,7 @@
void resetIfConfigTtlExpiredLocked(const int64_t timestampNs);
void OnConfigUpdatedLocked(const int64_t currentTimestampNs, const ConfigKey& key,
- const StatsdConfig& config, bool modularUpdate = false);
+ const StatsdConfig& config, bool modularUpdate);
void GetActiveConfigsLocked(const int uid, vector<int64_t>& outActiveConfigs);
@@ -338,6 +338,10 @@
FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation);
FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
+ FRIEND_TEST(ConfigUpdateE2eTest, TestHashStrings);
+ FRIEND_TEST(ConfigUpdateE2eTest, TestUidMapVersionStringInstaller);
+ FRIEND_TEST(ConfigUpdateE2eTest, TestConfigTtl);
+
FRIEND_TEST(CountMetricE2eTest, TestInitialConditionChanges);
FRIEND_TEST(CountMetricE2eTest, TestSlicedState);
FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithMap);
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index b270a52..4a7a2b7 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -158,7 +158,7 @@
AppStartMemoryStateCaptured app_start_memory_state_captured = 55 [(module) = "framework"];
ShutdownSequenceReported shutdown_sequence_reported = 56 [(module) = "framework"];
BootSequenceReported boot_sequence_reported = 57;
- DaveyOccurred davey_occurred = 58 [(module) = "statsd"];
+ DaveyOccurred davey_occurred = 58 [(module) = "statsd", deprecated = true];
OverlayStateChanged overlay_state_changed =
59 [(module) = "framework", (module) = "statsdtest"];
ForegroundServiceStateChanged foreground_service_state_changed
@@ -3609,6 +3609,8 @@
optional ForegroundState foreground_state = 7;
optional android.server.ErrorSource error_source = 8;
+
+ optional bool is_package_loading = 9;
}
/**
@@ -3670,6 +3672,8 @@
optional android.server.ErrorSource error_source = 7;
optional string package_name = 8;
+
+ optional bool is_package_loading = 9;
}
/**
diff --git a/cmds/statsd/src/config/ConfigListener.h b/cmds/statsd/src/config/ConfigListener.h
index dcd5e52..3d30137 100644
--- a/cmds/statsd/src/config/ConfigListener.h
+++ b/cmds/statsd/src/config/ConfigListener.h
@@ -39,7 +39,7 @@
* A configuration was added or updated.
*/
virtual void OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
- const StatsdConfig& config) = 0;
+ const StatsdConfig& config, bool modularUpdate = false) = 0;
/**
* A configuration was removed.
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index acc12aa..3b6e10b 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -188,6 +188,23 @@
mAlertTrackerMap = newAlertTrackerMap;
mAllPeriodicAlarmTrackers = newPeriodicAlarmTrackers;
+ mTtlNs = config.has_ttl_in_seconds() ? config.ttl_in_seconds() * NS_PER_SEC : -1;
+ refreshTtl(currentTimeNs);
+
+ mHashStringsInReport = config.hash_strings_in_metric_report();
+ mVersionStringsInReport = config.version_strings_in_metric_report();
+ mInstallerInReport = config.installer_in_metric_report();
+ mWhitelistedAtomIds.clear();
+ mWhitelistedAtomIds.insert(config.whitelisted_atom_ids().begin(),
+ config.whitelisted_atom_ids().end());
+ mShouldPersistHistory = config.persist_locally();
+
+ // Store the sub-configs used.
+ mAnnotations.clear();
+ for (const auto& annotation : config.annotation()) {
+ mAnnotations.emplace_back(annotation.field_int64(), annotation.field_int32());
+ }
+
mAllowedUid.clear();
mAllowedPkg.clear();
mDefaultPullUids.clear();
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index 23048ae..98d4bff 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -172,7 +172,7 @@
bool mVersionStringsInReport = false;
bool mInstallerInReport = false;
- const int64_t mTtlNs;
+ int64_t mTtlNs;
int64_t mTtlEndNs;
int64_t mLastReportTimeNs;
@@ -193,7 +193,7 @@
// To guard access to mAllowedLogSources
mutable std::mutex mAllowedLogSourcesMutex;
- const std::set<int32_t> mWhitelistedAtomIds;
+ std::set<int32_t> mWhitelistedAtomIds;
// We can pull any atom from these uids.
std::set<int32_t> mDefaultPullUids;
@@ -211,8 +211,7 @@
// Contains the annotations passed in with StatsdConfig.
std::list<std::pair<const int64_t, const int32_t>> mAnnotations;
- const bool mShouldPersistHistory;
-
+ bool mShouldPersistHistory;
// All event tags that are interesting to my metrics.
std::set<int> mTagIds;
@@ -327,6 +326,7 @@
FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
+ FRIEND_TEST(ConfigUpdateE2eTest, TestConfigTtl);
FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
diff --git a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp
index 6372361..af9606b 100644
--- a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp
+++ b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp
@@ -869,6 +869,14 @@
newMetricProducers.push_back(producer.value());
}
+ for (int i = 0; i < config.no_report_metric_size(); ++i) {
+ const int64_t noReportMetric = config.no_report_metric(i);
+ if (newMetricProducerMap.find(noReportMetric) == newMetricProducerMap.end()) {
+ ALOGW("no_report_metric %" PRId64 " not exist", noReportMetric);
+ return false;
+ }
+ noReportMetricIds.insert(noReportMetric);
+ }
const set<int> atomsAllowedFromAnyUid(config.whitelisted_atom_ids().begin(),
config.whitelisted_atom_ids().end());
for (int i = 0; i < allMetricsCount; i++) {
diff --git a/cmds/statsd/tests/ConfigManager_test.cpp b/cmds/statsd/tests/ConfigManager_test.cpp
index 9455304..1d83716 100644
--- a/cmds/statsd/tests/ConfigManager_test.cpp
+++ b/cmds/statsd/tests/ConfigManager_test.cpp
@@ -44,8 +44,8 @@
*/
class MockListener : public ConfigListener {
public:
- MOCK_METHOD3(OnConfigUpdated, void(const int64_t timestampNs, const ConfigKey& key,
- const StatsdConfig& config));
+ MOCK_METHOD4(OnConfigUpdated, void(const int64_t timestampNs, const ConfigKey& key,
+ const StatsdConfig& config, bool modularUpdate));
MOCK_METHOD1(OnConfigRemoved, void(const ConfigKey& key));
};
@@ -89,26 +89,26 @@
manager->StartupForTest();
// Add another one
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(1, StringToId("zzz")),
- StatsdConfigEq(91)))
+ EXPECT_CALL(*(listener.get()),
+ OnConfigUpdated(_, ConfigKeyEq(1, StringToId("zzz")), StatsdConfigEq(91), _))
.RetiresOnSaturation();
manager->UpdateConfig(ConfigKey(1, StringToId("zzz")), config91);
// Update It
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(1, StringToId("zzz")),
- StatsdConfigEq(92)))
+ EXPECT_CALL(*(listener.get()),
+ OnConfigUpdated(_, ConfigKeyEq(1, StringToId("zzz")), StatsdConfigEq(92), _))
.RetiresOnSaturation();
manager->UpdateConfig(ConfigKey(1, StringToId("zzz")), config92);
// Add one with the same uid but a different name
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(1, StringToId("yyy")),
- StatsdConfigEq(93)))
+ EXPECT_CALL(*(listener.get()),
+ OnConfigUpdated(_, ConfigKeyEq(1, StringToId("yyy")), StatsdConfigEq(93), _))
.RetiresOnSaturation();
manager->UpdateConfig(ConfigKey(1, StringToId("yyy")), config93);
// Add one with the same name but a different uid
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(2, StringToId("zzz")),
- StatsdConfigEq(94)))
+ EXPECT_CALL(*(listener.get()),
+ OnConfigUpdated(_, ConfigKeyEq(2, StringToId("zzz")), StatsdConfigEq(94), _))
.RetiresOnSaturation();
manager->UpdateConfig(ConfigKey(2, StringToId("zzz")), config94);
@@ -143,7 +143,7 @@
StatsdConfig config;
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, _, _)).Times(5);
+ EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, _, _, _)).Times(5);
EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("xxx"))));
EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("yyy"))));
EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("zzz"))));
diff --git a/cmds/statsd/tests/e2e/ConfigUpdate_e2e_test.cpp b/cmds/statsd/tests/e2e/ConfigUpdate_e2e_test.cpp
new file mode 100644
index 0000000..e01a0b6
--- /dev/null
+++ b/cmds/statsd/tests/e2e/ConfigUpdate_e2e_test.cpp
@@ -0,0 +1,307 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <gtest/gtest.h>
+
+#include <thread> // std::this_thread::sleep_for
+
+#include "android-base/stringprintf.h"
+#include "src/StatsLogProcessor.h"
+#include "src/storage/StorageManager.h"
+#include "tests/statsd_test_util.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+#ifdef __ANDROID__
+#define STATS_DATA_DIR "/data/misc/stats-data"
+using android::base::StringPrintf;
+
+namespace {
+
+StatsdConfig CreateSimpleConfig() {
+ StatsdConfig config;
+ config.add_allowed_log_source("AID_STATSD");
+ config.set_hash_strings_in_metric_report(false);
+
+ *config.add_atom_matcher() = CreateBatteryStateUsbMatcher();
+ // Simple count metric so the config isn't empty.
+ CountMetric* countMetric1 = config.add_count_metric();
+ countMetric1->set_id(StringToId("Count1"));
+ countMetric1->set_what(config.atom_matcher(0).id());
+ countMetric1->set_bucket(FIVE_MINUTES);
+ return config;
+}
+} // namespace
+
+// Setup for parameterized tests.
+class ConfigUpdateE2eTest : public TestWithParam<bool> {};
+
+INSTANTIATE_TEST_SUITE_P(ConfigUpdateE2eTest, ConfigUpdateE2eTest, testing::Bool());
+
+TEST_P(ConfigUpdateE2eTest, TestUidMapVersionStringInstaller) {
+ sp<UidMap> uidMap = new UidMap();
+ vector<int32_t> uids({1000});
+ vector<int64_t> versions({1});
+ vector<String16> apps({String16("app1")});
+ vector<String16> versionStrings({String16("v1")});
+ vector<String16> installers({String16("installer1")});
+ uidMap->updateMap(1, uids, versions, versionStrings, apps, installers);
+
+ StatsdConfig config = CreateSimpleConfig();
+ config.set_version_strings_in_metric_report(true);
+ config.set_installer_in_metric_report(false);
+ int64_t baseTimeNs = getElapsedRealtimeNs();
+
+ ConfigKey cfgKey(0, 12345);
+ sp<StatsLogProcessor> processor =
+ CreateStatsLogProcessor(baseTimeNs, baseTimeNs, config, cfgKey, nullptr, 0, uidMap);
+ EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+ sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
+ EXPECT_TRUE(metricsManager->isConfigValid());
+
+ // Now update.
+ config.set_version_strings_in_metric_report(false);
+ config.set_installer_in_metric_report(true);
+ processor->OnConfigUpdated(baseTimeNs + 1000, cfgKey, config, /*modularUpdate=*/GetParam());
+ EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+ EXPECT_EQ(metricsManager == processor->mMetricsManagers.begin()->second, GetParam());
+ EXPECT_TRUE(metricsManager->isConfigValid());
+
+ ConfigMetricsReportList reports;
+ vector<uint8_t> buffer;
+ processor->onDumpReport(cfgKey, baseTimeNs + 1001, false, true, ADB_DUMP, FAST, &buffer);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+ // First report is written to disk when the update happens.
+ ASSERT_EQ(reports.reports_size(), 2);
+ UidMapping uidMapping = reports.reports(1).uid_map();
+ ASSERT_EQ(uidMapping.snapshots_size(), 1);
+ ASSERT_EQ(uidMapping.snapshots(0).package_info_size(), 1);
+ EXPECT_FALSE(uidMapping.snapshots(0).package_info(0).has_version_string());
+ EXPECT_EQ(uidMapping.snapshots(0).package_info(0).installer(), "installer1");
+}
+
+TEST_P(ConfigUpdateE2eTest, TestHashStrings) {
+ sp<UidMap> uidMap = new UidMap();
+ vector<int32_t> uids({1000});
+ vector<int64_t> versions({1});
+ vector<String16> apps({String16("app1")});
+ vector<String16> versionStrings({String16("v1")});
+ vector<String16> installers({String16("installer1")});
+ uidMap->updateMap(1, uids, versions, versionStrings, apps, installers);
+
+ StatsdConfig config = CreateSimpleConfig();
+ config.set_version_strings_in_metric_report(true);
+ config.set_hash_strings_in_metric_report(true);
+ int64_t baseTimeNs = getElapsedRealtimeNs();
+
+ ConfigKey cfgKey(0, 12345);
+ sp<StatsLogProcessor> processor =
+ CreateStatsLogProcessor(baseTimeNs, baseTimeNs, config, cfgKey, nullptr, 0, uidMap);
+ EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+ sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
+ EXPECT_TRUE(metricsManager->isConfigValid());
+
+ // Now update.
+ config.set_hash_strings_in_metric_report(false);
+ processor->OnConfigUpdated(baseTimeNs + 1000, cfgKey, config, /*modularUpdate=*/GetParam());
+ EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+ EXPECT_EQ(metricsManager == processor->mMetricsManagers.begin()->second, GetParam());
+ EXPECT_TRUE(metricsManager->isConfigValid());
+
+ ConfigMetricsReportList reports;
+ vector<uint8_t> buffer;
+ processor->onDumpReport(cfgKey, baseTimeNs + 1001, false, true, ADB_DUMP, FAST, &buffer);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+ // First report is written to disk when the update happens.
+ ASSERT_EQ(reports.reports_size(), 2);
+ UidMapping uidMapping = reports.reports(1).uid_map();
+ ASSERT_EQ(uidMapping.snapshots_size(), 1);
+ ASSERT_EQ(uidMapping.snapshots(0).package_info_size(), 1);
+ EXPECT_TRUE(uidMapping.snapshots(0).package_info(0).has_version_string());
+ EXPECT_FALSE(uidMapping.snapshots(0).package_info(0).has_version_string_hash());
+}
+
+TEST_P(ConfigUpdateE2eTest, TestAnnotations) {
+ StatsdConfig config = CreateSimpleConfig();
+ StatsdConfig_Annotation* annotation = config.add_annotation();
+ annotation->set_field_int64(11);
+ annotation->set_field_int32(1);
+ int64_t baseTimeNs = getElapsedRealtimeNs();
+ ConfigKey cfgKey(0, 12345);
+ sp<StatsLogProcessor> processor =
+ CreateStatsLogProcessor(baseTimeNs, baseTimeNs, config, cfgKey);
+
+ // Now update
+ config.clear_annotation();
+ annotation = config.add_annotation();
+ annotation->set_field_int64(22);
+ annotation->set_field_int32(2);
+ processor->OnConfigUpdated(baseTimeNs + 1000, cfgKey, config, /*modularUpdate=*/GetParam());
+
+ ConfigMetricsReportList reports;
+ vector<uint8_t> buffer;
+ processor->onDumpReport(cfgKey, baseTimeNs + 1001, false, true, ADB_DUMP, FAST, &buffer);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+ // First report is written to disk when the update happens.
+ ASSERT_EQ(reports.reports_size(), 2);
+ ConfigMetricsReport report = reports.reports(1);
+ EXPECT_EQ(report.annotation_size(), 1);
+ EXPECT_EQ(report.annotation(0).field_int64(), 22);
+ EXPECT_EQ(report.annotation(0).field_int32(), 2);
+}
+
+TEST_P(ConfigUpdateE2eTest, TestPersistLocally) {
+ StatsdConfig config = CreateSimpleConfig();
+ config.set_persist_locally(false);
+ int64_t baseTimeNs = getElapsedRealtimeNs();
+ ConfigKey cfgKey(0, 12345);
+ sp<StatsLogProcessor> processor =
+ CreateStatsLogProcessor(baseTimeNs, baseTimeNs, config, cfgKey);
+ ConfigMetricsReportList reports;
+ vector<uint8_t> buffer;
+ processor->onDumpReport(cfgKey, baseTimeNs + 1001, false, true, ADB_DUMP, FAST, &buffer);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+ ASSERT_EQ(reports.reports_size(), 1);
+ // Number of reports should still be 1 since persist_locally is false.
+ reports.Clear();
+ buffer.clear();
+ processor->onDumpReport(cfgKey, baseTimeNs + 1001, false, true, ADB_DUMP, FAST, &buffer);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+ ASSERT_EQ(reports.reports_size(), 1);
+
+ // Now update.
+ config.set_persist_locally(true);
+ processor->OnConfigUpdated(baseTimeNs + 1000, cfgKey, config, /*modularUpdate=*/GetParam());
+
+ // Should get 2: 1 in memory + 1 on disk. Both should be saved on disk.
+ reports.Clear();
+ buffer.clear();
+ processor->onDumpReport(cfgKey, baseTimeNs + 1001, false, true, ADB_DUMP, FAST, &buffer);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+ ASSERT_EQ(reports.reports_size(), 2);
+ // Should get 3, 2 on disk + 1 in memory.
+ reports.Clear();
+ buffer.clear();
+ processor->onDumpReport(cfgKey, baseTimeNs + 1001, false, true, ADB_DUMP, FAST, &buffer);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+ ASSERT_EQ(reports.reports_size(), 3);
+ string suffix = StringPrintf("%d_%lld", cfgKey.GetUid(), (long long)cfgKey.GetId());
+ StorageManager::deleteSuffixedFiles(STATS_DATA_DIR, suffix.c_str());
+ string historySuffix =
+ StringPrintf("%d_%lld_history", cfgKey.GetUid(), (long long)cfgKey.GetId());
+ StorageManager::deleteSuffixedFiles(STATS_DATA_DIR, historySuffix.c_str());
+}
+
+TEST_P(ConfigUpdateE2eTest, TestNoReportMetrics) {
+ StatsdConfig config = CreateSimpleConfig();
+ // Second simple count metric.
+ CountMetric* countMetric = config.add_count_metric();
+ countMetric->set_id(StringToId("Count2"));
+ countMetric->set_what(config.atom_matcher(0).id());
+ countMetric->set_bucket(FIVE_MINUTES);
+ config.add_no_report_metric(config.count_metric(0).id());
+ int64_t baseTimeNs = getElapsedRealtimeNs();
+ ConfigKey cfgKey(0, 12345);
+ sp<StatsLogProcessor> processor =
+ CreateStatsLogProcessor(baseTimeNs, baseTimeNs, config, cfgKey);
+
+ // Now update.
+ config.clear_no_report_metric();
+ config.add_no_report_metric(config.count_metric(1).id());
+ processor->OnConfigUpdated(baseTimeNs + 1000, cfgKey, config, /*modularUpdate=*/GetParam());
+
+ ConfigMetricsReportList reports;
+ vector<uint8_t> buffer;
+ processor->onDumpReport(cfgKey, baseTimeNs + 1001, false, true, ADB_DUMP, FAST, &buffer);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+ // First report is written to disk when the update happens.
+ ASSERT_EQ(reports.reports_size(), 2);
+ // First report (before update) has the first count metric.
+ ASSERT_EQ(reports.reports(0).metrics_size(), 1);
+ EXPECT_EQ(reports.reports(0).metrics(0).metric_id(), config.count_metric(1).id());
+ // Second report (after update) has the first count metric.
+ ASSERT_EQ(reports.reports(1).metrics_size(), 1);
+ EXPECT_EQ(reports.reports(1).metrics(0).metric_id(), config.count_metric(0).id());
+}
+
+TEST_P(ConfigUpdateE2eTest, TestAtomsAllowedFromAnyUid) {
+ StatsdConfig config = CreateSimpleConfig();
+ int64_t baseTimeNs = getElapsedRealtimeNs();
+ ConfigKey cfgKey(0, 12345);
+ sp<StatsLogProcessor> processor =
+ CreateStatsLogProcessor(baseTimeNs, baseTimeNs, config, cfgKey);
+ // Uses AID_ROOT, which isn't in allowed log sources.
+ unique_ptr<LogEvent> event = CreateBatteryStateChangedEvent(
+ baseTimeNs + 2, BatteryPluggedStateEnum::BATTERY_PLUGGED_USB);
+ processor->OnLogEvent(event.get());
+ ConfigMetricsReportList reports;
+ vector<uint8_t> buffer;
+ processor->onDumpReport(cfgKey, baseTimeNs + 1001, true, true, ADB_DUMP, FAST, &buffer);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+ ASSERT_EQ(reports.reports_size(), 1);
+ // Check the metric and make sure it has 0 count.
+ ASSERT_EQ(reports.reports(0).metrics_size(), 1);
+ EXPECT_FALSE(reports.reports(0).metrics(0).has_count_metrics());
+
+ // Now update. Allow plugged state to be logged from any uid, so the atom will be counted.
+ config.add_whitelisted_atom_ids(util::PLUGGED_STATE_CHANGED);
+ processor->OnConfigUpdated(baseTimeNs + 1000, cfgKey, config, /*modularUpdate=*/GetParam());
+ unique_ptr<LogEvent> event2 = CreateBatteryStateChangedEvent(
+ baseTimeNs + 2000, BatteryPluggedStateEnum::BATTERY_PLUGGED_USB);
+ processor->OnLogEvent(event.get());
+ reports.Clear();
+ buffer.clear();
+ processor->onDumpReport(cfgKey, baseTimeNs + 3000, true, true, ADB_DUMP, FAST, &buffer);
+ EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+ ASSERT_EQ(reports.reports_size(), 2);
+ // Check the metric and make sure it has 0 count.
+ ASSERT_EQ(reports.reports(1).metrics_size(), 1);
+ EXPECT_TRUE(reports.reports(1).metrics(0).has_count_metrics());
+ ASSERT_EQ(reports.reports(1).metrics(0).count_metrics().data_size(), 1);
+ ASSERT_EQ(reports.reports(1).metrics(0).count_metrics().data(0).bucket_info_size(), 1);
+ EXPECT_EQ(reports.reports(1).metrics(0).count_metrics().data(0).bucket_info(0).count(), 1);
+}
+
+TEST_P(ConfigUpdateE2eTest, TestConfigTtl) {
+ StatsdConfig config = CreateSimpleConfig();
+ config.set_ttl_in_seconds(1);
+ int64_t baseTimeNs = getElapsedRealtimeNs();
+ ConfigKey cfgKey(0, 12345);
+ sp<StatsLogProcessor> processor =
+ CreateStatsLogProcessor(baseTimeNs, baseTimeNs, config, cfgKey);
+ EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+ sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
+ EXPECT_EQ(metricsManager->getTtlEndNs(), baseTimeNs + NS_PER_SEC);
+
+ config.set_ttl_in_seconds(5);
+ processor->OnConfigUpdated(baseTimeNs + 2 * NS_PER_SEC, cfgKey, config,
+ /*modularUpdate=*/GetParam());
+ metricsManager = processor->mMetricsManagers.begin()->second;
+ EXPECT_EQ(metricsManager->getTtlEndNs(), baseTimeNs + 7 * NS_PER_SEC);
+
+ // Clear the data stored on disk as a result of the update.
+ vector<uint8_t> buffer;
+ processor->onDumpReport(cfgKey, baseTimeNs + 3 * NS_PER_SEC, false, true, ADB_DUMP, FAST,
+ &buffer);
+}
+
+#else
+GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
+
+} // namespace statsd
+} // namespace os
+} // namespace android
diff --git a/config/hiddenapi-temp-blocklist.txt b/config/hiddenapi-temp-blocklist.txt
new file mode 100644
index 0000000..246eeea
--- /dev/null
+++ b/config/hiddenapi-temp-blocklist.txt
@@ -0,0 +1,55 @@
+Landroid/app/IActivityManager$Stub$Proxy;->setActivityController(Landroid/app/IActivityController;Z)V
+Landroid/app/IActivityManager$Stub$Proxy;->updatePersistentConfiguration(Landroid/content/res/Configuration;)V
+Landroid/app/IActivityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IActivityManager;
+Landroid/app/IInstrumentationWatcher$Stub;-><init>()V
+Landroid/app/INotificationManager$Stub;->TRANSACTION_enqueueNotificationWithTag:I
+Landroid/bluetooth/IBluetooth$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
+Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_enable:I
+Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_enable:I
+Landroid/companion/ICompanionDeviceDiscoveryService$Stub;-><init>()V
+Landroid/content/om/IOverlayManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/om/IOverlayManager;
+Landroid/content/pm/IPackageManager$Stub;->TRANSACTION_getApplicationInfo:I
+Landroid/hardware/ICameraService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/ICameraService;
+Landroid/hardware/input/IInputManager$Stub;->TRANSACTION_injectInputEvent:I
+Landroid/hardware/location/IActivityRecognitionHardwareClient$Stub;-><init>()V
+Landroid/hardware/usb/IUsbManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/usb/IUsbManager;
+Landroid/location/ICountryDetector$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ICountryDetector;
+Landroid/location/IGeofenceProvider$Stub;-><init>()V
+Landroid/location/ILocationManager$Stub;->TRANSACTION_getAllProviders:I
+Landroid/Manifest$permission;->CAPTURE_SECURE_VIDEO_OUTPUT:Ljava/lang/String;
+Landroid/Manifest$permission;->CAPTURE_VIDEO_OUTPUT:Ljava/lang/String;
+Landroid/Manifest$permission;->READ_FRAME_BUFFER:Ljava/lang/String;
+Landroid/media/IVolumeController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IVolumeController;
+Landroid/net/INetworkPolicyListener$Stub;-><init>()V
+Landroid/net/nsd/INsdManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/nsd/INsdManager;
+Landroid/net/sip/ISipSession$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/sip/ISipSession;
+Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getScanResults:I
+Landroid/net/wifi/p2p/IWifiP2pManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/p2p/IWifiP2pManager;
+Landroid/nfc/INfcAdapter$Stub;->TRANSACTION_enable:I
+Landroid/os/IPowerManager$Stub;->TRANSACTION_acquireWakeLock:I
+Landroid/os/IPowerManager$Stub;->TRANSACTION_goToSleep:I
+Landroid/service/euicc/IEuiccService$Stub;-><init>()V
+Landroid/service/media/IMediaBrowserServiceCallbacks$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/media/IMediaBrowserServiceCallbacks;
+Landroid/telephony/mbms/IMbmsStreamingSessionCallback$Stub;-><init>()V
+Landroid/telephony/mbms/IStreamingServiceCallback$Stub;-><init>()V
+Landroid/telephony/mbms/vendor/IMbmsStreamingService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/telephony/mbms/vendor/IMbmsStreamingService;
+Lcom/android/ims/ImsConfigListener$Stub;-><init>()V
+Lcom/android/ims/internal/IImsCallSession$Stub;-><init>()V
+Lcom/android/ims/internal/IImsConfig$Stub;-><init>()V
+Lcom/android/ims/internal/IImsEcbm$Stub;-><init>()V
+Lcom/android/ims/internal/IImsService$Stub;-><init>()V
+Lcom/android/ims/internal/IImsService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/ims/internal/IImsService;
+Lcom/android/ims/internal/IImsUt$Stub;-><init>()V
+Lcom/android/ims/internal/IImsVideoCallProvider$Stub;-><init>()V
+Lcom/android/ims/internal/uce/options/IOptionsService$Stub;-><init>()V
+Lcom/android/ims/internal/uce/presence/IPresenceService$Stub;-><init>()V
+Lcom/android/ims/internal/uce/uceservice/IUceListener$Stub;-><init>()V
+Lcom/android/ims/internal/uce/uceservice/IUceService$Stub;-><init>()V
+Lcom/android/internal/app/IVoiceInteractionManagerService$Stub$Proxy;->showSessionFromSession(Landroid/os/IBinder;Landroid/os/Bundle;I)Z
+Lcom/android/internal/appwidget/IAppWidgetService$Stub;->TRANSACTION_bindAppWidgetId:I
+Lcom/android/internal/location/ILocationProvider$Stub;-><init>()V
+Lcom/android/internal/location/ILocationProviderManager$Stub;-><init>()V
+Lcom/android/internal/location/ILocationProviderManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/location/ILocationProviderManager;
+Lcom/android/internal/telephony/ITelephony$Stub;->DESCRIPTOR:Ljava/lang/String;
+Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_dial:I
+Lcom/android/internal/widget/IRemoteViewsFactory$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/widget/IRemoteViewsFactory;
diff --git a/config/hiddenapi-unsupported.txt b/config/hiddenapi-unsupported.txt
index a3543dc..8a377ac 100644
--- a/config/hiddenapi-unsupported.txt
+++ b/config/hiddenapi-unsupported.txt
@@ -26,19 +26,14 @@
Landroid/app/IActivityManager$Stub$Proxy;->getProcessLimit()I
Landroid/app/IActivityManager$Stub$Proxy;->getProcessPss([I)[J
Landroid/app/IActivityManager$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/app/IActivityManager$Stub$Proxy;->setActivityController(Landroid/app/IActivityController;Z)V
-Landroid/app/IActivityManager$Stub$Proxy;->updatePersistentConfiguration(Landroid/content/res/Configuration;)V
-Landroid/app/IActivityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IActivityManager;
Landroid/app/IAlarmManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/app/IAlarmManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IAlarmManager;
Landroid/app/IAlarmManager$Stub;->TRANSACTION_remove:I
Landroid/app/IAlarmManager$Stub;->TRANSACTION_set:I
Landroid/app/IAssistDataReceiver$Stub;-><init>()V
-Landroid/app/IInstrumentationWatcher$Stub;-><init>()V
Landroid/app/INotificationManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/app/INotificationManager$Stub$Proxy;->areNotificationsEnabledForPackage(Ljava/lang/String;I)Z
Landroid/app/INotificationManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/INotificationManager;
-Landroid/app/INotificationManager$Stub;->TRANSACTION_enqueueNotificationWithTag:I
Landroid/app/IProcessObserver$Stub;-><init>()V
Landroid/app/ISearchManager$Stub$Proxy;->getGlobalSearchActivity()Landroid/content/ComponentName;
Landroid/app/ISearchManager$Stub$Proxy;->getWebSearchActivity()Landroid/content/ComponentName;
@@ -68,9 +63,7 @@
Landroid/app/trust/ITrustManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/app/usage/IUsageStatsManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/usage/IUsageStatsManager;
Landroid/bluetooth/IBluetooth$Stub$Proxy;->getAddress()Ljava/lang/String;
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
Landroid/bluetooth/IBluetooth$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetooth;
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_enable:I
Landroid/bluetooth/IBluetoothA2dp$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothA2dp;
Landroid/bluetooth/IBluetoothCallback$Stub;-><init>()V
Landroid/bluetooth/IBluetoothGattCallback$Stub;-><init>()V
@@ -79,11 +72,9 @@
Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub;-><init>()V
Landroid/bluetooth/IBluetoothManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/bluetooth/IBluetoothManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothManager;
-Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_enable:I
Landroid/bluetooth/IBluetoothManagerCallback$Stub;-><init>()V
Landroid/bluetooth/IBluetoothPbap$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothPbap;
Landroid/bluetooth/IBluetoothStateChangeCallback$Stub;-><init>()V
-Landroid/companion/ICompanionDeviceDiscoveryService$Stub;-><init>()V
Landroid/content/IClipboard$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/content/IClipboard$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IClipboard;
Landroid/content/IContentService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
@@ -108,7 +99,6 @@
Landroid/content/ISyncStatusObserver$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/content/ISyncStatusObserver$Stub;-><init>()V
Landroid/content/ISyncStatusObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/ISyncStatusObserver;
-Landroid/content/om/IOverlayManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/om/IOverlayManager;
Landroid/content/pm/IPackageDataObserver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/content/pm/IPackageDataObserver$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/content/pm/IPackageDataObserver$Stub;-><init>()V
@@ -141,7 +131,6 @@
Landroid/content/pm/IPackageManager$Stub$Proxy;->getPackagesForUid(I)[Ljava/lang/String;
Landroid/content/pm/IPackageManager$Stub$Proxy;->getSystemSharedLibraryNames()[Ljava/lang/String;
Landroid/content/pm/IPackageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageManager;
-Landroid/content/pm/IPackageManager$Stub;->TRANSACTION_getApplicationInfo:I
Landroid/content/pm/IPackageMoveObserver$Stub;-><init>()V
Landroid/content/pm/IPackageMoveObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageMoveObserver;
Landroid/content/pm/IPackageStatsObserver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
@@ -155,30 +144,20 @@
Landroid/hardware/display/IDisplayManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/display/IDisplayManager;
Landroid/hardware/fingerprint/IFingerprintService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/hardware/fingerprint/IFingerprintService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/fingerprint/IFingerprintService;
-Landroid/hardware/ICameraService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/ICameraService;
Landroid/hardware/input/IInputManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/hardware/input/IInputManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/input/IInputManager;
-Landroid/hardware/input/IInputManager$Stub;->TRANSACTION_injectInputEvent:I
-Landroid/hardware/location/IActivityRecognitionHardwareClient$Stub;-><init>()V
Landroid/hardware/location/IContextHubService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/location/IContextHubService;
Landroid/hardware/usb/IUsbManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/hardware/usb/IUsbManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/usb/IUsbManager;
-Landroid/location/ICountryDetector$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ICountryDetector;
Landroid/location/ICountryListener$Stub;-><init>()V
Landroid/location/IGeocodeProvider$Stub;-><init>()V
Landroid/location/IGeocodeProvider$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/IGeocodeProvider;
-Landroid/location/IGeofenceProvider$Stub;-><init>()V
Landroid/location/ILocationListener$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/location/ILocationListener$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/location/ILocationListener$Stub;-><init>()V
Landroid/location/ILocationListener$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ILocationListener;
Landroid/location/ILocationManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/location/ILocationManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ILocationManager;
-Landroid/location/ILocationManager$Stub;->TRANSACTION_getAllProviders:I
Landroid/location/INetInitiatedListener$Stub;-><init>()V
-Landroid/Manifest$permission;->CAPTURE_SECURE_VIDEO_OUTPUT:Ljava/lang/String;
-Landroid/Manifest$permission;->CAPTURE_VIDEO_OUTPUT:Ljava/lang/String;
-Landroid/Manifest$permission;->READ_FRAME_BUFFER:Ljava/lang/String;
Landroid/media/IAudioRoutesObserver$Stub;-><init>()V
Landroid/media/IAudioService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/media/IAudioService$Stub;-><init>()V
@@ -186,7 +165,6 @@
Landroid/media/IMediaRouterService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IMediaRouterService;
Landroid/media/IMediaScannerListener$Stub;-><init>()V
Landroid/media/IMediaScannerService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IMediaScannerService;
-Landroid/media/IVolumeController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IVolumeController;
Landroid/media/session/ISessionManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/session/ISessionManager;
Landroid/media/tv/ITvRemoteProvider$Stub;-><init>()V
Landroid/net/IConnectivityManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
@@ -200,23 +178,17 @@
Landroid/net/IConnectivityManager$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/net/IConnectivityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/IConnectivityManager;
Landroid/net/INetworkManagementEventObserver$Stub;-><init>()V
-Landroid/net/INetworkPolicyListener$Stub;-><init>()V
Landroid/net/INetworkPolicyManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkPolicyManager;
Landroid/net/INetworkScoreService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkScoreService;
Landroid/net/INetworkStatsService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/net/INetworkStatsService$Stub$Proxy;->getMobileIfaces()[Ljava/lang/String;
Landroid/net/INetworkStatsService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkStatsService;
-Landroid/net/nsd/INsdManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/nsd/INsdManager;
-Landroid/net/sip/ISipSession$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/sip/ISipSession;
Landroid/net/wifi/IWifiManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/net/wifi/IWifiManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/IWifiManager;
-Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getScanResults:I
Landroid/net/wifi/IWifiScanner$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/net/wifi/IWifiScanner$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/net/wifi/IWifiScanner$Stub;-><init>()V
Landroid/net/wifi/IWifiScanner$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/IWifiScanner;
-Landroid/net/wifi/p2p/IWifiP2pManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/p2p/IWifiP2pManager;
-Landroid/nfc/INfcAdapter$Stub;->TRANSACTION_enable:I
Landroid/os/IBatteryPropertiesRegistrar$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/os/IDeviceIdentifiersPolicyService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IDeviceIdentifiersPolicyService;
Landroid/os/IDeviceIdleController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IDeviceIdleController;
@@ -227,8 +199,6 @@
Landroid/os/IPowerManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/os/IPowerManager$Stub$Proxy;->isLightDeviceIdleMode()Z
Landroid/os/IPowerManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPowerManager;
-Landroid/os/IPowerManager$Stub;->TRANSACTION_acquireWakeLock:I
-Landroid/os/IPowerManager$Stub;->TRANSACTION_goToSleep:I
Landroid/os/IRecoverySystem$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IRecoverySystem;
Landroid/os/IRemoteCallback$Stub;-><init>()V
Landroid/os/IUpdateEngine$Stub;-><init>()V
@@ -241,16 +211,11 @@
Landroid/security/IKeyChainService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/security/IKeyChainService;
Landroid/security/keystore/IKeystoreService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/security/keystore/IKeystoreService;
Landroid/service/dreams/IDreamManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/dreams/IDreamManager;
-Landroid/service/euicc/IEuiccService$Stub;-><init>()V
-Landroid/service/media/IMediaBrowserServiceCallbacks$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/media/IMediaBrowserServiceCallbacks;
Landroid/service/notification/INotificationListener$Stub;-><init>()V
Landroid/service/persistentdata/IPersistentDataBlockService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/persistentdata/IPersistentDataBlockService;
Landroid/service/vr/IVrManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/vr/IVrManager;
Landroid/service/wallpaper/IWallpaperConnection$Stub;-><init>()V
Landroid/service/wallpaper/IWallpaperService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/wallpaper/IWallpaperService;
-Landroid/telephony/mbms/IMbmsStreamingSessionCallback$Stub;-><init>()V
-Landroid/telephony/mbms/IStreamingServiceCallback$Stub;-><init>()V
-Landroid/telephony/mbms/vendor/IMbmsStreamingService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/telephony/mbms/vendor/IMbmsStreamingService;
Landroid/view/accessibility/IAccessibilityManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/view/accessibility/IAccessibilityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/accessibility/IAccessibilityManager;
Landroid/view/autofill/IAutoFillManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
@@ -274,19 +239,7 @@
Landroid/webkit/IWebViewUpdateService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/webkit/IWebViewUpdateService$Stub$Proxy;->waitForAndGetProvider()Landroid/webkit/WebViewProviderResponse;
Landroid/webkit/IWebViewUpdateService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/webkit/IWebViewUpdateService;
-Lcom/android/ims/ImsConfigListener$Stub;-><init>()V
-Lcom/android/ims/internal/IImsCallSession$Stub;-><init>()V
Lcom/android/ims/internal/IImsCallSession$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/ims/internal/IImsCallSession;
-Lcom/android/ims/internal/IImsConfig$Stub;-><init>()V
-Lcom/android/ims/internal/IImsEcbm$Stub;-><init>()V
-Lcom/android/ims/internal/IImsService$Stub;-><init>()V
-Lcom/android/ims/internal/IImsService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/ims/internal/IImsService;
-Lcom/android/ims/internal/IImsUt$Stub;-><init>()V
-Lcom/android/ims/internal/IImsVideoCallProvider$Stub;-><init>()V
-Lcom/android/ims/internal/uce/options/IOptionsService$Stub;-><init>()V
-Lcom/android/ims/internal/uce/presence/IPresenceService$Stub;-><init>()V
-Lcom/android/ims/internal/uce/uceservice/IUceListener$Stub;-><init>()V
-Lcom/android/ims/internal/uce/uceservice/IUceService$Stub;-><init>()V
Lcom/android/internal/app/IAppOpsCallback$Stub;-><init>()V
Lcom/android/internal/app/IAppOpsService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Lcom/android/internal/app/IAppOpsService$Stub$Proxy;->checkOperation(IILjava/lang/String;)I
@@ -313,15 +266,10 @@
Lcom/android/internal/app/IBatteryStats$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Lcom/android/internal/app/IBatteryStats$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IBatteryStats;
Lcom/android/internal/app/IMediaContainerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IMediaContainerService;
-Lcom/android/internal/app/IVoiceInteractionManagerService$Stub$Proxy;->showSessionFromSession(Landroid/os/IBinder;Landroid/os/Bundle;I)Z
Lcom/android/internal/app/IVoiceInteractionManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IVoiceInteractionManagerService;
Lcom/android/internal/appwidget/IAppWidgetService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/appwidget/IAppWidgetService;
-Lcom/android/internal/appwidget/IAppWidgetService$Stub;->TRANSACTION_bindAppWidgetId:I
Lcom/android/internal/backup/IBackupTransport$Stub;-><init>()V
-Lcom/android/internal/location/ILocationProvider$Stub;-><init>()V
Lcom/android/internal/location/ILocationProvider$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/location/ILocationProvider;
-Lcom/android/internal/location/ILocationProviderManager$Stub;-><init>()V
-Lcom/android/internal/location/ILocationProviderManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/location/ILocationProviderManager;
Lcom/android/internal/os/IDropBoxManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/os/IDropBoxManagerService;
Lcom/android/internal/policy/IKeyguardService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardService;
Lcom/android/internal/policy/IKeyguardStateCallback$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardStateCallback;
@@ -343,9 +291,7 @@
Lcom/android/internal/telephony/ITelephony$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Lcom/android/internal/telephony/ITelephony$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ITelephony;
-Lcom/android/internal/telephony/ITelephony$Stub;->DESCRIPTOR:Ljava/lang/String;
Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_call:I
-Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_dial:I
Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_getDeviceId:I
Lcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Lcom/android/internal/telephony/ITelephonyRegistry$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ITelephonyRegistry;
@@ -355,4 +301,3 @@
Lcom/android/internal/view/IInputMethodManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodManager;
Lcom/android/internal/view/IInputMethodSession$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodSession;
Lcom/android/internal/widget/ILockSettings$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/widget/ILockSettings;
-Lcom/android/internal/widget/IRemoteViewsFactory$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/widget/IRemoteViewsFactory;
diff --git a/config/preloaded-classes b/config/preloaded-classes
index f56656b..ecf11c2 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -4532,7 +4532,6 @@
android.os.BadParcelableException
android.os.BaseBundle$NoImagePreloadHolder
android.os.BaseBundle
-android.os.BasicShellCommandHandler
android.os.BatteryManager
android.os.BatteryManagerInternal
android.os.BatteryProperty$1
@@ -9558,6 +9557,7 @@
com.android.internal.widget.VerifyCredentialResponse
com.android.internal.widget.ViewClippingUtil$ClippingParameters
com.android.internal.widget.ViewClippingUtil
+com.android.module.utils.BasicShellCommandHandler
com.android.okhttp.Address
com.android.okhttp.AndroidShimResponseCache
com.android.okhttp.Authenticator
diff --git a/core/api/current.txt b/core/api/current.txt
index 9562715..31264b9 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -7403,6 +7403,12 @@
field public static final int ERROR_UNKNOWN = 1; // 0x1
}
+ public final class UnsafeStateException extends java.lang.IllegalStateException implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.UnsafeStateException> CREATOR;
+ }
+
}
package android.app.assist {
@@ -41238,10 +41244,11 @@
method public String getKeystoreAlias();
method public int getOrigin();
method public int getPurposes();
+ method public int getSecurityLevel();
method @NonNull public String[] getSignaturePaddings();
method public int getUserAuthenticationType();
method public int getUserAuthenticationValidityDurationSeconds();
- method public boolean isInsideSecureHardware();
+ method @Deprecated public boolean isInsideSecureHardware();
method public boolean isInvalidatedByBiometricEnrollment();
method public boolean isTrustedUserPresenceRequired();
method public boolean isUserAuthenticationRequired();
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 7085f7b..3617967 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -43,18 +43,6 @@
}
-package android.graphics {
-
- public final class Compatibility {
- method public static void setTargetSdkVersion(int);
- }
-
- public final class ImageDecoder implements java.lang.AutoCloseable {
- method @AnyThread @NonNull public static android.graphics.ImageDecoder.Source createSource(@NonNull android.content.ContentResolver, @NonNull android.net.Uri, @Nullable android.content.res.Resources);
- }
-
-}
-
package android.media {
public class AudioManager {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index c6bf5a9..37a5389 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -750,12 +750,17 @@
method @RequiresPermission(android.Manifest.permission.ENTER_CAR_MODE_PRIORITIZED) public void enableCarMode(@IntRange(from=0) int, int);
method @RequiresPermission(android.Manifest.permission.READ_PROJECTION_STATE) public int getActiveProjectionTypes();
method @NonNull @RequiresPermission(android.Manifest.permission.READ_PROJECTION_STATE) public java.util.Set<java.lang.String> getProjectingPackages(int);
+ method @RequiresPermission(value=android.Manifest.permission.TOGGLE_AUTOMOTIVE_PROJECTION, conditional=true) public boolean releaseProjection(int);
method @RequiresPermission(android.Manifest.permission.READ_PROJECTION_STATE) public void removeOnProjectionStateChangeListener(@NonNull android.app.UiModeManager.OnProjectionStateChangeListener);
+ method @RequiresPermission(value=android.Manifest.permission.TOGGLE_AUTOMOTIVE_PROJECTION, conditional=true) public boolean requestProjection(int);
field public static final String ACTION_ENTER_CAR_MODE_PRIORITIZED = "android.app.action.ENTER_CAR_MODE_PRIORITIZED";
field public static final String ACTION_EXIT_CAR_MODE_PRIORITIZED = "android.app.action.EXIT_CAR_MODE_PRIORITIZED";
field public static final int DEFAULT_PRIORITY = 0; // 0x0
field public static final String EXTRA_CALLING_PACKAGE = "android.app.extra.CALLING_PACKAGE";
field public static final String EXTRA_PRIORITY = "android.app.extra.PRIORITY";
+ field public static final int PROJECTION_TYPE_ALL = 65535; // 0xffff
+ field public static final int PROJECTION_TYPE_AUTOMOTIVE = 1; // 0x1
+ field public static final int PROJECTION_TYPE_NONE = 0; // 0x0
}
public static interface UiModeManager.OnProjectionStateChangeListener {
@@ -4125,6 +4130,7 @@
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, @NonNull android.os.UserHandle);
method @Deprecated @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean setProviderEnabledForUser(@NonNull String, boolean, @NonNull android.os.UserHandle);
method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean unregisterGnssBatchedLocationCallback(@NonNull android.location.BatchedLocationCallback);
+ field public static final String FUSED_PROVIDER = "fused";
}
public final class LocationRequest implements android.os.Parcelable {
@@ -5026,6 +5032,7 @@
method public long getAvSyncTime(int);
method @Nullable public android.media.tv.tuner.DemuxCapabilities getDemuxCapabilities();
method @Nullable public android.media.tv.tuner.frontend.FrontendInfo getFrontendInfo();
+ method @Nullable public java.util.List<android.media.tv.tuner.frontend.FrontendInfo> getFrontendInfoList();
method @Nullable public android.media.tv.tuner.frontend.FrontendStatus getFrontendStatus(@NonNull int[]);
method public int linkFrontendToCiCam(int);
method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_TV_DESCRAMBLER) public android.media.tv.tuner.Descrambler openDescrambler();
@@ -5242,6 +5249,7 @@
public class Filter implements java.lang.AutoCloseable {
method public void close();
method public int configure(@NonNull android.media.tv.tuner.filter.FilterConfiguration);
+ method public int configureScramblingStatusEvent(int);
method public int flush();
method public int getId();
method public long getId64Bit();
@@ -5249,6 +5257,9 @@
method public int setDataSource(@Nullable android.media.tv.tuner.filter.Filter);
method public int start();
method public int stop();
+ field public static final int SCRAMBLING_STATUS_NOT_SCRAMBLED = 2; // 0x2
+ field public static final int SCRAMBLING_STATUS_SCRAMBLED = 4; // 0x4
+ field public static final int SCRAMBLING_STATUS_UNKNOWN = 1; // 0x1
field public static final int STATUS_DATA_READY = 1; // 0x1
field public static final int STATUS_HIGH_WATER = 4; // 0x4
field public static final int STATUS_LOW_WATER = 2; // 0x2
@@ -5349,7 +5360,7 @@
public class MmtpRecordEvent extends android.media.tv.tuner.filter.FilterEvent {
method public long getDataLength();
- method public int getFirstMbInSlice();
+ method public int getFirstMacroblockInSlice();
method public int getMpuSequenceNumber();
method public long getPts();
method public int getScHevcIndexMask();
@@ -5427,6 +5438,10 @@
method @NonNull public android.media.tv.tuner.filter.RecordSettings.Builder setTsIndexMask(int);
}
+ public final class ScramblingStatusEvent extends android.media.tv.tuner.filter.FilterEvent {
+ method public int getScramblingStatus();
+ }
+
public class SectionEvent extends android.media.tv.tuner.filter.FilterEvent {
method public int getDataLength();
method public int getSectionNumber();
@@ -5525,7 +5540,7 @@
public class TsRecordEvent extends android.media.tv.tuner.filter.FilterEvent {
method public long getDataLength();
- method public int getFirstMbInSlice();
+ method public int getFirstMacroblockInSlice();
method public int getPacketId();
method public long getPts();
method public int getScIndexMask();
@@ -8755,8 +8770,13 @@
ctor public DeviceIdAttestationException(@Nullable String, @Nullable Throwable);
}
+ public final class KeyGenParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+ method public int getNamespace();
+ }
+
public static final class KeyGenParameterSpec.Builder {
- method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUid(int);
+ method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setNamespace(int);
+ method @Deprecated @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUid(int);
}
}
@@ -10038,6 +10058,17 @@
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallQuality> CREATOR;
}
+ public final class CarrierBandwidth implements android.os.Parcelable {
+ ctor public CarrierBandwidth(int, int, int, int);
+ method public int describeContents();
+ method public int getPrimaryDownlinkCapacityKbps();
+ method public int getPrimaryUplinkCapacityKbps();
+ method public int getSecondaryDownlinkCapacityKbps();
+ method public int getSecondaryUplinkCapacityKbps();
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CarrierBandwidth> CREATOR;
+ field public static final int INVALID = -1; // 0xffffffff
+ }
+
public class CarrierConfigManager {
method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDefaultCarrierServicePackageName();
method @NonNull public static android.os.PersistableBundle getDefaultConfig();
@@ -10335,6 +10366,18 @@
field public static final int PHYSICAL_CELL_ID_UNKNOWN = -1; // 0xffffffff
}
+ public final class PinResult implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getAttemptsRemaining();
+ method public int getResult();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PinResult> CREATOR;
+ field public static final int PIN_RESULT_TYPE_ABORTED = 3; // 0x3
+ field public static final int PIN_RESULT_TYPE_FAILURE = 2; // 0x2
+ field public static final int PIN_RESULT_TYPE_INCORRECT = 1; // 0x1
+ field public static final int PIN_RESULT_TYPE_SUCCESS = 0; // 0x0
+ }
+
public final class PreciseCallState implements android.os.Parcelable {
ctor public PreciseCallState(int, int, int, int, int);
method public int describeContents();
@@ -10678,6 +10721,7 @@
public class TelephonyManager {
method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void call(String, String);
+ method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult changeIccLockPin(@NonNull String, @NonNull String);
method public int checkCarrierPrivilegesForPackage(String);
method public int checkCarrierPrivilegesForPackageAnyPhone(String);
method public void dial(String);
@@ -10691,6 +10735,7 @@
method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getAndUpdateDefaultRespondViaMessageApplication();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getCallForwarding(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CallForwardingInfoCallback);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getCallWaitingStatus(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+ method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CarrierBandwidth getCarrierBandwidth();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
@@ -10782,6 +10827,7 @@
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int);
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(int, boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataRoamingEnabled(boolean);
+ method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult setIccLockEnabled(boolean, @NonNull String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMobileDataPolicyEnabledStatus(int, boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean);
method public int setNrDualConnectivityState(int);
@@ -10797,10 +10843,12 @@
method @Deprecated public void setVisualVoicemailEnabled(android.telecom.PhoneAccountHandle, boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoiceActivationState(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void shutdownAllRadios();
+ method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult supplyIccLockPin(@NonNull String);
+ method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult supplyIccLockPuk(@NonNull String, @NonNull String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPin(String);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPinReportResult(String);
+ method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPinReportResult(String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPuk(String, String);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPukReportResult(String, String);
+ method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPukReportResult(String, String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean switchSlots(int[]);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void toggleRadioOnOff();
method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void updateOtaEmergencyNumberDbFilePath(@NonNull android.os.ParcelFileDescriptor);
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index db45ec5..ef4dfdf 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -369,12 +369,17 @@
method public boolean isCurrentInputMethodSetByOwner();
method public boolean isFactoryResetProtectionPolicySupported();
field public static final String ACTION_DATA_SHARING_RESTRICTION_APPLIED = "android.app.action.DATA_SHARING_RESTRICTION_APPLIED";
+ field public static final int OPERATION_LOCK_NOW = 1; // 0x1
}
public static final class SecurityLog.SecurityEvent implements android.os.Parcelable {
ctor public SecurityLog.SecurityEvent(long, byte[]);
}
+ public final class UnsafeStateException extends java.lang.IllegalStateException implements android.os.Parcelable {
+ method public int getOperation();
+ }
+
}
package android.app.blob {
@@ -2418,6 +2423,7 @@
public class TaskOrganizer extends android.window.WindowOrganizer {
ctor public TaskOrganizer();
+ method @BinderThread public void addStartingWindow(@NonNull android.app.ActivityManager.RunningTaskInfo, @NonNull android.os.IBinder);
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void createRootTask(int, int, @Nullable android.os.IBinder);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public boolean deleteRootTask(@NonNull android.window.WindowContainerToken);
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public java.util.List<android.app.ActivityManager.RunningTaskInfo> getChildTasks(@NonNull android.window.WindowContainerToken, @NonNull int[]);
@@ -2428,6 +2434,7 @@
method @BinderThread public void onTaskInfoChanged(@NonNull android.app.ActivityManager.RunningTaskInfo);
method @BinderThread public void onTaskVanished(@NonNull android.app.ActivityManager.RunningTaskInfo);
method @CallSuper @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public java.util.List<android.window.TaskAppearedInfo> registerOrganizer();
+ method @BinderThread public void removeStartingWindow(@NonNull android.app.ActivityManager.RunningTaskInfo);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void setInterceptBackPressedOnTaskRoot(@NonNull android.window.WindowContainerToken, boolean);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void setLaunchRoot(int, @NonNull android.window.WindowContainerToken);
method @CallSuper @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void unregisterOrganizer();
diff --git a/core/java/android/accounts/GrantCredentialsPermissionActivity.java b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
index 42bd80b..5dc6e60 100644
--- a/core/java/android/accounts/GrantCredentialsPermissionActivity.java
+++ b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
@@ -55,6 +55,9 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ getWindow().addSystemFlags(
+ android.view.WindowManager.LayoutParams
+ .SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
setContentView(R.layout.grant_credentials_permission);
setTitle(R.string.grant_permissions_header_text);
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index f9970dd..f17b815 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -490,89 +490,98 @@
@Retention(RetentionPolicy.SOURCE)
public @interface ProcessState {}
+ /*
+ * PROCESS_STATE_* must come from frameworks/base/core/java/android/app/ProcessStateEnum.aidl.
+ * This is to make sure that Java side uses the same values as native.
+ */
/** @hide Not a real process state. */
- public static final int PROCESS_STATE_UNKNOWN = -1;
+ public static final int PROCESS_STATE_UNKNOWN = ProcessStateEnum.UNKNOWN;
/** @hide Process is a persistent system process. */
- public static final int PROCESS_STATE_PERSISTENT = 0;
+ public static final int PROCESS_STATE_PERSISTENT = ProcessStateEnum.PERSISTENT;
/** @hide Process is a persistent system process and is doing UI. */
- public static final int PROCESS_STATE_PERSISTENT_UI = 1;
+ public static final int PROCESS_STATE_PERSISTENT_UI = ProcessStateEnum.PERSISTENT_UI;
/** @hide Process is hosting the current top activities. Note that this covers
* all activities that are visible to the user. */
@UnsupportedAppUsage
- public static final int PROCESS_STATE_TOP = 2;
+ public static final int PROCESS_STATE_TOP = ProcessStateEnum.TOP;
/** @hide Process is bound to a TOP app. */
- public static final int PROCESS_STATE_BOUND_TOP = 3;
+ public static final int PROCESS_STATE_BOUND_TOP = ProcessStateEnum.BOUND_TOP;
/** @hide Process is hosting a foreground service. */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static final int PROCESS_STATE_FOREGROUND_SERVICE = 4;
+ public static final int PROCESS_STATE_FOREGROUND_SERVICE = ProcessStateEnum.FOREGROUND_SERVICE;
/** @hide Process is hosting a foreground service due to a system binding. */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 5;
+ public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE =
+ ProcessStateEnum.BOUND_FOREGROUND_SERVICE;
/** @hide Process is important to the user, and something they are aware of. */
- public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 6;
+ public static final int PROCESS_STATE_IMPORTANT_FOREGROUND =
+ ProcessStateEnum.IMPORTANT_FOREGROUND;
/** @hide Process is important to the user, but not something they are aware of. */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 7;
+ public static final int PROCESS_STATE_IMPORTANT_BACKGROUND =
+ ProcessStateEnum.IMPORTANT_BACKGROUND;
/** @hide Process is in the background transient so we will try to keep running. */
- public static final int PROCESS_STATE_TRANSIENT_BACKGROUND = 8;
+ public static final int PROCESS_STATE_TRANSIENT_BACKGROUND =
+ ProcessStateEnum.TRANSIENT_BACKGROUND;
/** @hide Process is in the background running a backup/restore operation. */
- public static final int PROCESS_STATE_BACKUP = 9;
+ public static final int PROCESS_STATE_BACKUP = ProcessStateEnum.BACKUP;
/** @hide Process is in the background running a service. Unlike oom_adj, this level
* is used for both the normal running in background state and the executing
* operations state. */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static final int PROCESS_STATE_SERVICE = 10;
+ public static final int PROCESS_STATE_SERVICE = ProcessStateEnum.SERVICE;
/** @hide Process is in the background running a receiver. Note that from the
* perspective of oom_adj, receivers run at a higher foreground level, but for our
* prioritization here that is not necessary and putting them below services means
* many fewer changes in some process states as they receive broadcasts. */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static final int PROCESS_STATE_RECEIVER = 11;
+ public static final int PROCESS_STATE_RECEIVER = ProcessStateEnum.RECEIVER;
/** @hide Same as {@link #PROCESS_STATE_TOP} but while device is sleeping. */
- public static final int PROCESS_STATE_TOP_SLEEPING = 12;
+ public static final int PROCESS_STATE_TOP_SLEEPING = ProcessStateEnum.TOP_SLEEPING;
/** @hide Process is in the background, but it can't restore its state so we want
* to try to avoid killing it. */
- public static final int PROCESS_STATE_HEAVY_WEIGHT = 13;
+ public static final int PROCESS_STATE_HEAVY_WEIGHT = ProcessStateEnum.HEAVY_WEIGHT;
/** @hide Process is in the background but hosts the home activity. */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static final int PROCESS_STATE_HOME = 14;
+ public static final int PROCESS_STATE_HOME = ProcessStateEnum.HOME;
/** @hide Process is in the background but hosts the last shown activity. */
- public static final int PROCESS_STATE_LAST_ACTIVITY = 15;
+ public static final int PROCESS_STATE_LAST_ACTIVITY = ProcessStateEnum.LAST_ACTIVITY;
/** @hide Process is being cached for later use and contains activities. */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static final int PROCESS_STATE_CACHED_ACTIVITY = 16;
+ public static final int PROCESS_STATE_CACHED_ACTIVITY = ProcessStateEnum.CACHED_ACTIVITY;
/** @hide Process is being cached for later use and is a client of another cached
* process that contains activities. */
- public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 17;
+ public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT =
+ ProcessStateEnum.CACHED_ACTIVITY_CLIENT;
/** @hide Process is being cached for later use and has an activity that corresponds
* to an existing recent task. */
- public static final int PROCESS_STATE_CACHED_RECENT = 18;
+ public static final int PROCESS_STATE_CACHED_RECENT = ProcessStateEnum.CACHED_RECENT;
/** @hide Process is being cached for later use and is empty. */
- public static final int PROCESS_STATE_CACHED_EMPTY = 19;
+ public static final int PROCESS_STATE_CACHED_EMPTY = ProcessStateEnum.CACHED_EMPTY;
/** @hide Process does not exist. */
- public static final int PROCESS_STATE_NONEXISTENT = 20;
+ public static final int PROCESS_STATE_NONEXISTENT = ProcessStateEnum.NONEXISTENT;
/**
* The set of flags for process capability.
diff --git a/core/java/android/app/ProcessStateEnum.aidl b/core/java/android/app/ProcessStateEnum.aidl
new file mode 100644
index 0000000..a14e7a6
--- /dev/null
+++ b/core/java/android/app/ProcessStateEnum.aidl
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2020 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;
+
+/**
+ * Defines the PROCESS_STATE_* values used by ActivityManager.
+ * These values are shared by Java and native side.
+ * {@hide}
+ */
+@Backing(type="int")
+enum ProcessStateEnum {
+ /** @hide Not a real process state. */
+ UNKNOWN = -1,
+
+ /** @hide Process is a persistent system process. */
+ PERSISTENT = 0,
+
+ /** @hide Process is a persistent system process and is doing UI. */
+ PERSISTENT_UI = 1,
+
+ /** @hide Process is hosting the current top activities. Note that this covers
+ * all activities that are visible to the user. */
+ TOP = 2,
+
+ /** @hide Process is bound to a TOP app. */
+ BOUND_TOP = 3,
+
+ /** @hide Process is hosting a foreground service. */
+ FOREGROUND_SERVICE = 4,
+
+ /** @hide Process is hosting a foreground service due to a system binding. */
+ BOUND_FOREGROUND_SERVICE = 5,
+
+ /** @hide Process is important to the user, and something they are aware of. */
+ IMPORTANT_FOREGROUND = 6,
+
+ /** @hide Process is important to the user, but not something they are aware of. */
+ IMPORTANT_BACKGROUND = 7,
+
+ /** @hide Process is in the background transient so we will try to keep running. */
+ TRANSIENT_BACKGROUND = 8,
+
+ /** @hide Process is in the background running a backup/restore operation. */
+ BACKUP = 9,
+
+ /** @hide Process is in the background running a service. Unlike oom_adj, this level
+ * is used for both the normal running in background state and the executing
+ * operations state. */
+ SERVICE = 10,
+
+ /** @hide Process is in the background running a receiver. Note that from the
+ * perspective of oom_adj, receivers run at a higher foreground level, but for our
+ * prioritization here that is not necessary and putting them below services means
+ * many fewer changes in some process states as they receive broadcasts. */
+ RECEIVER = 11,
+
+ /** @hide Same as {@link #PROCESS_STATE_TOP} but while device is sleeping. */
+ TOP_SLEEPING = 12,
+
+ /** @hide Process is in the background, but it can't restore its state so we want
+ * to try to avoid killing it. */
+ HEAVY_WEIGHT = 13,
+
+ /** @hide Process is in the background but hosts the home activity. */
+ HOME = 14,
+
+ /** @hide Process is in the background but hosts the last shown activity. */
+ LAST_ACTIVITY = 15,
+
+ /** @hide Process is being cached for later use and contains activities. */
+ CACHED_ACTIVITY = 16,
+
+ /** @hide Process is being cached for later use and is a client of another cached
+ * process that contains activities. */
+ CACHED_ACTIVITY_CLIENT = 17,
+
+ /** @hide Process is being cached for later use and has an activity that corresponds
+ * to an existing recent task. */
+ CACHED_RECENT = 18,
+
+ /** @hide Process is being cached for later use and is empty. */
+ CACHED_EMPTY = 19,
+
+ /** @hide Process does not exist. */
+ NONEXISTENT = 20,
+
+}
diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java
index 8a6871f..e1c262c 100644
--- a/core/java/android/app/UiModeManager.java
+++ b/core/java/android/app/UiModeManager.java
@@ -651,6 +651,7 @@
*
* @hide
*/
+ @SystemApi
@TestApi
public static final int PROJECTION_TYPE_NONE = 0x0000;
/**
@@ -660,6 +661,7 @@
*
* @hide
*/
+ @SystemApi
@TestApi
public static final int PROJECTION_TYPE_AUTOMOTIVE = 0x0001;
/**
@@ -669,6 +671,7 @@
*
* @hide
*/
+ @SystemApi
@TestApi
public static final int PROJECTION_TYPE_ALL = 0xffff;
@@ -695,6 +698,7 @@
*
* @hide
*/
+ @SystemApi
@TestApi
@RequiresPermission(value = android.Manifest.permission.TOGGLE_AUTOMOTIVE_PROJECTION,
conditional = true)
@@ -723,6 +727,7 @@
*
* @hide
*/
+ @SystemApi
@TestApi
@RequiresPermission(value = android.Manifest.permission.TOGGLE_AUTOMOTIVE_PROJECTION,
conditional = true)
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 1d644c4..01f3932 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -122,6 +122,7 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
+// TODO(b/172376923) - add CarDevicePolicyManager examples below (or remove reference to it).
/**
* Public interface for managing policies enforced on a device. Most clients of this class must be
* registered with the system as a <a href="{@docRoot}guide/topics/admin/device-admin.html">device
@@ -130,6 +131,13 @@
* for that method specifies that it is restricted to either device or profile owners. Any
* application calling an api may only pass as an argument a device administrator component it
* owns. Otherwise, a {@link SecurityException} will be thrown.
+ *
+ * <p><b>Note: </b>on
+ * {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE automotive builds}, some methods can
+ * throw an {@link UnsafeStateException} exception (for example, if the vehicle is moving), so
+ * callers running on automotive builds should wrap every method call under the methods provided by
+ * {@code android.car.admin.CarDevicePolicyManager}.
+ *
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>
@@ -1972,6 +1980,7 @@
public static final int CODE_CANNOT_ADD_MANAGED_PROFILE = 11;
/**
+ * TODO (b/137101239): clean up split system user codes
* Result code for {@link #checkProvisioningPreCondition}.
*
* <p>Returned for {@link #ACTION_PROVISION_MANAGED_USER} and
@@ -1995,6 +2004,7 @@
public static final int CODE_DEVICE_ADMIN_NOT_SUPPORTED = 13;
/**
+ * TODO (b/137101239): clean up split system user codes
* Result code for {@link #checkProvisioningPreCondition}.
*
* <p>Returned for {@link #ACTION_PROVISION_MANAGED_PROFILE} when the device the user is a
@@ -2443,6 +2453,19 @@
@Retention(RetentionPolicy.SOURCE)
public @interface PersonalAppsSuspensionReason {}
+ /** @hide */
+ @TestApi
+ public static final int OPERATION_LOCK_NOW = 1;
+
+ // TODO(b/172376923) - add all operations
+ /** @hide */
+ @IntDef(prefix = "OPERATION_", value = {
+ OPERATION_LOCK_NOW,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public static @interface DevicePolicyOperation {
+ }
+
/**
* Return true if the given administrator component is currently active (enabled) in the system.
*
diff --git a/core/java/android/app/admin/DevicePolicySafetyChecker.java b/core/java/android/app/admin/DevicePolicySafetyChecker.java
new file mode 100644
index 0000000..1f8a933
--- /dev/null
+++ b/core/java/android/app/admin/DevicePolicySafetyChecker.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 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.admin;
+
+import android.annotation.NonNull;
+import android.app.admin.DevicePolicyManager.DevicePolicyOperation;
+
+/**
+ * Interface responsible to check if a {@link DevicePolicyManager} API can be safely executed.
+ *
+ * @hide
+ */
+public interface DevicePolicySafetyChecker {
+
+ /**
+ * Returns whether the given {@code operation} can be safely executed at the moment.
+ */
+ default boolean isDevicePolicyOperationSafe(@DevicePolicyOperation int operation) {
+ return true;
+ }
+
+ /**
+ * Returns a new exception for when the given {@code operation} cannot be safely executed.
+ */
+ @NonNull
+ default UnsafeStateException newUnsafeStateException(@DevicePolicyOperation int operation) {
+ return new UnsafeStateException(operation);
+ }
+}
diff --git a/core/java/android/app/admin/PasswordMetrics.java b/core/java/android/app/admin/PasswordMetrics.java
index 20a60bb..c95a74e 100644
--- a/core/java/android/app/admin/PasswordMetrics.java
+++ b/core/java/android/app/admin/PasswordMetrics.java
@@ -407,11 +407,6 @@
}
@Override
- boolean allowsNumericPassword() {
- return false;
- }
-
- @Override
boolean allowsCredType(int credType) {
return credType == CREDENTIAL_TYPE_PASSWORD;
}
@@ -428,11 +423,6 @@
}
@Override
- boolean allowsNumericPassword() {
- return false;
- }
-
- @Override
boolean allowsCredType(int credType) {
return credType == CREDENTIAL_TYPE_PASSWORD;
}
@@ -449,11 +439,6 @@
}
@Override
- boolean allowsNumericPassword() {
- return true;
- }
-
- @Override
boolean allowsCredType(int credType) {
return credType != CREDENTIAL_TYPE_NONE;
}
@@ -470,11 +455,6 @@
}
@Override
- boolean allowsNumericPassword() {
- return true;
- }
-
- @Override
boolean allowsCredType(int credType) {
return true;
}
@@ -484,7 +464,6 @@
abstract boolean canHaveSequence();
abstract int getMinimumLength(boolean containsNonNumeric);
- abstract boolean allowsNumericPassword();
abstract boolean allowsCredType(int credType);
ComplexityBucket(int complexityLevel) {
@@ -591,7 +570,14 @@
result.add(new PasswordValidationError(TOO_LONG, MAX_PASSWORD_LENGTH));
}
- final PasswordMetrics minMetrics = applyComplexity(adminMetrics, isPin, bucket);
+ // A flag indicating whether the provided password already has non-numeric characters in
+ // it or if the admin imposes the requirement of any non-numeric characters.
+ final boolean hasOrWouldNeedNonNumeric =
+ actualMetrics.nonNumeric > 0 || adminMetrics.nonNumeric > 0
+ || adminMetrics.letters > 0 || adminMetrics.lowerCase > 0
+ || adminMetrics.upperCase > 0 || adminMetrics.symbols > 0;
+ final PasswordMetrics minMetrics =
+ applyComplexity(adminMetrics, hasOrWouldNeedNonNumeric, bucket);
// Clamp required length between maximum and minimum valid values.
minMetrics.length = Math.min(MAX_PASSWORD_LENGTH,
@@ -684,23 +670,23 @@
* TODO: move to PasswordPolicy
*/
public static PasswordMetrics applyComplexity(
- PasswordMetrics adminMetrics, boolean isPin, int complexity) {
- return applyComplexity(adminMetrics, isPin, ComplexityBucket.forComplexity(complexity));
+ PasswordMetrics adminMetrics, boolean withNonNumericCharacters,
+ int complexity) {
+ return applyComplexity(adminMetrics, withNonNumericCharacters,
+ ComplexityBucket.forComplexity(complexity));
}
private static PasswordMetrics applyComplexity(
- PasswordMetrics adminMetrics, boolean isPin, ComplexityBucket bucket) {
+ PasswordMetrics adminMetrics, boolean withNonNumericCharacters,
+ ComplexityBucket bucket) {
final PasswordMetrics minMetrics = new PasswordMetrics(adminMetrics);
if (!bucket.canHaveSequence()) {
minMetrics.seqLength = Math.min(minMetrics.seqLength, MAX_ALLOWED_SEQUENCE);
}
- minMetrics.length = Math.max(minMetrics.length, bucket.getMinimumLength(!isPin));
-
- if (!isPin && !bucket.allowsNumericPassword()) {
- minMetrics.nonNumeric = Math.max(minMetrics.nonNumeric, 1);
- }
+ minMetrics.length = Math.max(minMetrics.length,
+ bucket.getMinimumLength(withNonNumericCharacters));
return minMetrics;
}
diff --git a/core/java/android/app/admin/UnsafeStateException.java b/core/java/android/app/admin/UnsafeStateException.java
new file mode 100644
index 0000000..9dcaae4
--- /dev/null
+++ b/core/java/android/app/admin/UnsafeStateException.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2020 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.admin;
+
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.app.admin.DevicePolicyManager.DevicePolicyOperation;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Exception thrown when a {@link DevicePolicyManager} operation failed because it was not safe
+ * to be executed at that moment.
+ *
+ * <p>For example, it can be thrown on
+ * {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE automotive devices} when the vehicle
+ * is moving.
+ */
+@SuppressWarnings("serial")
+public final class UnsafeStateException extends IllegalStateException implements Parcelable {
+
+ private final @DevicePolicyOperation int mOperation;
+
+ /** @hide */
+ public UnsafeStateException(@DevicePolicyOperation int operation) {
+ super();
+
+ mOperation = operation;
+ }
+
+ /** @hide */
+ @TestApi
+ public @DevicePolicyOperation int getOperation() {
+ return mOperation;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mOperation);
+ }
+
+ @NonNull
+ public static final Creator<UnsafeStateException> CREATOR =
+ new Creator<UnsafeStateException>() {
+
+ @Override
+ public UnsafeStateException createFromParcel(Parcel source) {
+ return new UnsafeStateException(source.readInt());
+ }
+
+ @Override
+ public UnsafeStateException[] newArray(int size) {
+ return new UnsafeStateException[size];
+ }
+ };
+}
diff --git a/core/java/android/app/backup/OWNERS b/core/java/android/app/backup/OWNERS
index 7e7710b..0f88811 100644
--- a/core/java/android/app/backup/OWNERS
+++ b/core/java/android/app/backup/OWNERS
@@ -1,4 +1,4 @@
# Bug component: 656484
-include platform/frameworks/base/services/backup:/OWNERS
+include platform/frameworks/base:/services/backup/OWNERS
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 1cca53f..81d9b11 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -2101,6 +2101,7 @@
}
/** @hide */
+ @SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
public boolean isOem() {
return (privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
}
@@ -2148,11 +2149,13 @@
}
/** @hide */
+ @SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
public boolean isVendor() {
return (privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
}
/** @hide */
+ @SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
public boolean isProduct() {
return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
}
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index bf32560..500b299 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -344,6 +344,29 @@
@Retention(RetentionPolicy.SOURCE)
public @interface HdmiCecControl {}
+ // -- Supported HDM-CEC versions.
+ /**
+ * Version constant for HDMI-CEC v1.4b.
+ *
+ * @hide
+ */
+ public static final int HDMI_CEC_VERSION_1_4_b = 0x05;
+ /**
+ * Version constant for HDMI-CEC v2.0.
+ *
+ * @hide
+ */
+ public static final int HDMI_CEC_VERSION_2_0 = 0x06;
+ /**
+ * @hide
+ */
+ @IntDef({
+ HDMI_CEC_VERSION_1_4_b,
+ HDMI_CEC_VERSION_2_0
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface HdmiCecVersion {}
+
// -- Which devices the playback device can send a <Standby> message to upon going to sleep.
/**
* Send <Standby> to TV only.
@@ -428,6 +451,12 @@
*/
public static final String CEC_SETTING_NAME_HDMI_CEC_ENABLED = "hdmi_cec_enabled";
/**
+ * Name of a setting controlling the version of HDMI-CEC used.
+ *
+ * @hide
+ */
+ public static final String CEC_SETTING_NAME_HDMI_CEC_VERSION = "hdmi_cec_version";
+ /**
* Name of a setting deciding on the Standby message behaviour on sleep.
*
* @hide
@@ -452,6 +481,7 @@
*/
@StringDef({
CEC_SETTING_NAME_HDMI_CEC_ENABLED,
+ CEC_SETTING_NAME_HDMI_CEC_VERSION,
CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
@@ -1415,6 +1445,51 @@
}
/**
+ * Set the 'hdmi_cec_version' option.
+ *
+ * @param value the desired value
+ * @throws IllegalArgumentException when the new value is not allowed.
+ * @throws RuntimeException when the HdmiControlService is not available.
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.HDMI_CEC)
+ public void setHdmiCecVersion(@NonNull @HdmiCecVersion int value) {
+ if (mService == null) {
+ Log.e(TAG, "HdmiControlService is not available");
+ throw new RuntimeException("HdmiControlService is not available");
+ }
+ try {
+ mService.setCecSettingIntValue(CEC_SETTING_NAME_HDMI_CEC_VERSION, value);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Get the value of 'hdmi_cec_enabled' option.
+ *
+ * @return the current value.
+ * @throws RuntimeException when the HdmiControlService is not available.
+ *
+ * @hide
+ */
+ @NonNull
+ @HdmiCecVersion
+ @RequiresPermission(android.Manifest.permission.HDMI_CEC)
+ public int getHdmiCecVersion() {
+ if (mService == null) {
+ Log.e(TAG, "HdmiControlService is not available");
+ throw new RuntimeException("HdmiControlService is not available");
+ }
+ try {
+ return mService.getCecSettingIntValue(CEC_SETTING_NAME_HDMI_CEC_VERSION);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Set the 'send_standby_on_sleep' option.
*
* @param value the desired value
diff --git a/core/java/android/hardware/iris/IIrisService.aidl b/core/java/android/hardware/iris/IIrisService.aidl
index b9eca3b..3d26318 100644
--- a/core/java/android/hardware/iris/IIrisService.aidl
+++ b/core/java/android/hardware/iris/IIrisService.aidl
@@ -22,5 +22,5 @@
*/
interface IIrisService {
// Give IrisService its ID. See AuthService.java
- void initializeConfiguration(int sensorId);
+ void initializeConfiguration(int sensorId, int strength);
}
diff --git a/core/java/android/os/BasicShellCommandHandler.java b/core/java/android/os/BasicShellCommandHandler.java
deleted file mode 100644
index 366da3d..0000000
--- a/core/java/android/os/BasicShellCommandHandler.java
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import android.util.Log;
-
-import java.io.BufferedInputStream;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-
-/**
- * Helper for implementing {@link Binder#onShellCommand Binder.onShellCommand}. This is meant to
- * be copied into mainline modules, so this class must not use any hidden APIs.
- *
- * @hide
- */
-public abstract class BasicShellCommandHandler {
- static final String TAG = "ShellCommand";
- static final boolean DEBUG = false;
-
- private Binder mTarget;
- private FileDescriptor mIn;
- private FileDescriptor mOut;
- private FileDescriptor mErr;
- private String[] mArgs;
-
- private String mCmd;
- private int mArgPos;
- private String mCurArgData;
-
- private FileInputStream mFileIn;
- private FileOutputStream mFileOut;
- private FileOutputStream mFileErr;
-
- private PrintWriter mOutPrintWriter;
- private PrintWriter mErrPrintWriter;
- private InputStream mInputStream;
-
- public void init(Binder target, FileDescriptor in, FileDescriptor out, FileDescriptor err,
- String[] args, int firstArgPos) {
- mTarget = target;
- mIn = in;
- mOut = out;
- mErr = err;
- mArgs = args;
- mCmd = null;
- mArgPos = firstArgPos;
- mCurArgData = null;
- mFileIn = null;
- mFileOut = null;
- mFileErr = null;
- mOutPrintWriter = null;
- mErrPrintWriter = null;
- mInputStream = null;
- }
-
- public int exec(Binder target, FileDescriptor in, FileDescriptor out, FileDescriptor err,
- String[] args) {
- String cmd;
- int start;
- if (args != null && args.length > 0) {
- cmd = args[0];
- start = 1;
- } else {
- cmd = null;
- start = 0;
- }
- init(target, in, out, err, args, start);
- mCmd = cmd;
-
- if (DEBUG) {
- RuntimeException here = new RuntimeException("here");
- here.fillInStackTrace();
- Log.d(TAG, "Starting command " + mCmd + " on " + mTarget, here);
- Log.d(TAG, "Calling uid=" + Binder.getCallingUid()
- + " pid=" + Binder.getCallingPid());
- }
- int res = -1;
- try {
- res = onCommand(mCmd);
- if (DEBUG) Log.d(TAG, "Executed command " + mCmd + " on " + mTarget);
- } catch (Throwable e) {
- // Unlike usual calls, in this case if an exception gets thrown
- // back to us we want to print it back in to the dump data, since
- // that is where the caller expects all interesting information to
- // go.
- PrintWriter eout = getErrPrintWriter();
- eout.println();
- eout.println("Exception occurred while executing '" + mCmd + "':");
- e.printStackTrace(eout);
- } finally {
- if (DEBUG) Log.d(TAG, "Flushing output streams on " + mTarget);
- if (mOutPrintWriter != null) {
- mOutPrintWriter.flush();
- }
- if (mErrPrintWriter != null) {
- mErrPrintWriter.flush();
- }
- if (DEBUG) Log.d(TAG, "Sending command result on " + mTarget);
- }
- if (DEBUG) Log.d(TAG, "Finished command " + mCmd + " on " + mTarget);
- return res;
- }
-
- /**
- * Return the raw FileDescriptor for the output stream.
- */
- public FileDescriptor getOutFileDescriptor() {
- return mOut;
- }
-
- /**
- * Return direct raw access (not buffered) to the command's output data stream.
- */
- public OutputStream getRawOutputStream() {
- if (mFileOut == null) {
- mFileOut = new FileOutputStream(mOut);
- }
- return mFileOut;
- }
-
- /**
- * Return a PrintWriter for formatting output to {@link #getRawOutputStream()}.
- */
- public PrintWriter getOutPrintWriter() {
- if (mOutPrintWriter == null) {
- mOutPrintWriter = new PrintWriter(getRawOutputStream());
- }
- return mOutPrintWriter;
- }
-
- /**
- * Return the raw FileDescriptor for the error stream.
- */
- public FileDescriptor getErrFileDescriptor() {
- return mErr;
- }
-
- /**
- * Return direct raw access (not buffered) to the command's error output data stream.
- */
- public OutputStream getRawErrorStream() {
- if (mFileErr == null) {
- mFileErr = new FileOutputStream(mErr);
- }
- return mFileErr;
- }
-
- /**
- * Return a PrintWriter for formatting output to {@link #getRawErrorStream()}.
- */
- public PrintWriter getErrPrintWriter() {
- if (mErr == null) {
- return getOutPrintWriter();
- }
- if (mErrPrintWriter == null) {
- mErrPrintWriter = new PrintWriter(getRawErrorStream());
- }
- return mErrPrintWriter;
- }
-
- /**
- * Return the raw FileDescriptor for the input stream.
- */
- public FileDescriptor getInFileDescriptor() {
- return mIn;
- }
-
- /**
- * Return direct raw access (not buffered) to the command's input data stream.
- */
- public InputStream getRawInputStream() {
- if (mFileIn == null) {
- mFileIn = new FileInputStream(mIn);
- }
- return mFileIn;
- }
-
- /**
- * Return buffered access to the command's {@link #getRawInputStream()}.
- */
- public InputStream getBufferedInputStream() {
- if (mInputStream == null) {
- mInputStream = new BufferedInputStream(getRawInputStream());
- }
- return mInputStream;
- }
-
- /**
- * Return the next option on the command line -- that is an argument that
- * starts with '-'. If the next argument is not an option, null is returned.
- */
- public String getNextOption() {
- if (mCurArgData != null) {
- String prev = mArgs[mArgPos - 1];
- throw new IllegalArgumentException("No argument expected after \"" + prev + "\"");
- }
- if (mArgPos >= mArgs.length) {
- return null;
- }
- String arg = mArgs[mArgPos];
- if (!arg.startsWith("-")) {
- return null;
- }
- mArgPos++;
- if (arg.equals("--")) {
- return null;
- }
- if (arg.length() > 1 && arg.charAt(1) != '-') {
- if (arg.length() > 2) {
- mCurArgData = arg.substring(2);
- return arg.substring(0, 2);
- } else {
- mCurArgData = null;
- return arg;
- }
- }
- mCurArgData = null;
- return arg;
- }
-
- /**
- * Return the next argument on the command line, whatever it is; if there are
- * no arguments left, return null.
- */
- public String getNextArg() {
- if (mCurArgData != null) {
- String arg = mCurArgData;
- mCurArgData = null;
- return arg;
- } else if (mArgPos < mArgs.length) {
- return mArgs[mArgPos++];
- } else {
- return null;
- }
- }
-
- public String peekNextArg() {
- if (mCurArgData != null) {
- return mCurArgData;
- } else if (mArgPos < mArgs.length) {
- return mArgs[mArgPos];
- } else {
- return null;
- }
- }
-
- /**
- * @return all the remaining arguments in the command without moving the current position.
- */
- public String[] peekRemainingArgs() {
- int remaining = getRemainingArgsCount();
- String[] args = new String[remaining];
- for (int pos = mArgPos; pos < mArgs.length; pos++) {
- args[pos - mArgPos] = mArgs[pos];
- }
- return args;
- }
-
- /**
- * Returns number of arguments that haven't been processed yet.
- */
- public int getRemainingArgsCount() {
- if (mArgPos >= mArgs.length) {
- return 0;
- }
- return mArgs.length - mArgPos;
- }
-
- /**
- * Return the next argument on the command line, whatever it is; if there are
- * no arguments left, throws an IllegalArgumentException to report this to the user.
- */
- public String getNextArgRequired() {
- String arg = getNextArg();
- if (arg == null) {
- String prev = mArgs[mArgPos - 1];
- throw new IllegalArgumentException("Argument expected after \"" + prev + "\"");
- }
- return arg;
- }
-
- public int handleDefaultCommands(String cmd) {
- if (cmd == null || "help".equals(cmd) || "-h".equals(cmd)) {
- onHelp();
- } else {
- getOutPrintWriter().println("Unknown command: " + cmd);
- }
- return -1;
- }
-
- public Binder getTarget() {
- return mTarget;
- }
-
- public String[] getAllArgs() {
- return mArgs;
- }
-
- /**
- * Implement parsing and execution of a command. If it isn't a command you understand,
- * call {@link #handleDefaultCommands(String)} and return its result as a last resort.
- * Use {@link #getNextOption()}, {@link #getNextArg()}, and {@link #getNextArgRequired()}
- * to process additional command line arguments. Command output can be written to
- * {@link #getOutPrintWriter()} and errors to {@link #getErrPrintWriter()}.
- *
- * <p class="caution">Note that no permission checking has been done before entering this
- * function, so you need to be sure to do your own security verification for any commands you
- * are executing. The easiest way to do this is to have the ShellCommand contain
- * only a reference to your service's aidl interface, and do all of your command
- * implementations on top of that -- that way you can rely entirely on your executing security
- * code behind that interface.</p>
- *
- * @param cmd The first command line argument representing the name of the command to execute.
- * @return Return the command result; generally 0 or positive indicates success and
- * negative values indicate error.
- */
- public abstract int onCommand(String cmd);
-
- /**
- * Implement this to print help text about your command to {@link #getOutPrintWriter()}.
- */
- public abstract void onHelp();
-}
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index d91c458..010459d 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -170,6 +170,15 @@
int FLAG_ONEWAY = 0x00000001;
/**
+ * Flag to {@link #transact}: request binder driver to clear transaction data.
+ *
+ * Be very careful when using this flag in Java, since Java objects read from a Java
+ * Parcel may be non-trivial to clear.
+ * @hide
+ */
+ int FLAG_CLEAR_BUF = 0x00000020;
+
+ /**
* @hide
*/
int FLAG_COLLECT_NOTED_APP_OPS = 0x00000002;
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index a04fcb5..5242750 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -300,6 +300,8 @@
private static final int EX_TRANSACTION_FAILED = -129;
@CriticalNative
+ private static native void nativeMarkSensitive(long nativePtr);
+ @CriticalNative
private static native int nativeDataSize(long nativePtr);
@CriticalNative
private static native int nativeDataAvail(long nativePtr);
@@ -522,6 +524,14 @@
public static native long getGlobalAllocCount();
/**
+ * Parcel data should be zero'd before realloc'd or deleted.
+ * @hide
+ */
+ public final void markSensitive() {
+ nativeMarkSensitive(mNativePtr);
+ }
+
+ /**
* Returns the total amount of data contained in the parcel.
*/
public final int dataSize() {
diff --git a/core/java/android/os/ShellCommand.java b/core/java/android/os/ShellCommand.java
index 3358ce1..a2173a6 100644
--- a/core/java/android/os/ShellCommand.java
+++ b/core/java/android/os/ShellCommand.java
@@ -19,15 +19,9 @@
import android.compat.annotation.UnsupportedAppUsage;
import android.util.Slog;
-import com.android.internal.util.FastPrintWriter;
+import com.android.modules.utils.BasicShellCommandHandler;
-import java.io.BufferedInputStream;
import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintWriter;
/**
* Helper for implementing {@link Binder#onShellCommand Binder.onShellCommand}.
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index b94031a..46a5caf 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -40,7 +40,9 @@
import android.media.AudioFormat;
import android.media.permission.Identity;
import android.os.AsyncTask;
+import android.os.Binder;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.Slog;
@@ -246,6 +248,7 @@
private final Callback mExternalCallback;
private final Object mLock = new Object();
private final Handler mHandler;
+ private final IBinder mBinder = new Binder();
private int mAvailability = STATE_NOT_READY;
@@ -450,7 +453,7 @@
Identity identity = new Identity();
identity.packageName = ActivityThread.currentOpPackageName();
mSoundTriggerSession = mModelManagementService.createSoundTriggerSessionAsOriginator(
- identity);
+ identity, mBinder);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
diff --git a/core/java/android/util/CharsetUtils.java b/core/java/android/util/CharsetUtils.java
new file mode 100644
index 0000000..80c2055
--- /dev/null
+++ b/core/java/android/util/CharsetUtils.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2020 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.util;
+
+import android.annotation.NonNull;
+
+import dalvik.annotation.optimization.FastNative;
+
+/**
+ * Specializations of {@code libcore.util.CharsetUtils} which enable efficient
+ * in-place encoding without making any new allocations.
+ * <p>
+ * These methods purposefully accept only non-movable byte array addresses to
+ * avoid extra JNI overhead.
+ *
+ * @hide
+ */
+public class CharsetUtils {
+ /**
+ * Attempt to encode the given string as UTF-8 into the destination byte
+ * array without making any new allocations.
+ *
+ * @param src string value to be encoded
+ * @param dest destination byte array to encode into
+ * @param destOff offset into destination where encoding should begin
+ * @param destLen length of destination
+ * @return the number of bytes written to the destination when encoded
+ * successfully, otherwise {@code -1} if not large enough
+ */
+ public static int toUtf8Bytes(@NonNull String src,
+ long dest, int destOff, int destLen) {
+ return toUtf8Bytes(src, src.length(), dest, destOff, destLen);
+ }
+
+ /**
+ * Attempt to encode the given string as UTF-8 into the destination byte
+ * array without making any new allocations.
+ *
+ * @param src string value to be encoded
+ * @param srcLen exact length of string to be encoded
+ * @param dest destination byte array to encode into
+ * @param destOff offset into destination where encoding should begin
+ * @param destLen length of destination
+ * @return the number of bytes written to the destination when encoded
+ * successfully, otherwise {@code -1} if not large enough
+ */
+ @FastNative
+ private static native int toUtf8Bytes(@NonNull String src, int srcLen,
+ long dest, int destOff, int destLen);
+}
diff --git a/core/java/android/util/TypedXmlPullParser.java b/core/java/android/util/TypedXmlPullParser.java
new file mode 100644
index 0000000..5ff7e5d
--- /dev/null
+++ b/core/java/android/util/TypedXmlPullParser.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2020 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.util;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import org.xmlpull.v1.XmlPullParser;
+
+import java.io.IOException;
+
+/**
+ * Specialization of {@link XmlPullParser} which adds explicit methods to
+ * support consistent and efficient conversion of primitive data types.
+ *
+ * @hide
+ */
+public interface TypedXmlPullParser extends XmlPullParser {
+ /**
+ * @return decoded strongly-typed {@link #getAttributeValue}, or
+ * {@code null} if malformed or undefined
+ */
+ @Nullable byte[] getAttributeBytesHex(@Nullable String namespace, @NonNull String name)
+ throws IOException;
+
+ /**
+ * @return decoded strongly-typed {@link #getAttributeValue}, or
+ * {@code null} if malformed or undefined
+ */
+ @Nullable byte[] getAttributeBytesBase64(@Nullable String namespace, @NonNull String name)
+ throws IOException;
+
+ /**
+ * @return decoded strongly-typed {@link #getAttributeValue}
+ * @throws IOException if the value is malformed or undefined
+ */
+ int getAttributeInt(@Nullable String namespace, @NonNull String name)
+ throws IOException;
+
+ /**
+ * @return decoded strongly-typed {@link #getAttributeValue}
+ * @throws IOException if the value is malformed or undefined
+ */
+ int getAttributeIntHex(@Nullable String namespace, @NonNull String name)
+ throws IOException;
+
+ /**
+ * @return decoded strongly-typed {@link #getAttributeValue}
+ * @throws IOException if the value is malformed or undefined
+ */
+ long getAttributeLong(@Nullable String namespace, @NonNull String name)
+ throws IOException;
+
+ /**
+ * @return decoded strongly-typed {@link #getAttributeValue}
+ * @throws IOException if the value is malformed or undefined
+ */
+ long getAttributeLongHex(@Nullable String namespace, @NonNull String name)
+ throws IOException;
+
+ /**
+ * @return decoded strongly-typed {@link #getAttributeValue}
+ * @throws IOException if the value is malformed or undefined
+ */
+ float getAttributeFloat(@Nullable String namespace, @NonNull String name)
+ throws IOException;
+
+ /**
+ * @return decoded strongly-typed {@link #getAttributeValue}
+ * @throws IOException if the value is malformed or undefined
+ */
+ double getAttributeDouble(@Nullable String namespace, @NonNull String name)
+ throws IOException;
+
+ /**
+ * @return decoded strongly-typed {@link #getAttributeValue}
+ * @throws IOException if the value is malformed or undefined
+ */
+ boolean getAttributeBoolean(@Nullable String namespace, @NonNull String name)
+ throws IOException;
+
+ /**
+ * @return decoded strongly-typed {@link #getAttributeValue}, otherwise
+ * default value if the value is malformed or undefined
+ */
+ default int getAttributeInt(@Nullable String namespace, @NonNull String name,
+ int defaultValue) {
+ try {
+ return getAttributeInt(namespace, name);
+ } catch (Exception ignored) {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * @return decoded strongly-typed {@link #getAttributeValue}, otherwise
+ * default value if the value is malformed or undefined
+ */
+ default int getAttributeIntHex(@Nullable String namespace, @NonNull String name,
+ int defaultValue) {
+ try {
+ return getAttributeIntHex(namespace, name);
+ } catch (Exception ignored) {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * @return decoded strongly-typed {@link #getAttributeValue}, otherwise
+ * default value if the value is malformed or undefined
+ */
+ default long getAttributeLong(@Nullable String namespace, @NonNull String name,
+ long defaultValue) {
+ try {
+ return getAttributeLong(namespace, name);
+ } catch (Exception ignored) {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * @return decoded strongly-typed {@link #getAttributeValue}, otherwise
+ * default value if the value is malformed or undefined
+ */
+ default long getAttributeLongHex(@Nullable String namespace, @NonNull String name,
+ long defaultValue) {
+ try {
+ return getAttributeLongHex(namespace, name);
+ } catch (Exception ignored) {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * @return decoded strongly-typed {@link #getAttributeValue}, otherwise
+ * default value if the value is malformed or undefined
+ */
+ default float getAttributeFloat(@Nullable String namespace, @NonNull String name,
+ float defaultValue) {
+ try {
+ return getAttributeFloat(namespace, name);
+ } catch (Exception ignored) {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * @return decoded strongly-typed {@link #getAttributeValue}, otherwise
+ * default value if the value is malformed or undefined
+ */
+ default double getAttributeDouble(@Nullable String namespace, @NonNull String name,
+ double defaultValue) {
+ try {
+ return getAttributeDouble(namespace, name);
+ } catch (Exception ignored) {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * @return decoded strongly-typed {@link #getAttributeValue}, otherwise
+ * default value if the value is malformed or undefined
+ */
+ default boolean getAttributeBoolean(@Nullable String namespace, @NonNull String name,
+ boolean defaultValue) {
+ try {
+ return getAttributeBoolean(namespace, name);
+ } catch (Exception ignored) {
+ return defaultValue;
+ }
+ }
+}
diff --git a/core/java/android/util/TypedXmlSerializer.java b/core/java/android/util/TypedXmlSerializer.java
new file mode 100644
index 0000000..fe5e3e6
--- /dev/null
+++ b/core/java/android/util/TypedXmlSerializer.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2020 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.util;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+
+/**
+ * Specialization of {@link XmlSerializer} which adds explicit methods to
+ * support consistent and efficient conversion of primitive data types.
+ *
+ * @hide
+ */
+public interface TypedXmlSerializer extends XmlSerializer {
+ /**
+ * Functionally equivalent to {@link #attribute(String, String, String)} but
+ * with the additional signal that the given value is a candidate for being
+ * canonicalized, similar to {@link String#intern()}.
+ */
+ @NonNull XmlSerializer attributeInterned(@Nullable String namespace, @NonNull String name,
+ @Nullable String value) throws IOException;
+
+ /**
+ * Encode the given strongly-typed value and serialize using
+ * {@link #attribute(String, String, String)}.
+ */
+ @NonNull XmlSerializer attributeBytesHex(@Nullable String namespace, @NonNull String name,
+ byte[] value) throws IOException;
+
+ /**
+ * Encode the given strongly-typed value and serialize using
+ * {@link #attribute(String, String, String)}.
+ */
+ @NonNull XmlSerializer attributeBytesBase64(@Nullable String namespace, @NonNull String name,
+ byte[] value) throws IOException;
+
+ /**
+ * Encode the given strongly-typed value and serialize using
+ * {@link #attribute(String, String, String)}.
+ */
+ @NonNull XmlSerializer attributeInt(@Nullable String namespace, @NonNull String name,
+ int value) throws IOException;
+
+ /**
+ * Encode the given strongly-typed value and serialize using
+ * {@link #attribute(String, String, String)}.
+ */
+ @NonNull XmlSerializer attributeIntHex(@Nullable String namespace, @NonNull String name,
+ int value) throws IOException;
+
+ /**
+ * Encode the given strongly-typed value and serialize using
+ * {@link #attribute(String, String, String)}.
+ */
+ @NonNull XmlSerializer attributeLong(@Nullable String namespace, @NonNull String name,
+ long value) throws IOException;
+
+ /**
+ * Encode the given strongly-typed value and serialize using
+ * {@link #attribute(String, String, String)}.
+ */
+ @NonNull XmlSerializer attributeLongHex(@Nullable String namespace, @NonNull String name,
+ long value) throws IOException;
+
+ /**
+ * Encode the given strongly-typed value and serialize using
+ * {@link #attribute(String, String, String)}.
+ */
+ @NonNull XmlSerializer attributeFloat(@Nullable String namespace, @NonNull String name,
+ float value) throws IOException;
+
+ /**
+ * Encode the given strongly-typed value and serialize using
+ * {@link #attribute(String, String, String)}.
+ */
+ @NonNull XmlSerializer attributeDouble(@Nullable String namespace, @NonNull String name,
+ double value) throws IOException;
+
+ /**
+ * Encode the given strongly-typed value and serialize using
+ * {@link #attribute(String, String, String)}.
+ */
+ @NonNull XmlSerializer attributeBoolean(@Nullable String namespace, @NonNull String name,
+ boolean value) throws IOException;
+}
diff --git a/core/java/android/util/Xml.java b/core/java/android/util/Xml.java
index e3b8fec..cc6ed2e 100644
--- a/core/java/android/util/Xml.java
+++ b/core/java/android/util/Xml.java
@@ -16,6 +16,14 @@
package android.util;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import com.android.internal.util.BinaryXmlPullParser;
+import com.android.internal.util.BinaryXmlSerializer;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.XmlUtils;
+
import libcore.util.XmlObjectFactory;
import org.xml.sax.ContentHandler;
@@ -26,11 +34,15 @@
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
/**
* XML utility methods.
@@ -99,6 +111,57 @@
}
/**
+ * Creates a new {@link TypedXmlPullParser} which is optimized for use
+ * inside the system, typically by supporting only a basic set of features.
+ * <p>
+ * In particular, the returned parser does not support namespaces, prefixes,
+ * properties, or options.
+ *
+ * @hide
+ */
+ public static @NonNull TypedXmlPullParser newFastPullParser() {
+ return XmlUtils.makeTyped(newPullParser());
+ }
+
+ /**
+ * Creates a new {@link XmlPullParser} that reads XML documents using a
+ * custom binary wire protocol which benchmarking has shown to be 8.5x
+ * faster than {@code Xml.newFastPullParser()} for a typical
+ * {@code packages.xml}.
+ *
+ * @hide
+ */
+ public static @NonNull TypedXmlPullParser newBinaryPullParser() {
+ return new BinaryXmlPullParser();
+ }
+
+ /**
+ * Creates a new {@link XmlPullParser} which is optimized for use inside the
+ * system, typically by supporting only a basic set of features.
+ * <p>
+ * This returned instance may be configured to read using an efficient
+ * binary format instead of a human-readable text format, depending on
+ * device feature flags.
+ * <p>
+ * To ensure that both formats are detected and transparently handled
+ * correctly, you must shift to using both {@link #resolveSerializer} and
+ * {@link #resolvePullParser}.
+ *
+ * @hide
+ */
+ public static @NonNull TypedXmlPullParser resolvePullParser(@NonNull InputStream in)
+ throws IOException {
+ // TODO: add support for binary format
+ final TypedXmlPullParser xml = newFastPullParser();
+ try {
+ xml.setInput(in, StandardCharsets.UTF_8.name());
+ } catch (XmlPullParserException e) {
+ throw new IOException(e);
+ }
+ return xml;
+ }
+
+ /**
* Creates a new xml serializer.
*/
public static XmlSerializer newSerializer() {
@@ -106,6 +169,129 @@
}
/**
+ * Creates a new {@link XmlSerializer} which is optimized for use inside the
+ * system, typically by supporting only a basic set of features.
+ * <p>
+ * In particular, the returned parser does not support namespaces, prefixes,
+ * properties, or options.
+ *
+ * @hide
+ */
+ public static @NonNull TypedXmlSerializer newFastSerializer() {
+ return XmlUtils.makeTyped(new FastXmlSerializer());
+ }
+
+ /**
+ * Creates a new {@link XmlSerializer} that writes XML documents using a
+ * custom binary wire protocol which benchmarking has shown to be 4.4x
+ * faster and use 2.8x less disk space than {@code Xml.newFastSerializer()}
+ * for a typical {@code packages.xml}.
+ *
+ * @hide
+ */
+ public static @NonNull TypedXmlSerializer newBinarySerializer() {
+ return new BinaryXmlSerializer();
+ }
+
+ /**
+ * Creates a new {@link XmlSerializer} which is optimized for use inside the
+ * system, typically by supporting only a basic set of features.
+ * <p>
+ * This returned instance may be configured to write using an efficient
+ * binary format instead of a human-readable text format, depending on
+ * device feature flags.
+ * <p>
+ * To ensure that both formats are detected and transparently handled
+ * correctly, you must shift to using both {@link #resolveSerializer} and
+ * {@link #resolvePullParser}.
+ *
+ * @hide
+ */
+ public static @NonNull TypedXmlSerializer resolveSerializer(@NonNull OutputStream out)
+ throws IOException {
+ // TODO: add support for binary format
+ final TypedXmlSerializer xml = newFastSerializer();
+ xml.setOutput(out, StandardCharsets.UTF_8.name());
+ return xml;
+ }
+
+ /**
+ * Copy the first XML document into the second document.
+ * <p>
+ * Implemented by reading all events from the given {@link XmlPullParser}
+ * and writing them directly to the given {@link XmlSerializer}. This can be
+ * useful for transparently converting between underlying wire protocols.
+ *
+ * @hide
+ */
+ public static void copy(@NonNull XmlPullParser in, @NonNull XmlSerializer out)
+ throws XmlPullParserException, IOException {
+ // Some parsers may have already consumed the event that starts the
+ // document, so we manually emit that event here for consistency
+ if (in.getEventType() == XmlPullParser.START_DOCUMENT) {
+ out.startDocument(in.getInputEncoding(), true);
+ }
+
+ while (true) {
+ final int token = in.nextToken();
+ switch (token) {
+ case XmlPullParser.START_DOCUMENT:
+ out.startDocument(in.getInputEncoding(), true);
+ break;
+ case XmlPullParser.END_DOCUMENT:
+ out.endDocument();
+ return;
+ case XmlPullParser.START_TAG:
+ out.startTag(normalizeNamespace(in.getNamespace()), in.getName());
+ for (int i = 0; i < in.getAttributeCount(); i++) {
+ out.attribute(normalizeNamespace(in.getAttributeNamespace(i)),
+ in.getAttributeName(i), in.getAttributeValue(i));
+ }
+ break;
+ case XmlPullParser.END_TAG:
+ out.endTag(normalizeNamespace(in.getNamespace()), in.getName());
+ break;
+ case XmlPullParser.TEXT:
+ out.text(in.getText());
+ break;
+ case XmlPullParser.CDSECT:
+ out.cdsect(in.getText());
+ break;
+ case XmlPullParser.ENTITY_REF:
+ out.entityRef(in.getName());
+ break;
+ case XmlPullParser.IGNORABLE_WHITESPACE:
+ out.ignorableWhitespace(in.getText());
+ break;
+ case XmlPullParser.PROCESSING_INSTRUCTION:
+ out.processingInstruction(in.getText());
+ break;
+ case XmlPullParser.COMMENT:
+ out.comment(in.getText());
+ break;
+ case XmlPullParser.DOCDECL:
+ out.docdecl(in.getText());
+ break;
+ default:
+ throw new IllegalStateException("Unknown token " + token);
+ }
+ }
+ }
+
+ /**
+ * Some parsers may return an empty string {@code ""} when a namespace in
+ * unsupported, which can confuse serializers. This method normalizes empty
+ * strings to be {@code null}.
+ */
+ private static @Nullable String normalizeNamespace(@Nullable String namespace) {
+ if (namespace == null || namespace.isEmpty()) {
+ return null;
+ } else {
+ return namespace;
+ }
+ }
+
+ /**
* Supported character encodings.
*/
public enum Encoding {
diff --git a/core/java/android/uwb/RangingParams.java b/core/java/android/uwb/RangingParams.java
deleted file mode 100644
index f23d9ed..0000000
--- a/core/java/android/uwb/RangingParams.java
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * Copyright 2020 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.uwb;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.PersistableBundle;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * An object used when requesting to open a new {@link RangingSession}.
- * <p>Use {@link RangingParams.Builder} to create an instance of this class.
- *
- * @hide
- */
-public final class RangingParams implements Parcelable {
- private final boolean mIsInitiator;
- private final boolean mIsController;
- private final Duration mSamplePeriod;
- private final UwbAddress mLocalDeviceAddress;
- private final List<UwbAddress> mRemoteDeviceAddresses;
- private final int mChannelNumber;
- private final int mTransmitPreambleCodeIndex;
- private final int mReceivePreambleCodeIndex;
- private final int mStsPhyPacketType;
- private final PersistableBundle mSpecificationParameters;
-
- private RangingParams(boolean isInitiator, boolean isController,
- @NonNull Duration samplingPeriod, @NonNull UwbAddress localDeviceAddress,
- @NonNull List<UwbAddress> remoteDeviceAddresses, int channelNumber,
- int transmitPreambleCodeIndex, int receivePreambleCodeIndex,
- @StsPhyPacketType int stsPhyPacketType,
- @NonNull PersistableBundle specificationParameters) {
- mIsInitiator = isInitiator;
- mIsController = isController;
- mSamplePeriod = samplingPeriod;
- mLocalDeviceAddress = localDeviceAddress;
- mRemoteDeviceAddresses = remoteDeviceAddresses;
- mChannelNumber = channelNumber;
- mTransmitPreambleCodeIndex = transmitPreambleCodeIndex;
- mReceivePreambleCodeIndex = receivePreambleCodeIndex;
- mStsPhyPacketType = stsPhyPacketType;
- mSpecificationParameters = specificationParameters;
- }
-
- /**
- * Get if the local device is the initiator
- *
- * @return true if the device is the initiator
- */
- public boolean isInitiator() {
- return mIsInitiator;
- }
-
- /**
- * Get if the local device is the controller
- *
- * @return true if the device is the controller
- */
- public boolean isController() {
- return mIsController;
- }
-
- /**
- * The desired amount of time between two adjacent samples of measurement
- *
- * @return the ranging sample period
- */
- @NonNull
- public Duration getSamplingPeriod() {
- return mSamplePeriod;
- }
-
- /**
- * Local device's {@link UwbAddress}
- *
- * <p>Simultaneous {@link RangingSession}s on the same device can have different results for
- * {@link #getLocalDeviceAddress()}.
- *
- * @return the local device's {@link UwbAddress}
- */
- @NonNull
- public UwbAddress getLocalDeviceAddress() {
- return mLocalDeviceAddress;
- }
-
- /**
- * Gets a list of all remote device's {@link UwbAddress}
- *
- * @return a {@link List} of {@link UwbAddress} representing the remote devices
- */
- @NonNull
- public List<UwbAddress> getRemoteDeviceAddresses() {
- return mRemoteDeviceAddresses;
- }
-
- /**
- * Channel number used between this device pair as defined by 802.15.4z
- *
- * Range: -1, 0-15
- *
- * @return the channel to use
- */
- public int getChannelNumber() {
- return mChannelNumber;
- }
-
- /**
- * Preamble index used between this device pair as defined by 802.15.4z
- *
- * Range: 0, 0-32
- *
- * @return the preamble index to use for transmitting
- */
- public int getTxPreambleIndex() {
- return mTransmitPreambleCodeIndex;
- }
-
- /**
- * preamble index used between this device pair as defined by 802.15.4z
- *
- * Range: 0, 13-16, 21-32
- *
- * @return the preamble index to use for receiving
- */
- public int getRxPreambleIndex() {
- return mReceivePreambleCodeIndex;
- }
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {
- STS_PHY_PACKET_TYPE_SP0,
- STS_PHY_PACKET_TYPE_SP1,
- STS_PHY_PACKET_TYPE_SP2,
- STS_PHY_PACKET_TYPE_SP3})
- public @interface StsPhyPacketType {}
-
- /**
- * PHY packet type SP0 when STS is used as defined by 802.15.4z
- */
- public static final int STS_PHY_PACKET_TYPE_SP0 = 0;
-
- /**
- * PHY packet type SP1 when STS is used as defined by 802.15.4z
- */
- public static final int STS_PHY_PACKET_TYPE_SP1 = 1;
-
- /**
- * PHY packet type SP2 when STS is used as defined by 802.15.4z
- */
- public static final int STS_PHY_PACKET_TYPE_SP2 = 2;
-
- /**
- * PHY packet type SP3 when STS is used as defined by 802.15.4z
- */
- public static final int STS_PHY_PACKET_TYPE_SP3 = 3;
-
- /**
- * Get the type of PHY packet when STS is used as defined by 802.15.4z
- *
- * @return the {@link StsPhyPacketType} to use
- */
- @StsPhyPacketType
- public int getStsPhyPacketType() {
- return mStsPhyPacketType;
- }
-
- /**
- * Parameters for a specific UWB protocol constructed using a support library.
- *
- * <p>Android reserves the '^android.*' namespace
- *
- * @return a {@link PersistableBundle} copy of protocol specific parameters
- */
- public @Nullable PersistableBundle getSpecificationParameters() {
- return new PersistableBundle(mSpecificationParameters);
- }
-
- /**
- * @hide
- */
- @Override
- public boolean equals(@Nullable Object obj) {
- if (this == obj) {
- return true;
- }
-
- if (obj instanceof RangingParams) {
- RangingParams other = (RangingParams) obj;
-
- return mIsInitiator == other.mIsInitiator
- && mIsController == other.mIsController
- && mSamplePeriod.equals(other.mSamplePeriod)
- && mLocalDeviceAddress.equals(other.mLocalDeviceAddress)
- && mRemoteDeviceAddresses.equals(other.mRemoteDeviceAddresses)
- && mChannelNumber == other.mChannelNumber
- && mTransmitPreambleCodeIndex == other.mTransmitPreambleCodeIndex
- && mReceivePreambleCodeIndex == other.mReceivePreambleCodeIndex
- && mStsPhyPacketType == other.mStsPhyPacketType
- && mSpecificationParameters.size() == other.mSpecificationParameters.size()
- && mSpecificationParameters.kindofEquals(other.mSpecificationParameters);
- }
- return false;
- }
-
- /**
- * @hide
- */
- @Override
- public int hashCode() {
- return Objects.hash(mIsInitiator, mIsController, mSamplePeriod, mLocalDeviceAddress,
- mRemoteDeviceAddresses, mChannelNumber, mTransmitPreambleCodeIndex,
- mReceivePreambleCodeIndex, mStsPhyPacketType, mSpecificationParameters);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeBoolean(mIsInitiator);
- dest.writeBoolean(mIsController);
- dest.writeLong(mSamplePeriod.getSeconds());
- dest.writeInt(mSamplePeriod.getNano());
- dest.writeParcelable(mLocalDeviceAddress, flags);
-
- UwbAddress[] remoteAddresses = new UwbAddress[mRemoteDeviceAddresses.size()];
- mRemoteDeviceAddresses.toArray(remoteAddresses);
- dest.writeParcelableArray(remoteAddresses, flags);
-
- dest.writeInt(mChannelNumber);
- dest.writeInt(mTransmitPreambleCodeIndex);
- dest.writeInt(mReceivePreambleCodeIndex);
- dest.writeInt(mStsPhyPacketType);
- dest.writePersistableBundle(mSpecificationParameters);
- }
-
- public static final @android.annotation.NonNull Creator<RangingParams> CREATOR =
- new Creator<RangingParams>() {
- @Override
- public RangingParams createFromParcel(Parcel in) {
- Builder builder = new Builder();
- builder.setIsInitiator(in.readBoolean());
- builder.setIsController(in.readBoolean());
- builder.setSamplePeriod(Duration.ofSeconds(in.readLong(), in.readInt()));
- builder.setLocalDeviceAddress(
- in.readParcelable(UwbAddress.class.getClassLoader()));
-
- UwbAddress[] remoteAddresses =
- in.readParcelableArray(null, UwbAddress.class);
- for (UwbAddress remoteAddress : remoteAddresses) {
- builder.addRemoteDeviceAddress(remoteAddress);
- }
-
- builder.setChannelNumber(in.readInt());
- builder.setTransmitPreambleCodeIndex(in.readInt());
- builder.setReceivePreambleCodeIndex(in.readInt());
- builder.setStsPhPacketType(in.readInt());
- builder.setSpecificationParameters(in.readPersistableBundle());
-
- return builder.build();
- }
-
- @Override
- public RangingParams[] newArray(int size) {
- return new RangingParams[size];
- }
- };
-
- /**
- * Builder class for {@link RangingParams}.
- */
- public static final class Builder {
- private boolean mIsInitiator = false;
- private boolean mIsController = false;
- private Duration mSamplePeriod = null;
- private UwbAddress mLocalDeviceAddress = null;
- private List<UwbAddress> mRemoteDeviceAddresses = new ArrayList<>();
- private int mChannelNumber = 0;
- private int mTransmitPreambleCodeIndex = 0;
- private int mReceivePreambleCodeIndex = 0;
- private int mStsPhyPacketType = STS_PHY_PACKET_TYPE_SP0;
- private PersistableBundle mSpecificationParameters = new PersistableBundle();
-
- /**
- * Set whether the device is the initiator or responder as defined by IEEE 802.15.4z
- *
- * @param isInitiator whether the device is the initiator (true) or responder (false)
- */
- public Builder setIsInitiator(boolean isInitiator) {
- mIsInitiator = isInitiator;
- return this;
- }
-
- /**
- * Set whether the local device is the controller or controlee as defined by IEEE 802.15.4z
- *
- * @param isController whether the device is the controller (true) or controlee (false)
- */
- public Builder setIsController(boolean isController) {
- mIsController = isController;
- return this;
- }
-
- /**
- * Set the time between ranging samples
- *
- * @param samplePeriod the time between ranging samples
- */
- public Builder setSamplePeriod(@NonNull Duration samplePeriod) {
- mSamplePeriod = samplePeriod;
- return this;
- }
-
- /**
- * Set the local device address
- *
- * @param localDeviceAddress the local device's address for the {@link RangingSession}
- */
- public Builder setLocalDeviceAddress(@NonNull UwbAddress localDeviceAddress) {
- mLocalDeviceAddress = localDeviceAddress;
- return this;
- }
-
- /**
- * Add a remote device's address to the ranging session
- *
- * @param remoteDeviceAddress a remote device's address for the {@link RangingSession}
- * @throws IllegalArgumentException if {@code remoteDeviceAddress} is already present.
- */
- public Builder addRemoteDeviceAddress(@NonNull UwbAddress remoteDeviceAddress) {
- if (mRemoteDeviceAddresses.contains(remoteDeviceAddress)) {
- throw new IllegalArgumentException(
- "Remote device address already added: " + remoteDeviceAddress.toString());
- }
- mRemoteDeviceAddresses.add(remoteDeviceAddress);
- return this;
- }
-
- /**
- * Set the IEEE 802.15.4z channel to use for the {@link RangingSession}
- * <p>Valid values are in the range [-1, 15]
- *
- * @param channelNumber the channel to use for the {@link RangingSession}
- * @throws IllegalArgumentException if {@code channelNumber} is invalid.
- */
- public Builder setChannelNumber(int channelNumber) {
- if (channelNumber < -1 || channelNumber > 15) {
- throw new IllegalArgumentException("Invalid channel number");
- }
- mChannelNumber = channelNumber;
- return this;
- }
-
- private static final Set<Integer> VALID_TX_PREAMBLE_CODES = new HashSet<Integer>(
- Arrays.asList(0, 13, 14, 15, 16, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32));
-
- /**
- * Set the IEEE 802.15.4z preamble code index to use when transmitting
- *
- * <p>Valid values are in the ranges: [0], [13-16], [21-32]
- *
- * @param transmitPreambleCodeIndex preamble code index to use for transmitting
- * @throws IllegalArgumentException if {@code transmitPreambleCodeIndex} is invalid.
- */
- public Builder setTransmitPreambleCodeIndex(int transmitPreambleCodeIndex) {
- if (!VALID_TX_PREAMBLE_CODES.contains(transmitPreambleCodeIndex)) {
- throw new IllegalArgumentException(
- "Invalid transmit preamble: " + transmitPreambleCodeIndex);
- }
- mTransmitPreambleCodeIndex = transmitPreambleCodeIndex;
- return this;
- }
-
- private static final Set<Integer> VALID_RX_PREAMBLE_CODES = new HashSet<Integer>(
- Arrays.asList(0, 16, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32));
-
- /**
- * Set the IEEE 802.15.4z preamble code index to use when receiving
- *
- * Valid values are in the ranges: [0], [16-32]
- *
- * @param receivePreambleCodeIndex preamble code index to use for receiving
- * @throws IllegalArgumentException if {@code receivePreambleCodeIndex} is invalid.
- */
- public Builder setReceivePreambleCodeIndex(int receivePreambleCodeIndex) {
- if (!VALID_RX_PREAMBLE_CODES.contains(receivePreambleCodeIndex)) {
- throw new IllegalArgumentException(
- "Invalid receive preamble: " + receivePreambleCodeIndex);
- }
- mReceivePreambleCodeIndex = receivePreambleCodeIndex;
- return this;
- }
-
- /**
- * Set the IEEE 802.15.4z PHY packet type when STS is used
- *
- * @param stsPhyPacketType PHY packet type when STS is used
- * @throws IllegalArgumentException if {@code stsPhyPacketType} is invalid.
- */
- public Builder setStsPhPacketType(@StsPhyPacketType int stsPhyPacketType) {
- if (stsPhyPacketType != STS_PHY_PACKET_TYPE_SP0
- && stsPhyPacketType != STS_PHY_PACKET_TYPE_SP1
- && stsPhyPacketType != STS_PHY_PACKET_TYPE_SP2
- && stsPhyPacketType != STS_PHY_PACKET_TYPE_SP3) {
- throw new IllegalArgumentException("unknown StsPhyPacketType: " + stsPhyPacketType);
- }
-
- mStsPhyPacketType = stsPhyPacketType;
- return this;
- }
-
- /**
- * Set the specification parameters
- *
- * <p>Creates a copy of the parameters
- *
- * @param parameters specification parameters built from support library
- */
- public Builder setSpecificationParameters(@NonNull PersistableBundle parameters) {
- mSpecificationParameters = new PersistableBundle(parameters);
- return this;
- }
-
- /**
- * Build the {@link RangingParams} object.
- *
- * @throws IllegalStateException if required parameters are missing
- */
- public RangingParams build() {
- if (mSamplePeriod == null) {
- throw new IllegalStateException("No sample period provided");
- }
-
- if (mLocalDeviceAddress == null) {
- throw new IllegalStateException("Local device address not provided");
- }
-
- if (mRemoteDeviceAddresses.size() == 0) {
- throw new IllegalStateException("No remote device address(es) provided");
- }
-
- return new RangingParams(mIsInitiator, mIsController, mSamplePeriod,
- mLocalDeviceAddress, mRemoteDeviceAddresses, mChannelNumber,
- mTransmitPreambleCodeIndex, mReceivePreambleCodeIndex, mStsPhyPacketType,
- mSpecificationParameters);
- }
- }
-}
diff --git a/core/java/android/uwb/RangingSession.java b/core/java/android/uwb/RangingSession.java
index f4033fe..8639269 100644
--- a/core/java/android/uwb/RangingSession.java
+++ b/core/java/android/uwb/RangingSession.java
@@ -30,7 +30,7 @@
* {@link RangingSession}.
*
* <p>To get an instance of {@link RangingSession}, first use
- * {@link UwbManager#openRangingSession(RangingParams, Executor, Callback)} to request to open a
+ * {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)} to request to open a
* session. Once the session is opened, a {@link RangingSession} object is provided through
* {@link RangingSession.Callback#onOpenSuccess(RangingSession, PersistableBundle)}. If opening a
* session fails, the failure is reported through {@link RangingSession.Callback#onClosed(int)} with
@@ -44,7 +44,7 @@
*/
public interface Callback {
/**
- * Invoked when {@link UwbManager#openRangingSession(RangingParams, Executor, Callback)}
+ * Invoked when {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)}
* is successful
*
* @param session the newly opened {@link RangingSession}
@@ -77,7 +77,7 @@
/**
* Indicates that the session failed to open due to erroneous parameters passed
- * to {@link UwbManager#openRangingSession(RangingParams, Executor, Callback)}
+ * to {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)}
*/
int CLOSE_REASON_LOCAL_BAD_PARAMETERS = 2;
@@ -137,8 +137,8 @@
* will still be invoked.
*
* <p>{@link Callback#onClosed(int)} will be invoked using the same callback
- * object given to {@link UwbManager#openRangingSession(RangingParams, Executor, Callback)} when
- * the {@link RangingSession} was opened. The callback will be invoked after each call to
+ * object given to {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)}
+ * when the {@link RangingSession} was opened. The callback will be invoked after each call to
* {@link #close()}, even if the {@link RangingSession} is already closed.
*/
@Override
diff --git a/core/java/android/uwb/UwbManager.java b/core/java/android/uwb/UwbManager.java
index 6bf7d6f..2f1e2de 100644
--- a/core/java/android/uwb/UwbManager.java
+++ b/core/java/android/uwb/UwbManager.java
@@ -279,7 +279,10 @@
* <p>An open {@link RangingSession} will be automatically closed if client application process
* dies.
*
- * @param params {@link RangingParams} used to initialize this {@link RangingSession}
+ * <p>A UWB support library must be used in order to construct the {@code parameter}
+ * {@link PersistableBundle}.
+ *
+ * @param parameters the parameters that define the ranging session
* @param executor {@link Executor} to run callbacks
* @param callbacks {@link RangingSession.Callback} to associate with the
* {@link RangingSession} that is being opened.
@@ -290,8 +293,9 @@
* {@link RangingSession.Callback#onOpenSuccess}.
*/
@NonNull
- public AutoCloseable openRangingSession(@NonNull RangingParams params,
- @NonNull Executor executor, @NonNull RangingSession.Callback callbacks) {
+ public AutoCloseable openRangingSession(@NonNull PersistableBundle parameters,
+ @NonNull Executor executor,
+ @NonNull RangingSession.Callback callbacks) {
throw new UnsupportedOperationException();
}
}
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index fbee833..bcb3a36 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -828,6 +828,9 @@
@VisibleForTesting
public void show(@InsetsType int types, boolean fromIme) {
+ if ((types & ime()) != 0) {
+ Log.d(TAG, "show(ime(), fromIme=" + fromIme + ")");
+ }
if (fromIme) {
ImeTracing.getInstance().triggerDump();
Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApiToImeReady", 0);
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index b4a841f..72f76d1 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -2237,6 +2237,8 @@
PRIVATE_FLAG_BEHAVIOR_CONTROLLED,
PRIVATE_FLAG_FIT_INSETS_CONTROLLED,
PRIVATE_FLAG_TRUSTED_OVERLAY,
+ PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME,
+ PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP,
})
public @interface PrivateFlags {}
@@ -2347,6 +2349,10 @@
equals = PRIVATE_FLAG_TRUSTED_OVERLAY,
name = "TRUSTED_OVERLAY"),
@ViewDebug.FlagToString(
+ mask = PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME,
+ equals = PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME,
+ name = "INSET_PARENT_FRAME_BY_IME"),
+ @ViewDebug.FlagToString(
mask = PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP,
equals = PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP,
name = "INTERCEPT_GLOBAL_DRAG_AND_DROP")
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 6243c63..f1cbd25 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1672,10 +1672,12 @@
checkFocus();
synchronized (mH) {
if (!hasServedByInputMethodLocked(view)) {
+ Log.w(TAG, "Ignoring showSoftInput() as view=" + view + " is not served.");
return false;
}
try {
+ Log.d(TAG, "showSoftInput() view=" + view + " flags=" + flags);
return mService.showSoftInput(
mClient, view.getWindowToken(), flags, resultReceiver);
} catch (RemoteException e) {
diff --git a/core/java/android/window/DisplayAreaOrganizer.java b/core/java/android/window/DisplayAreaOrganizer.java
index bc3e35c..6cc3cd3 100644
--- a/core/java/android/window/DisplayAreaOrganizer.java
+++ b/core/java/android/window/DisplayAreaOrganizer.java
@@ -78,6 +78,12 @@
public static final int FEATURE_FULLSCREEN_MAGNIFICATION = FEATURE_SYSTEM_FIRST + 5;
/**
+ * Display area for hiding display cutout feature
+ * @hide
+ */
+ public static final int FEATURE_HIDE_DISPLAY_CUTOUT = FEATURE_SYSTEM_FIRST + 6;
+
+ /**
* The last boundary of display area for system features
*/
public static final int FEATURE_SYSTEM_LAST = 10_000;
diff --git a/core/java/android/window/ITaskOrganizer.aidl b/core/java/android/window/ITaskOrganizer.aidl
index abca136..b503184 100644
--- a/core/java/android/window/ITaskOrganizer.aidl
+++ b/core/java/android/window/ITaskOrganizer.aidl
@@ -26,6 +26,21 @@
*/
oneway interface ITaskOrganizer {
/**
+ * Called when a Task is starting and the system would like to show a UI to indicate that an
+ * application is starting. The client is responsible to add/remove the starting window if it
+ * has create a starting window for the Task.
+ *
+ * @param taskInfo The information about the Task that's available
+ * @param appToken Token of the application being started.
+ */
+ void addStartingWindow(in ActivityManager.RunningTaskInfo taskInfo, IBinder appToken);
+
+ /**
+ * Called when the Task want to remove the starting window.
+ */
+ void removeStartingWindow(in ActivityManager.RunningTaskInfo taskInfo);
+
+ /**
* A callback when the Task is available for the registered organizer. The client is responsible
* for releasing the SurfaceControl in the callback. For non-root tasks, the leash may initially
* be hidden so it is up to the organizer to show this task.
diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java
index 4e20920..eda168d 100644
--- a/core/java/android/window/TaskOrganizer.java
+++ b/core/java/android/window/TaskOrganizer.java
@@ -85,6 +85,25 @@
}
/**
+ * Called when a Task is starting and the system would like to show a UI to indicate that an
+ * application is starting. The client is responsible to add/remove the starting window if it
+ * has create a starting window for the Task.
+ *
+ * @param taskInfo The information about the Task that's available
+ * @param appToken Token of the application being started.
+ * context to for resources
+ */
+ @BinderThread
+ public void addStartingWindow(@NonNull ActivityManager.RunningTaskInfo taskInfo,
+ @NonNull IBinder appToken) {}
+
+ /**
+ * Called when the Task want to remove the starting window.
+ */
+ @BinderThread
+ public void removeStartingWindow(@NonNull ActivityManager.RunningTaskInfo taskInfo) {}
+
+ /**
* Called when a task with the registered windowing mode can be controlled by this task
* organizer. For non-root tasks, the leash may initially be hidden so it is up to the organizer
* to show this task.
@@ -192,6 +211,15 @@
}
private final ITaskOrganizer mInterface = new ITaskOrganizer.Stub() {
+ @Override
+ public void addStartingWindow(ActivityManager.RunningTaskInfo taskInfo, IBinder appToken) {
+ TaskOrganizer.this.addStartingWindow(taskInfo, appToken);
+ }
+
+ @Override
+ public void removeStartingWindow(ActivityManager.RunningTaskInfo taskInfo) {
+ TaskOrganizer.this.removeStartingWindow(taskInfo);
+ }
@Override
public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
diff --git a/core/java/com/android/internal/app/ISoundTriggerService.aidl b/core/java/com/android/internal/app/ISoundTriggerService.aidl
index f8aac42..3874de3 100644
--- a/core/java/com/android/internal/app/ISoundTriggerService.aidl
+++ b/core/java/com/android/internal/app/ISoundTriggerService.aidl
@@ -38,8 +38,12 @@
*
* It is good practice to clear the binder calling identity prior to calling this, in case the
* caller is ever in the same process as the callee.
+ *
+ * The binder object being passed is used by the server to keep track of client death, in order
+ * to clean-up whenever that happens.
*/
- ISoundTriggerSession attachAsOriginator(in Identity originatorIdentity);
+ ISoundTriggerSession attachAsOriginator(in Identity originatorIdentity,
+ IBinder client);
/**
* Creates a new session.
@@ -54,7 +58,11 @@
*
* It is good practice to clear the binder calling identity prior to calling this, in case the
* caller is ever in the same process as the callee.
+ *
+ * The binder object being passed is used by the server to keep track of client death, in order
+ * to clean-up whenever that happens.
*/
ISoundTriggerSession attachAsMiddleman(in Identity middlemanIdentity,
- in Identity originatorIdentity);
+ in Identity originatorIdentity,
+ IBinder client);
}
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index 81c61aa..db25514 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -216,7 +216,11 @@
* Caller must provide an identity, used for permission tracking purposes.
* The uid/pid elements of the identity will be ignored by the server and replaced with the ones
* provided by binder.
+ *
+ * The client argument is any binder owned by the client, used for tracking is death and
+ * cleaning up in this event.
*/
IVoiceInteractionSoundTriggerSession createSoundTriggerSessionAsOriginator(
- in Identity originatorIdentity);
+ in Identity originatorIdentity,
+ IBinder client);
}
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index 137430b..bb7e2af 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -348,6 +348,57 @@
}
/**
+ * A helper method to translate interaction type to CUJ name.
+ *
+ * @param interactionType the interaction type defined in AtomsProto.java
+ * @return the name of the interaction type
+ */
+ public static String getNameOfInteraction(int interactionType) {
+ // There is an offset amount of 1 between cujType and interactionType.
+ return getNameOfCuj(interactionType - 1);
+ }
+
+ private static String getNameOfCuj(int cujType) {
+ switch (cujType) {
+ case CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE:
+ return "SHADE_EXPAND_COLLAPSE";
+ case CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE_LOCK:
+ return "SHADE_EXPAND_COLLAPSE_LOCK";
+ case CUJ_NOTIFICATION_SHADE_SCROLL_FLING:
+ return "SHADE_SCROLL_FLING";
+ case CUJ_NOTIFICATION_SHADE_ROW_EXPAND:
+ return "SHADE_ROW_EXPAND";
+ case CUJ_NOTIFICATION_SHADE_ROW_SWIPE:
+ return "SHADE_ROW_SWIPE";
+ case CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE:
+ return "SHADE_QS_EXPAND_COLLAPSE";
+ case CUJ_NOTIFICATION_SHADE_QS_SCROLL_SWIPE:
+ return "SHADE_QS_SCROLL_SWIPE";
+ case CUJ_LAUNCHER_APP_LAUNCH_FROM_RECENTS:
+ return "LAUNCHER_APP_LAUNCH_FROM_RECENTS";
+ case CUJ_LAUNCHER_APP_LAUNCH_FROM_ICON:
+ return "LAUNCHER_APP_LAUNCH_FROM_ICON";
+ case CUJ_LAUNCHER_APP_CLOSE_TO_HOME:
+ return "LAUNCHER_APP_CLOSE_TO_HOME";
+ case CUJ_LAUNCHER_APP_CLOSE_TO_PIP:
+ return "LAUNCHER_APP_CLOSE_TO_PIP";
+ case CUJ_LAUNCHER_QUICK_SWITCH:
+ return "LAUNCHER_QUICK_SWITCH";
+ case CUJ_NOTIFICATION_HEADS_UP_APPEAR:
+ return "NOTIFICATION_HEADS_UP_APPEAR";
+ case CUJ_NOTIFICATION_HEADS_UP_DISAPPEAR:
+ return "NOTIFICATION_HEADS_UP_DISAPPEAR";
+ case CUJ_NOTIFICATION_ADD:
+ return "NOTIFICATION_ADD";
+ case CUJ_NOTIFICATION_REMOVE:
+ return "NOTIFICATION_REMOVE";
+ case CUJ_NOTIFICATION_APP_START:
+ return "NOTIFICATION_APP_START";
+ }
+ return "UNKNOWN";
+ }
+
+ /**
* A class to represent a session.
*/
public static class Session {
diff --git a/core/java/com/android/internal/os/BaseCommand.java b/core/java/com/android/internal/os/BaseCommand.java
index c110b26..c85b5d7 100644
--- a/core/java/com/android/internal/os/BaseCommand.java
+++ b/core/java/com/android/internal/os/BaseCommand.java
@@ -18,9 +18,10 @@
package com.android.internal.os;
import android.compat.annotation.UnsupportedAppUsage;
-import android.os.BasicShellCommandHandler;
import android.os.Build;
+import com.android.modules.utils.BasicShellCommandHandler;
+
import java.io.PrintStream;
public abstract class BaseCommand {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index e7e75a8..7c442b4 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -4014,7 +4014,7 @@
/**
* Schedules a read of the latest cpu times before removing the isolated UID.
- * @see #removeIsolatedUidLocked(int)
+ * @see #removeIsolatedUidLocked(int, int, int)
*/
public void scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid) {
int curUid = mIsolatedUids.get(isolatedUid, -1);
@@ -4030,14 +4030,6 @@
* @see #scheduleRemoveIsolatedUidLocked(int, int)
*/
@GuardedBy("this")
- public void removeIsolatedUidLocked(int isolatedUid) {
- removeIsolatedUidLocked(isolatedUid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
- }
-
- /**
- * @see #removeIsolatedUidLocked(int)
- */
- @GuardedBy("this")
public void removeIsolatedUidLocked(int isolatedUid, long elapsedRealtimeMs, long uptimeMs) {
final int idx = mIsolatedUids.indexOfKey(isolatedUid);
if (idx >= 0) {
@@ -11429,13 +11421,6 @@
* Distribute WiFi energy info and network traffic to apps.
* @param info The energy information from the WiFi controller.
*/
- public void updateWifiState(@Nullable final WifiActivityEnergyInfo info) {
- updateWifiState(info, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
- }
-
- /**
- * @see #updateWifiState(WifiActivityEnergyInfo)
- */
public void updateWifiState(@Nullable final WifiActivityEnergyInfo info,
long elapsedRealtimeMs, long uptimeMs) {
if (DEBUG_ENERGY) {
@@ -11714,13 +11699,6 @@
/**
* Distribute Cell radio energy info and network traffic to apps.
*/
- public void updateMobileRadioState(@Nullable final ModemActivityInfo activityInfo) {
- updateMobileRadioState(activityInfo, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
- }
-
- /**
- * @see #updateMobileRadioState(ModemActivityInfo)
- */
public void updateMobileRadioState(@Nullable final ModemActivityInfo activityInfo,
long elapsedRealtimeMs, long uptimeMs) {
if (DEBUG_ENERGY) {
@@ -11954,13 +11932,6 @@
*
* @param info The energy information from the bluetooth controller.
*/
- public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) {
- updateBluetoothStateLocked(info, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
- }
-
- /**
- * @see #updateBluetoothStateLocked(BluetoothActivityEnergyInfo)
- */
public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info,
long elapsedRealtimeMs, long uptimeMs) {
if (DEBUG_ENERGY) {
@@ -12138,13 +12109,6 @@
* If RPM stats were fetched more recently than RPM_STATS_UPDATE_FREQ_MS ago, uses the old data
* instead of fetching it anew.
*/
- public void updateRpmStatsLocked() {
- updateRpmStatsLocked(mClocks.elapsedRealtime() * 1000);
- }
-
- /**
- * @see #updateRpmStatsLocked()
- */
public void updateRpmStatsLocked(long elapsedRealtimeUs) {
if (mPlatformIdleStateCallback == null) return;
long now = SystemClock.elapsedRealtime();
diff --git a/core/java/com/android/internal/util/BinaryXmlPullParser.java b/core/java/com/android/internal/util/BinaryXmlPullParser.java
new file mode 100644
index 0000000..da16eca
--- /dev/null
+++ b/core/java/com/android/internal/util/BinaryXmlPullParser.java
@@ -0,0 +1,899 @@
+/*
+ * Copyright (C) 2020 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.internal.util;
+
+import static com.android.internal.util.BinaryXmlSerializer.ATTRIBUTE;
+import static com.android.internal.util.BinaryXmlSerializer.PROTOCOL_MAGIC_VERSION_0;
+import static com.android.internal.util.BinaryXmlSerializer.TYPE_BOOLEAN_FALSE;
+import static com.android.internal.util.BinaryXmlSerializer.TYPE_BOOLEAN_TRUE;
+import static com.android.internal.util.BinaryXmlSerializer.TYPE_BYTES_BASE64;
+import static com.android.internal.util.BinaryXmlSerializer.TYPE_BYTES_HEX;
+import static com.android.internal.util.BinaryXmlSerializer.TYPE_DOUBLE;
+import static com.android.internal.util.BinaryXmlSerializer.TYPE_FLOAT;
+import static com.android.internal.util.BinaryXmlSerializer.TYPE_INT;
+import static com.android.internal.util.BinaryXmlSerializer.TYPE_INT_HEX;
+import static com.android.internal.util.BinaryXmlSerializer.TYPE_LONG;
+import static com.android.internal.util.BinaryXmlSerializer.TYPE_LONG_HEX;
+import static com.android.internal.util.BinaryXmlSerializer.TYPE_NULL;
+import static com.android.internal.util.BinaryXmlSerializer.TYPE_STRING;
+import static com.android.internal.util.BinaryXmlSerializer.TYPE_STRING_INTERNED;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.text.TextUtils;
+import android.util.Base64;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * Parser that reads XML documents using a custom binary wire protocol which
+ * benchmarking has shown to be 8.5x faster than {@link Xml.newFastPullParser()}
+ * for a typical {@code packages.xml}.
+ * <p>
+ * The high-level design of the wire protocol is to directly serialize the event
+ * stream, while efficiently and compactly writing strongly-typed primitives
+ * delivered through the {@link TypedXmlSerializer} interface.
+ * <p>
+ * Each serialized event is a single byte where the lower half is a normal
+ * {@link XmlPullParser} token and the upper half is an optional data type
+ * signal, such as {@link #TYPE_INT}.
+ * <p>
+ * This parser has some specific limitations:
+ * <ul>
+ * <li>Only the UTF-8 encoding is supported.
+ * <li>Variable length values, such as {@code byte[]} or {@link String}, are
+ * limited to 65,535 bytes in length. Note that {@link String} values are stored
+ * as UTF-8 on the wire.
+ * <li>Namespaces, prefixes, properties, and options are unsupported.
+ * </ul>
+ */
+public final class BinaryXmlPullParser implements TypedXmlPullParser {
+ /**
+ * Default buffer size, which matches {@code FastXmlSerializer}. This should
+ * be kept in sync with {@link BinaryXmlPullParser}.
+ */
+ private static final int BUFFER_SIZE = 32_768;
+
+ private FastDataInput mIn;
+
+ private int mCurrentToken = START_DOCUMENT;
+ private int mCurrentDepth = 0;
+ private String mCurrentName;
+ private String mCurrentText;
+
+ /**
+ * Pool of attributes parsed for the currently tag. All interactions should
+ * be done via {@link #obtainAttribute()}, {@link #findAttribute(String)},
+ * and {@link #resetAttributes()}.
+ */
+ private int mAttributeCount = 0;
+ private Attribute[] mAttributes;
+
+ @Override
+ public void setInput(InputStream is, String inputEncoding) throws XmlPullParserException {
+ if (inputEncoding != null && !StandardCharsets.UTF_8.name().equals(inputEncoding)) {
+ throw new UnsupportedOperationException();
+ }
+
+ mIn = new FastDataInput(is, BUFFER_SIZE);
+
+ mCurrentToken = START_DOCUMENT;
+ mCurrentDepth = 0;
+ mCurrentName = null;
+ mCurrentText = null;
+
+ mAttributeCount = 0;
+ mAttributes = new Attribute[8];
+ for (int i = 0; i < mAttributes.length; i++) {
+ mAttributes[i] = new Attribute();
+ }
+
+ try {
+ final byte[] magic = new byte[4];
+ mIn.readFully(magic);
+ if (!Arrays.equals(magic, PROTOCOL_MAGIC_VERSION_0)) {
+ throw new IOException("Unexpected magic " + bytesToHexString(magic));
+ }
+
+ // We're willing to immediately consume a START_DOCUMENT if present,
+ // but we're okay if it's missing
+ if (peekNextExternalToken() == START_DOCUMENT) {
+ consumeToken();
+ }
+ } catch (IOException e) {
+ throw new XmlPullParserException(e.toString());
+ }
+ }
+
+ @Override
+ public void setInput(Reader in) throws XmlPullParserException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int next() throws XmlPullParserException, IOException {
+ while (true) {
+ final int token = nextToken();
+ switch (token) {
+ case START_TAG:
+ case END_TAG:
+ case END_DOCUMENT:
+ return token;
+ case TEXT:
+ consumeAdditionalText();
+ // Per interface docs, empty text regions are skipped
+ if (mCurrentText == null || mCurrentText.length() == 0) {
+ continue;
+ } else {
+ return TEXT;
+ }
+ }
+ }
+ }
+
+ @Override
+ public int nextToken() throws XmlPullParserException, IOException {
+ if (mCurrentToken == XmlPullParser.END_TAG) {
+ mCurrentDepth--;
+ }
+
+ int token;
+ try {
+ token = peekNextExternalToken();
+ consumeToken();
+ } catch (EOFException e) {
+ token = END_DOCUMENT;
+ }
+ switch (token) {
+ case XmlPullParser.START_TAG:
+ // We need to peek forward to find the next external token so
+ // that we parse all pending INTERNAL_ATTRIBUTE tokens
+ peekNextExternalToken();
+ mCurrentDepth++;
+ break;
+ }
+ mCurrentToken = token;
+ return token;
+ }
+
+ /**
+ * Peek at the next "external" token without consuming it.
+ * <p>
+ * External tokens, such as {@link #START_TAG}, are expected by typical
+ * {@link XmlPullParser} clients. In contrast, internal tokens, such as
+ * {@link #ATTRIBUTE}, are not expected by typical clients.
+ * <p>
+ * This method consumes any internal events until it reaches the next
+ * external event.
+ */
+ private int peekNextExternalToken() throws IOException, XmlPullParserException {
+ while (true) {
+ final int token = peekNextToken();
+ switch (token) {
+ case ATTRIBUTE:
+ consumeToken();
+ continue;
+ default:
+ return token;
+ }
+ }
+ }
+
+ /**
+ * Peek at the next token in the underlying stream without consuming it.
+ */
+ private int peekNextToken() throws IOException {
+ return mIn.peekByte() & 0x0f;
+ }
+
+ /**
+ * Parse and consume the next token in the underlying stream.
+ */
+ private void consumeToken() throws IOException, XmlPullParserException {
+ final int event = mIn.readByte();
+ final int token = event & 0x0f;
+ final int type = event & 0xf0;
+ switch (token) {
+ case ATTRIBUTE: {
+ final Attribute attr = obtainAttribute();
+ attr.name = mIn.readInternedUTF();
+ attr.type = type;
+ switch (type) {
+ case TYPE_NULL:
+ case TYPE_BOOLEAN_TRUE:
+ case TYPE_BOOLEAN_FALSE:
+ // Nothing extra to fill in
+ break;
+ case TYPE_STRING:
+ attr.valueString = mIn.readUTF();
+ break;
+ case TYPE_STRING_INTERNED:
+ attr.valueString = mIn.readInternedUTF();
+ break;
+ case TYPE_BYTES_HEX:
+ case TYPE_BYTES_BASE64:
+ final int len = mIn.readUnsignedShort();
+ final byte[] res = new byte[len];
+ mIn.readFully(res);
+ attr.valueBytes = res;
+ break;
+ case TYPE_INT:
+ case TYPE_INT_HEX:
+ attr.valueInt = mIn.readInt();
+ break;
+ case TYPE_LONG:
+ case TYPE_LONG_HEX:
+ attr.valueLong = mIn.readLong();
+ break;
+ case TYPE_FLOAT:
+ attr.valueFloat = mIn.readFloat();
+ break;
+ case TYPE_DOUBLE:
+ attr.valueDouble = mIn.readDouble();
+ break;
+ default:
+ throw new IOException("Unexpected data type " + type);
+ }
+ break;
+ }
+ case XmlPullParser.START_DOCUMENT: {
+ break;
+ }
+ case XmlPullParser.END_DOCUMENT: {
+ break;
+ }
+ case XmlPullParser.START_TAG: {
+ mCurrentName = mIn.readInternedUTF();
+ resetAttributes();
+ break;
+ }
+ case XmlPullParser.END_TAG: {
+ mCurrentName = mIn.readInternedUTF();
+ resetAttributes();
+ break;
+ }
+ case XmlPullParser.TEXT:
+ case XmlPullParser.CDSECT:
+ case XmlPullParser.PROCESSING_INSTRUCTION:
+ case XmlPullParser.COMMENT:
+ case XmlPullParser.DOCDECL:
+ case XmlPullParser.IGNORABLE_WHITESPACE: {
+ mCurrentText = mIn.readUTF();
+ break;
+ }
+ case XmlPullParser.ENTITY_REF: {
+ mCurrentName = mIn.readUTF();
+ mCurrentText = resolveEntity(mCurrentName);
+ break;
+ }
+ default: {
+ throw new IOException("Unknown token " + token + " with type " + type);
+ }
+ }
+ }
+
+ /**
+ * When the current tag is {@link #TEXT}, consume all subsequent "text"
+ * events, as described by {@link #next}. When finished, the current event
+ * will still be {@link #TEXT}.
+ */
+ private void consumeAdditionalText() throws IOException, XmlPullParserException {
+ String combinedText = mCurrentText;
+ while (true) {
+ final int token = peekNextExternalToken();
+ switch (token) {
+ case COMMENT:
+ case PROCESSING_INSTRUCTION:
+ // Quietly consumed
+ consumeToken();
+ break;
+ case TEXT:
+ case CDSECT:
+ case ENTITY_REF:
+ // Additional text regions collected
+ consumeToken();
+ combinedText += mCurrentText;
+ break;
+ default:
+ // Next token is something non-text, so wrap things up
+ mCurrentToken = TEXT;
+ mCurrentName = null;
+ mCurrentText = combinedText;
+ return;
+ }
+ }
+ }
+
+ static @NonNull String resolveEntity(@NonNull String entity)
+ throws XmlPullParserException {
+ switch (entity) {
+ case "lt": return "<";
+ case "gt": return ">";
+ case "amp": return "&";
+ case "apos": return "'";
+ case "quot": return "\"";
+ }
+ if (entity.length() > 1 && entity.charAt(0) == '#') {
+ final char c = (char) Integer.parseInt(entity.substring(1));
+ return new String(new char[] { c });
+ }
+ throw new XmlPullParserException("Unknown entity " + entity);
+ }
+
+ @Override
+ public void require(int type, String namespace, String name)
+ throws XmlPullParserException, IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ if (mCurrentToken != type || !Objects.equals(mCurrentName, name)) {
+ throw new XmlPullParserException(getPositionDescription());
+ }
+ }
+
+ @Override
+ public String nextText() throws XmlPullParserException, IOException {
+ if (getEventType() != START_TAG) {
+ throw new XmlPullParserException(getPositionDescription());
+ }
+ int eventType = next();
+ if (eventType == TEXT) {
+ String result = getText();
+ eventType = next();
+ if (eventType != END_TAG) {
+ throw new XmlPullParserException(getPositionDescription());
+ }
+ return result;
+ } else if (eventType == END_TAG) {
+ return "";
+ } else {
+ throw new XmlPullParserException(getPositionDescription());
+ }
+ }
+
+ @Override
+ public int nextTag() throws XmlPullParserException, IOException {
+ int eventType = next();
+ if (eventType == TEXT && isWhitespace()) {
+ eventType = next();
+ }
+ if (eventType != START_TAG && eventType != END_TAG) {
+ throw new XmlPullParserException(getPositionDescription());
+ }
+ return eventType;
+ }
+
+ /**
+ * Allocate and return a new {@link Attribute} associated with the tag being
+ * currently processed. This will automatically grow the internal pool as
+ * needed.
+ */
+ private @NonNull Attribute obtainAttribute() {
+ if (mAttributeCount == mAttributes.length) {
+ final int before = mAttributes.length;
+ final int after = before + (before >> 1);
+ mAttributes = Arrays.copyOf(mAttributes, after);
+ for (int i = before; i < after; i++) {
+ mAttributes[i] = new Attribute();
+ }
+ }
+ return mAttributes[mAttributeCount++];
+ }
+
+ /**
+ * Clear any {@link Attribute} instances that have been allocated by
+ * {@link #obtainAttribute()}, returning them into the pool for recycling.
+ */
+ private void resetAttributes() {
+ for (int i = 0; i < mAttributeCount; i++) {
+ mAttributes[i].reset();
+ }
+ mAttributeCount = 0;
+ }
+
+ /**
+ * Search through the pool of currently allocated {@link Attribute}
+ * instances for one that matches the given name.
+ */
+ private @NonNull Attribute findAttribute(@NonNull String name) throws IOException {
+ for (int i = 0; i < mAttributeCount; i++) {
+ if (Objects.equals(mAttributes[i].name, name)) {
+ return mAttributes[i];
+ }
+ }
+ throw new IOException("Missing attribute " + name);
+ }
+
+ @Override
+ public String getAttributeValue(String namespace, String name) {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ try {
+ return findAttribute(name).getValueString();
+ } catch (IOException e) {
+ // Missing attributes default to null
+ return null;
+ }
+ }
+
+ @Override
+ public String getAttributeValue(int index) {
+ return mAttributes[index].getValueString();
+ }
+
+ @Override
+ public byte[] getAttributeBytesHex(String namespace, String name) throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ return findAttribute(name).getValueBytesHex();
+ }
+
+ @Override
+ public byte[] getAttributeBytesBase64(String namespace, String name) throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ return findAttribute(name).getValueBytesBase64();
+ }
+
+ @Override
+ public int getAttributeInt(String namespace, String name) throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ return findAttribute(name).getValueInt();
+ }
+
+ @Override
+ public int getAttributeIntHex(String namespace, String name) throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ return findAttribute(name).getValueIntHex();
+ }
+
+ @Override
+ public long getAttributeLong(String namespace, String name) throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ return findAttribute(name).getValueLong();
+ }
+
+ @Override
+ public long getAttributeLongHex(String namespace, String name) throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ return findAttribute(name).getValueLongHex();
+ }
+
+ @Override
+ public float getAttributeFloat(String namespace, String name) throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ return findAttribute(name).getValueFloat();
+ }
+
+ @Override
+ public double getAttributeDouble(String namespace, String name) throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ return findAttribute(name).getValueDouble();
+ }
+
+ @Override
+ public boolean getAttributeBoolean(String namespace, String name) throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ return findAttribute(name).getValueBoolean();
+ }
+
+ @Override
+ public String getText() {
+ return mCurrentText;
+ }
+
+ @Override
+ public char[] getTextCharacters(int[] holderForStartAndLength) {
+ final char[] chars = mCurrentText.toCharArray();
+ holderForStartAndLength[0] = 0;
+ holderForStartAndLength[1] = chars.length;
+ return chars;
+ }
+
+ @Override
+ public String getInputEncoding() {
+ return StandardCharsets.UTF_8.name();
+ }
+
+ @Override
+ public int getDepth() {
+ return mCurrentDepth;
+ }
+
+ @Override
+ public String getPositionDescription() {
+ // Not very helpful, but it's the best information we have
+ return "Token " + mCurrentToken + " at depth " + mCurrentDepth;
+ }
+
+ @Override
+ public int getLineNumber() {
+ return -1;
+ }
+
+ @Override
+ public int getColumnNumber() {
+ return -1;
+ }
+
+ @Override
+ public boolean isWhitespace() throws XmlPullParserException {
+ switch (mCurrentToken) {
+ case IGNORABLE_WHITESPACE:
+ return true;
+ case TEXT:
+ case CDSECT:
+ return !TextUtils.isGraphic(mCurrentText);
+ default:
+ throw new XmlPullParserException("Not applicable for token " + mCurrentToken);
+ }
+ }
+
+ @Override
+ public String getNamespace() {
+ switch (mCurrentToken) {
+ case START_TAG:
+ case END_TAG:
+ // Namespaces are unsupported
+ return NO_NAMESPACE;
+ default:
+ return null;
+ }
+ }
+
+ @Override
+ public String getName() {
+ return mCurrentName;
+ }
+
+ @Override
+ public String getPrefix() {
+ // Prefixes are not supported
+ return null;
+ }
+
+ @Override
+ public boolean isEmptyElementTag() throws XmlPullParserException {
+ switch (mCurrentToken) {
+ case START_TAG:
+ try {
+ return (peekNextExternalToken() == END_TAG);
+ } catch (IOException e) {
+ throw new XmlPullParserException(e.toString());
+ }
+ default:
+ throw new XmlPullParserException("Not at START_TAG");
+ }
+ }
+
+ @Override
+ public int getAttributeCount() {
+ return mAttributeCount;
+ }
+
+ @Override
+ public String getAttributeNamespace(int index) {
+ // Namespaces are unsupported
+ return NO_NAMESPACE;
+ }
+
+ @Override
+ public String getAttributeName(int index) {
+ return mAttributes[index].name;
+ }
+
+ @Override
+ public String getAttributePrefix(int index) {
+ // Prefixes are not supported
+ return null;
+ }
+
+ @Override
+ public String getAttributeType(int index) {
+ // Validation is not supported
+ return "CDATA";
+ }
+
+ @Override
+ public boolean isAttributeDefault(int index) {
+ // Validation is not supported
+ return false;
+ }
+
+ @Override
+ public int getEventType() throws XmlPullParserException {
+ return mCurrentToken;
+ }
+
+ @Override
+ public int getNamespaceCount(int depth) throws XmlPullParserException {
+ // Namespaces are unsupported
+ return 0;
+ }
+
+ @Override
+ public String getNamespacePrefix(int pos) throws XmlPullParserException {
+ // Namespaces are unsupported
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getNamespaceUri(int pos) throws XmlPullParserException {
+ // Namespaces are unsupported
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getNamespace(String prefix) {
+ // Namespaces are unsupported
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void defineEntityReplacementText(String entityName, String replacementText)
+ throws XmlPullParserException {
+ // Custom entities are not supported
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setFeature(String name, boolean state) throws XmlPullParserException {
+ // Features are not supported
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean getFeature(String name) {
+ // Features are not supported
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setProperty(String name, Object value) throws XmlPullParserException {
+ // Properties are not supported
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Object getProperty(String name) {
+ // Properties are not supported
+ throw new UnsupportedOperationException();
+ }
+
+ private static IllegalArgumentException illegalNamespace() {
+ throw new IllegalArgumentException("Namespaces are not supported");
+ }
+
+ /**
+ * Holder representing a single attribute. This design enables object
+ * recycling without resorting to autoboxing.
+ * <p>
+ * To support conversion between human-readable XML and binary XML, the
+ * various accessor methods will transparently convert from/to
+ * human-readable values when needed.
+ */
+ private static class Attribute {
+ public String name;
+ public int type;
+
+ public String valueString;
+ public byte[] valueBytes;
+ public int valueInt;
+ public long valueLong;
+ public float valueFloat;
+ public double valueDouble;
+
+ public void reset() {
+ name = null;
+ valueString = null;
+ valueBytes = null;
+ }
+
+ public @Nullable String getValueString() {
+ switch (type) {
+ case TYPE_NULL:
+ return null;
+ case TYPE_STRING:
+ case TYPE_STRING_INTERNED:
+ return valueString;
+ case TYPE_BYTES_HEX:
+ return bytesToHexString(valueBytes);
+ case TYPE_BYTES_BASE64:
+ return Base64.encodeToString(valueBytes, Base64.NO_WRAP);
+ case TYPE_INT:
+ return Integer.toString(valueInt);
+ case TYPE_INT_HEX:
+ return Integer.toString(valueInt, 16);
+ case TYPE_LONG:
+ return Long.toString(valueLong);
+ case TYPE_LONG_HEX:
+ return Long.toString(valueLong, 16);
+ case TYPE_FLOAT:
+ return Float.toString(valueFloat);
+ case TYPE_DOUBLE:
+ return Double.toString(valueDouble);
+ case TYPE_BOOLEAN_TRUE:
+ return "true";
+ case TYPE_BOOLEAN_FALSE:
+ return "false";
+ default:
+ // Unknown data type; null is the best we can offer
+ return null;
+ }
+ }
+
+ public @Nullable byte[] getValueBytesHex() throws IOException {
+ switch (type) {
+ case TYPE_NULL:
+ return null;
+ case TYPE_BYTES_HEX:
+ case TYPE_BYTES_BASE64:
+ return valueBytes;
+ case TYPE_STRING:
+ return hexStringToBytes(valueString);
+ default:
+ throw new IOException("Invalid conversion from " + type);
+ }
+ }
+
+ public @Nullable byte[] getValueBytesBase64() throws IOException {
+ switch (type) {
+ case TYPE_NULL:
+ return null;
+ case TYPE_BYTES_HEX:
+ case TYPE_BYTES_BASE64:
+ return valueBytes;
+ case TYPE_STRING:
+ return Base64.decode(valueString, Base64.NO_WRAP);
+ default:
+ throw new IOException("Invalid conversion from " + type);
+ }
+ }
+
+ public int getValueInt() throws IOException {
+ switch (type) {
+ case TYPE_INT:
+ case TYPE_INT_HEX:
+ return valueInt;
+ case TYPE_STRING:
+ return Integer.parseInt(valueString);
+ default:
+ throw new IOException("Invalid conversion from " + type);
+ }
+ }
+
+ public int getValueIntHex() throws IOException {
+ switch (type) {
+ case TYPE_INT:
+ case TYPE_INT_HEX:
+ return valueInt;
+ case TYPE_STRING:
+ return Integer.parseInt(valueString, 16);
+ default:
+ throw new IOException("Invalid conversion from " + type);
+ }
+ }
+
+ public long getValueLong() throws IOException {
+ switch (type) {
+ case TYPE_LONG:
+ case TYPE_LONG_HEX:
+ return valueLong;
+ case TYPE_STRING:
+ return Long.parseLong(valueString);
+ default:
+ throw new IOException("Invalid conversion from " + type);
+ }
+ }
+
+ public long getValueLongHex() throws IOException {
+ switch (type) {
+ case TYPE_LONG:
+ case TYPE_LONG_HEX:
+ return valueLong;
+ case TYPE_STRING:
+ return Long.parseLong(valueString, 16);
+ default:
+ throw new IOException("Invalid conversion from " + type);
+ }
+ }
+
+ public float getValueFloat() throws IOException {
+ switch (type) {
+ case TYPE_FLOAT:
+ return valueFloat;
+ case TYPE_STRING:
+ return Float.parseFloat(valueString);
+ default:
+ throw new IOException("Invalid conversion from " + type);
+ }
+ }
+
+ public double getValueDouble() throws IOException {
+ switch (type) {
+ case TYPE_DOUBLE:
+ return valueDouble;
+ case TYPE_STRING:
+ return Double.parseDouble(valueString);
+ default:
+ throw new IOException("Invalid conversion from " + type);
+ }
+ }
+
+ public boolean getValueBoolean() throws IOException {
+ switch (type) {
+ case TYPE_BOOLEAN_TRUE:
+ return true;
+ case TYPE_BOOLEAN_FALSE:
+ return false;
+ case TYPE_STRING:
+ if ("true".equalsIgnoreCase(valueString)) {
+ return true;
+ } else if ("false".equalsIgnoreCase(valueString)) {
+ return false;
+ } else {
+ throw new IOException("Invalid boolean: " + valueString);
+ }
+ default:
+ throw new IOException("Invalid conversion from " + type);
+ }
+ }
+ }
+
+ // NOTE: To support unbundled clients, we include an inlined copy
+ // of hex conversion logic from HexDump below
+ private final static char[] HEX_DIGITS =
+ { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+ private static int toByte(char c) throws IOException {
+ if (c >= '0' && c <= '9') return (c - '0');
+ if (c >= 'A' && c <= 'F') return (c - 'A' + 10);
+ if (c >= 'a' && c <= 'f') return (c - 'a' + 10);
+ throw new IOException("Invalid hex char '" + c + "'");
+ }
+
+ static String bytesToHexString(byte[] value) {
+ final int length = value.length;
+ final char[] buf = new char[length * 2];
+ int bufIndex = 0;
+ for (int i = 0; i < length; i++) {
+ byte b = value[i];
+ buf[bufIndex++] = HEX_DIGITS[(b >>> 4) & 0x0F];
+ buf[bufIndex++] = HEX_DIGITS[b & 0x0F];
+ }
+ return new String(buf);
+ }
+
+ static byte[] hexStringToBytes(String value) throws IOException {
+ final int length = value.length();
+ if (length % 2 != 0) {
+ throw new IOException("Invalid hex length " + length);
+ }
+ byte[] buffer = new byte[length / 2];
+ for (int i = 0; i < length; i += 2) {
+ buffer[i / 2] = (byte) ((toByte(value.charAt(i)) << 4)
+ | toByte(value.charAt(i + 1)));
+ }
+ return buffer;
+ }
+}
diff --git a/core/java/com/android/internal/util/BinaryXmlSerializer.java b/core/java/com/android/internal/util/BinaryXmlSerializer.java
new file mode 100644
index 0000000..d3fcf71
--- /dev/null
+++ b/core/java/com/android/internal/util/BinaryXmlSerializer.java
@@ -0,0 +1,396 @@
+/*
+ * Copyright (C) 2020 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.internal.util;
+
+import static org.xmlpull.v1.XmlPullParser.CDSECT;
+import static org.xmlpull.v1.XmlPullParser.COMMENT;
+import static org.xmlpull.v1.XmlPullParser.DOCDECL;
+import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
+import static org.xmlpull.v1.XmlPullParser.END_TAG;
+import static org.xmlpull.v1.XmlPullParser.ENTITY_REF;
+import static org.xmlpull.v1.XmlPullParser.IGNORABLE_WHITESPACE;
+import static org.xmlpull.v1.XmlPullParser.PROCESSING_INSTRUCTION;
+import static org.xmlpull.v1.XmlPullParser.START_DOCUMENT;
+import static org.xmlpull.v1.XmlPullParser.START_TAG;
+import static org.xmlpull.v1.XmlPullParser.TEXT;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.TypedXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
+/**
+ * Serializer that writes XML documents using a custom binary wire protocol
+ * which benchmarking has shown to be 4.3x faster and use 2.4x less disk space
+ * than {@code Xml.newFastSerializer()} for a typical {@code packages.xml}.
+ * <p>
+ * The high-level design of the wire protocol is to directly serialize the event
+ * stream, while efficiently and compactly writing strongly-typed primitives
+ * delivered through the {@link TypedXmlSerializer} interface.
+ * <p>
+ * Each serialized event is a single byte where the lower half is a normal
+ * {@link XmlPullParser} token and the upper half is an optional data type
+ * signal, such as {@link #TYPE_INT}.
+ * <p>
+ * This serializer has some specific limitations:
+ * <ul>
+ * <li>Only the UTF-8 encoding is supported.
+ * <li>Variable length values, such as {@code byte[]} or {@link String}, are
+ * limited to 65,535 bytes in length. Note that {@link String} values are stored
+ * as UTF-8 on the wire.
+ * <li>Namespaces, prefixes, properties, and options are unsupported.
+ * </ul>
+ */
+public final class BinaryXmlSerializer implements TypedXmlSerializer {
+ /**
+ * The wire protocol always begins with a well-known magic value of
+ * {@code ABX_}, representing "Android Binary XML." The final byte is a
+ * version number which may be incremented as the protocol changes.
+ */
+ static final byte[] PROTOCOL_MAGIC_VERSION_0 = new byte[] { 0x41, 0x42, 0x58, 0x00 };
+
+ /**
+ * Internal token which represents an attribute associated with the most
+ * recent {@link #START_TAG} token.
+ */
+ static final int ATTRIBUTE = 15;
+
+ static final int TYPE_NULL = 1 << 4;
+ static final int TYPE_STRING = 2 << 4;
+ static final int TYPE_STRING_INTERNED = 3 << 4;
+ static final int TYPE_BYTES_HEX = 4 << 4;
+ static final int TYPE_BYTES_BASE64 = 5 << 4;
+ static final int TYPE_INT = 6 << 4;
+ static final int TYPE_INT_HEX = 7 << 4;
+ static final int TYPE_LONG = 8 << 4;
+ static final int TYPE_LONG_HEX = 9 << 4;
+ static final int TYPE_FLOAT = 10 << 4;
+ static final int TYPE_DOUBLE = 11 << 4;
+ static final int TYPE_BOOLEAN_TRUE = 12 << 4;
+ static final int TYPE_BOOLEAN_FALSE = 13 << 4;
+
+ /**
+ * Default buffer size, which matches {@code FastXmlSerializer}. This should
+ * be kept in sync with {@link BinaryXmlPullParser}.
+ */
+ private static final int BUFFER_SIZE = 32_768;
+
+ private FastDataOutput mOut;
+
+ /**
+ * Stack of tags which are currently active via {@link #startTag} and which
+ * haven't been terminated via {@link #endTag}.
+ */
+ private int mTagCount = 0;
+ private String[] mTagNames;
+
+ /**
+ * Write the given token and optional {@link String} into our buffer.
+ */
+ private void writeToken(int token, @Nullable String text) throws IOException {
+ if (text != null) {
+ mOut.writeByte(token | TYPE_STRING);
+ mOut.writeUTF(text);
+ } else {
+ mOut.writeByte(token | TYPE_NULL);
+ }
+ }
+
+ @Override
+ public void setOutput(@NonNull OutputStream os, @Nullable String encoding) throws IOException {
+ if (encoding != null && !StandardCharsets.UTF_8.name().equals(encoding)) {
+ throw new UnsupportedOperationException();
+ }
+
+ mOut = new FastDataOutput(os, BUFFER_SIZE);
+ mOut.write(PROTOCOL_MAGIC_VERSION_0);
+
+ mTagCount = 0;
+ mTagNames = new String[8];
+ }
+
+ @Override
+ public void setOutput(Writer writer) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void flush() throws IOException {
+ mOut.flush();
+ }
+
+ @Override
+ public void startDocument(@Nullable String encoding, @Nullable Boolean standalone)
+ throws IOException {
+ if (encoding != null && !StandardCharsets.UTF_8.name().equals(encoding)) {
+ throw new UnsupportedOperationException();
+ }
+ mOut.writeByte(START_DOCUMENT | TYPE_NULL);
+ }
+
+ @Override
+ public void endDocument() throws IOException {
+ mOut.writeByte(END_DOCUMENT | TYPE_NULL);
+ flush();
+ }
+
+ @Override
+ public int getDepth() {
+ return mTagCount;
+ }
+
+ @Override
+ public String getNamespace() {
+ // Namespaces are unsupported
+ return XmlPullParser.NO_NAMESPACE;
+ }
+
+ @Override
+ public String getName() {
+ return mTagNames[mTagCount - 1];
+ }
+
+ @Override
+ public XmlSerializer startTag(String namespace, String name) throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ if (mTagCount == mTagNames.length) {
+ mTagNames = Arrays.copyOf(mTagNames, mTagCount + (mTagCount >> 1));
+ }
+ mTagNames[mTagCount++] = name;
+ mOut.writeByte(START_TAG | TYPE_STRING_INTERNED);
+ mOut.writeInternedUTF(name);
+ return this;
+ }
+
+ @Override
+ public XmlSerializer endTag(String namespace, String name) throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ mTagCount--;
+ mOut.writeByte(END_TAG | TYPE_STRING_INTERNED);
+ mOut.writeInternedUTF(name);
+ return this;
+ }
+
+ @Override
+ public XmlSerializer attribute(String namespace, String name, String value) throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ mOut.writeByte(ATTRIBUTE | TYPE_STRING);
+ mOut.writeInternedUTF(name);
+ mOut.writeUTF(value);
+ return this;
+ }
+
+ @Override
+ public XmlSerializer attributeInterned(String namespace, String name, String value)
+ throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ mOut.writeByte(ATTRIBUTE | TYPE_STRING_INTERNED);
+ mOut.writeInternedUTF(name);
+ mOut.writeInternedUTF(value);
+ return this;
+ }
+
+ @Override
+ public XmlSerializer attributeBytesHex(String namespace, String name, byte[] value)
+ throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ mOut.writeByte(ATTRIBUTE | TYPE_BYTES_HEX);
+ mOut.writeInternedUTF(name);
+ mOut.writeShort(value.length);
+ mOut.write(value);
+ return this;
+ }
+
+ @Override
+ public XmlSerializer attributeBytesBase64(String namespace, String name, byte[] value)
+ throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ mOut.writeByte(ATTRIBUTE | TYPE_BYTES_BASE64);
+ mOut.writeInternedUTF(name);
+ mOut.writeShort(value.length);
+ mOut.write(value);
+ return this;
+ }
+
+ @Override
+ public XmlSerializer attributeInt(String namespace, String name, int value)
+ throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ mOut.writeByte(ATTRIBUTE | TYPE_INT);
+ mOut.writeInternedUTF(name);
+ mOut.writeInt(value);
+ return this;
+ }
+
+ @Override
+ public XmlSerializer attributeIntHex(String namespace, String name, int value)
+ throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ mOut.writeByte(ATTRIBUTE | TYPE_INT_HEX);
+ mOut.writeInternedUTF(name);
+ mOut.writeInt(value);
+ return this;
+ }
+
+ @Override
+ public XmlSerializer attributeLong(String namespace, String name, long value)
+ throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ mOut.writeByte(ATTRIBUTE | TYPE_LONG);
+ mOut.writeInternedUTF(name);
+ mOut.writeLong(value);
+ return this;
+ }
+
+ @Override
+ public XmlSerializer attributeLongHex(String namespace, String name, long value)
+ throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ mOut.writeByte(ATTRIBUTE | TYPE_LONG_HEX);
+ mOut.writeInternedUTF(name);
+ mOut.writeLong(value);
+ return this;
+ }
+
+ @Override
+ public XmlSerializer attributeFloat(String namespace, String name, float value)
+ throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ mOut.writeByte(ATTRIBUTE | TYPE_FLOAT);
+ mOut.writeInternedUTF(name);
+ mOut.writeFloat(value);
+ return this;
+ }
+
+ @Override
+ public XmlSerializer attributeDouble(String namespace, String name, double value)
+ throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ mOut.writeByte(ATTRIBUTE | TYPE_DOUBLE);
+ mOut.writeInternedUTF(name);
+ mOut.writeDouble(value);
+ return this;
+ }
+
+ @Override
+ public XmlSerializer attributeBoolean(String namespace, String name, boolean value)
+ throws IOException {
+ if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
+ if (value) {
+ mOut.writeByte(ATTRIBUTE | TYPE_BOOLEAN_TRUE);
+ mOut.writeInternedUTF(name);
+ } else {
+ mOut.writeByte(ATTRIBUTE | TYPE_BOOLEAN_FALSE);
+ mOut.writeInternedUTF(name);
+ }
+ return this;
+ }
+
+ @Override
+ public XmlSerializer text(char[] buf, int start, int len) throws IOException {
+ writeToken(TEXT, new String(buf, start, len));
+ return this;
+ }
+
+ @Override
+ public XmlSerializer text(String text) throws IOException {
+ writeToken(TEXT, text);
+ return this;
+ }
+
+ @Override
+ public void cdsect(String text) throws IOException {
+ writeToken(CDSECT, text);
+ }
+
+ @Override
+ public void entityRef(String text) throws IOException {
+ writeToken(ENTITY_REF, text);
+ }
+
+ @Override
+ public void processingInstruction(String text) throws IOException {
+ writeToken(PROCESSING_INSTRUCTION, text);
+ }
+
+ @Override
+ public void comment(String text) throws IOException {
+ writeToken(COMMENT, text);
+ }
+
+ @Override
+ public void docdecl(String text) throws IOException {
+ writeToken(DOCDECL, text);
+ }
+
+ @Override
+ public void ignorableWhitespace(String text) throws IOException {
+ writeToken(IGNORABLE_WHITESPACE, text);
+ }
+
+ @Override
+ public void setFeature(String name, boolean state) {
+ // Quietly handle no-op features
+ if ("http://xmlpull.org/v1/doc/features.html#indent-output".equals(name)) {
+ return;
+ }
+ // Features are not supported
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean getFeature(String name) {
+ // Features are not supported
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setProperty(String name, Object value) {
+ // Properties are not supported
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Object getProperty(String name) {
+ // Properties are not supported
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setPrefix(String prefix, String namespace) {
+ // Prefixes are not supported
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getPrefix(String namespace, boolean generatePrefix) {
+ // Prefixes are not supported
+ throw new UnsupportedOperationException();
+ }
+
+ private static IllegalArgumentException illegalNamespace() {
+ throw new IllegalArgumentException("Namespaces are not supported");
+ }
+}
diff --git a/core/java/com/android/internal/util/FastDataInput.java b/core/java/com/android/internal/util/FastDataInput.java
new file mode 100644
index 0000000..2e8cb47
--- /dev/null
+++ b/core/java/com/android/internal/util/FastDataInput.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2020 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.internal.util;
+
+import android.annotation.NonNull;
+
+import java.io.BufferedInputStream;
+import java.io.Closeable;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * Optimized implementation of {@link DataInput} which buffers data in memory
+ * from the underlying {@link InputStream}.
+ * <p>
+ * Benchmarks have demonstrated this class is 3x more efficient than using a
+ * {@link DataInputStream} with a {@link BufferedInputStream}.
+ */
+public class FastDataInput implements DataInput, Closeable {
+ private static final int MAX_UNSIGNED_SHORT = 65_535;
+
+ private final InputStream mIn;
+
+ private final byte[] mBuffer;
+ private final int mBufferCap;
+
+ private int mBufferPos;
+ private int mBufferLim;
+
+ /**
+ * Values that have been "interned" by {@link #readInternedUTF()}.
+ */
+ private int mStringRefCount = 0;
+ private String[] mStringRefs = new String[32];
+
+ public FastDataInput(@NonNull InputStream in, int bufferSize) {
+ mIn = Objects.requireNonNull(in);
+ if (bufferSize < 8) {
+ throw new IllegalArgumentException();
+ }
+
+ mBuffer = new byte[bufferSize];
+ mBufferCap = mBuffer.length;
+ }
+
+ private void fill(int need) throws IOException {
+ final int remain = mBufferLim - mBufferPos;
+ System.arraycopy(mBuffer, mBufferPos, mBuffer, 0, remain);
+ mBufferPos = 0;
+ mBufferLim = remain;
+ need -= remain;
+
+ while (need > 0) {
+ int c = mIn.read(mBuffer, mBufferLim, mBufferCap - mBufferLim);
+ if (c == -1) {
+ throw new EOFException();
+ } else {
+ mBufferLim += c;
+ need -= c;
+ }
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ mIn.close();
+ }
+
+ @Override
+ public void readFully(byte[] b) throws IOException {
+ readFully(b, 0, b.length);
+ }
+
+ @Override
+ public void readFully(byte[] b, int off, int len) throws IOException {
+ // Attempt to read directly from buffer space if there's enough room,
+ // otherwise fall back to chunking into place
+ if (mBufferCap >= len) {
+ if (mBufferLim - mBufferPos < len) fill(len);
+ System.arraycopy(mBuffer, mBufferPos, b, off, len);
+ mBufferPos += len;
+ } else {
+ final int remain = mBufferLim - mBufferPos;
+ System.arraycopy(mBuffer, mBufferPos, b, off, remain);
+ mBufferPos += remain;
+ off += remain;
+ len -= remain;
+
+ while (len > 0) {
+ int c = mIn.read(b, off, len);
+ if (c == -1) {
+ throw new EOFException();
+ } else {
+ off += c;
+ len -= c;
+ }
+ }
+ }
+ }
+
+ @Override
+ public String readUTF() throws IOException {
+ // Attempt to read directly from buffer space if there's enough room,
+ // otherwise fall back to chunking into place
+ final int len = readUnsignedShort();
+ if (mBufferCap >= len) {
+ if (mBufferLim - mBufferPos < len) fill(len);
+ final String res = new String(mBuffer, mBufferPos, len, StandardCharsets.UTF_8);
+ mBufferPos += len;
+ return res;
+ } else {
+ final byte[] tmp = new byte[len];
+ readFully(tmp, 0, tmp.length);
+ return new String(tmp, StandardCharsets.UTF_8);
+ }
+ }
+
+ /**
+ * Read a {@link String} value with the additional signal that the given
+ * value is a candidate for being canonicalized, similar to
+ * {@link String#intern()}.
+ * <p>
+ * Canonicalization is implemented by writing each unique string value once
+ * the first time it appears, and then writing a lightweight {@code short}
+ * reference when that string is written again in the future.
+ *
+ * @see FastDataOutput#writeInternedUTF(String)
+ */
+ public @NonNull String readInternedUTF() throws IOException {
+ final int ref = readUnsignedShort();
+ if (ref == MAX_UNSIGNED_SHORT) {
+ final String s = readUTF();
+
+ // We can only safely intern when we have remaining values; if we're
+ // full we at least sent the string value above
+ if (mStringRefCount < MAX_UNSIGNED_SHORT) {
+ if (mStringRefCount == mStringRefs.length) {
+ mStringRefs = Arrays.copyOf(mStringRefs,
+ mStringRefCount + (mStringRefCount >> 1));
+ }
+ mStringRefs[mStringRefCount++] = s;
+ }
+
+ return s;
+ } else {
+ return mStringRefs[ref];
+ }
+ }
+
+ @Override
+ public boolean readBoolean() throws IOException {
+ return readByte() != 0;
+ }
+
+ /**
+ * Returns the same decoded value as {@link #readByte()} but without
+ * actually consuming the underlying data.
+ */
+ public byte peekByte() throws IOException {
+ if (mBufferLim - mBufferPos < 1) fill(1);
+ return mBuffer[mBufferPos];
+ }
+
+ @Override
+ public byte readByte() throws IOException {
+ if (mBufferLim - mBufferPos < 1) fill(1);
+ return mBuffer[mBufferPos++];
+ }
+
+ @Override
+ public int readUnsignedByte() throws IOException {
+ return Byte.toUnsignedInt(readByte());
+ }
+
+ @Override
+ public short readShort() throws IOException {
+ if (mBufferLim - mBufferPos < 2) fill(2);
+ return (short) (((mBuffer[mBufferPos++] & 0xff) << 8) |
+ ((mBuffer[mBufferPos++] & 0xff) << 0));
+ }
+
+ @Override
+ public int readUnsignedShort() throws IOException {
+ return Short.toUnsignedInt((short) readShort());
+ }
+
+ @Override
+ public char readChar() throws IOException {
+ return (char) readShort();
+ }
+
+ @Override
+ public int readInt() throws IOException {
+ if (mBufferLim - mBufferPos < 4) fill(4);
+ return (((mBuffer[mBufferPos++] & 0xff) << 24) |
+ ((mBuffer[mBufferPos++] & 0xff) << 16) |
+ ((mBuffer[mBufferPos++] & 0xff) << 8) |
+ ((mBuffer[mBufferPos++] & 0xff) << 0));
+ }
+
+ @Override
+ public long readLong() throws IOException {
+ if (mBufferLim - mBufferPos < 8) fill(8);
+ int h = ((mBuffer[mBufferPos++] & 0xff) << 24) |
+ ((mBuffer[mBufferPos++] & 0xff) << 16) |
+ ((mBuffer[mBufferPos++] & 0xff) << 8) |
+ ((mBuffer[mBufferPos++] & 0xff) << 0);
+ int l = ((mBuffer[mBufferPos++] & 0xff) << 24) |
+ ((mBuffer[mBufferPos++] & 0xff) << 16) |
+ ((mBuffer[mBufferPos++] & 0xff) << 8) |
+ ((mBuffer[mBufferPos++] & 0xff) << 0);
+ return (((long) h) << 32L) | ((long) l) & 0xffffffffL;
+ }
+
+ @Override
+ public float readFloat() throws IOException {
+ return Float.intBitsToFloat(readInt());
+ }
+
+ @Override
+ public double readDouble() throws IOException {
+ return Double.longBitsToDouble(readLong());
+ }
+
+ @Override
+ public int skipBytes(int n) throws IOException {
+ // Callers should read data piecemeal
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String readLine() throws IOException {
+ // Callers should read data piecemeal
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/core/java/com/android/internal/util/FastDataOutput.java b/core/java/com/android/internal/util/FastDataOutput.java
new file mode 100644
index 0000000..2530501
--- /dev/null
+++ b/core/java/com/android/internal/util/FastDataOutput.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2020 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.internal.util;
+
+import android.annotation.NonNull;
+import android.util.CharsetUtils;
+
+import dalvik.system.VMRuntime;
+
+import java.io.BufferedOutputStream;
+import java.io.Closeable;
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.Flushable;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Objects;
+
+/**
+ * Optimized implementation of {@link DataOutput} which buffers data in memory
+ * before flushing to the underlying {@link OutputStream}.
+ * <p>
+ * Benchmarks have demonstrated this class is 2x more efficient than using a
+ * {@link DataOutputStream} with a {@link BufferedOutputStream}.
+ */
+public class FastDataOutput implements DataOutput, Flushable, Closeable {
+ private static final int MAX_UNSIGNED_SHORT = 65_535;
+
+ private final OutputStream mOut;
+
+ private final byte[] mBuffer;
+ private final long mBufferPtr;
+ private final int mBufferCap;
+
+ private int mBufferPos;
+
+ /**
+ * Values that have been "interned" by {@link #writeInternedUTF(String)}.
+ */
+ private HashMap<String, Short> mStringRefs = new HashMap<>();
+
+ public FastDataOutput(@NonNull OutputStream out, int bufferSize) {
+ mOut = Objects.requireNonNull(out);
+ if (bufferSize < 8) {
+ throw new IllegalArgumentException();
+ }
+
+ mBuffer = (byte[]) VMRuntime.getRuntime().newNonMovableArray(byte.class, bufferSize);
+ mBufferPtr = VMRuntime.getRuntime().addressOf(mBuffer);
+ mBufferCap = mBuffer.length;
+ }
+
+ private void drain() throws IOException {
+ if (mBufferPos > 0) {
+ mOut.write(mBuffer, 0, mBufferPos);
+ mBufferPos = 0;
+ }
+ }
+
+ @Override
+ public void flush() throws IOException {
+ drain();
+ mOut.flush();
+ }
+
+ @Override
+ public void close() throws IOException {
+ mOut.close();
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ writeByte(b);
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ write(b, 0, b.length);
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ if (mBufferCap < len) {
+ drain();
+ mOut.write(b, off, len);
+ } else {
+ if (mBufferCap - mBufferPos < len) drain();
+ System.arraycopy(b, off, mBuffer, mBufferPos, len);
+ mBufferPos += len;
+ }
+ }
+
+ @Override
+ public void writeUTF(String s) throws IOException {
+ // Attempt to write directly to buffer space if there's enough room,
+ // otherwise fall back to chunking into place
+ if (mBufferCap - mBufferPos < 2 + s.length()) drain();
+ final int res = CharsetUtils.toUtf8Bytes(s, mBufferPtr, mBufferPos + 2,
+ mBufferCap - mBufferPos - 2);
+ if (res >= 0) {
+ if (res > MAX_UNSIGNED_SHORT) {
+ throw new IOException("UTF-8 length too large: " + res);
+ }
+ writeShort(res);
+ mBufferPos += res;
+ } else {
+ final byte[] tmp = s.getBytes(StandardCharsets.UTF_8);
+ if (tmp.length > MAX_UNSIGNED_SHORT) {
+ throw new IOException("UTF-8 length too large: " + res);
+ }
+ writeShort(tmp.length);
+ write(tmp, 0, tmp.length);
+ }
+ }
+
+ /**
+ * Write a {@link String} value with the additional signal that the given
+ * value is a candidate for being canonicalized, similar to
+ * {@link String#intern()}.
+ * <p>
+ * Canonicalization is implemented by writing each unique string value once
+ * the first time it appears, and then writing a lightweight {@code short}
+ * reference when that string is written again in the future.
+ *
+ * @see FastDataInput#readInternedUTF()
+ */
+ public void writeInternedUTF(@NonNull String s) throws IOException {
+ Short ref = mStringRefs.get(s);
+ if (ref != null) {
+ writeShort(ref);
+ } else {
+ writeShort(MAX_UNSIGNED_SHORT);
+ writeUTF(s);
+
+ // We can only safely intern when we have remaining values; if we're
+ // full we at least sent the string value above
+ ref = (short) mStringRefs.size();
+ if (ref < MAX_UNSIGNED_SHORT) {
+ mStringRefs.put(s, ref);
+ }
+ }
+ }
+
+ @Override
+ public void writeBoolean(boolean v) throws IOException {
+ writeByte(v ? 1 : 0);
+ }
+
+ @Override
+ public void writeByte(int v) throws IOException {
+ if (mBufferCap - mBufferPos < 1) drain();
+ mBuffer[mBufferPos++] = (byte) ((v >> 0) & 0xff);
+ }
+
+ @Override
+ public void writeShort(int v) throws IOException {
+ if (mBufferCap - mBufferPos < 2) drain();
+ mBuffer[mBufferPos++] = (byte) ((v >> 8) & 0xff);
+ mBuffer[mBufferPos++] = (byte) ((v >> 0) & 0xff);
+ }
+
+ @Override
+ public void writeChar(int v) throws IOException {
+ writeShort((short) v);
+ }
+
+ @Override
+ public void writeInt(int v) throws IOException {
+ if (mBufferCap - mBufferPos < 4) drain();
+ mBuffer[mBufferPos++] = (byte) ((v >> 24) & 0xff);
+ mBuffer[mBufferPos++] = (byte) ((v >> 16) & 0xff);
+ mBuffer[mBufferPos++] = (byte) ((v >> 8) & 0xff);
+ mBuffer[mBufferPos++] = (byte) ((v >> 0) & 0xff);
+ }
+
+ @Override
+ public void writeLong(long v) throws IOException {
+ if (mBufferCap - mBufferPos < 8) drain();
+ int i = (int) (v >> 32);
+ mBuffer[mBufferPos++] = (byte) ((i >> 24) & 0xff);
+ mBuffer[mBufferPos++] = (byte) ((i >> 16) & 0xff);
+ mBuffer[mBufferPos++] = (byte) ((i >> 8) & 0xff);
+ mBuffer[mBufferPos++] = (byte) ((i >> 0) & 0xff);
+ i = (int) v;
+ mBuffer[mBufferPos++] = (byte) ((i >> 24) & 0xff);
+ mBuffer[mBufferPos++] = (byte) ((i >> 16) & 0xff);
+ mBuffer[mBufferPos++] = (byte) ((i >> 8) & 0xff);
+ mBuffer[mBufferPos++] = (byte) ((i >> 0) & 0xff);
+ }
+
+ @Override
+ public void writeFloat(float v) throws IOException {
+ writeInt(Float.floatToIntBits(v));
+ }
+
+ @Override
+ public void writeDouble(double v) throws IOException {
+ writeLong(Double.doubleToLongBits(v));
+ }
+
+ @Override
+ public void writeBytes(String s) throws IOException {
+ // Callers should use writeUTF()
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void writeChars(String s) throws IOException {
+ // Callers should use writeUTF()
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/core/java/com/android/internal/util/XmlPullParserWrapper.java b/core/java/com/android/internal/util/XmlPullParserWrapper.java
new file mode 100644
index 0000000..efa17ef
--- /dev/null
+++ b/core/java/com/android/internal/util/XmlPullParserWrapper.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2020 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.internal.util;
+
+import android.annotation.NonNull;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Objects;
+
+/**
+ * Wrapper which delegates all calls through to the given {@link XmlPullParser}.
+ */
+public class XmlPullParserWrapper implements XmlPullParser {
+ private final XmlPullParser mWrapped;
+
+ public XmlPullParserWrapper(@NonNull XmlPullParser wrapped) {
+ mWrapped = Objects.requireNonNull(wrapped);
+ }
+
+ public void setFeature(String name, boolean state) throws XmlPullParserException {
+ mWrapped.setFeature(name, state);
+ }
+
+ public boolean getFeature(String name) {
+ return mWrapped.getFeature(name);
+ }
+
+ public void setProperty(String name, Object value) throws XmlPullParserException {
+ mWrapped.setProperty(name, value);
+ }
+
+ public Object getProperty(String name) {
+ return mWrapped.getProperty(name);
+ }
+
+ public void setInput(Reader in) throws XmlPullParserException {
+ mWrapped.setInput(in);
+ }
+
+ public void setInput(InputStream inputStream, String inputEncoding)
+ throws XmlPullParserException {
+ mWrapped.setInput(inputStream, inputEncoding);
+ }
+
+ public String getInputEncoding() {
+ return mWrapped.getInputEncoding();
+ }
+
+ public void defineEntityReplacementText(String entityName, String replacementText)
+ throws XmlPullParserException {
+ mWrapped.defineEntityReplacementText(entityName, replacementText);
+ }
+
+ public int getNamespaceCount(int depth) throws XmlPullParserException {
+ return mWrapped.getNamespaceCount(depth);
+ }
+
+ public String getNamespacePrefix(int pos) throws XmlPullParserException {
+ return mWrapped.getNamespacePrefix(pos);
+ }
+
+ public String getNamespaceUri(int pos) throws XmlPullParserException {
+ return mWrapped.getNamespaceUri(pos);
+ }
+
+ public String getNamespace(String prefix) {
+ return mWrapped.getNamespace(prefix);
+ }
+
+ public int getDepth() {
+ return mWrapped.getDepth();
+ }
+
+ public String getPositionDescription() {
+ return mWrapped.getPositionDescription();
+ }
+
+ public int getLineNumber() {
+ return mWrapped.getLineNumber();
+ }
+
+ public int getColumnNumber() {
+ return mWrapped.getColumnNumber();
+ }
+
+ public boolean isWhitespace() throws XmlPullParserException {
+ return mWrapped.isWhitespace();
+ }
+
+ public String getText() {
+ return mWrapped.getText();
+ }
+
+ public char[] getTextCharacters(int[] holderForStartAndLength) {
+ return mWrapped.getTextCharacters(holderForStartAndLength);
+ }
+
+ public String getNamespace() {
+ return mWrapped.getNamespace();
+ }
+
+ public String getName() {
+ return mWrapped.getName();
+ }
+
+ public String getPrefix() {
+ return mWrapped.getPrefix();
+ }
+
+ public boolean isEmptyElementTag() throws XmlPullParserException {
+ return mWrapped.isEmptyElementTag();
+ }
+
+ public int getAttributeCount() {
+ return mWrapped.getAttributeCount();
+ }
+
+ public String getAttributeNamespace(int index) {
+ return mWrapped.getAttributeNamespace(index);
+ }
+
+ public String getAttributeName(int index) {
+ return mWrapped.getAttributeName(index);
+ }
+
+ public String getAttributePrefix(int index) {
+ return mWrapped.getAttributePrefix(index);
+ }
+
+ public String getAttributeType(int index) {
+ return mWrapped.getAttributeType(index);
+ }
+
+ public boolean isAttributeDefault(int index) {
+ return mWrapped.isAttributeDefault(index);
+ }
+
+ public String getAttributeValue(int index) {
+ return mWrapped.getAttributeValue(index);
+ }
+
+ public String getAttributeValue(String namespace, String name) {
+ return mWrapped.getAttributeValue(namespace, name);
+ }
+
+ public int getEventType() throws XmlPullParserException {
+ return mWrapped.getEventType();
+ }
+
+ public int next() throws XmlPullParserException, IOException {
+ return mWrapped.next();
+ }
+
+ public int nextToken() throws XmlPullParserException, IOException {
+ return mWrapped.nextToken();
+ }
+
+ public void require(int type, String namespace, String name)
+ throws XmlPullParserException, IOException {
+ mWrapped.require(type, namespace, name);
+ }
+
+ public String nextText() throws XmlPullParserException, IOException {
+ return mWrapped.nextText();
+ }
+
+ public int nextTag() throws XmlPullParserException, IOException {
+ return mWrapped.nextTag();
+ }
+}
diff --git a/core/java/com/android/internal/util/XmlSerializerWrapper.java b/core/java/com/android/internal/util/XmlSerializerWrapper.java
new file mode 100644
index 0000000..2131db0
--- /dev/null
+++ b/core/java/com/android/internal/util/XmlSerializerWrapper.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2020 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.internal.util;
+
+import android.annotation.NonNull;
+
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.util.Objects;
+
+/**
+ * Wrapper which delegates all calls through to the given {@link XmlSerializer}.
+ */
+public class XmlSerializerWrapper {
+ private final XmlSerializer mWrapped;
+
+ public XmlSerializerWrapper(@NonNull XmlSerializer wrapped) {
+ mWrapped = Objects.requireNonNull(wrapped);
+ }
+
+ public void setFeature(String name, boolean state) {
+ mWrapped.setFeature(name, state);
+ }
+
+ public boolean getFeature(String name) {
+ return mWrapped.getFeature(name);
+ }
+
+ public void setProperty(String name, Object value) {
+ mWrapped.setProperty(name, value);
+ }
+
+ public Object getProperty(String name) {
+ return mWrapped.getProperty(name);
+ }
+
+ public void setOutput(OutputStream os, String encoding) throws IOException {
+ mWrapped.setOutput(os, encoding);
+ }
+
+ public void setOutput(Writer writer)
+ throws IOException, IllegalArgumentException, IllegalStateException {
+ mWrapped.setOutput(writer);
+ }
+
+ public void startDocument(String encoding, Boolean standalone) throws IOException {
+ mWrapped.startDocument(encoding, standalone);
+ }
+
+ public void endDocument() throws IOException {
+ mWrapped.endDocument();
+ }
+
+ public void setPrefix(String prefix, String namespace) throws IOException {
+ mWrapped.setPrefix(prefix, namespace);
+ }
+
+ public String getPrefix(String namespace, boolean generatePrefix) {
+ return mWrapped.getPrefix(namespace, generatePrefix);
+ }
+
+ public int getDepth() {
+ return mWrapped.getDepth();
+ }
+
+ public String getNamespace() {
+ return mWrapped.getNamespace();
+ }
+
+ public String getName() {
+ return mWrapped.getName();
+ }
+
+ public XmlSerializer startTag(String namespace, String name) throws IOException {
+ return mWrapped.startTag(namespace, name);
+ }
+
+ public XmlSerializer attribute(String namespace, String name, String value)
+ throws IOException {
+ return mWrapped.attribute(namespace, name, value);
+ }
+
+ public XmlSerializer endTag(String namespace, String name) throws IOException {
+ return mWrapped.endTag(namespace, name);
+ }
+
+ public XmlSerializer text(String text) throws IOException{
+ return mWrapped.text(text);
+ }
+
+ public XmlSerializer text(char[] buf, int start, int len) throws IOException {
+ return mWrapped.text(buf, start, len);
+ }
+
+ public void cdsect(String text)
+ throws IOException, IllegalArgumentException, IllegalStateException {
+ mWrapped.cdsect(text);
+ }
+
+ public void entityRef(String text) throws IOException {
+ mWrapped.entityRef(text);
+ }
+
+ public void processingInstruction(String text) throws IOException {
+ mWrapped.processingInstruction(text);
+ }
+
+ public void comment(String text) throws IOException {
+ mWrapped.comment(text);
+ }
+
+ public void docdecl(String text) throws IOException {
+ mWrapped.docdecl(text);
+ }
+
+ public void ignorableWhitespace(String text) throws IOException {
+ mWrapped.ignorableWhitespace(text);
+ }
+
+ public void flush() throws IOException {
+ mWrapped.flush();
+ }
+}
diff --git a/core/java/com/android/internal/util/XmlUtils.java b/core/java/com/android/internal/util/XmlUtils.java
index bd6b950..cdd0e04 100644
--- a/core/java/com/android/internal/util/XmlUtils.java
+++ b/core/java/com/android/internal/util/XmlUtils.java
@@ -16,6 +16,7 @@
package com.android.internal.util;
+import android.annotation.NonNull;
import android.compat.annotation.UnsupportedAppUsage;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
@@ -24,6 +25,8 @@
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Base64;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
import android.util.Xml;
import libcore.util.HexEncoding;
@@ -48,9 +51,193 @@
/** {@hide} */
public class XmlUtils {
-
private static final String STRING_ARRAY_SEPARATOR = ":";
+ private static class ForcedTypedXmlSerializer extends XmlSerializerWrapper
+ implements TypedXmlSerializer {
+ public ForcedTypedXmlSerializer(XmlSerializer wrapped) {
+ super(wrapped);
+ }
+
+ @Override
+ public XmlSerializer attributeInterned(String namespace, String name, String value)
+ throws IOException {
+ return attribute(namespace, name, value);
+ }
+
+ @Override
+ public XmlSerializer attributeBytesHex(String namespace, String name, byte[] value)
+ throws IOException {
+ return attribute(namespace, name, HexDump.toHexString(value));
+ }
+
+ @Override
+ public XmlSerializer attributeBytesBase64(String namespace, String name, byte[] value)
+ throws IOException {
+ return attribute(namespace, name, Base64.encodeToString(value, Base64.NO_WRAP));
+ }
+
+ @Override
+ public XmlSerializer attributeInt(String namespace, String name, int value)
+ throws IOException {
+ return attribute(namespace, name, Integer.toString(value));
+ }
+
+ @Override
+ public XmlSerializer attributeIntHex(String namespace, String name, int value)
+ throws IOException {
+ return attribute(namespace, name, Integer.toString(value, 16));
+ }
+
+ @Override
+ public XmlSerializer attributeLong(String namespace, String name, long value)
+ throws IOException {
+ return attribute(namespace, name, Long.toString(value));
+ }
+
+ @Override
+ public XmlSerializer attributeLongHex(String namespace, String name, long value)
+ throws IOException {
+ return attribute(namespace, name, Long.toString(value, 16));
+ }
+
+ @Override
+ public XmlSerializer attributeFloat(String namespace, String name, float value)
+ throws IOException {
+ return attribute(namespace, name, Float.toString(value));
+ }
+
+ @Override
+ public XmlSerializer attributeDouble(String namespace, String name, double value)
+ throws IOException {
+ return attribute(namespace, name, Double.toString(value));
+ }
+
+ @Override
+ public XmlSerializer attributeBoolean(String namespace, String name, boolean value)
+ throws IOException {
+ return attribute(namespace, name, Boolean.toString(value));
+ }
+ }
+
+ /**
+ * Return a specialization of the given {@link XmlSerializer} which has
+ * explicit methods to support consistent and efficient conversion of
+ * primitive data types.
+ */
+ public static @NonNull TypedXmlSerializer makeTyped(@NonNull XmlSerializer xml) {
+ if (xml instanceof TypedXmlSerializer) {
+ return (TypedXmlSerializer) xml;
+ } else {
+ return new ForcedTypedXmlSerializer(xml);
+ }
+ }
+
+ private static class ForcedTypedXmlPullParser extends XmlPullParserWrapper
+ implements TypedXmlPullParser {
+ public ForcedTypedXmlPullParser(XmlPullParser wrapped) {
+ super(wrapped);
+ }
+
+ @Override
+ public byte[] getAttributeBytesHex(String namespace, String name) throws IOException {
+ try {
+ return HexDump.hexStringToByteArray(getAttributeValue(namespace, name));
+ } catch (Exception e) {
+ throw new IOException("Invalid attribute " + name, e);
+ }
+ }
+
+ @Override
+ public byte[] getAttributeBytesBase64(String namespace, String name) throws IOException {
+ try {
+ return Base64.decode(getAttributeValue(namespace, name), Base64.NO_WRAP);
+ } catch (Exception e) {
+ throw new IOException("Invalid attribute " + name, e);
+ }
+ }
+
+ @Override
+ public int getAttributeInt(String namespace, String name) throws IOException {
+ try {
+ return Integer.parseInt(getAttributeValue(namespace, name));
+ } catch (NumberFormatException e) {
+ throw new IOException("Invalid attribute " + name, e);
+ }
+ }
+
+ @Override
+ public int getAttributeIntHex(String namespace, String name) throws IOException {
+ try {
+ return Integer.parseInt(getAttributeValue(namespace, name), 16);
+ } catch (NumberFormatException e) {
+ throw new IOException("Invalid attribute " + name, e);
+ }
+ }
+
+ @Override
+ public long getAttributeLong(String namespace, String name) throws IOException {
+ try {
+ return Long.parseLong(getAttributeValue(namespace, name));
+ } catch (NumberFormatException e) {
+ throw new IOException("Invalid attribute " + name, e);
+ }
+ }
+
+ @Override
+ public long getAttributeLongHex(String namespace, String name) throws IOException {
+ try {
+ return Long.parseLong(getAttributeValue(namespace, name), 16);
+ } catch (NumberFormatException e) {
+ throw new IOException("Invalid attribute " + name, e);
+ }
+ }
+
+ @Override
+ public float getAttributeFloat(String namespace, String name) throws IOException {
+ try {
+ return Float.parseFloat(getAttributeValue(namespace, name));
+ } catch (NumberFormatException e) {
+ throw new IOException("Invalid attribute " + name, e);
+ }
+ }
+
+ @Override
+ public double getAttributeDouble(String namespace, String name) throws IOException {
+ try {
+ return Double.parseDouble(getAttributeValue(namespace, name));
+ } catch (NumberFormatException e) {
+ throw new IOException("Invalid attribute " + name, e);
+ }
+ }
+
+ @Override
+ public boolean getAttributeBoolean(String namespace, String name) throws IOException {
+ final String value = getAttributeValue(namespace, name);
+ if ("true".equalsIgnoreCase(value)) {
+ return true;
+ } else if ("false".equalsIgnoreCase(value)) {
+ return false;
+ } else {
+ throw new IOException("Invalid attribute " + name,
+ new IllegalArgumentException("For input string: \"" + value + "\""));
+ }
+ }
+ }
+
+ /**
+ * Return a specialization of the given {@link XmlPullParser} which has
+ * explicit methods to support consistent and efficient conversion of
+ * primitive data types.
+ */
+ public static @NonNull TypedXmlPullParser makeTyped(@NonNull XmlPullParser xml) {
+ if (xml instanceof TypedXmlPullParser) {
+ return (TypedXmlPullParser) xml;
+ } else {
+ return new ForcedTypedXmlPullParser(xml);
+ }
+ }
+
@UnsupportedAppUsage
public static void skipCurrentTag(XmlPullParser parser)
throws XmlPullParserException, IOException {
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 3dae1b5..8c83d7c 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -134,6 +134,7 @@
"android_service_DataLoaderService.cpp",
"android_util_AssetManager.cpp",
"android_util_Binder.cpp",
+ "android_util_CharsetUtils.cpp",
"android_util_MemoryIntArray.cpp",
"android_util_Process.cpp",
"android_media_AudioDeviceAttributes.cpp",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 27b23bd..14e74a8 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -105,6 +105,7 @@
*/
extern int register_android_app_admin_SecurityLog(JNIEnv* env);
extern int register_android_content_AssetManager(JNIEnv* env);
+extern int register_android_util_CharsetUtils(JNIEnv* env);
extern int register_android_util_EventLog(JNIEnv* env);
extern int register_android_util_Log(JNIEnv* env);
extern int register_android_util_MemoryIntArray(JNIEnv* env);
@@ -1449,6 +1450,7 @@
REG_JNI(register_com_android_internal_os_RuntimeInit),
REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
REG_JNI(register_android_os_SystemClock),
+ REG_JNI(register_android_util_CharsetUtils),
REG_JNI(register_android_util_EventLog),
REG_JNI(register_android_util_Log),
REG_JNI(register_android_util_MemoryIntArray),
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index f05c6a4..787d348 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -90,6 +90,14 @@
env->CallVoidMethod(parcelObj, gParcelOffsets.recycle);
}
+static void android_os_Parcel_markSensitive(jlong nativePtr)
+{
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel) {
+ parcel->markSensitive();
+ }
+}
+
static jint android_os_Parcel_dataSize(jlong nativePtr)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
@@ -741,6 +749,8 @@
static const JNINativeMethod gParcelMethods[] = {
// @CriticalNative
+ {"nativeMarkSensitive", "(J)V", (void*)android_os_Parcel_markSensitive},
+ // @CriticalNative
{"nativeDataSize", "(J)I", (void*)android_os_Parcel_dataSize},
// @CriticalNative
{"nativeDataAvail", "(J)I", (void*)android_os_Parcel_dataAvail},
diff --git a/core/jni/android_util_CharsetUtils.cpp b/core/jni/android_util_CharsetUtils.cpp
new file mode 100644
index 0000000..3e1d4a7
--- /dev/null
+++ b/core/jni/android_util_CharsetUtils.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "core_jni_helpers.h"
+#include "nativehelper/scoped_primitive_array.h"
+
+namespace android {
+
+static jint android_util_CharsetUtils_toUtf8Bytes(JNIEnv *env, jobject clazz,
+ jstring src, jint srcLen, jlong dest, jint destOff, jint destLen) {
+ char *destPtr = reinterpret_cast<char*>(dest);
+
+ // Quickly check if destination has plenty of room for worst-case
+ // 4-bytes-per-char encoded size
+ if (destOff >= 0 && destOff + (srcLen * 4) < destLen) {
+ env->GetStringUTFRegion(src, 0, srcLen, destPtr + destOff);
+ return strlen(destPtr + destOff + srcLen) + srcLen;
+ }
+
+ // String still might fit in destination, but we need to measure
+ // its actual encoded size to be sure
+ const size_t encodedLen = env->GetStringUTFLength(src);
+ if (destOff >= 0 && destOff + encodedLen < destLen) {
+ env->GetStringUTFRegion(src, 0, srcLen, destPtr + destOff);
+ return encodedLen;
+ }
+
+ return -1;
+}
+
+static const JNINativeMethod methods[] = {
+ // @FastNative
+ {"toUtf8Bytes", "(Ljava/lang/String;IJII)I",
+ (void*)android_util_CharsetUtils_toUtf8Bytes},
+};
+
+int register_android_util_CharsetUtils(JNIEnv *env) {
+ return RegisterMethodsOrDie(env, "android/util/CharsetUtils", methods, NELEM(methods));
+}
+
+}
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 433a46b..3295df1 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4510,4 +4510,7 @@
activity-level letterboxing (size-compat mode). Therefore this override can control the
maximum screen area that can be occupied by the app in the letterbox mode. -->
<item name="config_taskLetterboxAspectRatio" format="float" type="dimen">0.0</item>
+
+ <!-- If true, hide the display cutout with display area -->
+ <bool name="config_hideDisplayCutoutWithDisplayArea">false</bool>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6960fb3..fba431c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4095,4 +4095,6 @@
<java-symbol type="dimen" name="controls_thumbnail_image_max_width" />
<java-symbol type="dimen" name="config_taskLetterboxAspectRatio" />
+
+ <java-symbol type="bool" name="config_hideDisplayCutoutWithDisplayArea" />
</resources>
diff --git a/core/tests/coretests/src/android/graphics/TypefaceTest.java b/core/tests/coretests/src/android/graphics/TypefaceTest.java
index cfed2ce..4393e9e7 100644
--- a/core/tests/coretests/src/android/graphics/TypefaceTest.java
+++ b/core/tests/coretests/src/android/graphics/TypefaceTest.java
@@ -17,12 +17,14 @@
package android.graphics;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Resources;
+import android.graphics.fonts.SystemFonts;
+import android.os.SharedMemory;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.LargeTest;
@@ -35,9 +37,8 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Random;
@RunWith(AndroidJUnit4.class)
@@ -54,14 +55,33 @@
Typeface.create(Typeface.MONOSPACE, 0)
};
+ private static final int[] STYLES = {
+ Typeface.NORMAL, Typeface.BOLD, Typeface.ITALIC, Typeface.BOLD_ITALIC,
+ };
+
@SmallTest
@Test
- public void testBasic() throws Exception {
- assertTrue("basic", Typeface.DEFAULT != null);
- assertTrue("basic", Typeface.DEFAULT_BOLD != null);
- assertTrue("basic", Typeface.SANS_SERIF != null);
- assertTrue("basic", Typeface.SERIF != null);
- assertTrue("basic", Typeface.MONOSPACE != null);
+ public void testBasic() {
+ assertNotEquals("basic", 0, Typeface.DEFAULT.native_instance);
+ assertNotEquals("basic", 0, Typeface.DEFAULT_BOLD.native_instance);
+ assertNotEquals("basic", 0, Typeface.SANS_SERIF.native_instance);
+ assertNotEquals("basic", 0, Typeface.SERIF.native_instance);
+ assertNotEquals("basic", 0, Typeface.MONOSPACE.native_instance);
+ assertEquals("basic", Typeface.NORMAL, Typeface.DEFAULT.getStyle());
+ assertEquals("basic", Typeface.BOLD, Typeface.DEFAULT_BOLD.getStyle());
+ assertEquals("basic", Typeface.NORMAL, Typeface.SANS_SERIF.getStyle());
+ assertEquals("basic", Typeface.NORMAL, Typeface.SERIF.getStyle());
+ assertEquals("basic", Typeface.NORMAL, Typeface.MONOSPACE.getStyle());
+ }
+
+ @SmallTest
+ @Test
+ public void testDefaults() {
+ for (int style : STYLES) {
+ String msg = "style = " + style;
+ assertNotEquals(msg, 0, Typeface.defaultFromStyle(style).native_instance);
+ assertEquals(msg, style, Typeface.defaultFromStyle(style).getStyle());
+ }
}
@SmallTest
@@ -178,21 +198,67 @@
@SmallTest
@Test
public void testSerialize() throws Exception {
- int size = Typeface.writeTypefaces(null, Arrays.asList(mFaces));
- ByteBuffer buffer = ByteBuffer.allocateDirect(size);
- Typeface.writeTypefaces(buffer, Arrays.asList(mFaces));
- List<Typeface> copiedTypefaces = Typeface.readTypefaces(buffer);
- assertNotNull(copiedTypefaces);
- assertEquals(mFaces.length, copiedTypefaces.size());
- for (int i = 0; i < mFaces.length; i++) {
- Typeface original = mFaces[i];
- Typeface copied = copiedTypefaces.get(i);
+ HashMap<String, Typeface> systemFontMap = new HashMap<>();
+ Typeface.initSystemDefaultTypefaces(systemFontMap, SystemFonts.getRawSystemFallbackMap(),
+ SystemFonts.getAliases());
+ SharedMemory sharedMemory = Typeface.serializeFontMap(systemFontMap);
+ Map<String, Typeface> copiedFontMap = Typeface.deserializeFontMap(sharedMemory);
+ assertEquals(systemFontMap.size(), copiedFontMap.size());
+ for (String key : systemFontMap.keySet()) {
+ assertTrue(copiedFontMap.containsKey(key));
+ Typeface original = systemFontMap.get(key);
+ Typeface copied = copiedFontMap.get(key);
assertEquals(original.getStyle(), copied.getStyle());
assertEquals(original.getWeight(), copied.getWeight());
assertEquals(measureText(original, "hello"), measureText(copied, "hello"), 1e-6);
}
}
+ @SmallTest
+ @Test
+ public void testSetSystemFontMap() throws Exception {
+ Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ Resources res = context.getResources();
+ Map<String, Typeface> fontMap = Map.of(
+ "sans-serif", Typeface.create(res.getFont(R.font.samplefont), Typeface.NORMAL),
+ "serif", Typeface.create(res.getFont(R.font.samplefont2), Typeface.NORMAL),
+ "monospace", Typeface.create(res.getFont(R.font.samplefont3), Typeface.NORMAL),
+ "sample", Typeface.create(res.getFont(R.font.samplefont4), Typeface.NORMAL),
+ "sample-italic", Typeface.create(res.getFont(R.font.samplefont4), Typeface.ITALIC));
+ Typeface.setSystemFontMap(fontMap);
+
+ // Test public static final fields
+ assertEquals(fontMap.get("sans-serif").native_instance, Typeface.DEFAULT.native_instance);
+ assertNotEquals(0, Typeface.DEFAULT_BOLD.native_instance);
+ assertEquals(
+ fontMap.get("sans-serif").native_instance, Typeface.SANS_SERIF.native_instance);
+ assertEquals(fontMap.get("serif").native_instance, Typeface.SERIF.native_instance);
+ assertEquals(fontMap.get("monospace").native_instance, Typeface.MONOSPACE.native_instance);
+ assertEquals(Typeface.NORMAL, Typeface.DEFAULT.getStyle());
+ assertEquals(Typeface.BOLD, Typeface.DEFAULT_BOLD.getStyle());
+ assertEquals(Typeface.NORMAL, Typeface.SANS_SERIF.getStyle());
+ assertEquals(Typeface.NORMAL, Typeface.SERIF.getStyle());
+ assertEquals(Typeface.NORMAL, Typeface.MONOSPACE.getStyle());
+
+ // Test defaults
+ assertEquals(
+ fontMap.get("sans-serif").native_instance,
+ Typeface.defaultFromStyle(Typeface.NORMAL).native_instance);
+ for (int style : STYLES) {
+ String msg = "style = " + style;
+ assertNotEquals(msg, 0, Typeface.defaultFromStyle(style).native_instance);
+ assertEquals(msg, style, Typeface.defaultFromStyle(style).getStyle());
+ }
+
+ // Test create()
+ assertEquals(
+ fontMap.get("sample").native_instance,
+ Typeface.create("sample", Typeface.NORMAL).native_instance);
+ assertEquals(
+ fontMap.get("sample-italic").native_instance,
+ Typeface.create("sample-italic", Typeface.ITALIC).native_instance);
+ }
+
private static float measureText(Typeface typeface, String text) {
Paint paint = new Paint();
paint.setTypeface(typeface);
diff --git a/core/tests/coretests/src/android/util/BinaryXmlTest.java b/core/tests/coretests/src/android/util/BinaryXmlTest.java
new file mode 100644
index 0000000..be63a0e
--- /dev/null
+++ b/core/tests/coretests/src/android/util/BinaryXmlTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2020 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.util;
+
+import static android.util.XmlTest.assertNext;
+import static android.util.XmlTest.buildPersistableBundle;
+import static android.util.XmlTest.doPersistableBundleRead;
+import static android.util.XmlTest.doPersistableBundleWrite;
+
+import static org.junit.Assert.assertEquals;
+import static org.xmlpull.v1.XmlPullParser.START_TAG;
+
+import android.os.PersistableBundle;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.nio.charset.StandardCharsets;
+
+@RunWith(AndroidJUnit4.class)
+public class BinaryXmlTest {
+ /**
+ * Verify that we can write and read large numbers of interned
+ * {@link String} values.
+ */
+ @Test
+ public void testLargeInterned_Binary() throws Exception {
+ // We're okay with the tag itself being interned
+ final int count = (1 << 16) - 2;
+
+ final TypedXmlSerializer out = Xml.newBinarySerializer();
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ out.setOutput(os, StandardCharsets.UTF_8.name());
+ out.startTag(null, "tag");
+ for (int i = 0; i < count; i++) {
+ out.attribute(null, "name" + i, "value");
+ }
+ out.endTag(null, "tag");
+ out.flush();
+
+ final TypedXmlPullParser in = Xml.newBinaryPullParser();
+ final ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
+ in.setInput(is, StandardCharsets.UTF_8.name());
+ assertNext(in, START_TAG, "tag", 1);
+ assertEquals(count, in.getAttributeCount());
+ }
+
+ @Test
+ public void testTranscode_FastToBinary() throws Exception {
+ doTranscode(Xml.newFastSerializer(), Xml.newFastPullParser(),
+ Xml.newBinarySerializer(), Xml.newBinaryPullParser());
+ }
+
+ @Test
+ public void testTranscode_BinaryToFast() throws Exception {
+ doTranscode(Xml.newBinarySerializer(), Xml.newBinaryPullParser(),
+ Xml.newFastSerializer(), Xml.newFastPullParser());
+ }
+
+ /**
+ * Verify that a complex {@link PersistableBundle} can be transcoded using
+ * the two given formats with the original structure intact.
+ */
+ private static void doTranscode(TypedXmlSerializer firstOut, TypedXmlPullParser firstIn,
+ TypedXmlSerializer secondOut, TypedXmlPullParser secondIn) throws Exception {
+ final PersistableBundle expected = buildPersistableBundle();
+ final byte[] firstRaw = doPersistableBundleWrite(firstOut, expected);
+
+ // Perform actual transcoding between the two formats
+ final ByteArrayInputStream is = new ByteArrayInputStream(firstRaw);
+ firstIn.setInput(is, StandardCharsets.UTF_8.name());
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ secondOut.setOutput(os, StandardCharsets.UTF_8.name());
+ Xml.copy(firstIn, secondOut);
+
+ // Yes, this string-based check is fragile, but kindofEquals() is broken
+ // when working with nested objects and arrays
+ final PersistableBundle actual = doPersistableBundleRead(secondIn, os.toByteArray());
+ assertEquals(expected.toString(), actual.toString());
+ }
+}
diff --git a/core/tests/coretests/src/android/util/CharsetUtilsTest.java b/core/tests/coretests/src/android/util/CharsetUtilsTest.java
new file mode 100644
index 0000000..04cb3d7
--- /dev/null
+++ b/core/tests/coretests/src/android/util/CharsetUtilsTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2020 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.util;
+
+import static org.junit.Assert.assertEquals;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.util.HexDump;
+
+import dalvik.system.VMRuntime;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class CharsetUtilsTest {
+ private byte[] dest;
+ private long destPtr;
+
+ @Before
+ public void setUp() {
+ dest = (byte[]) VMRuntime.getRuntime().newNonMovableArray(byte.class, 8);
+ destPtr = VMRuntime.getRuntime().addressOf(dest);
+ }
+
+ @Test
+ public void testUtf8_Empty() {
+ assertEquals(0, CharsetUtils.toUtf8Bytes("", destPtr, 0, dest.length));
+ assertEquals("0000000000000000", HexDump.toHexString(dest));
+ }
+
+ @Test
+ public void testUtf8_Simple() {
+ assertEquals(7, CharsetUtils.toUtf8Bytes("example", destPtr, 0, dest.length));
+ assertEquals("6578616D706C6500", HexDump.toHexString(dest));
+ }
+
+ @Test
+ public void testUtf8_Complex() {
+ assertEquals(3, CharsetUtils.toUtf8Bytes("☃", destPtr, 4, dest.length));
+ assertEquals("00000000E2988300", HexDump.toHexString(dest));
+ }
+
+ @Test
+ public void testUtf8_Bounds() {
+ assertEquals(-1, CharsetUtils.toUtf8Bytes("foo", destPtr, 0, 0));
+ assertEquals(-1, CharsetUtils.toUtf8Bytes("foo", destPtr, 0, 2));
+ assertEquals(-1, CharsetUtils.toUtf8Bytes("foo", destPtr, -2, 8));
+ assertEquals(-1, CharsetUtils.toUtf8Bytes("foo", destPtr, 6, 8));
+ assertEquals(-1, CharsetUtils.toUtf8Bytes("foo", destPtr, 10, 8));
+ }
+
+ @Test
+ public void testUtf8_Overwrite() {
+ assertEquals(5, CharsetUtils.toUtf8Bytes("!!!!!", destPtr, 0, dest.length));
+ assertEquals(3, CharsetUtils.toUtf8Bytes("...", destPtr, 0, dest.length));
+ assertEquals(1, CharsetUtils.toUtf8Bytes("?", destPtr, 0, dest.length));
+ assertEquals("3F002E0021000000", HexDump.toHexString(dest));
+ }
+}
diff --git a/core/tests/coretests/src/android/util/XmlTest.java b/core/tests/coretests/src/android/util/XmlTest.java
new file mode 100644
index 0000000..2ae9cdf
--- /dev/null
+++ b/core/tests/coretests/src/android/util/XmlTest.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2020 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.util;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
+import static org.xmlpull.v1.XmlPullParser.END_TAG;
+import static org.xmlpull.v1.XmlPullParser.START_DOCUMENT;
+import static org.xmlpull.v1.XmlPullParser.START_TAG;
+import static org.xmlpull.v1.XmlPullParser.TEXT;
+
+import android.os.PersistableBundle;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.util.XmlUtils;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
+@RunWith(AndroidJUnit4.class)
+public class XmlTest {
+ @Test
+ public void testLargeValues_Normal() throws Exception {
+ doLargeValues(XmlUtils.makeTyped(Xml.newSerializer()),
+ XmlUtils.makeTyped(Xml.newPullParser()));
+ }
+
+ @Test
+ public void testLargeValues_Fast() throws Exception {
+ doLargeValues(Xml.newFastSerializer(),
+ Xml.newFastPullParser());
+ }
+
+ @Test
+ public void testLargeValues_Binary() throws Exception {
+ doLargeValues(Xml.newBinarySerializer(),
+ Xml.newBinaryPullParser());
+ }
+
+ /**
+ * Verify that we can write and read large {@link String} and {@code byte[]}
+ * without issues.
+ */
+ private static void doLargeValues(TypedXmlSerializer out, TypedXmlPullParser in)
+ throws Exception {
+ final char[] chars = new char[(1 << 16) - 1];
+ Arrays.fill(chars, '!');
+
+ final String string = new String(chars);
+ final byte[] bytes = string.getBytes();
+ assertEquals(chars.length, bytes.length);
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ out.setOutput(os, StandardCharsets.UTF_8.name());
+ out.startTag(null, "tag");
+ out.attribute(null, "string", string);
+ out.attributeBytesBase64(null, "bytes", bytes);
+ out.endTag(null, "tag");
+ out.flush();
+
+ final ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
+ in.setInput(is, StandardCharsets.UTF_8.name());
+ assertNext(in, START_TAG, "tag", 1);
+ assertEquals(2, in.getAttributeCount());
+ assertEquals(string, in.getAttributeValue(null, "string"));
+ assertArrayEquals(bytes, in.getAttributeBytesBase64(null, "bytes"));
+ }
+
+ @Test
+ public void testPersistableBundle_Normal() throws Exception {
+ doPersistableBundle(XmlUtils.makeTyped(Xml.newSerializer()),
+ XmlUtils.makeTyped(Xml.newPullParser()));
+ }
+
+ @Test
+ public void testPersistableBundle_Fast() throws Exception {
+ doPersistableBundle(Xml.newFastSerializer(),
+ Xml.newFastPullParser());
+ }
+
+ @Test
+ public void testPersistableBundle_Binary() throws Exception {
+ doPersistableBundle(Xml.newBinarySerializer(),
+ Xml.newBinaryPullParser());
+ }
+
+ /**
+ * Verify that a complex {@link PersistableBundle} can be serialized out and
+ * then parsed in with the original structure intact.
+ */
+ private static void doPersistableBundle(TypedXmlSerializer out, TypedXmlPullParser in)
+ throws Exception {
+ final PersistableBundle expected = buildPersistableBundle();
+ final byte[] raw = doPersistableBundleWrite(out, expected);
+
+ // Yes, this string-based check is fragile, but kindofEquals() is broken
+ // when working with nested objects and arrays
+ final PersistableBundle actual = doPersistableBundleRead(in, raw);
+ assertEquals(expected.toString(), actual.toString());
+ }
+
+ static PersistableBundle buildPersistableBundle() {
+ final PersistableBundle outer = new PersistableBundle();
+
+ outer.putBoolean("boolean", true);
+ outer.putInt("int", 42);
+ outer.putLong("long", 43L);
+ outer.putDouble("double", 44d);
+ outer.putString("string", "com.example <and></and> & more");
+
+ outer.putBooleanArray("boolean[]", new boolean[] { true, false, true });
+ outer.putIntArray("int[]", new int[] { 42, 43, 44 });
+ outer.putLongArray("long[]", new long[] { 43L, 44L, 45L });
+ outer.putDoubleArray("double[]", new double[] { 43d, 44d, 45d });
+ outer.putStringArray("string[]", new String[] { "foo", "bar", "baz" });
+
+ final PersistableBundle nested = new PersistableBundle();
+ nested.putString("nested_key", "nested_value");
+ outer.putPersistableBundle("nested", nested);
+
+ return outer;
+ }
+
+ static byte[] doPersistableBundleWrite(TypedXmlSerializer out, PersistableBundle bundle)
+ throws Exception {
+ // We purposefully omit START/END_DOCUMENT events here to verify correct
+ // behavior of what PersistableBundle does internally
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ out.setOutput(os, StandardCharsets.UTF_8.name());
+ out.startTag(null, "bundle");
+ bundle.saveToXml(out);
+ out.endTag(null, "bundle");
+ out.flush();
+ return os.toByteArray();
+ }
+
+ static PersistableBundle doPersistableBundleRead(TypedXmlPullParser in, byte[] raw)
+ throws Exception {
+ final ByteArrayInputStream is = new ByteArrayInputStream(raw);
+ in.setInput(is, StandardCharsets.UTF_8.name());
+ in.next();
+ return PersistableBundle.restoreFromXml(in);
+ }
+
+ @Test
+ public void testVerify_Normal() throws Exception {
+ doVerify(XmlUtils.makeTyped(Xml.newSerializer()),
+ XmlUtils.makeTyped(Xml.newPullParser()));
+ }
+
+ @Test
+ public void testVerify_Fast() throws Exception {
+ doVerify(Xml.newFastSerializer(),
+ Xml.newFastPullParser());
+ }
+
+ @Test
+ public void testVerify_Binary() throws Exception {
+ doVerify(Xml.newBinarySerializer(),
+ Xml.newBinaryPullParser());
+ }
+
+ /**
+ * Verify that example test data is correctly serialized and parsed
+ * end-to-end using the given objects.
+ */
+ private static void doVerify(TypedXmlSerializer out, TypedXmlPullParser in) throws Exception {
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ out.setOutput(os, StandardCharsets.UTF_8.name());
+ doVerifyWrite(out);
+ out.flush();
+
+ final ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
+ in.setInput(is, StandardCharsets.UTF_8.name());
+ doVerifyRead(in);
+ }
+
+ private static final String TEST_STRING = "com.example";
+ private static final byte[] TEST_BYTES = new byte[] { 0, 1, 2, 3, 4, 3, 2, 1, 0 };
+
+ private static void doVerifyWrite(TypedXmlSerializer out) throws Exception {
+ out.startDocument(StandardCharsets.UTF_8.name(), true);
+ out.startTag(null, "one");
+ {
+ out.startTag(null, "two");
+ {
+ out.attribute(null, "string", TEST_STRING);
+ out.attribute(null, "stringNumber", "49");
+ out.attributeBytesHex(null, "bytesHex", TEST_BYTES);
+ out.attributeBytesBase64(null, "bytesBase64", TEST_BYTES);
+ out.attributeInt(null, "int", 43);
+ out.attributeIntHex(null, "intHex", 44);
+ out.attributeLong(null, "long", 45L);
+ out.attributeLongHex(null, "longHex", 46L);
+ out.attributeFloat(null, "float", 47f);
+ out.attributeDouble(null, "double", 48d);
+ out.attributeBoolean(null, "boolean", true);
+ }
+ out.endTag(null, "two");
+
+ out.startTag(null, "three");
+ {
+ out.text("foo");
+ out.startTag(null, "four");
+ {
+ }
+ out.endTag(null, "four");
+ out.text("bar");
+ out.text("baz");
+ }
+ out.endTag(null, "three");
+ }
+ out.endTag(null, "one");
+ out.endDocument();
+ }
+
+ private static void doVerifyRead(TypedXmlPullParser in) throws Exception {
+ assertEquals(START_DOCUMENT, in.getEventType());
+ assertNext(in, START_TAG, "one", 1);
+ {
+ assertNext(in, START_TAG, "two", 2);
+ {
+ assertEquals(11, in.getAttributeCount());
+ assertEquals(TEST_STRING, in.getAttributeValue(null, "string"));
+ assertArrayEquals(TEST_BYTES, in.getAttributeBytesHex(null, "bytesHex"));
+ assertArrayEquals(TEST_BYTES, in.getAttributeBytesBase64(null, "bytesBase64"));
+ assertEquals(43, in.getAttributeInt(null, "int"));
+ assertEquals(44, in.getAttributeIntHex(null, "intHex"));
+ assertEquals(45L, in.getAttributeLong(null, "long"));
+ assertEquals(46L, in.getAttributeLongHex(null, "longHex"));
+ assertEquals(47f, in.getAttributeFloat(null, "float"), 0.01);
+ assertEquals(48d, in.getAttributeDouble(null, "double"), 0.01);
+ assertEquals(true, in.getAttributeBoolean(null, "boolean"));
+
+ // Also verify that typed values are available as strings
+ assertEquals("000102030403020100", in.getAttributeValue(null, "bytesHex"));
+ assertEquals("AAECAwQDAgEA", in.getAttributeValue(null, "bytesBase64"));
+ assertEquals("43", in.getAttributeValue(null, "int"));
+ assertEquals("2c", in.getAttributeValue(null, "intHex"));
+ assertEquals("45", in.getAttributeValue(null, "long"));
+ assertEquals("2e", in.getAttributeValue(null, "longHex"));
+ assertEquals("true", in.getAttributeValue(null, "boolean"));
+
+ // And that raw strings can be parsed too
+ assertEquals("49", in.getAttributeValue(null, "stringNumber"));
+ assertEquals(49, in.getAttributeInt(null, "stringNumber"));
+ }
+ assertNext(in, END_TAG, "two", 2);
+
+ assertNext(in, START_TAG, "three", 2);
+ {
+ assertNext(in, TEXT);
+ assertEquals("foo", in.getText().trim());
+ assertNext(in, START_TAG, "four", 3);
+ {
+ assertEquals(0, in.getAttributeCount());
+ }
+ assertNext(in, END_TAG, "four", 3);
+ assertNext(in, TEXT);
+ assertEquals("barbaz", in.getText().trim());
+ }
+ assertNext(in, END_TAG, "three", 2);
+ }
+ assertNext(in, END_TAG, "one", 1);
+ assertNext(in, END_DOCUMENT);
+ }
+
+ static void assertNext(TypedXmlPullParser in, int token) throws Exception {
+ // We're willing to skip over empty text regions, which some
+ // serializers emit transparently
+ int event;
+ while ((event = in.next()) == TEXT && in.getText().trim().length() == 0) {
+ }
+ assertEquals("next", token, event);
+ assertEquals("getEventType", token, in.getEventType());
+ }
+
+ static void assertNext(TypedXmlPullParser in, int token, String name, int depth)
+ throws Exception {
+ assertNext(in, token);
+ assertEquals("getName", name, in.getName());
+ assertEquals("getDepth", depth, in.getDepth());
+ }
+}
diff --git a/core/tests/coretests/src/com/android/internal/util/FastDataTest.java b/core/tests/coretests/src/com/android/internal/util/FastDataTest.java
new file mode 100644
index 0000000..841d659
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/util/FastDataTest.java
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2020 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.internal.util;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import android.annotation.NonNull;
+import android.util.ExceptionUtils;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.function.Consumer;
+
+@RunWith(AndroidJUnit4.class)
+public class FastDataTest {
+ private static final String TEST_SHORT_STRING = "a";
+ private static final String TEST_LONG_STRING = "com☃example☃typical☃package☃name";
+ private static final byte[] TEST_BYTES = TEST_LONG_STRING.getBytes(StandardCharsets.UTF_16LE);
+
+ @Test
+ public void testEndOfFile_Int() throws Exception {
+ try (FastDataInput in = new FastDataInput(new ByteArrayInputStream(
+ new byte[] { 1 }), 1000)) {
+ assertThrows(EOFException.class, () -> in.readInt());
+ }
+ try (FastDataInput in = new FastDataInput(new ByteArrayInputStream(
+ new byte[] { 1, 1, 1, 1 }), 1000)) {
+ assertEquals(1, in.readByte());
+ assertThrows(EOFException.class, () -> in.readInt());
+ }
+ }
+
+ @Test
+ public void testEndOfFile_String() throws Exception {
+ try (FastDataInput in = new FastDataInput(new ByteArrayInputStream(
+ new byte[] { 1 }), 1000)) {
+ assertThrows(EOFException.class, () -> in.readUTF());
+ }
+ try (FastDataInput in = new FastDataInput(new ByteArrayInputStream(
+ new byte[] { 1, 1, 1, 1 }), 1000)) {
+ assertThrows(EOFException.class, () -> in.readUTF());
+ }
+ }
+
+ @Test
+ public void testEndOfFile_Bytes_Small() throws Exception {
+ try (FastDataInput in = new FastDataInput(new ByteArrayInputStream(
+ new byte[] { 1, 1, 1, 1 }), 1000)) {
+ final byte[] tmp = new byte[10];
+ assertThrows(EOFException.class, () -> in.readFully(tmp));
+ }
+ try (FastDataInput in = new FastDataInput(new ByteArrayInputStream(
+ new byte[] { 1, 1, 1, 1 }), 1000)) {
+ final byte[] tmp = new byte[10_000];
+ assertThrows(EOFException.class, () -> in.readFully(tmp));
+ }
+ }
+
+ @Test
+ public void testUTF_Bounds() throws Exception {
+ final char[] buf = new char[65_535];
+ try (FastDataOutput out = new FastDataOutput(new ByteArrayOutputStream(), BOUNCE_SIZE)) {
+ // Writing simple string will fit fine
+ Arrays.fill(buf, '!');
+ final String simple = new String(buf);
+ out.writeUTF(simple);
+ out.writeInternedUTF(simple);
+
+ // Just one complex char will cause it to overflow
+ buf[0] = '☃';
+ final String complex = new String(buf);
+ assertThrows(IOException.class, () -> out.writeUTF(complex));
+ assertThrows(IOException.class, () -> out.writeInternedUTF(complex));
+ }
+ }
+
+ @Test
+ public void testBounce_Char() throws Exception {
+ doBounce((out) -> {
+ out.writeChar('\0');
+ out.writeChar('☃');
+ }, (in) -> {
+ assertEquals('\0', in.readChar());
+ assertEquals('☃', in.readChar());
+ });
+ }
+
+ @Test
+ public void testBounce_Short() throws Exception {
+ doBounce((out) -> {
+ out.writeShort(0);
+ out.writeShort((short) 0x0f0f);
+ out.writeShort((short) 0xf0f0);
+ out.writeShort(Short.MIN_VALUE);
+ out.writeShort(Short.MAX_VALUE);
+ }, (in) -> {
+ assertEquals(0, in.readShort());
+ assertEquals((short) 0x0f0f, in.readShort());
+ assertEquals((short) 0xf0f0, in.readShort());
+ assertEquals(Short.MIN_VALUE, in.readShort());
+ assertEquals(Short.MAX_VALUE, in.readShort());
+ });
+ }
+
+ @Test
+ public void testBounce_Int() throws Exception {
+ doBounce((out) -> {
+ out.writeInt(0);
+ out.writeInt(0x0f0f0f0f);
+ out.writeInt(0xf0f0f0f0);
+ out.writeInt(Integer.MIN_VALUE);
+ out.writeInt(Integer.MAX_VALUE);
+ }, (in) -> {
+ assertEquals(0, in.readInt());
+ assertEquals(0x0f0f0f0f, in.readInt());
+ assertEquals(0xf0f0f0f0, in.readInt());
+ assertEquals(Integer.MIN_VALUE, in.readInt());
+ assertEquals(Integer.MAX_VALUE, in.readInt());
+ });
+ }
+
+ @Test
+ public void testBounce_Long() throws Exception {
+ doBounce((out) -> {
+ out.writeLong(0);
+ out.writeLong(0x0f0f0f0f0f0f0f0fL);
+ out.writeLong(0xf0f0f0f0f0f0f0f0L);
+ out.writeLong(Long.MIN_VALUE);
+ out.writeLong(Long.MAX_VALUE);
+ }, (in) -> {
+ assertEquals(0, in.readLong());
+ assertEquals(0x0f0f0f0f0f0f0f0fL, in.readLong());
+ assertEquals(0xf0f0f0f0f0f0f0f0L, in.readLong());
+ assertEquals(Long.MIN_VALUE, in.readLong());
+ assertEquals(Long.MAX_VALUE, in.readLong());
+ });
+ }
+
+ @Test
+ public void testBounce_UTF() throws Exception {
+ doBounce((out) -> {
+ out.writeUTF("");
+ out.writeUTF("☃");
+ out.writeUTF("example");
+ }, (in) -> {
+ assertEquals("", in.readUTF());
+ assertEquals("☃", in.readUTF());
+ assertEquals("example", in.readUTF());
+ });
+ }
+
+ @Test
+ public void testBounce_UTF_Exact() throws Exception {
+ final char[] expectedBuf = new char[BOUNCE_SIZE];
+ Arrays.fill(expectedBuf, '!');
+ final String expected = new String(expectedBuf);
+
+ doBounce((out) -> {
+ out.writeUTF(expected);
+ }, (in) -> {
+ final String actual = in.readUTF();
+ assertEquals(expected.length(), actual.length());
+ assertEquals(expected, actual);
+ });
+ }
+
+ @Test
+ public void testBounce_UTF_Maximum() throws Exception {
+ final char[] expectedBuf = new char[65_535];
+ Arrays.fill(expectedBuf, '!');
+ final String expected = new String(expectedBuf);
+
+ doBounce((out) -> {
+ out.writeUTF(expected);
+ }, (in) -> {
+ final String actual = in.readUTF();
+ assertEquals(expected.length(), actual.length());
+ assertEquals(expected, actual);
+ }, 1);
+ }
+
+ @Test
+ public void testBounce_InternedUTF() throws Exception {
+ doBounce((out) -> {
+ out.writeInternedUTF("foo");
+ out.writeInternedUTF("bar");
+ out.writeInternedUTF("baz");
+ out.writeInternedUTF("bar");
+ out.writeInternedUTF("foo");
+ }, (in) -> {
+ assertEquals("foo", in.readInternedUTF());
+ assertEquals("bar", in.readInternedUTF());
+ assertEquals("baz", in.readInternedUTF());
+ assertEquals("bar", in.readInternedUTF());
+ assertEquals("foo", in.readInternedUTF());
+ });
+ }
+
+ /**
+ * Verify that when we overflow the maximum number of interned string
+ * references, we still transport the raw string values successfully.
+ */
+ @Test
+ public void testBounce_InternedUTF_Maximum() throws Exception {
+ final int num = 70_000;
+ doBounce((out) -> {
+ for (int i = 0; i < num; i++) {
+ out.writeInternedUTF("foo" + i);
+ }
+ }, (in) -> {
+ for (int i = 0; i < num; i++) {
+ assertEquals("foo" + i, in.readInternedUTF());
+ }
+ }, 1);
+ }
+
+ @Test
+ public void testBounce_Bytes() throws Exception {
+ doBounce((out) -> {
+ out.write(TEST_BYTES, 8, 32);
+ out.writeInt(64);
+ }, (in) -> {
+ final byte[] tmp = new byte[128];
+ in.readFully(tmp, 8, 32);
+ assertArrayEquals(Arrays.copyOfRange(TEST_BYTES, 8, 8 + 32),
+ Arrays.copyOfRange(tmp, 8, 8 + 32));
+ assertEquals(64, in.readInt());
+ });
+ }
+
+ @Test
+ public void testBounce_Mixed() throws Exception {
+ doBounce((out) -> {
+ out.writeBoolean(true);
+ out.writeBoolean(false);
+ out.writeByte(1);
+ out.writeShort(2);
+ out.writeInt(4);
+ out.writeUTF(TEST_SHORT_STRING);
+ out.writeUTF(TEST_LONG_STRING);
+ out.writeLong(8L);
+ out.writeFloat(16f);
+ out.writeDouble(32d);
+ }, (in) -> {
+ assertEquals(true, in.readBoolean());
+ assertEquals(false, in.readBoolean());
+ assertEquals(1, in.readByte());
+ assertEquals(2, in.readShort());
+ assertEquals(4, in.readInt());
+ assertEquals(TEST_SHORT_STRING, in.readUTF());
+ assertEquals(TEST_LONG_STRING, in.readUTF());
+ assertEquals(8L, in.readLong());
+ assertEquals(16f, in.readFloat(), 0.01);
+ assertEquals(32d, in.readDouble(), 0.01);
+ });
+ }
+
+ /**
+ * Buffer size to use for {@link #doBounce}; purposefully chosen to be a
+ * small prime number to help uncover edge cases.
+ */
+ private static final int BOUNCE_SIZE = 11;
+
+ /**
+ * Number of times to repeat message when bouncing; repeating is used to
+ * help uncover edge cases.
+ */
+ private static final int BOUNCE_REPEAT = 1_000;
+
+ /**
+ * Verify that some common data can be written and read back, effectively
+ * "bouncing" it through a serialized representation.
+ */
+ private static void doBounce(@NonNull ThrowingConsumer<FastDataOutput> out,
+ @NonNull ThrowingConsumer<FastDataInput> in) throws Exception {
+ doBounce(out, in, BOUNCE_REPEAT);
+ }
+
+ private static void doBounce(@NonNull ThrowingConsumer<FastDataOutput> out,
+ @NonNull ThrowingConsumer<FastDataInput> in, int count) throws Exception {
+ final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ final FastDataOutput outData = new FastDataOutput(outStream, BOUNCE_SIZE);
+ for (int i = 0; i < count; i++) {
+ out.accept(outData);
+ }
+ outData.flush();
+
+ final ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray());
+ final FastDataInput inData = new FastDataInput(inStream, BOUNCE_SIZE);
+ for (int i = 0; i < count; i++) {
+ in.accept(inData);
+ }
+ }
+
+ private static <T extends Exception> void assertThrows(Class<T> clazz, ThrowingRunnable r)
+ throws Exception {
+ try {
+ r.run();
+ fail("Expected " + clazz + " to be thrown");
+ } catch (Exception e) {
+ if (!clazz.isAssignableFrom(e.getClass())) {
+ throw e;
+ }
+ }
+ }
+
+ public interface ThrowingRunnable {
+ void run() throws Exception;
+ }
+
+ public interface ThrowingConsumer<T> extends Consumer<T> {
+ void acceptOrThrow(T t) throws Exception;
+
+ @Override
+ default void accept(T t) {
+ try {
+ acceptOrThrow(t);
+ } catch (Exception ex) {
+ throw ExceptionUtils.propagate(ex);
+ }
+ }
+ }
+}
diff --git a/core/tests/uwbtests/src/android/uwb/RangingParamsTest.java b/core/tests/uwbtests/src/android/uwb/RangingParamsTest.java
deleted file mode 100644
index 8095c99..0000000
--- a/core/tests/uwbtests/src/android/uwb/RangingParamsTest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2020 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.uwb;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-import android.os.PersistableBundle;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.time.Duration;
-
-/**
- * Test of {@link RangingParams}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class RangingParamsTest {
-
- @Test
- public void testParams_Build() {
- UwbAddress local = UwbAddress.fromBytes(new byte[] {(byte) 0xA0, (byte) 0x57});
- UwbAddress remote = UwbAddress.fromBytes(new byte[] {(byte) 0x4D, (byte) 0x8C});
- int channel = 9;
- int rxPreamble = 16;
- int txPreamble = 21;
- boolean isController = true;
- boolean isInitiator = false;
- @RangingParams.StsPhyPacketType int stsPhyType = RangingParams.STS_PHY_PACKET_TYPE_SP2;
- Duration samplePeriod = Duration.ofSeconds(1, 234);
- PersistableBundle specParams = new PersistableBundle();
- specParams.putString("protocol", "some_protocol");
-
- RangingParams params = new RangingParams.Builder()
- .setChannelNumber(channel)
- .setReceivePreambleCodeIndex(rxPreamble)
- .setTransmitPreambleCodeIndex(txPreamble)
- .setLocalDeviceAddress(local)
- .addRemoteDeviceAddress(remote)
- .setIsController(isController)
- .setIsInitiator(isInitiator)
- .setSamplePeriod(samplePeriod)
- .setStsPhPacketType(stsPhyType)
- .setSpecificationParameters(specParams)
- .build();
-
- assertEquals(params.getLocalDeviceAddress(), local);
- assertEquals(params.getRemoteDeviceAddresses().size(), 1);
- assertEquals(params.getRemoteDeviceAddresses().get(0), remote);
- assertEquals(params.getChannelNumber(), channel);
- assertEquals(params.isController(), isController);
- assertEquals(params.isInitiator(), isInitiator);
- assertEquals(params.getRxPreambleIndex(), rxPreamble);
- assertEquals(params.getTxPreambleIndex(), txPreamble);
- assertEquals(params.getStsPhyPacketType(), stsPhyType);
- assertEquals(params.getSamplingPeriod(), samplePeriod);
- assertTrue(params.getSpecificationParameters().kindofEquals(specParams));
- }
-
- @Test
- public void testParcel() {
- Parcel parcel = Parcel.obtain();
- RangingParams params = new RangingParams.Builder()
- .setChannelNumber(9)
- .setReceivePreambleCodeIndex(16)
- .setTransmitPreambleCodeIndex(21)
- .setLocalDeviceAddress(UwbTestUtils.getUwbAddress(false))
- .addRemoteDeviceAddress(UwbTestUtils.getUwbAddress(true))
- .setIsController(false)
- .setIsInitiator(true)
- .setSamplePeriod(Duration.ofSeconds(2))
- .setStsPhPacketType(RangingParams.STS_PHY_PACKET_TYPE_SP1)
- .build();
- params.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- RangingParams fromParcel = RangingParams.CREATOR.createFromParcel(parcel);
- assertEquals(params, fromParcel);
- }
-}
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index bda84dd..ba2e52a 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -284,28 +284,28 @@
</family>
<family lang="und-Ethi">
<font weight="400" style="normal">NotoSansEthiopic-VF.ttf
- <axis tag="wght" stylevalue="400" />
+ <axis tag="wght" stylevalue="400"/>
</font>
<font weight="500" style="normal">NotoSansEthiopic-VF.ttf
- <axis tag="wght" stylevalue="500" />
+ <axis tag="wght" stylevalue="500"/>
</font>
<font weight="600" style="normal">NotoSansEthiopic-VF.ttf
- <axis tag="wght" stylevalue="600" />
+ <axis tag="wght" stylevalue="600"/>
</font>
<font weight="700" style="normal">NotoSansEthiopic-VF.ttf
- <axis tag="wght" stylevalue="700" />
+ <axis tag="wght" stylevalue="700"/>
</font>
<font weight="400" style="normal" fallbackFor="serif">NotoSerifEthiopic-VF.ttf
- <axis tag="wght" stylevalue="400" />
+ <axis tag="wght" stylevalue="400"/>
</font>
<font weight="500" style="normal" fallbackFor="serif">NotoSerifEthiopic-VF.ttf
- <axis tag="wght" stylevalue="500" />
+ <axis tag="wght" stylevalue="500"/>
</font>
<font weight="600" style="normal" fallbackFor="serif">NotoSerifEthiopic-VF.ttf
- <axis tag="wght" stylevalue="600" />
+ <axis tag="wght" stylevalue="600"/>
</font>
<font weight="700" style="normal" fallbackFor="serif">NotoSerifEthiopic-VF.ttf
- <axis tag="wght" stylevalue="700" />
+ <axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Hebr">
@@ -326,54 +326,54 @@
</family>
<family lang="und-Armn">
<font weight="400" style="normal">NotoSansArmenian-VF.ttf
- <axis tag="wght" stylevalue="400" />
+ <axis tag="wght" stylevalue="400"/>
</font>
<font weight="500" style="normal">NotoSansArmenian-VF.ttf
- <axis tag="wght" stylevalue="500" />
+ <axis tag="wght" stylevalue="500"/>
</font>
<font weight="600" style="normal">NotoSansArmenian-VF.ttf
- <axis tag="wght" stylevalue="600" />
+ <axis tag="wght" stylevalue="600"/>
</font>
<font weight="700" style="normal">NotoSansArmenian-VF.ttf
- <axis tag="wght" stylevalue="700" />
+ <axis tag="wght" stylevalue="700"/>
</font>
<font weight="400" style="normal" fallbackFor="serif">NotoSerifArmenian-VF.ttf
- <axis tag="wght" stylevalue="400" />
+ <axis tag="wght" stylevalue="400"/>
</font>
<font weight="500" style="normal" fallbackFor="serif">NotoSerifArmenian-VF.ttf
- <axis tag="wght" stylevalue="500" />
+ <axis tag="wght" stylevalue="500"/>
</font>
<font weight="600" style="normal" fallbackFor="serif">NotoSerifArmenian-VF.ttf
- <axis tag="wght" stylevalue="600" />
+ <axis tag="wght" stylevalue="600"/>
</font>
<font weight="700" style="normal" fallbackFor="serif">NotoSerifArmenian-VF.ttf
- <axis tag="wght" stylevalue="700" />
+ <axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Geor,und-Geok">
<font weight="400" style="normal">NotoSansGeorgian-VF.ttf
- <axis tag="wght" stylevalue="400" />
+ <axis tag="wght" stylevalue="400"/>
</font>
<font weight="500" style="normal">NotoSansGeorgian-VF.ttf
- <axis tag="wght" stylevalue="500" />
+ <axis tag="wght" stylevalue="500"/>
</font>
<font weight="600" style="normal">NotoSansGeorgian-VF.ttf
- <axis tag="wght" stylevalue="600" />
+ <axis tag="wght" stylevalue="600"/>
</font>
<font weight="700" style="normal">NotoSansGeorgian-VF.ttf
- <axis tag="wght" stylevalue="700" />
+ <axis tag="wght" stylevalue="700"/>
</font>
<font weight="400" style="normal" fallbackFor="serif">NotoSerifGeorgian-VF.ttf
- <axis tag="wght" stylevalue="400" />
+ <axis tag="wght" stylevalue="400"/>
</font>
<font weight="500" style="normal" fallbackFor="serif">NotoSerifGeorgian-VF.ttf
- <axis tag="wght" stylevalue="500" />
+ <axis tag="wght" stylevalue="500"/>
</font>
<font weight="600" style="normal" fallbackFor="serif">NotoSerifGeorgian-VF.ttf
- <axis tag="wght" stylevalue="600" />
+ <axis tag="wght" stylevalue="600"/>
</font>
<font weight="700" style="normal" fallbackFor="serif">NotoSerifGeorgian-VF.ttf
- <axis tag="wght" stylevalue="700" />
+ <axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Deva" variant="elegant">
@@ -491,44 +491,44 @@
</family>
<family lang="und-Khmr" variant="elegant">
<font weight="100" style="normal">NotoSansKhmer-VF.ttf
- <axis tag="wdth" stylevalue="100.0" />
- <axis tag="wght" stylevalue="26.0" />
+ <axis tag="wdth" stylevalue="100.0"/>
+ <axis tag="wght" stylevalue="26.0"/>
</font>
<font weight="200" style="normal">NotoSansKhmer-VF.ttf
- <axis tag="wdth" stylevalue="100.0" />
- <axis tag="wght" stylevalue="39.0" />
+ <axis tag="wdth" stylevalue="100.0"/>
+ <axis tag="wght" stylevalue="39.0"/>
</font>
<font weight="300" style="normal">NotoSansKhmer-VF.ttf
- <axis tag="wdth" stylevalue="100.0" />
- <axis tag="wght" stylevalue="58.0" />
+ <axis tag="wdth" stylevalue="100.0"/>
+ <axis tag="wght" stylevalue="58.0"/>
</font>
<font weight="400" style="normal">NotoSansKhmer-VF.ttf
- <axis tag="wdth" stylevalue="100.0" />
- <axis tag="wght" stylevalue="90.0" />
+ <axis tag="wdth" stylevalue="100.0"/>
+ <axis tag="wght" stylevalue="90.0"/>
</font>
<font weight="500" style="normal">NotoSansKhmer-VF.ttf
- <axis tag="wdth" stylevalue="100.0" />
- <axis tag="wght" stylevalue="108.0" />
+ <axis tag="wdth" stylevalue="100.0"/>
+ <axis tag="wght" stylevalue="108.0"/>
</font>
<font weight="600" style="normal">NotoSansKhmer-VF.ttf
- <axis tag="wdth" stylevalue="100.0" />
- <axis tag="wght" stylevalue="128.0" />
+ <axis tag="wdth" stylevalue="100.0"/>
+ <axis tag="wght" stylevalue="128.0"/>
</font>
<font weight="700" style="normal">NotoSansKhmer-VF.ttf
- <axis tag="wdth" stylevalue="100.0" />
- <axis tag="wght" stylevalue="151.0" />
+ <axis tag="wdth" stylevalue="100.0"/>
+ <axis tag="wght" stylevalue="151.0"/>
</font>
<font weight="800" style="normal">NotoSansKhmer-VF.ttf
- <axis tag="wdth" stylevalue="100.0" />
- <axis tag="wght" stylevalue="169.0" />
+ <axis tag="wdth" stylevalue="100.0"/>
+ <axis tag="wght" stylevalue="169.0"/>
</font>
<font weight="900" style="normal">NotoSansKhmer-VF.ttf
- <axis tag="wdth" stylevalue="100.0" />
- <axis tag="wght" stylevalue="190.0" />
+ <axis tag="wdth" stylevalue="100.0"/>
+ <axis tag="wght" stylevalue="190.0"/>
</font>
<font weight="400" style="normal" fallbackFor="serif">NotoSerifKhmer-Regular.otf</font>
<font weight="700" style="normal" fallbackFor="serif">NotoSerifKhmer-Bold.otf</font>
- </family>
+ </family>
<family lang="und-Khmr" variant="compact">
<font weight="400" style="normal">NotoSansKhmerUI-Regular.ttf</font>
<font weight="700" style="normal">NotoSansKhmerUI-Bold.ttf</font>
@@ -568,16 +568,16 @@
</family>
<family lang="und-Adlm">
<font weight="400" style="normal">NotoSansAdlam-VF.ttf
- <axis tag="wght" stylevalue="400" />
+ <axis tag="wght" stylevalue="400"/>
</font>
<font weight="500" style="normal">NotoSansAdlam-VF.ttf
- <axis tag="wght" stylevalue="500" />
+ <axis tag="wght" stylevalue="500"/>
</font>
<font weight="600" style="normal">NotoSansAdlam-VF.ttf
- <axis tag="wght" stylevalue="600" />
+ <axis tag="wght" stylevalue="600"/>
</font>
<font weight="700" style="normal">NotoSansAdlam-VF.ttf
- <axis tag="wght" stylevalue="700" />
+ <axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Avst">
@@ -762,8 +762,18 @@
<font weight="400" style="normal">NotoSansTaiViet-Regular.ttf</font>
</family>
<family lang="und-Tibt">
- <font weight="400" style="normal">NotoSansTibetan-Regular.ttf</font>
- <font weight="700" style="normal">NotoSansTibetan-Bold.ttf</font>
+ <font weight="400" style="normal">NotoSerifTibetan-VF.ttf
+ <axis tag="wght" stylevalue="400"/>
+ </font>
+ <font weight="500" style="normal">NotoSerifTibetan-VF.ttf
+ <axis tag="wght" stylevalue="500"/>
+ </font>
+ <font weight="600" style="normal">NotoSerifTibetan-VF.ttf
+ <axis tag="wght" stylevalue="600"/>
+ </font>
+ <font weight="700" style="normal">NotoSerifTibetan-VF.ttf
+ <axis tag="wght" stylevalue="700"/>
+ </font>
</family>
<family lang="und-Tfng">
<font weight="400" style="normal">NotoSansTifinagh-Regular.otf</font>
@@ -893,4 +903,83 @@
<family lang="und-Wara">
<font weight="400" style="normal">NotoSansWarangCiti-Regular.otf</font>
</family>
+ <family lang="und-Gran">
+ <font weight="400" style="normal">NotoSansGrantha-Regular.ttf</font>
+ </family>
+ <family lang="und-Modi">
+ <font weight="400" style="normal">NotoSansModi-Regular.ttf</font>
+ </family>
+ <family lang="und-Dogr">
+ <font weight="400" style="normal">NotoSerifDogra-Regular.ttf</font>
+ </family>
+ <family lang="und-Medf">
+ <font weight="400" style="normal">NotoSansMedefaidrin-VF.ttf
+ <axis tag="wght" stylevalue="400"/>
+ </font>
+ <font weight="500" style="normal">NotoSansMedefaidrin-VF.ttf
+ <axis tag="wght" stylevalue="500"/>
+ </font>
+ <font weight="600" style="normal">NotoSansMedefaidrin-VF.ttf
+ <axis tag="wght" stylevalue="600"/>
+ </font>
+ <font weight="700" style="normal">NotoSansMedefaidrin-VF.ttf
+ <axis tag="wght" stylevalue="700"/>
+ </font>
+ </family>
+ <family lang="und-Soyo">
+ <font weight="400" style="normal">NotoSansSoyombo-VF.ttf
+ <axis tag="wght" stylevalue="400"/>
+ </font>
+ <font weight="500" style="normal">NotoSansSoyombo-VF.ttf
+ <axis tag="wght" stylevalue="500"/>
+ </font>
+ <font weight="600" style="normal">NotoSansSoyombo-VF.ttf
+ <axis tag="wght" stylevalue="600"/>
+ </font>
+ <font weight="700" style="normal">NotoSansSoyombo-VF.ttf
+ <axis tag="wght" stylevalue="700"/>
+ </font>
+ </family>
+ <family lang="und-Takr">
+ <font weight="400" style="normal">NotoSansTakri-VF.ttf
+ <axis tag="wght" stylevalue="400"/>
+ </font>
+ <font weight="500" style="normal">NotoSansTakri-VF.ttf
+ <axis tag="wght" stylevalue="500"/>
+ </font>
+ <font weight="600" style="normal">NotoSansTakri-VF.ttf
+ <axis tag="wght" stylevalue="600"/>
+ </font>
+ <font weight="700" style="normal">NotoSansTakri-VF.ttf
+ <axis tag="wght" stylevalue="700"/>
+ </font>
+ </family>
+ <family lang="und-Hmnp">
+ <font weight="400" style="normal">NotoSerifNyiakengPuachueHmong-VF.ttf
+ <axis tag="wght" stylevalue="400"/>
+ </font>
+ <font weight="500" style="normal">NotoSerifNyiakengPuachueHmong-VF.ttf
+ <axis tag="wght" stylevalue="500"/>
+ </font>
+ <font weight="600" style="normal">NotoSerifNyiakengPuachueHmong-VF.ttf
+ <axis tag="wght" stylevalue="600"/>
+ </font>
+ <font weight="700" style="normal">NotoSerifNyiakengPuachueHmong-VF.ttf
+ <axis tag="wght" stylevalue="700"/>
+ </font>
+ </family>
+ <family lang="und-Yezi">
+ <font weight="400" style="normal">NotoSerifYezidi-VF.ttf
+ <axis tag="wght" stylevalue="400"/>
+ </font>
+ <font weight="500" style="normal">NotoSerifYezidi-VF.ttf
+ <axis tag="wght" stylevalue="500"/>
+ </font>
+ <font weight="600" style="normal">NotoSerifYezidi-VF.ttf
+ <axis tag="wght" stylevalue="600"/>
+ </font>
+ <font weight="700" style="normal">NotoSerifYezidi-VF.ttf
+ <axis tag="wght" stylevalue="700"/>
+ </font>
+ </family>
</familyset>
diff --git a/graphics/java/android/graphics/Compatibility.java b/graphics/java/android/graphics/Compatibility.java
index ed84912..747fbf1 100644
--- a/graphics/java/android/graphics/Compatibility.java
+++ b/graphics/java/android/graphics/Compatibility.java
@@ -16,14 +16,11 @@
package android.graphics;
-import android.annotation.SystemApi;
-
/**
* Helper class for graphics classes to retrieve the targetSdkVersion, as
* specified by the app.
* @hide
*/
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public final class Compatibility {
private Compatibility() {}
@@ -34,7 +31,6 @@
* application. No other code should call this.
* @hide
*/
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static void setTargetSdkVersion(int targetSdkVersion) {
sTargetSdkVersion = targetSdkVersion;
Canvas.setCompatibilityVersion(targetSdkVersion);
diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java
index 4cac7fb..3732285 100644
--- a/graphics/java/android/graphics/ImageDecoder.java
+++ b/graphics/java/android/graphics/ImageDecoder.java
@@ -27,7 +27,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Px;
-import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.annotation.WorkerThread;
import android.content.ContentResolver;
@@ -916,12 +915,8 @@
/**
* Provide Resources for density scaling.
*
- * This is a SystemApi to enable legacy behavior, so there is no need to
- * make it public like the version above, which does not have a Resources
- * parameter.
* @hide
*/
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@AnyThread
@NonNull
public static Source createSource(@NonNull ContentResolver cr,
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index c58e5f3..d44cb9c 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -34,8 +34,12 @@
import android.graphics.fonts.SystemFonts;
import android.os.Build;
import android.os.ParcelFileDescriptor;
+import android.os.SharedMemory;
+import android.os.Trace;
import android.provider.FontRequest;
import android.provider.FontsContract;
+import android.system.ErrnoException;
+import android.system.OsConstants;
import android.text.FontConfig;
import android.util.Base64;
import android.util.LongSparseArray;
@@ -50,6 +54,7 @@
import libcore.util.NativeAllocationRegistry;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -57,6 +62,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -79,19 +85,19 @@
Typeface.class.getClassLoader(), nativeGetReleaseFunc());
/** The default NORMAL typeface object */
- public static final Typeface DEFAULT;
+ public static final Typeface DEFAULT = new Typeface();
/**
* The default BOLD typeface object. Note: this may be not actually be
* bold, depending on what fonts are installed. Call getStyle() to know
* for sure.
*/
- public static final Typeface DEFAULT_BOLD;
+ public static final Typeface DEFAULT_BOLD = new Typeface();
/** The NORMAL style of the default sans serif typeface. */
- public static final Typeface SANS_SERIF;
+ public static final Typeface SANS_SERIF = new Typeface();
/** The NORMAL style of the default serif typeface. */
- public static final Typeface SERIF;
+ public static final Typeface SERIF = new Typeface();
/** The NORMAL style of the default monospace typeface. */
- public static final Typeface MONOSPACE;
+ public static final Typeface MONOSPACE = new Typeface();
/**
* The default {@link Typeface}s for different text styles.
@@ -133,7 +139,7 @@
* Use public API {@link #create(String, int)} to get the typeface for given familyName.
*/
@UnsupportedAppUsage(trackingBug = 123769347)
- static final Map<String, Typeface> sSystemFontMap;
+ static final Map<String, Typeface> sSystemFontMap = new HashMap<>();
// We cannot support sSystemFallbackMap since we will migrate to public FontFamily API.
/**
@@ -150,6 +156,9 @@
@UnsupportedAppUsage
public long native_instance;
+ // This destructs native_instance.
+ private Runnable mCleaner;
+
/** @hide */
@IntDef(value = {NORMAL, BOLD, ITALIC, BOLD_ITALIC})
@Retention(RetentionPolicy.SOURCE)
@@ -1086,19 +1095,41 @@
return new Typeface(nativeCreateFromArray(ptrArray, weight, italic));
}
+ /**
+ * Creates a fake Typeface object that are later modified to point to another Typeface object
+ * using {@link #reset(Typeface, int)}.
+ *
+ * <p>This constructor is only for filling 'static final' Typeface instances in Zygote process.
+ */
+ private Typeface() {
+ }
+
// don't allow clients to call this directly
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private Typeface(long ni) {
+ init(ni);
+ }
+
+ private void init(long ni) {
if (ni == 0) {
throw new RuntimeException("native typeface cannot be made");
}
-
+ if (mCleaner != null) {
+ mCleaner.run();
+ }
native_instance = ni;
- sRegistry.registerNativeAllocation(this, native_instance);
+ mCleaner = sRegistry.registerNativeAllocation(this, native_instance);
mStyle = nativeGetStyle(ni);
mWeight = nativeGetWeight(ni);
}
+ private void reset(Typeface typeface, int style) {
+ // Just create a new native instance without looking into the cache, because we are going to
+ // claim the ownership.
+ long ni = nativeCreateFromTypeface(typeface.native_instance, style);
+ init(ni);
+ }
+
private static Typeface getSystemDefaultTypeface(@NonNull String familyName) {
Typeface tf = sSystemFontMap.get(familyName);
return tf == null ? Typeface.DEFAULT : tf;
@@ -1137,23 +1168,105 @@
}
}
- static {
- final HashMap<String, Typeface> systemFontMap = new HashMap<>();
- initSystemDefaultTypefaces(systemFontMap, SystemFonts.getRawSystemFallbackMap(),
- SystemFonts.getAliases());
- sSystemFontMap = Collections.unmodifiableMap(systemFontMap);
+ /** @hide */
+ public static SharedMemory serializeFontMap(Map<String, Typeface> fontMap)
+ throws IOException, ErrnoException {
+ long[] nativePtrs = new long[fontMap.size()];
+ // The name table will not be large, so let's create a byte array in memory.
+ ByteArrayOutputStream namesBytes = new ByteArrayOutputStream();
+ int i = 0;
+ for (Map.Entry<String, Typeface> entry : fontMap.entrySet()) {
+ nativePtrs[i++] = entry.getValue().native_instance;
+ writeString(namesBytes, entry.getKey());
+ }
+ int typefacesBytesCount = nativeWriteTypefaces(null, nativePtrs);
+ // int (typefacesBytesCount), typefaces, namesBytes
+ SharedMemory sharedMemory = SharedMemory.create(
+ "fontMap", Integer.BYTES + typefacesBytesCount + namesBytes.size());
+ ByteBuffer writableBuffer = sharedMemory.mapReadWrite().order(ByteOrder.BIG_ENDIAN);
+ try {
+ writableBuffer.putInt(typefacesBytesCount);
+ int writtenBytesCount = nativeWriteTypefaces(writableBuffer.slice(), nativePtrs);
+ if (writtenBytesCount != typefacesBytesCount) {
+ throw new IOException(String.format("Unexpected bytes written: %d, expected: %d",
+ writtenBytesCount, typefacesBytesCount));
+ }
+ writableBuffer.position(writableBuffer.position() + writtenBytesCount);
+ writableBuffer.put(namesBytes.toByteArray());
+ } finally {
+ SharedMemory.unmap(writableBuffer);
+ }
+ sharedMemory.setProtect(OsConstants.PROT_READ);
+ return sharedMemory;
+ }
+
+ /** @hide */
+ @VisibleForTesting
+ public static Map<String, Typeface> deserializeFontMap(SharedMemory sharedMemory)
+ throws IOException, ErrnoException {
+ Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "deserializeFontMap");
+ try {
+ // TODO: unmap buffer when all Typefaces are gone.
+ // Currently deserializeFontMap() should be called at most once per process, so we don't
+ // need to unmap this buffer.
+ ByteBuffer buffer = sharedMemory.mapReadOnly().order(ByteOrder.BIG_ENDIAN);
+ Map<String, Typeface> fontMap = new HashMap<>();
+ int typefacesBytesCount = buffer.getInt();
+ long[] nativePtrs = nativeReadTypefaces(buffer.slice());
+ if (nativePtrs == null) {
+ throw new IOException("Could not read typefaces");
+ }
+ buffer.position(buffer.position() + typefacesBytesCount);
+ for (long nativePtr : nativePtrs) {
+ String name = readString(buffer);
+ fontMap.put(name, new Typeface(nativePtr));
+ }
+ return fontMap;
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
+ }
+ }
+
+ private static String readString(ByteBuffer buffer) {
+ int length = buffer.getInt();
+ byte[] bytes = new byte[length];
+ buffer.get(bytes);
+ return new String(bytes);
+ }
+
+ private static void writeString(ByteArrayOutputStream bos, String value) throws IOException {
+ byte[] bytes = value.getBytes();
+ writeInt(bos, bytes.length);
+ bos.write(bytes);
+ }
+
+ private static void writeInt(ByteArrayOutputStream bos, int value) {
+ // Write in the big endian order.
+ bos.write((value >> 24) & 0xFF);
+ bos.write((value >> 16) & 0xFF);
+ bos.write((value >> 8) & 0xFF);
+ bos.write(value & 0xFF);
+ }
+
+ /** @hide */
+ @VisibleForTesting
+ public static void setSystemFontMap(Map<String, Typeface> systemFontMap) {
+ sSystemFontMap.clear();
+ sSystemFontMap.putAll(systemFontMap);
// We can't assume DEFAULT_FAMILY available on Roboletric.
if (sSystemFontMap.containsKey(DEFAULT_FAMILY)) {
setDefault(sSystemFontMap.get(DEFAULT_FAMILY));
}
- // Set up defaults and typefaces exposed in public API
- DEFAULT = create((String) null, 0);
- DEFAULT_BOLD = create((String) null, Typeface.BOLD);
- SANS_SERIF = create("sans-serif", 0);
- SERIF = create("serif", 0);
- MONOSPACE = create("monospace", 0);
+ // Set up defaults and typefaces exposed in public API.
+ // We cannot use getSystemDefaultTypeface() here to initialize DEFAULT, because it returns
+ // DEFAULT.
+ DEFAULT.reset(sDefaultTypeface, Typeface.NORMAL);
+ DEFAULT_BOLD.reset(sDefaultTypeface, Typeface.BOLD);
+ SANS_SERIF.reset(getSystemDefaultTypeface("sans-serif"), Typeface.NORMAL);
+ SERIF.reset(getSystemDefaultTypeface("serif"), Typeface.NORMAL);
+ MONOSPACE.reset(getSystemDefaultTypeface("monospace"), Typeface.NORMAL);
sDefaults = new Typeface[] {
DEFAULT,
@@ -1173,6 +1286,13 @@
}
}
+ static {
+ final HashMap<String, Typeface> systemFontMap = new HashMap<>();
+ initSystemDefaultTypefaces(systemFontMap, SystemFonts.getRawSystemFallbackMap(),
+ SystemFonts.getAliases());
+ setSystemFontMap(systemFontMap);
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -1210,36 +1330,6 @@
return Arrays.binarySearch(mSupportedAxes, axis) >= 0;
}
- /**
- * Writes Typeface instances to the ByteBuffer and returns the number of bytes written.
- *
- * <p>If {@code buffer} is null, this method returns the number of bytes required to serialize
- * the typefaces, without writing anything.
- * @hide
- */
- public static int writeTypefaces(
- @Nullable ByteBuffer buffer, @NonNull List<Typeface> typefaces) {
- long[] nativePtrs = new long[typefaces.size()];
- for (int i = 0; i < nativePtrs.length; i++) {
- nativePtrs[i] = typefaces.get(i).native_instance;
- }
- return nativeWriteTypefaces(buffer, nativePtrs);
- }
-
- /**
- * Reads serialized Typeface instances from the ByteBuffer. Returns null on errors.
- * @hide
- */
- public static @Nullable List<Typeface> readTypefaces(@NonNull ByteBuffer buffer) {
- long[] nativePtrs = nativeReadTypefaces(buffer);
- if (nativePtrs == null) return null;
- List<Typeface> typefaces = new ArrayList<>(nativePtrs.length);
- for (long nativePtr : nativePtrs) {
- typefaces.add(new Typeface(nativePtr));
- }
- return typefaces;
- }
-
private static native long nativeCreateFromTypeface(long native_instance, int style);
private static native long nativeCreateFromTypefaceWithExactStyle(
long native_instance, int weight, boolean italic);
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
index 71e6559..d1b4464 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
@@ -23,6 +23,7 @@
import android.security.keymaster.ExportResult;
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterDefs;
+import android.sysprop.Keystore2Properties;
import java.io.IOException;
import java.security.KeyFactory;
@@ -111,6 +112,26 @@
putSecretKeyFactoryImpl("HmacSHA512");
}
+ private static boolean sKeystore2Enabled;
+
+ /**
+ * This function indicates whether or not Keystore 2.0 is enabled. Some parts of the
+ * Keystore SPI must behave subtly differently when Keystore 2.0 is enabled. However,
+ * the platform property that indicates that Keystore 2.0 is enabled is not readable
+ * by applications. So we set this value when {@code install()} is called because it
+ * is called by zygote, which can access Keystore2Properties.
+ *
+ * This function can be removed once the transition to Keystore 2.0 is complete.
+ * b/171305684
+ *
+ * @return true if Keystore 2.0 is enabled.
+ * @hide
+ */
+ public static boolean isKeystore2Enabled() {
+ return sKeystore2Enabled;
+ }
+
+
/**
* Installs a new instance of this provider (and the
* {@link AndroidKeyStoreBCWorkaroundProvider}).
@@ -138,6 +159,11 @@
// priority.
Security.addProvider(workaroundProvider);
}
+
+ // {@code install()} is run by zygote when this property is still accessible. We store its
+ // value so that the Keystore SPI can act accordingly without having to access an internal
+ // property.
+ sKeystore2Enabled = Keystore2Properties.keystore2_enabled().orElse(false);
}
private void putSecretKeyFactoryImpl(String algorithm) {
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
index 9707260..3694d63 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
@@ -211,7 +211,11 @@
userAuthenticationValidWhileOnBody,
trustedUserPresenceRequired,
invalidatedByBiometricEnrollment,
- userConfirmationRequired);
+ userConfirmationRequired,
+ // Keystore 1.0 does not tell us the exact security level of the key
+ // so we report an unknown but secure security level.
+ insideSecureHardware ? KeyProperties.SECURITY_LEVEL_UNKNOWN_SECURE
+ : KeyProperties.SECURITY_LEVEL_SOFTWARE);
}
private static BigInteger getGateKeeperSecureUserId() throws ProviderException {
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 688c4a7..e9aac7d 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -27,7 +27,6 @@
import android.hardware.biometrics.BiometricPrompt;
import android.os.Build;
import android.security.GateKeeper;
-import android.security.KeyStore;
import android.text.TextUtils;
import java.math.BigInteger;
@@ -246,7 +245,7 @@
private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048
private final String mKeystoreAlias;
- private final int mUid;
+ private final int mNamespace;
private final int mKeySize;
private final AlgorithmParameterSpec mSpec;
private final X500Principal mCertificateSubject;
@@ -286,7 +285,7 @@
*/
public KeyGenParameterSpec(
String keyStoreAlias,
- int uid,
+ int namespace,
int keySize,
AlgorithmParameterSpec spec,
X500Principal certificateSubject,
@@ -337,7 +336,7 @@
}
mKeystoreAlias = keyStoreAlias;
- mUid = uid;
+ mNamespace = namespace;
mKeySize = keySize;
mSpec = spec;
mCertificateSubject = certificateSubject;
@@ -382,11 +381,43 @@
* Returns the UID which will own the key. {@code -1} is an alias for the UID of the current
* process.
*
+ * @deprecated See deprecation message on {@link KeyGenParameterSpec.Builder#setUid(int)}.
+ * Known namespaces will be translated to their legacy UIDs. Unknown
+ * Namespaces will yield {@link IllegalStateException}.
+ *
* @hide
*/
@UnsupportedAppUsage
+ @Deprecated
public int getUid() {
- return mUid;
+ if (!AndroidKeyStoreProvider.isKeystore2Enabled()) {
+ // If Keystore2 has not been enabled we have to behave as if mNamespace is actually
+ // a UID, because we are still being used with the old Keystore SPI.
+ // TODO This if statement and body can be removed when the Keystore 2 migration is
+ // complete. b/171563717
+ return mNamespace;
+ }
+ try {
+ return KeyProperties.namespaceToLegacyUid(mNamespace);
+ } catch (IllegalArgumentException e) {
+ throw new IllegalStateException("getUid called on KeyGenParameterSpec with non legacy"
+ + " keystore namespace.", e);
+ }
+ }
+
+ /**
+ * Returns the target namespace for the key.
+ * See {@link KeyGenParameterSpec.Builder#setNamespace(int)}.
+ *
+ * @return The numeric namespace as configured in the keystore2_key_contexts files of Android's
+ * SEPolicy.
+ * TODO b/171806779 link to public Keystore 2.0 documentation.
+ * See bug for more details for now.
+ * @hide
+ */
+ @SystemApi
+ public int getNamespace() {
+ return mNamespace;
}
/**
@@ -767,7 +798,7 @@
private final String mKeystoreAlias;
private @KeyProperties.PurposeEnum int mPurposes;
- private int mUid = KeyStore.UID_SELF;
+ private int mNamespace = KeyProperties.NAMESPACE_APPLICATION;
private int mKeySize = -1;
private AlgorithmParameterSpec mSpec;
private X500Principal mCertificateSubject;
@@ -830,7 +861,7 @@
*/
public Builder(@NonNull KeyGenParameterSpec sourceSpec) {
this(sourceSpec.getKeystoreAlias(), sourceSpec.getPurposes());
- mUid = sourceSpec.getUid();
+ mNamespace = sourceSpec.getNamespace();
mKeySize = sourceSpec.getKeySize();
mSpec = sourceSpec.getAlgorithmParameterSpec();
mCertificateSubject = sourceSpec.getCertificateSubject();
@@ -873,12 +904,51 @@
*
* @param uid UID or {@code -1} for the UID of the current process.
*
+ * @deprecated Setting the UID of the target namespace is based on a hardcoded
+ * hack in the Keystore service. This is no longer supported with Keystore 2.0/Android S.
+ * Instead, dedicated non UID based namespaces can be configured in SEPolicy using
+ * the keystore2_key_contexts files. The functionality of this method will be supported
+ * by mapping knows special UIDs, such as WIFI, to the newly configured SELinux based
+ * namespaces. Unknown UIDs will yield {@link IllegalArgumentException}.
+ *
* @hide
*/
@SystemApi
@NonNull
+ @Deprecated
public Builder setUid(int uid) {
- mUid = uid;
+ if (!AndroidKeyStoreProvider.isKeystore2Enabled()) {
+ // If Keystore2 has not been enabled we have to behave as if mNamespace is actually
+ // a UID, because we are still being used with the old Keystore SPI.
+ // TODO This if statement and body can be removed when the Keystore 2 migration is
+ // complete. b/171563717
+ mNamespace = uid;
+ return this;
+ }
+ mNamespace = KeyProperties.legacyUidToNamespace(uid);
+ return this;
+ }
+
+ /**
+ * Set the designated SELinux namespace that the key shall live in. The caller must
+ * have sufficient permissions to install a key in the given namespace. Namespaces
+ * can be created using SEPolicy. The keystore2_key_contexts files map numeric
+ * namespaces to SELinux labels, and SEPolicy can be used to grant access to these
+ * namespaces to the desired target context. This is the preferred way to share
+ * keys between system and vendor components, e.g., WIFI settings and WPA supplicant.
+ *
+ * @param namespace Numeric SELinux namespace as configured in keystore2_key_contexts
+ * of Android's SEPolicy.
+ * TODO b/171806779 link to public Keystore 2.0 documentation.
+ * See bug for more details for now.
+ * @return this Builder object.
+ *
+ * @hide
+ */
+ @SystemApi
+ @NonNull
+ public Builder setNamespace(int namespace) {
+ mNamespace = namespace;
return this;
}
@@ -1489,7 +1559,7 @@
public KeyGenParameterSpec build() {
return new KeyGenParameterSpec(
mKeystoreAlias,
- mUid,
+ mNamespace,
mKeySize,
mSpec,
mCertificateSubject,
diff --git a/keystore/java/android/security/keystore/KeyInfo.java b/keystore/java/android/security/keystore/KeyInfo.java
index d891a25..7158d0c 100644
--- a/keystore/java/android/security/keystore/KeyInfo.java
+++ b/keystore/java/android/security/keystore/KeyInfo.java
@@ -84,6 +84,7 @@
private final boolean mTrustedUserPresenceRequired;
private final boolean mInvalidatedByBiometricEnrollment;
private final boolean mUserConfirmationRequired;
+ private final @KeyProperties.SecurityLevelEnum int mSecurityLevel;
/**
* @hide
@@ -107,7 +108,8 @@
boolean userAuthenticationValidWhileOnBody,
boolean trustedUserPresenceRequired,
boolean invalidatedByBiometricEnrollment,
- boolean userConfirmationRequired) {
+ boolean userConfirmationRequired,
+ @KeyProperties.SecurityLevelEnum int securityLevel) {
mKeystoreAlias = keystoreKeyAlias;
mInsideSecureHardware = insideSecureHardware;
mOrigin = origin;
@@ -131,6 +133,7 @@
mTrustedUserPresenceRequired = trustedUserPresenceRequired;
mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
mUserConfirmationRequired = userConfirmationRequired;
+ mSecurityLevel = securityLevel;
}
/**
@@ -144,7 +147,10 @@
* Returns {@code true} if the key resides inside secure hardware (e.g., Trusted Execution
* Environment (TEE) or Secure Element (SE)). Key material of such keys is available in
* plaintext only inside the secure hardware and is not exposed outside of it.
+ *
+ * @deprecated This method is superseded by @see getSecurityLevel.
*/
+ @Deprecated
public boolean isInsideSecureHardware() {
return mInsideSecureHardware;
}
@@ -355,4 +361,17 @@
public boolean isTrustedUserPresenceRequired() {
return mTrustedUserPresenceRequired;
}
+
+ /**
+ * Returns the security level that the key is protected by.
+ * {@code KeyProperties.SecurityLevelEnum.TRUSTED_ENVIRONMENT} and
+ * {@code KeyProperties.SecurityLevelEnum.STRONGBOX} indicate that the key material resides
+ * in secure hardware. Key material of such keys is available in
+ * plaintext only inside the secure hardware and is not exposed outside of it.
+ *
+ * <p>See {@link KeyProperties}.{@code SecurityLevelEnum} constants.
+ */
+ public @KeyProperties.SecurityLevelEnum int getSecurityLevel() {
+ return mSecurityLevel;
+ }
}
diff --git a/keystore/java/android/security/keystore/KeyProperties.java b/keystore/java/android/security/keystore/KeyProperties.java
index 9050c69..5928540 100644
--- a/keystore/java/android/security/keystore/KeyProperties.java
+++ b/keystore/java/android/security/keystore/KeyProperties.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringDef;
+import android.security.KeyStore;
import android.security.keymaster.KeymasterDefs;
import libcore.util.EmptyArray;
@@ -857,4 +858,43 @@
}
}
+ /**
+ * This value indicates the implicit keystore namespace of the calling application.
+ * It is used by default. Only select system components can choose a different namespace
+ * which it must be configured in SEPolicy.
+ * @hide
+ */
+ public static final int NAMESPACE_APPLICATION = -1;
+
+ /**
+ * For legacy support, translate namespaces into known UIDs.
+ * @hide
+ */
+ public static int namespaceToLegacyUid(int namespace) {
+ switch (namespace) {
+ case NAMESPACE_APPLICATION:
+ return KeyStore.UID_SELF;
+ // TODO Translate WIFI and VPN UIDs once the namespaces are defined.
+ // b/171305388 and b/171305607
+ default:
+ throw new IllegalArgumentException("No UID corresponding to namespace "
+ + namespace);
+ }
+ }
+
+ /**
+ * For legacy support, translate namespaces into known UIDs.
+ * @hide
+ */
+ public static int legacyUidToNamespace(int uid) {
+ switch (uid) {
+ case KeyStore.UID_SELF:
+ return NAMESPACE_APPLICATION;
+ // TODO Translate WIFI and VPN UIDs once the namespaces are defined.
+ // b/171305388 and b/171305607
+ default:
+ throw new IllegalArgumentException("No namespace corresponding to uid "
+ + uid);
+ }
+ }
}
diff --git a/libs/WindowManager/Shell/OWNERS b/libs/WindowManager/Shell/OWNERS
index 4390004..36da7aa 100644
--- a/libs/WindowManager/Shell/OWNERS
+++ b/libs/WindowManager/Shell/OWNERS
@@ -1,4 +1,5 @@
# sysui owners
hwwang@google.com
mrenouf@google.com
-winsonc@google.com
\ No newline at end of file
+winsonc@google.com
+madym@google.com
diff --git a/libs/WindowManager/Shell/res/layout/bubble_menu_view.xml b/libs/WindowManager/Shell/res/layout/bubble_menu_view.xml
index 0c1d1a5..d19b653 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_menu_view.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_menu_view.xml
@@ -16,14 +16,16 @@
-->
<com.android.wm.shell.bubbles.BubbleMenuView
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="#66000000"
android:visibility="gone"
- android:id="@+id/bubble_menu_container">
+ android:id="@+id/bubble_menu_container"
+ tools:ignore="MissingClass">
<FrameLayout
- android:layout_height="@dimen/individual_bubble_size"
+ android:layout_height="@dimen/bubble_menu_item_height"
android:layout_width="wrap_content"
android:background="#FFFFFF"
android:id="@+id/bubble_menu_view">
diff --git a/libs/WindowManager/Shell/res/layout/bubble_overflow_button.xml b/libs/WindowManager/Shell/res/layout/bubble_overflow_button.xml
index 61000fe..e392cdc2 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_overflow_button.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_overflow_button.xml
@@ -17,6 +17,6 @@
<com.android.wm.shell.bubbles.BadgedImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/bubble_overflow_button"
- android:layout_width="@dimen/individual_bubble_size"
- android:layout_height="@dimen/individual_bubble_size"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:src="@drawable/bubble_ic_overflow_button"/>
diff --git a/libs/WindowManager/Shell/res/layout/bubble_view.xml b/libs/WindowManager/Shell/res/layout/bubble_view.xml
index a28bd678..2b4b9e9 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_view.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_view.xml
@@ -17,5 +17,5 @@
<com.android.wm.shell.bubbles.BadgedImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/bubble_view"
- android:layout_width="@dimen/individual_bubble_size"
- android:layout_height="@dimen/individual_bubble_size"/>
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 8a60aaf..25d034c 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -99,12 +99,12 @@
<dimen name="bubble_flyout_avatar_message_space">6dp</dimen>
<!-- Padding between status bar and bubbles when displayed in expanded state -->
<dimen name="bubble_padding_top">16dp</dimen>
+ <!-- Max amount of space between bubbles when expanded. -->
+ <dimen name="bubble_max_spacing">16dp</dimen>
<!-- Size of individual bubbles. -->
<dimen name="individual_bubble_size">60dp</dimen>
<!-- Size of bubble bitmap. -->
<dimen name="bubble_bitmap_size">52dp</dimen>
- <!-- Size of bubble icon bitmap. -->
- <dimen name="bubble_overflow_icon_bitmap_size">24dp</dimen>
<!-- Extra padding added to the touchable rect for bubbles so they are easier to grab. -->
<dimen name="bubble_touch_padding">12dp</dimen>
<!-- Size of the circle around the bubbles when they're in the dismiss target. -->
@@ -136,6 +136,8 @@
<dimen name="bubble_dismiss_slop">16dp</dimen>
<!-- Height of button allowing users to adjust settings for bubbles. -->
<dimen name="bubble_manage_button_height">48dp</dimen>
+ <!-- Height of an item in the bubble manage menu. -->
+ <dimen name="bubble_menu_item_height">60dp</dimen>
<!-- Max width of the message bubble-->
<dimen name="bubble_message_max_width">144dp</dimen>
<!-- Min width of the message bubble -->
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellDump.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellDump.java
index 4ba84223..bb9accd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellDump.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellDump.java
@@ -16,8 +16,7 @@
package com.android.wm.shell;
-import com.android.wm.shell.common.DisplayImeController;
-import com.android.wm.shell.draganddrop.DragAndDropController;
+import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.splitscreen.SplitScreen;
@@ -33,16 +32,19 @@
private final Optional<SplitScreen> mSplitScreenOptional;
private final Optional<Pip> mPipOptional;
private final Optional<OneHanded> mOneHandedOptional;
+ private final Optional<HideDisplayCutout> mHideDisplayCutout;
private final ShellTaskOrganizer mShellTaskOrganizer;
public ShellDump(ShellTaskOrganizer shellTaskOrganizer,
Optional<SplitScreen> splitScreenOptional,
Optional<Pip> pipOptional,
- Optional<OneHanded> oneHandedOptional) {
+ Optional<OneHanded> oneHandedOptional,
+ Optional<HideDisplayCutout> hideDisplayCutout) {
mShellTaskOrganizer = shellTaskOrganizer;
mSplitScreenOptional = splitScreenOptional;
mPipOptional = pipOptional;
mOneHandedOptional = oneHandedOptional;
+ mHideDisplayCutout = hideDisplayCutout;
}
public void dump(PrintWriter pw) {
@@ -52,5 +54,6 @@
mPipOptional.ifPresent(pip -> pip.dump(pw));
mSplitScreenOptional.ifPresent(splitScreen -> splitScreen.dump(pw));
mOneHandedOptional.ifPresent(oneHanded -> oneHanded.dump(pw));
+ mHideDisplayCutout.ifPresent(hideDisplayCutout -> hideDisplayCutout.dump(pw));
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index 2d20fee..ece063c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -27,6 +27,7 @@
import android.annotation.IntDef;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.WindowConfiguration.WindowingMode;
+import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
import android.util.ArrayMap;
@@ -44,6 +45,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.startingsurface.StartingSurfaceDrawer;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -104,21 +106,26 @@
private final Transitions mTransitions;
private final Object mLock = new Object();
+ private final StartingSurfaceDrawer mStartingSurfaceDrawer;
public ShellTaskOrganizer(SyncTransactionQueue syncQueue, TransactionPool transactionPool,
- ShellExecutor mainExecutor, ShellExecutor animExecutor) {
- this(null, syncQueue, transactionPool, mainExecutor, animExecutor);
+ ShellExecutor mainExecutor, ShellExecutor animExecutor, Context context) {
+ this(null, syncQueue, transactionPool, mainExecutor, animExecutor, context);
}
@VisibleForTesting
ShellTaskOrganizer(ITaskOrganizerController taskOrganizerController,
SyncTransactionQueue syncQueue, TransactionPool transactionPool,
- ShellExecutor mainExecutor, ShellExecutor animExecutor) {
+ ShellExecutor mainExecutor, ShellExecutor animExecutor, Context context) {
super(taskOrganizerController, mainExecutor);
addListenerForType(new FullscreenTaskListener(syncQueue), TASK_LISTENER_TYPE_FULLSCREEN);
addListenerForType(new LetterboxTaskListener(syncQueue), TASK_LISTENER_TYPE_LETTERBOX);
mTransitions = new Transitions(this, transactionPool, mainExecutor, animExecutor);
if (Transitions.ENABLE_SHELL_TRANSITIONS) registerTransitionPlayer(mTransitions);
+ // TODO(b/131727939) temporarily live here, the starting surface drawer should be controlled
+ // by a controller, that class should be create while porting
+ // ActivityRecord#addStartingWindow to WMShell.
+ mStartingSurfaceDrawer = new StartingSurfaceDrawer(context);
}
@Override
@@ -235,6 +242,16 @@
}
@Override
+ public void addStartingWindow(RunningTaskInfo taskInfo, IBinder appToken) {
+ mStartingSurfaceDrawer.addStartingWindow(taskInfo, appToken);
+ }
+
+ @Override
+ public void removeStartingWindow(RunningTaskInfo taskInfo) {
+ mStartingSurfaceDrawer.removeStartingWindow(taskInfo);
+ }
+
+ @Override
public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) {
synchronized (mLock) {
onTaskAppeared(new TaskAppearedInfo(taskInfo, leash));
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
index 4d06c03..32c6e36 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
@@ -31,7 +31,6 @@
import android.widget.ImageView;
import com.android.launcher3.icons.DotRenderer;
-import com.android.wm.shell.R;
import com.android.wm.shell.animation.Interpolators;
import java.util.EnumSet;
@@ -75,9 +74,8 @@
private boolean mDotIsAnimating = false;
private BubbleViewProvider mBubble;
+ private BubblePositioner mPositioner;
- private int mBubbleBitmapSize;
- private int mBubbleSize;
private DotRenderer mDotRenderer;
private DotRenderer.DrawParams mDrawParams;
private boolean mOnLeft;
@@ -101,18 +99,21 @@
public BadgedImageView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- mBubbleBitmapSize = getResources().getDimensionPixelSize(R.dimen.bubble_bitmap_size);
- mBubbleSize = getResources().getDimensionPixelSize(R.dimen.individual_bubble_size);
mDrawParams = new DotRenderer.DrawParams();
- Path iconPath = PathParser.createPathFromPathData(
- getResources().getString(com.android.internal.R.string.config_icon_mask));
- mDotRenderer = new DotRenderer(mBubbleBitmapSize, iconPath, DEFAULT_PATH_SIZE);
-
setFocusable(true);
setClickable(true);
}
+ public void initialize(BubblePositioner positioner) {
+ mPositioner = positioner;
+
+ Path iconPath = PathParser.createPathFromPathData(
+ getResources().getString(com.android.internal.R.string.config_icon_mask));
+ mDotRenderer = new DotRenderer(mPositioner.getBubbleBitmapSize(),
+ iconPath, DEFAULT_PATH_SIZE);
+ }
+
public void showDotAndBadge(boolean onLeft) {
removeDotSuppressionFlag(BadgedImageView.SuppressionFlag.BEHIND_STACK);
animateDotBadgePositions(onLeft);
@@ -186,7 +187,8 @@
* @param iconPath The new icon path to use when calculating dot position.
*/
void drawDot(Path iconPath) {
- mDotRenderer = new DotRenderer(mBubbleBitmapSize, iconPath, DEFAULT_PATH_SIZE);
+ mDotRenderer = new DotRenderer(mPositioner.getBubbleBitmapSize(),
+ iconPath, DEFAULT_PATH_SIZE);
invalidate();
}
@@ -310,13 +312,13 @@
bubbleCanvas.setDrawFilter(new PaintFlagsDrawFilter(DITHER_FLAG, FILTER_BITMAP_FLAG));
bubbleCanvas.setBitmap(bubble);
-
- final int badgeSize = (int) (ICON_BADGE_SCALE * mBubbleSize);
+ final int bubbleSize = bubble.getWidth();
+ final int badgeSize = (int) (ICON_BADGE_SCALE * bubbleSize);
if (mOnLeft) {
- badge.setBounds(0, mBubbleSize - badgeSize, badgeSize, mBubbleSize);
+ badge.setBounds(0, bubbleSize - badgeSize, badgeSize, bubbleSize);
} else {
- badge.setBounds(mBubbleSize - badgeSize, mBubbleSize - badgeSize,
- mBubbleSize, mBubbleSize);
+ badge.setBounds(bubbleSize - badgeSize, bubbleSize - badgeSize,
+ bubbleSize, bubbleSize);
}
badge.draw(bubbleCanvas);
bubbleCanvas.setBitmap(null);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
index 93ed395..122f917 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
@@ -310,7 +310,7 @@
*
* @param callback the callback to notify one the bubble is ready to be displayed.
* @param context the context for the bubble.
- * @param controller
+ * @param controller the bubble controller.
* @param stackView the stackView the bubble is eventually added to.
* @param iconFactory the iconfactory use to create badged images for the bubble.
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 05acb55..eb3a3a2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -95,12 +95,6 @@
private BubblePositioner mBubblePositioner;
private SysuiProxy mSysuiProxy;
- /**
- * The relative position of the stack when we removed it and nulled it out. If the stack is
- * re-created, it will re-appear at this position.
- */
- @Nullable private BubbleStackView.RelativeStackPosition mPositionFromRemovedStack;
-
// Tracks the id of the current (foreground) user.
private int mCurrentUserId;
// Saves notification keys of active bubbles when users are switched.
@@ -176,12 +170,12 @@
Handler mainHandler,
ShellTaskOrganizer organizer) {
BubbleLogger logger = new BubbleLogger(uiEventLogger);
- return new BubbleController(context,
- new BubbleData(context, logger), synchronizer,
- floatingContentCoordinator, new BubbleDataRepository(context, launcherApps),
- statusBarService, windowManager,
- windowManagerShellWrapper, launcherApps, logger, mainHandler, organizer,
- new BubblePositioner(context, windowManager));
+ BubblePositioner positioner = new BubblePositioner(context, windowManager);
+ BubbleData data = new BubbleData(context, logger, positioner);
+ return new BubbleController(context, data, synchronizer, floatingContentCoordinator,
+ new BubbleDataRepository(context, launcherApps),
+ statusBarService, windowManager, windowManagerShellWrapper, launcherApps,
+ logger, mainHandler, organizer, positioner);
}
/**
@@ -207,6 +201,7 @@
mLogger = bubbleLogger;
mMainHandler = mainHandler;
+ mBubblePositioner = positioner;
mBubbleData = data;
mBubbleData.setListener(mBubbleDataListener);
mBubbleData.setSuppressionChangedListener(bubble -> {
@@ -249,7 +244,6 @@
mBubbleIconFactory = new BubbleIconFactory(context);
mTaskOrganizer = organizer;
- mBubblePositioner = positioner;
launcherApps.registerCallback(new LauncherApps.Callback() {
@Override
@@ -388,8 +382,6 @@
if (mStackView == null) {
mStackView = new BubbleStackView(
mContext, this, mBubbleData, mSurfaceSynchronizer, mFloatingContentCoordinator);
- mStackView.setStackStartPosition(mPositionFromRemovedStack);
- mStackView.addView(mBubbleScrim);
mStackView.onOrientationChanged();
if (mExpandListener != null) {
mStackView.setExpandListener(mExpandListener);
@@ -429,7 +421,11 @@
try {
mAddedToWindowManager = true;
+ mBubbleData.getOverflow().initialize(this);
+ mStackView.addView(mBubbleScrim);
mWindowManager.addView(mStackView, mWmLayoutParams);
+ // Position info is dependent on us being attached to a window
+ mBubblePositioner.update(mOrientation);
} catch (IllegalStateException e) {
// This means the stack has already been added. This shouldn't happen...
e.printStackTrace();
@@ -449,10 +445,9 @@
try {
mAddedToWindowManager = false;
if (mStackView != null) {
- mPositionFromRemovedStack = mStackView.getRelativeStackPosition();
mWindowManager.removeView(mStackView);
mStackView.removeView(mBubbleScrim);
- mStackView = null;
+ mBubbleData.getOverflow().cleanUpExpandedState();
} else {
Log.w(TAG, "StackView added to WindowManager, but was null when removing!");
}
@@ -544,7 +539,7 @@
}
if (newConfig.fontScale != mFontScale) {
mFontScale = newConfig.fontScale;
- mStackView.updateFlyout(mFontScale);
+ mStackView.updateFontScale(mFontScale);
}
if (newConfig.getLayoutDirection() != mLayoutDirection) {
mLayoutDirection = newConfig.getLayoutDirection();
@@ -584,7 +579,7 @@
if (mStackView == null) {
return false;
}
- return mBubbleData.hasBubbles();
+ return mBubbleData.hasBubbles() || mBubbleData.isShowingOverflow();
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index b6a97e2..e24ff06 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -69,7 +69,7 @@
boolean selectionChanged;
boolean orderChanged;
boolean expanded;
- @Nullable Bubble selectedBubble;
+ @Nullable BubbleViewProvider selectedBubble;
@Nullable Bubble addedBubble;
@Nullable Bubble updatedBubble;
@Nullable Bubble addedOverflowBubble;
@@ -116,13 +116,15 @@
}
private final Context mContext;
+ private final BubblePositioner mPositioner;
/** Bubbles that are actively in the stack. */
private final List<Bubble> mBubbles;
/** Bubbles that aged out to overflow. */
private final List<Bubble> mOverflowBubbles;
/** Bubbles that are being loaded but haven't been added to the stack just yet. */
private final HashMap<String, Bubble> mPendingBubbles;
- private Bubble mSelectedBubble;
+ private BubbleViewProvider mSelectedBubble;
+ private final BubbleOverflow mOverflow;
private boolean mShowingOverflow;
private boolean mExpanded;
private final int mMaxBubbles;
@@ -153,9 +155,11 @@
*/
private HashMap<String, String> mSuppressedGroupKeys = new HashMap<>();
- public BubbleData(Context context, BubbleLogger bubbleLogger) {
+ public BubbleData(Context context, BubbleLogger bubbleLogger, BubblePositioner positioner) {
mContext = context;
mLogger = bubbleLogger;
+ mPositioner = positioner;
+ mOverflow = new BubbleOverflow(context, positioner);
mBubbles = new ArrayList<>();
mOverflowBubbles = new ArrayList<>();
mPendingBubbles = new HashMap<>();
@@ -178,6 +182,10 @@
return !mBubbles.isEmpty();
}
+ public boolean hasOverflowBubbles() {
+ return !mOverflowBubbles.isEmpty();
+ }
+
public boolean isExpanded() {
return mExpanded;
}
@@ -195,10 +203,14 @@
}
@Nullable
- public Bubble getSelectedBubble() {
+ public BubbleViewProvider getSelectedBubble() {
return mSelectedBubble;
}
+ public BubbleOverflow getOverflow() {
+ return mOverflow;
+ }
+
/** Return a read-only current active bubble lists. */
public List<Bubble> getActiveBubbles() {
return Collections.unmodifiableList(mBubbles);
@@ -212,7 +224,7 @@
dispatchPendingChanges();
}
- public void setSelectedBubble(Bubble bubble) {
+ public void setSelectedBubble(BubbleViewProvider bubble) {
if (DEBUG_BUBBLE_DATA) {
Log.d(TAG, "setSelectedBubble: " + bubble);
}
@@ -224,6 +236,10 @@
mShowingOverflow = showingOverflow;
}
+ boolean isShowingOverflow() {
+ return mShowingOverflow && (isExpanded() || mPositioner.showingInTaskbar());
+ }
+
/**
* Constructs a new bubble or returns an existing one. Does not add new bubbles to
* bubble data, must go through {@link #notificationEntryUpdated(Bubble, boolean, boolean)}
@@ -264,8 +280,8 @@
/**
* When this method is called it is expected that all info in the bubble has completed loading.
- * @see Bubble#inflate(BubbleViewInfoTask.Callback, Context,
- * BubbleStackView, BubbleIconFactory, boolean).
+ * @see Bubble#inflate(BubbleViewInfoTask.Callback, Context, BubbleController, BubbleStackView,
+ * BubbleIconFactory, boolean)
*/
void notificationEntryUpdated(Bubble bubble, boolean suppressFlyout, boolean showInShade) {
if (DEBUG_BUBBLE_DATA) {
@@ -484,10 +500,17 @@
Bubble bubbleToRemove = mBubbles.get(indexToRemove);
bubbleToRemove.stopInflation();
if (mBubbles.size() == 1) {
- // Going to become empty, handle specially.
- setExpandedInternal(false);
- // Don't use setSelectedBubbleInternal because we don't want to trigger an applyUpdate
- mSelectedBubble = null;
+ if (hasOverflowBubbles() && (mPositioner.showingInTaskbar() || isExpanded())) {
+ // No more active bubbles but we have stuff in the overflow -- select that view
+ // if we're already expanded or always showing.
+ setShowingOverflow(true);
+ setSelectedBubbleInternal(mOverflow);
+ } else {
+ setExpandedInternal(false);
+ // Don't use setSelectedBubbleInternal because we don't want to trigger an
+ // applyUpdate
+ mSelectedBubble = null;
+ }
}
if (indexToRemove < mBubbles.size() - 1) {
// Removing anything but the last bubble means positions will change.
@@ -505,7 +528,7 @@
if (Objects.equals(mSelectedBubble, bubbleToRemove)) {
// Move selection to the new bubble at the same position.
int newIndex = Math.min(indexToRemove, mBubbles.size() - 1);
- Bubble newSelected = mBubbles.get(newIndex);
+ BubbleViewProvider newSelected = mBubbles.get(newIndex);
setSelectedBubbleInternal(newSelected);
}
maybeSendDeleteIntent(reason, bubbleToRemove);
@@ -564,7 +587,7 @@
*
* @param bubble the new selected bubble
*/
- private void setSelectedBubbleInternal(@Nullable Bubble bubble) {
+ private void setSelectedBubbleInternal(@Nullable BubbleViewProvider bubble) {
if (DEBUG_BUBBLE_DATA) {
Log.d(TAG, "setSelectedBubbleInternal: " + bubble);
}
@@ -572,14 +595,17 @@
return;
}
// Otherwise, if we are showing the overflow menu, return to the previously selected bubble.
-
- if (bubble != null && !mBubbles.contains(bubble) && !mOverflowBubbles.contains(bubble)) {
+ boolean isOverflow = bubble != null && BubbleOverflow.KEY.equals(bubble.getKey());
+ if (bubble != null
+ && !mBubbles.contains(bubble)
+ && !mOverflowBubbles.contains(bubble)
+ && !isOverflow) {
Log.e(TAG, "Cannot select bubble which doesn't exist!"
+ " (" + bubble + ") bubbles=" + mBubbles);
return;
}
- if (mExpanded && bubble != null) {
- bubble.markAsAccessedAt(mTimeSource.currentTimeMillis());
+ if (mExpanded && bubble != null && !isOverflow) {
+ ((Bubble) bubble).markAsAccessedAt(mTimeSource.currentTimeMillis());
}
mSelectedBubble = bubble;
mStateChange.selectedBubble = bubble;
@@ -629,7 +655,7 @@
return;
}
if (shouldExpand) {
- if (mBubbles.isEmpty()) {
+ if (mBubbles.isEmpty() && !mShowingOverflow) {
Log.e(TAG, "Attempt to expand stack when empty!");
return;
}
@@ -637,7 +663,9 @@
Log.e(TAG, "Attempt to expand stack without selected bubble!");
return;
}
- mSelectedBubble.markAsAccessedAt(mTimeSource.currentTimeMillis());
+ if (mSelectedBubble instanceof Bubble) {
+ ((Bubble) mSelectedBubble).markAsAccessedAt(mTimeSource.currentTimeMillis());
+ }
mStateChange.orderChanged |= repackAll();
} else if (!mBubbles.isEmpty()) {
// Apply ordering and grouping rules from expanded -> collapsed, then save
@@ -647,14 +675,18 @@
if (mShowingOverflow) {
// Show previously selected bubble instead of overflow menu on next expansion.
- setSelectedBubbleInternal(mSelectedBubble);
+ if (!mSelectedBubble.getKey().equals(mOverflow.getKey())) {
+ setSelectedBubbleInternal(mSelectedBubble);
+ } else {
+ setSelectedBubbleInternal(mBubbles.get(0));
+ }
}
if (mBubbles.indexOf(mSelectedBubble) > 0) {
// Move the selected bubble to the top while collapsed.
int index = mBubbles.indexOf(mSelectedBubble);
if (index != 0) {
- mBubbles.remove(mSelectedBubble);
- mBubbles.add(0, mSelectedBubble);
+ mBubbles.remove((Bubble) mSelectedBubble);
+ mBubbles.add(0, (Bubble) mSelectedBubble);
mStateChange.orderChanged = true;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDebugConfig.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDebugConfig.java
index 53f4e87..dc2ace9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDebugConfig.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDebugConfig.java
@@ -45,6 +45,7 @@
static final boolean DEBUG_EXPERIMENTS = true;
static final boolean DEBUG_OVERFLOW = false;
static final boolean DEBUG_USER_EDUCATION = false;
+ static final boolean DEBUG_POSITIONER = false;
private static final boolean FORCE_SHOW_USER_EDUCATION = false;
private static final String FORCE_SHOW_USER_EDUCATION_SETTING =
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index 74521c7..646e75a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -639,7 +639,9 @@
}
/**
- * Cleans up anything related to the task and TaskView.
+ * Cleans up anything related to the task and TaskView. If this view should be reused after this
+ * method is called, then {@link #initialize(BubbleController, BubbleStackView)} must be invoked
+ * first.
*/
public void cleanUpExpandedState() {
if (DEBUG_BUBBLE_EXPANDED_VIEW) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
index 460e0e7..19c3cf9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
@@ -68,9 +68,8 @@
private final int mFlyoutPadding;
private final int mFlyoutSpaceFromBubble;
private final int mPointerSize;
- private final int mBubbleSize;
- private final int mBubbleBitmapSize;
- private final float mBubbleIconTopPadding;
+ private int mBubbleSize;
+ private int mBubbleBitmapSize;
private final int mFlyoutElevation;
private final int mBubbleElevation;
@@ -83,9 +82,9 @@
private final TextView mMessageText;
/** Values related to the 'new' dot which we use to figure out where to collapse the flyout. */
- private final float mNewDotRadius;
- private final float mNewDotSize;
- private final float mOriginalDotSize;
+ private float mNewDotRadius;
+ private float mNewDotSize;
+ private float mOriginalDotSize;
/**
* The paint used to draw the background, whose color changes as the flyout transitions to the
@@ -169,17 +168,9 @@
mFlyoutSpaceFromBubble = res.getDimensionPixelSize(R.dimen.bubble_flyout_space_from_bubble);
mPointerSize = res.getDimensionPixelSize(R.dimen.bubble_flyout_pointer_size);
- mBubbleSize = res.getDimensionPixelSize(R.dimen.individual_bubble_size);
- mBubbleBitmapSize = res.getDimensionPixelSize(R.dimen.bubble_bitmap_size);
- mBubbleIconTopPadding = (mBubbleSize - mBubbleBitmapSize) / 2f;
-
mBubbleElevation = res.getDimensionPixelSize(R.dimen.bubble_elevation);
mFlyoutElevation = res.getDimensionPixelSize(R.dimen.bubble_flyout_elevation);
- mOriginalDotSize = SIZE_PERCENTAGE * mBubbleBitmapSize;
- mNewDotRadius = (DOT_SCALE * mOriginalDotSize) / 2f;
- mNewDotSize = mNewDotRadius * 2f;
-
final TypedArray ta = mContext.obtainStyledAttributes(
new int[] {
android.R.attr.colorBackgroundFloating,
@@ -306,7 +297,15 @@
@Nullable Runnable onLayoutComplete,
@Nullable Runnable onHide,
float[] dotCenter,
- boolean hideDot) {
+ boolean hideDot,
+ BubblePositioner positioner) {
+
+ mBubbleBitmapSize = positioner.getBubbleBitmapSize();
+ mBubbleSize = positioner.getBubbleSize();
+
+ mOriginalDotSize = SIZE_PERCENTAGE * mBubbleBitmapSize;
+ mNewDotRadius = (DOT_SCALE * mOriginalDotSize) / 2f;
+ mNewDotSize = mNewDotRadius * 2f;
updateFlyoutMessage(flyoutMessage, parentWidth);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
index 686d2d4..8ab2f63 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
@@ -29,14 +29,18 @@
import android.util.PathParser
import android.util.TypedValue
import android.view.LayoutInflater
-import android.view.View
import android.widget.FrameLayout
import com.android.wm.shell.R
+/**
+ * The icon in the bubble overflow is scaled down, this is the percent of the normal bubble bitmap
+ * size to use.
+ */
+const val ICON_BITMAP_SIZE_PERCENT = 0.46f
+
class BubbleOverflow(
private val context: Context,
- private val controller: BubbleController,
- private val stack: BubbleStackView
+ private val positioner: BubblePositioner
) : BubbleViewProvider {
private lateinit var bitmap: Bitmap
@@ -48,41 +52,42 @@
private var showDot = false
private val inflater: LayoutInflater = LayoutInflater.from(context)
- private val expandedView: BubbleExpandedView = inflater
- .inflate(R.layout.bubble_expanded_view, null /* root */, false /* attachToRoot */)
- as BubbleExpandedView
- private val overflowBtn: BadgedImageView = inflater
- .inflate(R.layout.bubble_overflow_button, null /* root */, false /* attachToRoot */)
- as BadgedImageView
+ private var expandedView: BubbleExpandedView?
+ private var overflowBtn: BadgedImageView?
+
init {
updateResources()
- with(expandedView) {
- initialize(controller, stack)
- setOverflow(true)
- applyThemeAttrs()
- }
- with(overflowBtn) {
- setContentDescription(context.resources.getString(
- R.string.bubble_overflow_button_content_description))
- updateBtnTheme()
- }
+ bitmapSize = positioner.bubbleBitmapSize
+ iconBitmapSize = (bitmapSize * ICON_BITMAP_SIZE_PERCENT).toInt()
+ expandedView = null
+ overflowBtn = null
+ }
+
+ /** Call before use and again if cleanUpExpandedState was called. */
+ fun initialize(controller: BubbleController) {
+ getExpandedView()?.initialize(controller, controller.stackView)
+ getExpandedView()?.setOverflow(true)
+ }
+
+ fun cleanUpExpandedState() {
+ expandedView?.cleanUpExpandedState()
+ expandedView = null
}
fun update() {
updateResources()
- expandedView.applyThemeAttrs()
+ getExpandedView()?.applyThemeAttrs()
// Apply inset and new style to fresh icon drawable.
- overflowBtn.setImageResource(R.drawable.bubble_ic_overflow_button)
+ getIconView()?.setImageResource(R.drawable.bubble_ic_overflow_button)
updateBtnTheme()
}
fun updateResources() {
- bitmapSize = context.resources.getDimensionPixelSize(R.dimen.bubble_bitmap_size)
- iconBitmapSize = context.resources.getDimensionPixelSize(
- R.dimen.bubble_overflow_icon_bitmap_size)
- val bubbleSize = context.resources.getDimensionPixelSize(R.dimen.individual_bubble_size)
- overflowBtn.setLayoutParams(FrameLayout.LayoutParams(bubbleSize, bubbleSize))
- expandedView.updateDimensions()
+ bitmapSize = positioner.bubbleBitmapSize
+ iconBitmapSize = (bitmapSize * 0.46f).toInt()
+ val bubbleSize = positioner.bubbleSize
+ overflowBtn?.setLayoutParams(FrameLayout.LayoutParams(bubbleSize, bubbleSize))
+ expandedView?.updateDimensions()
}
private fun updateBtnTheme() {
@@ -92,7 +97,7 @@
val typedValue = TypedValue()
context.theme.resolveAttribute(android.R.attr.colorAccent, typedValue, true)
val colorAccent = res.getColor(typedValue.resourceId)
- overflowBtn.drawable?.setTint(colorAccent)
+ overflowBtn?.drawable?.setTint(colorAccent)
dotColor = colorAccent
val iconFactory = BubbleIconFactory(context)
@@ -103,7 +108,7 @@
val bg = ColorDrawable(res.getColor(
if (nightMode) R.color.bubbles_dark else R.color.bubbles_light))
- val fg = InsetDrawable(overflowBtn.drawable,
+ val fg = InsetDrawable(overflowBtn?.drawable,
bitmapSize - iconBitmapSize /* inset */)
bitmap = iconFactory.createBadgedIconBitmap(AdaptiveIconDrawable(bg, fg),
null /* user */, true /* shrinkNonAdaptiveIcons */).icon
@@ -111,7 +116,7 @@
// Update dot path
dotPath = PathParser.createPathFromPathData(
res.getString(com.android.internal.R.string.config_icon_mask))
- val scale = iconFactory.normalizer.getScale(overflowBtn.getDrawable(),
+ val scale = iconFactory.normalizer.getScale(getIconView()!!.getDrawable(),
null /* outBounds */, null /* path */, null /* outMaskShape */)
val radius = BadgedImageView.DEFAULT_PATH_SIZE / 2f
val matrix = Matrix()
@@ -120,20 +125,26 @@
dotPath.transform(matrix)
// Attach BubbleOverflow to BadgedImageView
- overflowBtn.setRenderedBubble(this)
- overflowBtn.removeDotSuppressionFlag(BadgedImageView.SuppressionFlag.FLYOUT_VISIBLE)
+ overflowBtn?.setRenderedBubble(this)
+ overflowBtn?.removeDotSuppressionFlag(BadgedImageView.SuppressionFlag.FLYOUT_VISIBLE)
}
fun setVisible(visible: Int) {
- overflowBtn.visibility = visible
+ overflowBtn?.visibility = visible
}
fun setShowDot(show: Boolean) {
showDot = show
- overflowBtn.updateDotVisibility(true /* animate */)
+ overflowBtn?.updateDotVisibility(true /* animate */)
}
override fun getExpandedView(): BubbleExpandedView? {
+ if (expandedView == null) {
+ expandedView = inflater.inflate(R.layout.bubble_expanded_view,
+ null /* root */, false /* attachToRoot */) as BubbleExpandedView
+ expandedView?.applyThemeAttrs()
+ updateResources()
+ }
return expandedView
}
@@ -158,10 +169,20 @@
}
override fun setContentVisibility(visible: Boolean) {
- expandedView.setContentVisibility(visible)
+ expandedView?.setContentVisibility(visible)
}
- override fun getIconView(): View? {
+ override fun getIconView(): BadgedImageView? {
+ if (overflowBtn == null) {
+ overflowBtn = inflater.inflate(R.layout.bubble_overflow_button,
+ null /* root */, false /* attachToRoot */) as BadgedImageView
+ overflowBtn?.initialize(positioner)
+ overflowBtn?.setContentDescription(context.resources.getString(
+ R.string.bubble_overflow_button_content_description))
+ val bubbleSize = positioner.bubbleSize
+ overflowBtn?.setLayoutParams(FrameLayout.LayoutParams(bubbleSize, bubbleSize))
+ updateBtnTheme()
+ }
return overflowBtn
}
@@ -170,7 +191,7 @@
}
override fun getTaskId(): Int {
- return if (expandedView != null) expandedView.getTaskId() else INVALID_TASK_ID
+ return if (expandedView != null) expandedView!!.getTaskId() else INVALID_TASK_ID
}
companion object {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowActivity.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowActivity.java
index 2759b59..cfd0066 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowActivity.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowActivity.java
@@ -111,11 +111,11 @@
IBinder binder = intent.getExtras().getBinder(EXTRA_BUBBLE_CONTROLLER);
if (binder instanceof ObjectWrapper) {
mController = ((ObjectWrapper<BubbleController>) binder).get();
+ updateOverflow();
}
} else {
Log.w(TAG, "Bubble overflow activity created without bubble controller!");
}
- updateOverflow();
}
void updateOverflow() {
@@ -138,7 +138,9 @@
final int viewHeight = recyclerViewHeight / rows;
mAdapter = new BubbleOverflowAdapter(getApplicationContext(), mOverflowBubbles,
- mController::promoteBubbleFromOverflow, viewWidth, viewHeight);
+ mController::promoteBubbleFromOverflow,
+ mController.getPositioner(),
+ viewWidth, viewHeight);
mRecyclerView.setAdapter(mAdapter);
mOverflowBubbles.clear();
@@ -257,15 +259,20 @@
private Context mContext;
private Consumer<Bubble> mPromoteBubbleFromOverflow;
+ private BubblePositioner mPositioner;
private List<Bubble> mBubbles;
private int mWidth;
private int mHeight;
- public BubbleOverflowAdapter(Context context, List<Bubble> list, Consumer<Bubble> promoteBubble,
+ BubbleOverflowAdapter(Context context,
+ List<Bubble> list,
+ Consumer<Bubble> promoteBubble,
+ BubblePositioner positioner,
int width, int height) {
mContext = context;
mBubbles = list;
mPromoteBubbleFromOverflow = promoteBubble;
+ mPositioner = positioner;
mWidth = width;
mHeight = height;
}
@@ -295,7 +302,7 @@
TextView viewName = overflowView.findViewById(R.id.bubble_view_name);
viewName.setTextColor(textColor);
- return new ViewHolder(overflowView);
+ return new ViewHolder(overflowView, mPositioner);
}
@Override
@@ -348,9 +355,10 @@
public BadgedImageView iconView;
public TextView textView;
- public ViewHolder(LinearLayout v) {
+ ViewHolder(LinearLayout v, BubblePositioner positioner) {
super(v);
iconView = v.findViewById(R.id.bubble_view);
+ iconView.initialize(positioner);
textView = v.findViewById(R.id.bubble_view_name);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index eccd009..46e8e11 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -16,45 +16,99 @@
package com.android.wm.shell.bubbles;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
import android.content.Context;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.Insets;
+import android.graphics.PointF;
import android.graphics.Rect;
+import android.graphics.RectF;
+import android.util.Log;
+import android.view.View;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowMetrics;
import androidx.annotation.VisibleForTesting;
+import com.android.wm.shell.R;
+
+import java.lang.annotation.Retention;
+
/**
* Keeps track of display size, configuration, and specific bubble sizes. One place for all
* placement and positioning calculations to refer to.
*/
public class BubblePositioner {
+ private static final String TAG = BubbleDebugConfig.TAG_WITH_CLASS_NAME
+ ? "BubblePositioner"
+ : BubbleDebugConfig.TAG_BUBBLES;
+ @Retention(SOURCE)
+ @IntDef({TASKBAR_POSITION_RIGHT, TASKBAR_POSITION_LEFT, TASKBAR_POSITION_BOTTOM})
+ @interface TaskbarPosition {}
+ public static final int TASKBAR_POSITION_RIGHT = 0;
+ public static final int TASKBAR_POSITION_LEFT = 1;
+ public static final int TASKBAR_POSITION_BOTTOM = 2;
+
+ /**
+ * The bitmap in the bubble is slightly smaller than the overall size of the bubble.
+ * This is the percentage to scale the image down based on the overall bubble size.
+ */
+ private static final float BUBBLE_BITMAP_SIZE_PERCENT = 0.86f;
+
+ private Context mContext;
private WindowManager mWindowManager;
private Rect mPositionRect;
private int mOrientation;
private Insets mInsets;
+ private int mBubbleSize;
+ private int mBubbleBitmapSize;
+
+ private PointF mPinLocation;
+ private PointF mRestingStackPosition;
+
+ private boolean mShowingInTaskbar;
+ private @TaskbarPosition int mTaskbarPosition;
+ private int mTaskbarIconSize;
+
public BubblePositioner(Context context, WindowManager windowManager) {
+ mContext = context;
mWindowManager = windowManager;
update(Configuration.ORIENTATION_UNDEFINED);
}
+ /**
+ * Updates orientation, available space, and inset information. Call this when config changes
+ * occur or when added to a window.
+ */
public void update(int orientation) {
WindowMetrics windowMetrics = mWindowManager.getCurrentWindowMetrics();
- mPositionRect = new Rect(windowMetrics.getBounds());
+ if (windowMetrics == null) {
+ return;
+ }
WindowInsets metricInsets = windowMetrics.getWindowInsets();
Insets insets = metricInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()
| WindowInsets.Type.statusBars()
| WindowInsets.Type.displayCutout());
- update(orientation, insets, windowMetrics.getBounds());
+
+ if (BubbleDebugConfig.DEBUG_POSITIONER) {
+ Log.w(TAG, "update positioner:"
+ + " landscape= " + (orientation == Configuration.ORIENTATION_LANDSCAPE)
+ + " insets: " + insets
+ + " bounds: " + windowMetrics.getBounds()
+ + " showingInTaskbar: " + mShowingInTaskbar);
+ }
+ updateInternal(orientation, insets, windowMetrics.getBounds());
}
@VisibleForTesting
- public void update(int orientation, Insets insets, Rect bounds) {
+ public void updateInternal(int orientation, Insets insets, Rect bounds) {
mOrientation = orientation;
mInsets = insets;
@@ -63,27 +117,156 @@
mPositionRect.top += mInsets.top;
mPositionRect.right -= mInsets.right;
mPositionRect.bottom -= mInsets.bottom;
+
+ Resources res = mContext.getResources();
+ mBubbleSize = res.getDimensionPixelSize(R.dimen.individual_bubble_size);
+ mBubbleBitmapSize = res.getDimensionPixelSize(R.dimen.bubble_bitmap_size);
+ adjustForTaskbar();
}
/**
- * @return a rect of available screen space for displaying bubbles in the correct orientation,
- * accounting for system bars and cutouts.
+ * Updates position information to account for taskbar state.
+ *
+ * @param taskbarPosition which position the taskbar is displayed in.
+ * @param showingInTaskbar whether the taskbar is being shown.
+ */
+ public void updateForTaskbar(int iconSize,
+ @TaskbarPosition int taskbarPosition, boolean showingInTaskbar) {
+ mShowingInTaskbar = showingInTaskbar;
+ mTaskbarIconSize = iconSize;
+ mTaskbarPosition = taskbarPosition;
+ update(mOrientation);
+ }
+
+ /**
+ * Taskbar insets appear as navigationBar insets, however, unlike navigationBar this should
+ * not inset bubbles UI as bubbles floats above the taskbar. This adjust the available space
+ * and insets to account for the taskbar.
+ */
+ // TODO(b/171559950): When the insets are reported correctly we can remove this logic
+ private void adjustForTaskbar() {
+ // When bar is showing on edges... subtract that inset because we appear on top
+ if (mShowingInTaskbar && mTaskbarPosition != TASKBAR_POSITION_BOTTOM) {
+ WindowInsets metricInsets = mWindowManager.getCurrentWindowMetrics().getWindowInsets();
+ Insets navBarInsets = metricInsets.getInsetsIgnoringVisibility(
+ WindowInsets.Type.navigationBars());
+ int newInsetLeft = mInsets.left;
+ int newInsetRight = mInsets.right;
+ if (mTaskbarPosition == TASKBAR_POSITION_LEFT) {
+ mPositionRect.left -= navBarInsets.left;
+ newInsetLeft -= navBarInsets.left;
+ } else if (mTaskbarPosition == TASKBAR_POSITION_RIGHT) {
+ mPositionRect.right += navBarInsets.right;
+ newInsetRight -= navBarInsets.right;
+ }
+ mInsets = Insets.of(newInsetLeft, mInsets.top, newInsetRight, mInsets.bottom);
+ }
+ }
+
+ /**
+ * @return a rect of available screen space accounting for orientation, system bars and cutouts.
+ * Does not account for IME.
*/
public Rect getAvailableRect() {
return mPositionRect;
}
/**
- * @return the current orientation.
- */
- public int getOrientation() {
- return mOrientation;
- }
-
- /**
- * @return the relevant insets (status bar, nav bar, cutouts).
+ * @return the relevant insets (status bar, nav bar, cutouts). If taskbar is showing, its
+ * inset is not included here.
*/
public Insets getInsets() {
return mInsets;
}
+
+ /**
+ * @return whether the device is in landscape orientation.
+ */
+ public boolean isLandscape() {
+ return mOrientation == Configuration.ORIENTATION_LANDSCAPE;
+ }
+
+ /**
+ * Indicates how bubbles appear when expanded.
+ *
+ * When false, bubbles display at the top of the screen with the expanded view
+ * below them. When true, bubbles display at the edges of the screen with the expanded view
+ * to the left or right side.
+ */
+ public boolean showBubblesVertically() {
+ return mOrientation == Configuration.ORIENTATION_LANDSCAPE
+ || mShowingInTaskbar;
+ }
+
+ /** Size of the bubble account for badge & dot. */
+ public int getBubbleSize() {
+ int bsize = (mShowingInTaskbar && mTaskbarIconSize > 0)
+ ? mTaskbarIconSize
+ : mBubbleSize;
+ return bsize;
+ }
+
+ /** Size of the bitmap within the bubble */
+ public int getBubbleBitmapSize() {
+ float size = (mShowingInTaskbar && mTaskbarIconSize > 0)
+ ? (mTaskbarIconSize * BUBBLE_BITMAP_SIZE_PERCENT)
+ : mBubbleBitmapSize;
+ return (int) size;
+ }
+
+ /**
+ * Sets the stack's most recent position along the edge of the screen. This is saved when the
+ * last bubble is removed, so that the stack can be restored in its previous position.
+ */
+ public void setRestingPosition(PointF position) {
+ if (mRestingStackPosition == null) {
+ mRestingStackPosition = new PointF(position);
+ } else {
+ mRestingStackPosition.set(position);
+ }
+ }
+
+ /** The position the bubble stack should rest at when collapsed. */
+ public PointF getRestingPosition() {
+ if (mPinLocation != null) {
+ return mPinLocation;
+ }
+ if (mRestingStackPosition == null) {
+ return getDefaultStartPosition();
+ }
+ return mRestingStackPosition;
+ }
+
+ /**
+ * @return the stack position to use if we don't have a saved location or if user education
+ * is being shown.
+ */
+ public PointF getDefaultStartPosition() {
+ // Start on the left if we're in LTR, right otherwise.
+ final boolean startOnLeft =
+ mContext.getResources().getConfiguration().getLayoutDirection()
+ != View.LAYOUT_DIRECTION_RTL;
+ final float startingVerticalOffset = mContext.getResources().getDimensionPixelOffset(
+ R.dimen.bubble_stack_starting_offset_y);
+ // TODO: placement bug here because mPositionRect doesn't handle the overhanging edge
+ return new BubbleStackView.RelativeStackPosition(
+ startOnLeft,
+ startingVerticalOffset / mPositionRect.height())
+ .getAbsolutePositionInRegion(new RectF(mPositionRect));
+ }
+
+ /**
+ * @return whether the bubble stack is pinned to the taskbar.
+ */
+ public boolean showingInTaskbar() {
+ return mShowingInTaskbar;
+ }
+
+ /**
+ * In some situations bubbles will be pinned to a specific onscreen location. This sets the
+ * location to anchor the stack to.
+ */
+ public void setPinnedLocation(PointF point) {
+ mPinLocation = point;
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 155f342..cbe9845 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -30,7 +30,6 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
-import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.ColorMatrix;
@@ -228,7 +227,7 @@
* once it collapses.
*/
@Nullable
- private Bubble mBubbleToExpandAfterFlyoutCollapse = null;
+ private BubbleViewProvider mBubbleToExpandAfterFlyoutCollapse = null;
/** Layout change listener that moves the stack to the nearest valid position on rotation. */
private OnLayoutChangeListener mOrientationChangedListener;
@@ -572,6 +571,16 @@
mBubbleContainer.setActiveController(mStackAnimationController);
hideFlyoutImmediate();
+ if (!mPositioner.showingInTaskbar()) {
+ // Also, save the magnetized stack so we can dispatch touch events to it.
+ mMagnetizedObject = mStackAnimationController.getMagnetizedStack(
+ mMagneticTarget);
+ mMagnetizedObject.setMagnetListener(mStackMagnetListener);
+ } else {
+ // In taskbar, the stack isn't draggable so we shouldn't dispatch touch events.
+ mMagnetizedObject = null;
+ }
+
// Also, save the magnetized stack so we can dispatch touch events to it.
mMagnetizedObject = mStackAnimationController.getMagnetizedStack(mMagneticTarget);
mMagnetizedObject.setMagnetListener(mStackMagnetListener);
@@ -593,7 +602,9 @@
public void onMove(@NonNull View v, @NonNull MotionEvent ev, float viewInitialX,
float viewInitialY, float dx, float dy) {
// If we're expanding or collapsing, ignore all touch events.
- if (mIsExpansionAnimating) {
+ if (mIsExpansionAnimating
+ // Also ignore events if we shouldn't be draggable.
+ || (mPositioner.showingInTaskbar() && !mIsExpanded)) {
return;
}
@@ -603,7 +614,7 @@
// First, see if the magnetized object consumes the event - if so, we shouldn't move the
// bubble since it's stuck to the target.
if (!passEventToMagnetizedObject(ev)) {
- if (mBubbleData.isExpanded()) {
+ if (mBubbleData.isExpanded() || mPositioner.showingInTaskbar()) {
mExpandedAnimationController.dragBubbleOut(
v, viewInitialX + dx, viewInitialY + dy);
} else {
@@ -701,7 +712,6 @@
}
};
- @Nullable
private BubbleOverflow mBubbleOverflow;
private StackEducationView mStackEduView;
private ManageEducationView mManageEduView;
@@ -745,7 +755,7 @@
ta.recycle();
final Runnable onBubbleAnimatedOut = () -> {
- if (getBubbleCount() == 0) {
+ if (getBubbleCount() == 0 && !mBubbleData.isShowingOverflow()) {
mBubbleController.onAllBubblesAnimatedOut();
}
};
@@ -818,15 +828,16 @@
setFocusable(true);
mBubbleContainer.bringToFront();
- mBubbleOverflow = new BubbleOverflow(getContext(), bubbleController, this);
+ mBubbleOverflow = mBubbleData.getOverflow();
mBubbleContainer.addView(mBubbleOverflow.getIconView(),
mBubbleContainer.getChildCount() /* index */,
- new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT));
+ new FrameLayout.LayoutParams(mPositioner.getBubbleSize(),
+ mPositioner.getBubbleSize()));
updateOverflow();
mBubbleOverflow.getIconView().setOnClickListener((View v) -> {
- setSelectedBubble(mBubbleOverflow);
- showManageMenu(false);
+ mBubbleData.setShowingOverflow(true);
+ mBubbleData.setSelectedBubble(mBubbleOverflow);
+ mBubbleData.setExpanded(true);
});
setOnApplyWindowInsetsListener((View view, WindowInsets insets) -> {
@@ -997,11 +1008,12 @@
mManageMenu.findViewById(R.id.bubble_manage_menu_settings_container).setOnClickListener(
view -> {
showManageMenu(false /* show */);
- final Bubble bubble = mBubbleData.getSelectedBubble();
+ final BubbleViewProvider bubble = mBubbleData.getSelectedBubble();
if (bubble != null && mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) {
- final Intent intent = bubble.getSettingsIntent(mContext);
+ // If it's in the stack it's a proper Bubble.
+ final Intent intent = ((Bubble) bubble).getSettingsIntent(mContext);
mBubbleData.setExpanded(false);
- mContext.startActivityAsUser(intent, bubble.getUser());
+ mContext.startActivityAsUser(intent, ((Bubble) bubble).getUser());
logBubbleEvent(bubble,
FrameworkStatsLog.BUBBLE_UICHANGED__ACTION__HEADER_GO_TO_SETTINGS);
}
@@ -1067,7 +1079,7 @@
mStackEduView = new StackEducationView(mContext);
addView(mStackEduView);
}
- return mStackEduView.show(mStackAnimationController.getStartPosition());
+ return mStackEduView.show(mPositioner.getDefaultStartPosition());
}
private void updateUserEdu() {
@@ -1093,7 +1105,7 @@
addView(mFlyout, new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
}
- void updateFlyout(float fontScale) {
+ void updateFontScale(float fontScale) {
mFlyout.updateFontSize(fontScale);
}
@@ -1130,7 +1142,9 @@
Resources res = getContext().getResources();
mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
- mRelativeStackPositionBeforeRotation = mStackAnimationController.getRelativeStackPosition();
+ mRelativeStackPositionBeforeRotation = new RelativeStackPosition(
+ mPositioner.getRestingPosition(),
+ mStackAnimationController.getAllowableStackPositionRegion());
mManageMenu.setVisibility(View.INVISIBLE);
mShowingManage = false;
@@ -1157,7 +1171,7 @@
Resources res = getContext().getResources();
mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
- mBubbleSize = getResources().getDimensionPixelSize(R.dimen.individual_bubble_size);
+ mBubbleSize = mPositioner.getBubbleSize();
for (Bubble b : mBubbleData.getBubbles()) {
if (b.getIconView() == null) {
Log.d(TAG, "Display size changed. Icon null: " + b);
@@ -1165,6 +1179,7 @@
}
b.getIconView().setLayoutParams(new LayoutParams(mBubbleSize, mBubbleSize));
}
+ mBubbleOverflow.getIconView().setLayoutParams(new LayoutParams(mBubbleSize, mBubbleSize));
mExpandedAnimationController.updateResources();
mStackAnimationController.updateResources();
mDismissView.updateResources();
@@ -1199,8 +1214,8 @@
super.onDetachedFromWindow();
getViewTreeObserver().removeOnPreDrawListener(mViewUpdater);
getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
- if (mBubbleOverflow != null && mBubbleOverflow.getExpandedView() != null) {
- mBubbleOverflow.getExpandedView().cleanUpExpandedState();
+ if (mBubbleOverflow != null) {
+ mBubbleOverflow.cleanUpExpandedState();
}
}
@@ -1390,8 +1405,7 @@
if (getBubbleCount() == 0 && shouldShowStackEdu()) {
// Override the default stack position if we're showing user education.
- mStackAnimationController.setStackPosition(
- mStackAnimationController.getStartPosition());
+ mStackAnimationController.setStackPosition(mPositioner.getDefaultStartPosition());
}
if (getBubbleCount() == 0) {
@@ -1410,7 +1424,8 @@
bubble.getIconView().setOnTouchListener(mBubbleTouchListener);
mBubbleContainer.addView(bubble.getIconView(), 0,
- new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
+ new FrameLayout.LayoutParams(mPositioner.getBubbleSize(),
+ mPositioner.getBubbleSize()));
animateInFlyoutForBubble(bubble);
requestUpdate();
logBubbleEvent(bubble, FrameworkStatsLog.BUBBLE_UICHANGED__ACTION__POSTED);
@@ -1441,10 +1456,9 @@
}
private void updateOverflowVisibility() {
- if (mBubbleOverflow == null) {
- return;
- }
- mBubbleOverflow.setVisible(mIsExpanded ? VISIBLE : GONE);
+ mBubbleOverflow.setVisible((mIsExpanded || mBubbleData.isShowingOverflow())
+ ? VISIBLE
+ : GONE);
}
// via BubbleData.Listener
@@ -1614,6 +1628,11 @@
mBubbleController.hideCurrentInputMethod();
}
+ /** Set the stack position to whatever the positioner says. */
+ void updateStackPosition() {
+ mStackAnimationController.setStackPosition(mPositioner.getRestingPosition());
+ }
+
private void beforeExpandedViewAnimation() {
mIsExpansionAnimating = true;
hideFlyoutImmediate();
@@ -1629,8 +1648,7 @@
private void animateExpansion() {
cancelDelayedExpandCollapseSwitchAnimations();
- final boolean isLandscape =
- mPositioner.getOrientation() == Configuration.ORIENTATION_LANDSCAPE;
+ final boolean showVertically = mPositioner.showBubblesVertically();
mIsExpanded = true;
if (mStackEduView != null) {
mStackEduView.hide(true /* fromExpansion */);
@@ -1650,14 +1668,19 @@
mExpandedViewContainer.setTranslationY(getExpandedViewY());
mExpandedViewContainer.setAlpha(1f);
- // X-value of the bubble we're expanding, once it's settled in its row.
+ int index;
+ if (mExpandedBubble != null && BubbleOverflow.KEY.equals(mExpandedBubble.getKey())) {
+ index = mBubbleData.getBubbles().size();
+ } else {
+ index = getBubbleIndex(mExpandedBubble);
+ }
+ // Position of the bubble we're expanding, once it's settled in its row.
final float bubbleWillBeAt =
- mExpandedAnimationController.getBubbleXOrYForOrientation(
- mBubbleData.getBubbles().indexOf(mExpandedBubble));
+ mExpandedAnimationController.getBubbleXOrYForOrientation(index);
// How far horizontally the bubble will be animating. We'll wait a bit longer for bubbles
// that are animating farther, so that the expanded view doesn't move as much.
- final float relevantStackPosition = isLandscape
+ final float relevantStackPosition = showVertically
? mStackAnimationController.getStackPosition().y
: mStackAnimationController.getStackPosition().x;
final float distanceAnimated = Math.abs(bubbleWillBeAt - relevantStackPosition);
@@ -1674,7 +1697,7 @@
}
// Set the pivot point for the scale, so the expanded view animates out from the bubble.
- if (isLandscape) {
+ if (showVertically) {
float pivotX;
float pivotY = bubbleWillBeAt + mBubbleSize / 2f;
if (mStackOnLeftOrWillBe) {
@@ -1709,7 +1732,7 @@
if (mExpandedBubble == null || mExpandedBubble.getIconView() == null) {
return;
}
- float translation = isLandscape
+ float translation = showVertically
? mExpandedBubble.getIconView().getTranslationY()
: mExpandedBubble.getIconView().getTranslationX();
mExpandedViewContainerMatrix.postTranslate(
@@ -1761,13 +1784,17 @@
// We want to visually collapse into this bubble during the animation.
final View expandingFromBubble = mExpandedBubble.getIconView();
+ int index;
+ if (mExpandedBubble != null && BubbleOverflow.KEY.equals(mExpandedBubble.getKey())) {
+ index = mBubbleData.getBubbles().size();
+ } else {
+ index = mBubbleData.getBubbles().indexOf(mExpandedBubble);
+ }
// Value the bubble is animating from (back into the stack).
final float expandingFromBubbleAt =
- mExpandedAnimationController.getBubbleXOrYForOrientation(
- mBubbleData.getBubbles().indexOf(mExpandedBubble));
- final boolean isLandscape =
- mPositioner.getOrientation() == Configuration.ORIENTATION_LANDSCAPE;
- if (isLandscape) {
+ mExpandedAnimationController.getBubbleXOrYForOrientation(index);
+ final boolean showVertically = mPositioner.showBubblesVertically();
+ if (mPositioner.showBubblesVertically()) {
float pivotX;
float pivotY = expandingFromBubbleAt + mBubbleSize / 2f;
if (mStackOnLeftOrWillBe) {
@@ -1792,7 +1819,7 @@
.addUpdateListener((target, values) -> {
if (expandingFromBubble != null) {
// Follow the bubble as it translates!
- if (isLandscape) {
+ if (showVertically) {
mExpandedViewContainerMatrix.postTranslate(
0f, expandingFromBubble.getTranslationY()
- expandingFromBubbleAt);
@@ -1849,7 +1876,7 @@
.spring(DynamicAnimation.SCALE_Y, 0f, mScaleOutSpringConfig)
.withEndActions(this::releaseAnimatingOutBubbleBuffer);
- if (mPositioner.getOrientation() == Configuration.ORIENTATION_LANDSCAPE) {
+ if (mPositioner.showBubblesVertically()) {
float translationX = mStackAnimationController.isStackOnLeftSide()
? mAnimatingOutSurfaceContainer.getTranslationX() + mBubbleSize * 2
: mAnimatingOutSurfaceContainer.getTranslationX();
@@ -1874,7 +1901,7 @@
mExpandedViewContainer.setAlpha(1f);
mExpandedViewContainer.setVisibility(View.VISIBLE);
- if (mPositioner.getOrientation() == Configuration.ORIENTATION_LANDSCAPE) {
+ if (mPositioner.showBubblesVertically()) {
float pivotX;
float pivotY = expandingFromBubbleDestination + mBubbleSize / 2f;
if (mStackOnLeftOrWillBe) {
@@ -2113,7 +2140,7 @@
}
}
- private void dismissBubbleIfExists(@Nullable Bubble bubble) {
+ private void dismissBubbleIfExists(@Nullable BubbleViewProvider bubble) {
if (bubble != null && mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) {
mBubbleData.dismissBubbleWithKey(bubble.getKey(), Bubbles.DISMISS_USER_GESTURE);
}
@@ -2180,7 +2207,7 @@
*/
float getExpandedViewY() {
final int top = mPositioner.getAvailableRect().top;
- if (mPositioner.getOrientation() == Configuration.ORIENTATION_LANDSCAPE) {
+ if (mPositioner.showBubblesVertically()) {
return top + mExpandedViewPadding;
} else {
return top + mBubbleSize + mBubblePaddingTop;
@@ -2278,7 +2305,8 @@
expandFlyoutAfterDelay /* onLayoutComplete */,
mAfterFlyoutHidden,
bubble.getIconView().getDotCenter(),
- !bubble.showDot());
+ !bubble.showDot(),
+ mPositioner);
}
mFlyout.bringToFront();
});
@@ -2321,7 +2349,7 @@
}
if (!mIsExpanded) {
- if (getBubbleCount() > 0) {
+ if (getBubbleCount() > 0 || mBubbleData.isShowingOverflow()) {
mBubbleContainer.getChildAt(0).getBoundsOnScreen(outRect);
// Increase the touch target size of the bubble
outRect.top -= mBubbleTouchPadding;
@@ -2550,7 +2578,7 @@
Insets insets = mPositioner.getInsets();
int leftPadding = insets.left + mExpandedViewPadding;
int rightPadding = insets.right + mExpandedViewPadding;
- if (mPositioner.getOrientation() == Configuration.ORIENTATION_LANDSCAPE) {
+ if (mPositioner.showBubblesVertically()) {
if (!mStackAnimationController.isStackOnLeftSide()) {
rightPadding += mPointerHeight + mBubbleSize;
} else {
@@ -2581,7 +2609,9 @@
bv.setZ((mMaxBubbles * mBubbleElevation) - i);
if (mIsExpanded) {
- bv.showDotAndBadge(false /* onLeft */);
+ // If we're not displaying vertically, we always show the badge on the left.
+ boolean onLeft = mPositioner.showBubblesVertically() && !mStackOnLeftOrWillBe;
+ bv.showDotAndBadge(onLeft);
} else if (i == 0) {
bv.showDotAndBadge(!mStackOnLeftOrWillBe);
} else {
@@ -2599,7 +2629,7 @@
return;
}
float bubblePosition = mExpandedAnimationController.getBubbleXOrYForOrientation(index);
- if (mPositioner.getOrientation() == Configuration.ORIENTATION_LANDSCAPE) {
+ if (mPositioner.showBubblesVertically()) {
float x = mStackOnLeftOrWillBe
? mPositioner.getAvailableRect().left
: mPositioner.getAvailableRect().right
@@ -2661,21 +2691,11 @@
.floatValue();
}
- /** Set the start position of the bubble stack. */
- public void setStackStartPosition(RelativeStackPosition position) {
- mStackAnimationController.setStackStartPosition(position);
- }
-
/** @return the position of the bubble stack. */
public PointF getStackPosition() {
return mStackAnimationController.getStackPosition();
}
- /** @return the relative position of the bubble stack. */
- public RelativeStackPosition getRelativeStackPosition() {
- return mStackAnimationController.getRelativeStackPosition();
- }
-
/**
* Logs the bubble UI event.
*
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 0b68306..e21ba63 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
@@ -134,6 +134,7 @@
LayoutInflater inflater = LayoutInflater.from(c);
info.imageView = (BadgedImageView) inflater.inflate(
R.layout.bubble_view, stackView, false /* attachToRoot */);
+ info.imageView.initialize(controller.getPositioner());
info.expandedView = (BubbleExpandedView) inflater.inflate(
R.layout.bubble_expanded_view, stackView, false /* attachToRoot */);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
index 61fbf81..18aaa96 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
@@ -84,7 +84,11 @@
private float mBubbleSizePx;
/** Max number of bubbles shown in row above expanded view. */
private int mBubblesMaxRendered;
-
+ /** Max amount of space to have between bubbles when expanded. */
+ private int mBubblesMaxSpace;
+ /** Amount of space between the bubbles when expanded. */
+ private float mSpaceBetweenBubbles;
+ /** Whether the expand / collapse animation is running. */
private boolean mAnimatingExpand = false;
/**
@@ -205,8 +209,17 @@
mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
mStackOffsetPx = res.getDimensionPixelSize(R.dimen.bubble_stack_offset);
mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
- mBubbleSizePx = res.getDimensionPixelSize(R.dimen.individual_bubble_size);
+ mBubbleSizePx = mPositioner.getBubbleSize();
mBubblesMaxRendered = res.getInteger(R.integer.bubbles_max_rendered);
+ mBubblesMaxSpace = res.getDimensionPixelSize(R.dimen.bubble_max_spacing);
+ final float availableSpace = mPositioner.isLandscape()
+ ? mPositioner.getAvailableRect().height()
+ : mPositioner.getAvailableRect().width();
+ final float spaceForMaxBubbles = (mExpandedViewPadding * 2)
+ + (mBubblesMaxRendered + 1) * mBubbleSizePx;
+ float spaceBetweenBubbles =
+ (availableSpace - spaceForMaxBubbles) / mBubblesMaxRendered;
+ mSpaceBetweenBubbles = Math.min(spaceBetweenBubbles, mBubblesMaxSpace);
}
/**
@@ -250,13 +263,15 @@
final Path path = new Path();
path.moveTo(bubble.getTranslationX(), bubble.getTranslationY());
- final float expandedY = getExpandedY();
+ final float expandedY = mPositioner.showBubblesVertically()
+ ? getBubbleXOrYForOrientation(index)
+ : getExpandedY();
if (expanding) {
// If we're expanding, first draw a line from the bubble's current position to the
// top of the screen.
path.lineTo(bubble.getTranslationX(), expandedY);
// Then, draw a line across the screen to the bubble's resting position.
- if (mPositioner.getOrientation() == Configuration.ORIENTATION_LANDSCAPE) {
+ if (mPositioner.showBubblesVertically()) {
Rect availableRect = mPositioner.getAvailableRect();
boolean onLeft = mCollapsePoint != null
&& mCollapsePoint.x < (availableRect.width() / 2f);
@@ -422,6 +437,9 @@
* bubbles to accommodate it if it was previously dragged out past the threshold.
*/
public void snapBubbleBack(View bubbleView, float velX, float velY) {
+ if (mLayout == null) {
+ return;
+ }
final int index = mLayout.indexOfChild(bubbleView);
animationForChildAtIndex(index)
@@ -580,7 +598,7 @@
return;
}
- if (mPositioner.getOrientation() == Configuration.ORIENTATION_LANDSCAPE) {
+ if (mPositioner.showBubblesVertically()) {
Rect availableRect = mPositioner.getAvailableRect();
boolean onLeft = mCollapsePoint != null
&& mCollapsePoint.x < (availableRect.width() / 2f);
@@ -613,23 +631,15 @@
if (mLayout == null) {
return 0;
}
+ final float positionInBar = index * (mBubbleSizePx + mSpaceBetweenBubbles);
Rect availableRect = mPositioner.getAvailableRect();
- final boolean isLandscape =
- mPositioner.getOrientation() == Configuration.ORIENTATION_LANDSCAPE;
- final float availableSpace = isLandscape
- ? availableRect.height()
- : availableRect.width();
- final float spaceForMaxBubbles = (mExpandedViewPadding * 2)
- + (mBubblesMaxRendered + 1) * mBubbleSizePx;
- final float spaceBetweenBubbles =
- (availableSpace - spaceForMaxBubbles) / mBubblesMaxRendered;
+ final boolean isLandscape = mPositioner.showBubblesVertically();
final float expandedStackSize = (mLayout.getChildCount() * mBubbleSizePx)
- + ((mLayout.getChildCount() - 1) * spaceBetweenBubbles);
+ + ((mLayout.getChildCount() - 1) * mSpaceBetweenBubbles);
final float centerPosition = isLandscape
? availableRect.centerY()
: availableRect.centerX();
final float rowStart = centerPosition - (expandedStackSize / 2f);
- final float positionInBar = index * (mBubbleSizePx + spaceBetweenBubbles);
return rowStart + positionInBar;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java
index d7f2e4b..24a8809d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java
@@ -133,12 +133,6 @@
/** Whether or not the stack's start position has been set. */
private boolean mStackMovedToStartPosition = false;
- /**
- * The stack's most recent position along the edge of the screen. This is saved when the last
- * bubble is removed, so that the stack can be restored in its previous position.
- */
- private PointF mRestingStackPosition;
-
/** The height of the most recently visible IME. */
private float mImeHeight = 0f;
@@ -434,6 +428,9 @@
* Where the stack would be if it were snapped to the nearest horizontal edge (left or right).
*/
public PointF getStackPositionAlongNearestHorizontalEdge() {
+ if (mPositioner.showingInTaskbar()) {
+ return mPositioner.getRestingPosition();
+ }
final PointF stackPos = getStackPosition();
final boolean onLeft = mLayout.isFirstChildXLeftOfCenter(stackPos.x);
final RectF bounds = getAllowableStackPositionRegion();
@@ -447,7 +444,7 @@
pw.println("StackAnimationController state:");
pw.print(" isActive: "); pw.println(isActiveController());
pw.print(" restingStackPos: ");
- pw.println(mRestingStackPosition != null ? mRestingStackPosition.toString() : "null");
+ pw.println(mPositioner.getRestingPosition().toString());
pw.print(" currentStackPos: "); pw.println(mStackPosition.toString());
pw.print(" isMovingFromFlinging: "); pw.println(mIsMovingFromFlinging);
pw.print(" withinDismiss: "); pw.println(isStackStuckToTarget());
@@ -501,7 +498,7 @@
.addEndListener((animation, canceled, endValue, endVelocity) -> {
if (!canceled) {
- mRestingStackPosition.set(mStackPosition);
+ mPositioner.setRestingPosition(mStackPosition);
springFirstBubbleWithStackFollowing(property, spring, endVelocity,
finalPosition != null
@@ -679,7 +676,7 @@
// resting position - the touch location is not a valid resting
// position. We'll set this when the stack springs to the left or
// right side of the screen after the touch gesture ends.
- mRestingStackPosition.set(mStackPosition);
+ mPositioner.setRestingPosition(mStackPosition);
}
if (after != null) {
@@ -772,10 +769,9 @@
if (getBubbleCount() > 0) {
animationForChildAtIndex(0).translationX(mStackPosition.x).start();
} else {
+ // TODO: still needed with positioner?
// When all children are removed ensure stack position is sane
- setStackPosition(mRestingStackPosition == null
- ? getStartPosition()
- : mRestingStackPosition);
+ mPositioner.setRestingPosition(mPositioner.getRestingPosition());
// Remove the stack from the coordinator since we don't have any bubbles and aren't
// visible.
@@ -848,8 +844,8 @@
mSwapAnimationOffset = res.getDimensionPixelSize(R.dimen.bubble_swap_animation_offset);
mMaxBubbles = res.getInteger(R.integer.bubbles_max_rendered);
mElevation = res.getDimensionPixelSize(R.dimen.bubble_elevation);
- mBubbleSize = res.getDimensionPixelSize(R.dimen.individual_bubble_size);
- mBubbleBitmapSize = res.getDimensionPixelSize(R.dimen.bubble_bitmap_size);
+ mBubbleSize = mPositioner.getBubbleSize();
+ mBubbleBitmapSize = mPositioner.getBubbleBitmapSize();
mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
mBubbleOffscreen = res.getDimensionPixelSize(R.dimen.bubble_stack_offscreen);
}
@@ -873,9 +869,8 @@
// Post to ensure that the layout's width and height have been calculated.
mLayout.setVisibility(View.INVISIBLE);
mLayout.post(() -> {
- setStackPosition(mRestingStackPosition == null
- ? getStartPosition()
- : mRestingStackPosition);
+ setStackPosition(mPositioner.getRestingPosition());
+
mStackMovedToStartPosition = true;
mLayout.setVisibility(View.VISIBLE);
@@ -919,11 +914,7 @@
Log.d(TAG, String.format("Setting position to (%f, %f).", pos.x, pos.y));
mStackPosition.set(pos.x, pos.y);
- if (mRestingStackPosition == null) {
- mRestingStackPosition = new PointF();
- }
-
- mRestingStackPosition.set(mStackPosition);
+ mPositioner.setRestingPosition(mStackPosition);
// If we're not the active controller, we don't want to physically move the bubble views.
if (isActiveController()) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
index c77f594..625c0a7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
@@ -38,6 +38,7 @@
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
+import android.util.Slog;
import android.util.SparseArray;
import android.view.DragEvent;
import android.view.LayoutInflater;
@@ -71,10 +72,6 @@
private final SparseArray<PerDisplay> mDisplayDropTargets = new SparseArray<>();
private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();
- // A count of the number of active drags in progress to ensure that we only hide the window when
- // all the drag animations have completed
- private int mActiveDragCount;
-
public DragAndDropController(Context context, DisplayController displayController) {
mContext = context;
mDisplayController = displayController;
@@ -160,7 +157,11 @@
switch (event.getAction()) {
case ACTION_DRAG_STARTED:
- mActiveDragCount++;
+ if (pd.activeDragCount != 0) {
+ Slog.w(TAG, "Unexpected drag start during an active drag");
+ return false;
+ }
+ pd.activeDragCount++;
pd.dragLayout.prepare(mDisplayController.getDisplayLayout(displayId),
event.getClipData());
setDropTargetWindowVisibility(pd, View.VISIBLE);
@@ -184,9 +185,9 @@
// TODO(b/169894807): Ensure sure it's not possible to get ENDED without DROP
// or EXITED
if (!pd.dragLayout.hasDropped()) {
- mActiveDragCount--;
+ pd.activeDragCount--;
pd.dragLayout.hide(event, () -> {
- if (mActiveDragCount == 0) {
+ if (pd.activeDragCount == 0) {
// Hide the window if another drag hasn't been started while animating
// the drag-end
setDropTargetWindowVisibility(pd, View.INVISIBLE);
@@ -203,9 +204,9 @@
*/
private boolean handleDrop(DragEvent event, PerDisplay pd) {
final SurfaceControl dragSurface = event.getDragSurface();
- mActiveDragCount--;
+ pd.activeDragCount--;
return pd.dragLayout.drop(event, dragSurface, () -> {
- if (mActiveDragCount == 0) {
+ if (pd.activeDragCount == 0) {
// Hide the window if another drag hasn't been started while animating the drop
setDropTargetWindowVisibility(pd, View.INVISIBLE);
}
@@ -245,6 +246,9 @@
final DragLayout dragLayout;
boolean isHandlingDrag;
+ // A count of the number of active drags in progress to ensure that we only hide the window
+ // when all the drag animations have completed
+ int activeDragCount;
PerDisplay(int dispId, Context c, WindowManager w, FrameLayout rv, DragLayout dl) {
displayId = dispId;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutout.java
new file mode 100644
index 0000000..38e0519
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutout.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020 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.hidedisplaycutout;
+
+import android.content.res.Configuration;
+
+import androidx.annotation.NonNull;
+
+import java.io.PrintWriter;
+
+/**
+ * Interface to engage hide display cutout feature.
+ */
+public interface HideDisplayCutout {
+ /**
+ * Notifies {@link Configuration} changed.
+ * @param newConfig
+ */
+ void onConfigurationChanged(Configuration newConfig);
+
+ /**
+ * Dumps hide display cutout status.
+ */
+ void dump(@NonNull PrintWriter pw);
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutController.java
new file mode 100644
index 0000000..e4e2546
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutController.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2020 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.hidedisplaycutout;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.os.SystemProperties;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.wm.shell.common.DisplayController;
+
+import java.io.PrintWriter;
+
+/**
+ * Manages the hide display cutout status.
+ */
+public class HideDisplayCutoutController implements HideDisplayCutout {
+ private static final String TAG = "HideDisplayCutoutController";
+
+ private final Context mContext;
+ private final HideDisplayCutoutOrganizer mOrganizer;
+ @VisibleForTesting
+ boolean mEnabled;
+
+ HideDisplayCutoutController(Context context, HideDisplayCutoutOrganizer organizer) {
+ mContext = context;
+ mOrganizer = organizer;
+ updateStatus();
+ }
+
+ /**
+ * Creates {@link HideDisplayCutoutController}, returns {@code null} if the feature is not
+ * supported.
+ */
+ @Nullable
+ public static HideDisplayCutoutController create(
+ Context context, DisplayController displayController) {
+ // The SystemProperty is set for devices that support this feature and is used to control
+ // whether to create the HideDisplayCutout instance.
+ // It's defined in the device.mk (e.g. device/google/crosshatch/device.mk).
+ if (!SystemProperties.getBoolean("ro.support_hide_display_cutout", false)) {
+ return null;
+ }
+
+ HideDisplayCutoutOrganizer organizer =
+ new HideDisplayCutoutOrganizer(context, displayController);
+ return new HideDisplayCutoutController(context, organizer);
+ }
+
+ @VisibleForTesting
+ void updateStatus() {
+ // The config value is used for controlling enabling/disabling status of the feature and is
+ // defined in the config.xml in a "Hide Display Cutout" overlay package (e.g. device/google/
+ // crosshatch/crosshatch/overlay/packages/apps/overlays/NoCutoutOverlay).
+ final boolean enabled = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_hideDisplayCutoutWithDisplayArea);
+ if (enabled == mEnabled) {
+ return;
+ }
+
+ mEnabled = enabled;
+ if (enabled) {
+ mOrganizer.enableHideDisplayCutout();
+ } else {
+ mOrganizer.disableHideDisplayCutout();
+ }
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ updateStatus();
+ }
+
+ @Override
+ public void dump(@NonNull PrintWriter pw) {
+ final String prefix = " ";
+ pw.print(TAG);
+ pw.println(" states: ");
+ pw.print(prefix);
+ pw.print("mEnabled=");
+ pw.println(mEnabled);
+ mOrganizer.dump(pw);
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java
new file mode 100644
index 0000000..090d227
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2020 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.hidedisplaycutout;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import android.content.Context;
+import android.graphics.Insets;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.RotationUtils;
+import android.view.Display;
+import android.view.DisplayCutout;
+import android.view.Surface;
+import android.view.SurfaceControl;
+import android.window.DisplayAreaAppearedInfo;
+import android.window.DisplayAreaInfo;
+import android.window.DisplayAreaOrganizer;
+import android.window.WindowContainerToken;
+import android.window.WindowContainerTransaction;
+
+import androidx.annotation.GuardedBy;
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.internal.R;
+import com.android.wm.shell.common.DisplayChangeController;
+import com.android.wm.shell.common.DisplayController;
+
+import java.io.PrintWriter;
+import java.util.List;
+
+/**
+ * Manages the display areas of hide display cutout feature.
+ */
+class HideDisplayCutoutOrganizer extends DisplayAreaOrganizer {
+ private static final String TAG = "HideDisplayCutoutOrganizer";
+
+ private final Context mContext;
+ private final DisplayController mDisplayController;
+
+ @VisibleForTesting
+ @GuardedBy("this")
+ ArrayMap<WindowContainerToken, SurfaceControl> mDisplayAreaMap = new ArrayMap();
+ // The default display bound in natural orientation.
+ private final Rect mDefaultDisplayBounds = new Rect();
+ @VisibleForTesting
+ final Rect mCurrentDisplayBounds = new Rect();
+ // The default display cutout in natural orientation.
+ private Insets mDefaultCutoutInsets;
+ private Insets mCurrentCutoutInsets;
+ private boolean mIsDefaultPortrait;
+ private int mStatusBarHeight;
+ @VisibleForTesting
+ int mOffsetX;
+ @VisibleForTesting
+ int mOffsetY;
+ @VisibleForTesting
+ int mRotation;
+
+ /**
+ * Handles rotation based on OnDisplayChangingListener callback.
+ */
+ private final DisplayChangeController.OnDisplayChangingListener mRotationController =
+ (display, fromRotation, toRotation, wct) -> {
+ mRotation = toRotation;
+ updateBoundsAndOffsets(true /* enable */);
+ final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ applyAllBoundsAndOffsets(wct, t);
+ // Only apply t here since the server will do the wct.apply when the method
+ // finishes.
+ t.apply();
+ };
+
+ HideDisplayCutoutOrganizer(Context context, DisplayController displayController) {
+ mContext = context;
+ mDisplayController = displayController;
+ }
+
+ @Override
+ public void onDisplayAreaAppeared(@NonNull DisplayAreaInfo displayAreaInfo,
+ @NonNull SurfaceControl leash) {
+ if (!addDisplayAreaInfoAndLeashToMap(displayAreaInfo, leash)) {
+ return;
+ }
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
+ applyBoundsAndOffsets(displayAreaInfo.token, leash, wct, tx);
+ applyTransaction(wct, tx);
+ }
+
+ @Override
+ public void onDisplayAreaVanished(@NonNull DisplayAreaInfo displayAreaInfo) {
+ synchronized (this) {
+ if (!mDisplayAreaMap.containsKey(displayAreaInfo.token)) {
+ Log.w(TAG, "Unrecognized token: " + displayAreaInfo.token);
+ return;
+ }
+
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ applyBoundsAndOffsets(
+ displayAreaInfo.token, mDisplayAreaMap.get(displayAreaInfo.token), wct, t);
+ applyTransaction(wct, t);
+ mDisplayAreaMap.remove(displayAreaInfo.token);
+ }
+ }
+
+ private void updateDisplayAreaMap(List<DisplayAreaAppearedInfo> displayAreaInfos) {
+ for (int i = 0; i < displayAreaInfos.size(); i++) {
+ final DisplayAreaInfo info = displayAreaInfos.get(i).getDisplayAreaInfo();
+ final SurfaceControl leash = displayAreaInfos.get(i).getLeash();
+ addDisplayAreaInfoAndLeashToMap(info, leash);
+ }
+ }
+
+ @VisibleForTesting
+ boolean addDisplayAreaInfoAndLeashToMap(@NonNull DisplayAreaInfo displayAreaInfo,
+ @NonNull SurfaceControl leash) {
+ synchronized (this) {
+ if (displayAreaInfo.displayId != DEFAULT_DISPLAY) {
+ return false;
+ }
+ if (mDisplayAreaMap.containsKey(displayAreaInfo.token)) {
+ Log.w(TAG, "Already appeared token: " + displayAreaInfo.token);
+ return false;
+ }
+ mDisplayAreaMap.put(displayAreaInfo.token, leash);
+ return true;
+ }
+ }
+
+ /**
+ * Enables hide display cutout.
+ */
+ void enableHideDisplayCutout() {
+ mDisplayController.addDisplayChangingController(mRotationController);
+ final Display display = mDisplayController.getDisplay(DEFAULT_DISPLAY);
+ if (display != null) {
+ mRotation = display.getRotation();
+ }
+ final List<DisplayAreaAppearedInfo> displayAreaInfos =
+ registerOrganizer(DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT);
+ updateDisplayAreaMap(displayAreaInfos);
+ updateBoundsAndOffsets(true /* enabled */);
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ applyAllBoundsAndOffsets(wct, t);
+ applyTransaction(wct, t);
+ }
+
+ /**
+ * Disables hide display cutout.
+ */
+ void disableHideDisplayCutout() {
+ updateBoundsAndOffsets(false /* enabled */);
+ mDisplayController.removeDisplayChangingController(mRotationController);
+ unregisterOrganizer();
+ }
+
+ @VisibleForTesting
+ Insets getDisplayCutoutInsetsOfNaturalOrientation() {
+ final Display display = mDisplayController.getDisplay(DEFAULT_DISPLAY);
+ if (display == null) {
+ return Insets.NONE;
+ }
+ DisplayCutout cutout = display.getCutout();
+ Insets insets = cutout != null ? Insets.of(cutout.getSafeInsets()) : Insets.NONE;
+ return mRotation != Surface.ROTATION_0
+ ? RotationUtils.rotateInsets(insets, 4 /* total number of rotation */ - mRotation)
+ : insets;
+ }
+
+ @VisibleForTesting
+ Rect getDisplayBoundsOfNaturalOrientation() {
+ Point realSize = new Point(0, 0);
+ final Display display = mDisplayController.getDisplay(DEFAULT_DISPLAY);
+ if (display != null) {
+ display.getRealSize(realSize);
+ }
+ final boolean isDisplaySizeFlipped = isDisplaySizeFlipped();
+ return new Rect(
+ 0,
+ 0,
+ isDisplaySizeFlipped ? realSize.y : realSize.x,
+ isDisplaySizeFlipped ? realSize.x : realSize.y);
+ }
+
+ private boolean isDisplaySizeFlipped() {
+ return mRotation == Surface.ROTATION_90 || mRotation == Surface.ROTATION_270;
+ }
+
+ /**
+ * Updates bounds and offsets according to current state.
+ *
+ * @param enabled whether the hide display cutout feature is enabled.
+ */
+ @VisibleForTesting
+ void updateBoundsAndOffsets(boolean enabled) {
+ if (!enabled) {
+ resetBoundsAndOffsets();
+ } else {
+ initDefaultValuesIfNeeded();
+
+ // Reset to default values.
+ mCurrentDisplayBounds.set(mDefaultDisplayBounds);
+ mOffsetX = 0;
+ mOffsetY = 0;
+
+ // Update bounds and insets according to the rotation.
+ mCurrentCutoutInsets = RotationUtils.rotateInsets(mDefaultCutoutInsets, mRotation);
+ if (isDisplaySizeFlipped()) {
+ mCurrentDisplayBounds.set(
+ mCurrentDisplayBounds.top,
+ mCurrentDisplayBounds.left,
+ mCurrentDisplayBounds.bottom,
+ mCurrentDisplayBounds.right);
+ }
+ mCurrentDisplayBounds.inset(mCurrentCutoutInsets);
+
+ // Replace the top bound with the max(status bar height, cutout height) if there is
+ // cutout on the top side.
+ mStatusBarHeight = getStatusBarHeight();
+ if (mCurrentCutoutInsets.top != 0) {
+ mCurrentDisplayBounds.top = Math.max(mStatusBarHeight, mCurrentCutoutInsets.top);
+ }
+ mOffsetX = mCurrentDisplayBounds.left;
+ mOffsetY = mCurrentDisplayBounds.top;
+ }
+ }
+
+ private void resetBoundsAndOffsets() {
+ mCurrentDisplayBounds.setEmpty();
+ mOffsetX = 0;
+ mOffsetY = 0;
+ }
+
+ private void initDefaultValuesIfNeeded() {
+ if (!mDefaultDisplayBounds.isEmpty()) {
+ return;
+ }
+ mDefaultDisplayBounds.set(getDisplayBoundsOfNaturalOrientation());
+ mDefaultCutoutInsets = getDisplayCutoutInsetsOfNaturalOrientation();
+ mIsDefaultPortrait = mDefaultDisplayBounds.width() < mDefaultDisplayBounds.height();
+ }
+
+ private void applyAllBoundsAndOffsets(
+ WindowContainerTransaction wct, SurfaceControl.Transaction t) {
+ synchronized (this) {
+ mDisplayAreaMap.forEach((token, leash) -> {
+ applyBoundsAndOffsets(token, leash, wct, t);
+ });
+ }
+ }
+
+ @VisibleForTesting
+ void applyBoundsAndOffsets(WindowContainerToken token, SurfaceControl leash,
+ WindowContainerTransaction wct, SurfaceControl.Transaction t) {
+ wct.setBounds(token, mCurrentDisplayBounds.isEmpty() ? null : mCurrentDisplayBounds);
+ t.setPosition(leash, mOffsetX, mOffsetY);
+ }
+
+ @VisibleForTesting
+ void applyTransaction(WindowContainerTransaction wct, SurfaceControl.Transaction t) {
+ applyTransaction(wct);
+ t.apply();
+ }
+
+ private int getStatusBarHeight() {
+ final boolean isLandscape =
+ mIsDefaultPortrait ? isDisplaySizeFlipped() : !isDisplaySizeFlipped();
+ return mContext.getResources().getDimensionPixelSize(
+ isLandscape ? R.dimen.status_bar_height_landscape
+ : R.dimen.status_bar_height_portrait);
+ }
+
+ void dump(@NonNull PrintWriter pw) {
+ final String prefix = " ";
+ pw.print(TAG);
+ pw.println(" states: ");
+ synchronized (this) {
+ pw.print(prefix);
+ pw.print("mDisplayAreaMap=");
+ pw.println(mDisplayAreaMap);
+ }
+ pw.print(prefix);
+ pw.print("getDisplayBoundsOfNaturalOrientation()=");
+ pw.println(getDisplayBoundsOfNaturalOrientation());
+ pw.print(prefix);
+ pw.print("mDefaultDisplayBounds=");
+ pw.println(mDefaultDisplayBounds);
+ pw.print(prefix);
+ pw.print("mCurrentDisplayBounds=");
+ pw.println(mCurrentDisplayBounds);
+ pw.print(prefix);
+ pw.print("mDefaultCutoutInsets=");
+ pw.println(mDefaultCutoutInsets);
+ pw.print(prefix);
+ pw.print("mCurrentCutoutInsets=");
+ pw.println(mCurrentCutoutInsets);
+ pw.print(prefix);
+ pw.print("mRotation=");
+ pw.println(mRotation);
+ pw.print(prefix);
+ pw.print("mStatusBarHeight=");
+ pw.println(mStatusBarHeight);
+ pw.print(prefix);
+ pw.print("mOffsetX=");
+ pw.println(mOffsetX);
+ pw.print(prefix);
+ pw.print("mOffsetY=");
+ pw.println(mOffsetY);
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
index d211d65..d7b56ae 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
@@ -368,12 +368,11 @@
}
/**
- * Stash PiP to the closest edge.
+ * Stash PiP to the closest edge. We set velocityY to 0 to limit pure horizontal motion.
*/
- void stashToEdge(
- float velocityX, float velocityY, @Nullable Runnable postBoundsUpdateCallback) {
+ void stashToEdge(float velocityX, @Nullable Runnable postBoundsUpdateCallback) {
mPipBoundsState.setStashed(velocityX < 0 ? STASH_TYPE_LEFT : STASH_TYPE_RIGHT);
- movetoTarget(velocityX, velocityY, postBoundsUpdateCallback, true /* isStash */);
+ movetoTarget(velocityX, 0 /* velocityY */, postBoundsUpdateCallback, true /* isStash */);
}
private void movetoTarget(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
index ae1dd38..36d2768 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
@@ -64,11 +64,7 @@
public class PipTouchHandler {
private static final String TAG = "PipTouchHandler";
- /** Duration of the dismiss scrim fading in/out. */
- private static final int DISMISS_TRANSITION_DURATION_MS = 200;
-
- /* The multiplier to apply scale the target size by when applying the magnetic field radius */
- private static final float MAGNETIC_FIELD_RADIUS_MULTIPLIER = 1.25f;
+ private static final float STASH_MINIMUM_VELOCITY_X = 3000.f;
// Allow PIP to resize to a slightly bigger state upon touch
private final boolean mEnableResize;
@@ -87,11 +83,10 @@
private boolean mShowPipMenuOnAnimationEnd = false;
/**
- * Whether PIP stash is enabled or not. When enabled, if at the time of fling-release the
- * PIP bounds is outside the left/right edge of the screen, it will be shown in "stashed" mode,
- * where PIP will only show partially.
+ * Whether PIP stash is enabled or not. When enabled, if the user flings toward the edge of the
+ * screen, it will be shown in "stashed" mode, where PIP will only show partially.
*/
- private boolean mEnableStash = false;
+ private boolean mEnableStash = true;
// The current movement bounds
private Rect mMovementBounds = new Rect();
@@ -206,13 +201,13 @@
mEnableStash = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_SYSTEMUI,
PIP_STASHING,
- /* defaultValue = */ false);
+ /* defaultValue = */ true);
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
context.getMainExecutor(),
properties -> {
if (properties.getKeyset().contains(PIP_STASHING)) {
mEnableStash = properties.getBoolean(
- PIP_STASHING, /* defaultValue = */ false);
+ PIP_STASHING, /* defaultValue = */ true);
}
});
}
@@ -710,6 +705,7 @@
private final Point mStartPosition = new Point();
private final PointF mDelta = new PointF();
private boolean mShouldHideMenuAfterFling;
+ private float mDownSavedFraction = -1f;
@Override
public void onDown(PipTouchState touchState) {
@@ -722,6 +718,7 @@
mStartPosition.set(bounds.left, bounds.top);
mMovementWithinDismiss = touchState.getDownTouchPosition().y >= mMovementBounds.bottom;
mMotionHelper.setSpringingToTouch(false);
+ mDownSavedFraction = mPipBoundsHandler.getSnapFraction(mPipBoundsState.getBounds());
// If the menu is still visible then just poke the menu
// so that it will timeout after the user stops touching it
@@ -790,13 +787,15 @@
// Reset the touch state on up before the fling settles
mTouchState.reset();
- final Rect animatingBounds = getPossiblyAnimatingBounds();
- // If User releases the PIP window while it's out of the display bounds, put
- // PIP into stashed mode.
- if (mEnableStash
- && (animatingBounds.right > mPipBoundsState.getDisplayBounds().right
- || animatingBounds.left < mPipBoundsState.getDisplayBounds().left)) {
- mMotionHelper.stashToEdge(vel.x, vel.y, this::stashEndAction /* endAction */);
+ // If user flings the PIP window above the minimum velocity, stash PIP.
+ // Only allow stashing to the edge if the user starts dragging the PIP from that
+ // edge.
+ if (mEnableStash && !mPipBoundsState.isStashed()
+ && ((vel.x > STASH_MINIMUM_VELOCITY_X
+ && mDownSavedFraction > 1f && mDownSavedFraction < 2f)
+ || (vel.x < -STASH_MINIMUM_VELOCITY_X
+ && mDownSavedFraction > 3f && mDownSavedFraction < 4f))) {
+ mMotionHelper.stashToEdge(vel.x, this::stashEndAction /* endAction */);
} else {
mMotionHelper.flingToSnapTarget(vel.x, vel.y,
this::flingEndAction /* endAction */);
@@ -834,6 +833,7 @@
mTouchState.scheduleDoubleTapTimeoutCallback();
}
}
+ mDownSavedFraction = -1f;
return true;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java
index fd055d1..c23bc1d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java
@@ -44,7 +44,6 @@
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
-import android.util.Pair;
import android.view.DisplayInfo;
import com.android.wm.shell.R;
@@ -57,7 +56,6 @@
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipTaskOrganizer;
-import com.android.wm.shell.pip.PipUtils;
import java.util.ArrayList;
import java.util.List;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
new file mode 100644
index 0000000..ee79824
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2020 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.startingsurface;
+
+import static android.content.Context.CONTEXT_RESTRICTED;
+import static android.content.res.Configuration.EMPTY;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.hardware.display.DisplayManager;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.view.Display;
+import android.view.View;
+import android.view.WindowManager;
+import android.window.TaskOrganizer;
+
+import com.android.internal.R;
+import com.android.internal.policy.PhoneWindow;
+
+import java.util.function.Consumer;
+
+/**
+ * Implementation to draw the starting window to an application, and remove the starting window
+ * until the application displays its own window.
+ *
+ * When receive {@link TaskOrganizer#addStartingWindow} callback, use this class to create a
+ * starting window and attached to the Task, then when the Task want to remove the starting window,
+ * the TaskOrganizer will receive {@link TaskOrganizer#removeStartingWindow} callback then use this
+ * class to remove the starting window of the Task.
+ * @hide
+ */
+public class StartingSurfaceDrawer {
+ private static final String TAG = StartingSurfaceDrawer.class.getSimpleName();
+ private static final boolean DEBUG_SPLASH_SCREEN = false;
+
+ private final Context mContext;
+ private final DisplayManager mDisplayManager;
+
+ // TODO(b/131727939) remove this when clearing ActivityRecord
+ private static final int REMOVE_WHEN_TIMEOUT = 2000;
+
+ public StartingSurfaceDrawer(Context context) {
+ mContext = context;
+ mDisplayManager = mContext.getSystemService(DisplayManager.class);
+ }
+
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
+ private final SparseArray<TaskScreenView> mTaskScreenViews = new SparseArray<>();
+
+ /** Obtain proper context for showing splash screen on the provided display. */
+ private Context getDisplayContext(Context context, int displayId) {
+ if (displayId == DEFAULT_DISPLAY) {
+ // The default context fits.
+ return context;
+ }
+
+ final Display targetDisplay = mDisplayManager.getDisplay(displayId);
+ if (targetDisplay == null) {
+ // Failed to obtain the non-default display where splash screen should be shown,
+ // lets not show at all.
+ return null;
+ }
+
+ return context.createDisplayContext(targetDisplay);
+ }
+
+ /**
+ * Called when a task need a starting window.
+ */
+ public void addStartingWindow(ActivityManager.RunningTaskInfo taskInfo, IBinder appToken) {
+
+ final ActivityInfo activityInfo = taskInfo.topActivityInfo;
+ final int displayId = taskInfo.displayId;
+ if (activityInfo.packageName == null) {
+ return;
+ }
+
+ CharSequence nonLocalizedLabel = activityInfo.nonLocalizedLabel;
+ int labelRes = activityInfo.labelRes;
+ if (activityInfo.nonLocalizedLabel == null && activityInfo.labelRes == 0) {
+ ApplicationInfo app = activityInfo.applicationInfo;
+ nonLocalizedLabel = app.nonLocalizedLabel;
+ labelRes = app.labelRes;
+ }
+
+ Context context = mContext;
+ final int theme = activityInfo.getThemeResource();
+ if (DEBUG_SPLASH_SCREEN) {
+ Slog.d(TAG, "addSplashScreen " + activityInfo.packageName
+ + ": nonLocalizedLabel=" + nonLocalizedLabel + " theme="
+ + Integer.toHexString(theme) + " task= " + taskInfo.taskId);
+ }
+
+ // Obtain proper context to launch on the right display.
+ final Context displayContext = getDisplayContext(context, displayId);
+ if (displayContext == null) {
+ // Can't show splash screen on requested display, so skip showing at all.
+ return;
+ }
+ context = displayContext;
+
+ if (theme != context.getThemeResId() || labelRes != 0) {
+ try {
+ context = context.createPackageContext(
+ activityInfo.packageName, CONTEXT_RESTRICTED);
+ context.setTheme(theme);
+ } catch (PackageManager.NameNotFoundException e) {
+ // Ignore
+ }
+ }
+
+ final Configuration taskConfig = taskInfo.getConfiguration();
+ if (taskConfig != null && !taskConfig.equals(EMPTY)) {
+ if (DEBUG_SPLASH_SCREEN) {
+ Slog.d(TAG, "addSplashScreen: creating context based"
+ + " on task Configuration " + taskConfig + " for splash screen");
+ }
+ final Context overrideContext = context.createConfigurationContext(taskConfig);
+ overrideContext.setTheme(theme);
+ final TypedArray typedArray = overrideContext.obtainStyledAttributes(
+ com.android.internal.R.styleable.Window);
+ final int resId = typedArray.getResourceId(R.styleable.Window_windowBackground, 0);
+ if (resId != 0 && overrideContext.getDrawable(resId) != null) {
+ // We want to use the windowBackground for the override context if it is
+ // available, otherwise we use the default one to make sure a themed starting
+ // window is displayed for the app.
+ if (DEBUG_SPLASH_SCREEN) {
+ Slog.d(TAG, "addSplashScreen: apply overrideConfig"
+ + taskConfig + " to starting window resId=" + resId);
+ }
+ context = overrideContext;
+ }
+ typedArray.recycle();
+ }
+
+ int windowFlags = 0;
+ if ((activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
+ windowFlags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+ }
+
+ final boolean[] showWallpaper = new boolean[1];
+ final int[] splashscreenContentResId = new int[1];
+ getWindowResFromContext(context, a -> {
+ splashscreenContentResId[0] =
+ a.getResourceId(R.styleable.Window_windowSplashscreenContent, 0);
+ showWallpaper[0] = a.getBoolean(R.styleable.Window_windowShowWallpaper, false);
+ });
+ if (showWallpaper[0]) {
+ windowFlags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+ }
+
+ final PhoneWindow win = new PhoneWindow(context);
+ win.setIsStartingWindow(true);
+
+ CharSequence label = context.getResources().getText(labelRes, null);
+ // Only change the accessibility title if the label is localized
+ if (label != null) {
+ win.setTitle(label, true);
+ } else {
+ win.setTitle(nonLocalizedLabel, false);
+ }
+
+ win.setType(WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
+
+ // Assumes it's safe to show starting windows of launched apps while
+ // the keyguard is being hidden. This is okay because starting windows never show
+ // secret information.
+ // TODO(b/113840485): Occluded may not only happen on default display
+ if (displayId == DEFAULT_DISPLAY) {
+ windowFlags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
+ }
+
+ // Force the window flags: this is a fake window, so it is not really
+ // touchable or focusable by the user. We also add in the ALT_FOCUSABLE_IM
+ // flag because we do know that the next window will take input
+ // focus, so we want to get the IME window up on top of us right away.
+ win.setFlags(windowFlags
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+ windowFlags
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
+
+ final int iconRes = activityInfo.getIconResource();
+ final int logoRes = activityInfo.getLogoResource();
+ win.setDefaultIcon(iconRes);
+ win.setDefaultLogo(logoRes);
+
+ win.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
+ WindowManager.LayoutParams.MATCH_PARENT);
+
+ final WindowManager.LayoutParams params = win.getAttributes();
+ params.token = appToken;
+ params.packageName = activityInfo.packageName;
+ params.windowAnimations = win.getWindowStyle().getResourceId(
+ com.android.internal.R.styleable.Window_windowAnimationStyle, 0);
+ params.privateFlags |=
+ WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED;
+ params.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
+ // Setting as trusted overlay to let touches pass through. This is safe because this
+ // window is controlled by the system.
+ params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
+
+ final Resources res = context.getResources();
+ final boolean supportsScreen = res != null && (res.getCompatibilityInfo() != null
+ && res.getCompatibilityInfo().supportsScreen());
+ if (!supportsScreen) {
+ params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
+ }
+
+ params.setTitle("Splash Screen " + activityInfo.packageName);
+ addSplashscreenContent(win, context, splashscreenContentResId[0]);
+
+ final View view = win.getDecorView();
+
+ if (DEBUG_SPLASH_SCREEN) {
+ Slog.d(TAG, "Adding splash screen window for "
+ + activityInfo.packageName + " / " + appToken + ": " + view);
+ }
+ final WindowManager wm = context.getSystemService(WindowManager.class);
+ postAddWindow(taskInfo.taskId, appToken, view, wm, params);
+ }
+
+ /**
+ * Called when the content of a task is ready to show, starting window can be removed.
+ */
+ public void removeStartingWindow(ActivityManager.RunningTaskInfo taskInfo) {
+ if (DEBUG_SPLASH_SCREEN) {
+ Slog.d(TAG, "Task start finish, remove starting surface for task " + taskInfo.taskId);
+ }
+ mHandler.post(() -> removeWindowSynced(taskInfo.taskId));
+ }
+
+ protected void postAddWindow(int taskId, IBinder appToken,
+ View view, WindowManager wm, WindowManager.LayoutParams params) {
+ mHandler.post(() -> {
+ boolean shouldSaveView = true;
+ try {
+ wm.addView(view, params);
+ } catch (WindowManager.BadTokenException e) {
+ // ignore
+ Slog.w(TAG, appToken + " already running, starting window not displayed. "
+ + e.getMessage());
+ shouldSaveView = false;
+ } catch (RuntimeException e) {
+ // don't crash if something else bad happens, for example a
+ // failure loading resources because we are loading from an app
+ // on external storage that has been unmounted.
+ Slog.w(TAG, appToken + " failed creating starting window", e);
+ shouldSaveView = false;
+ } finally {
+ if (view != null && view.getParent() == null) {
+ Slog.w(TAG, "view not successfully added to wm, removing view");
+ wm.removeViewImmediate(view);
+ shouldSaveView = false;
+ }
+ }
+
+ if (shouldSaveView) {
+ removeWindowSynced(taskId);
+ mHandler.postDelayed(() -> removeWindowSynced(taskId), REMOVE_WHEN_TIMEOUT);
+ final TaskScreenView tView = new TaskScreenView(view);
+ mTaskScreenViews.put(taskId, tView);
+ }
+ });
+ }
+
+ protected void removeWindowSynced(int taskId) {
+ final TaskScreenView preView = mTaskScreenViews.get(taskId);
+ if (preView != null) {
+ if (preView.mDecorView != null) {
+ if (DEBUG_SPLASH_SCREEN) {
+ Slog.v(TAG, "Removing splash screen window for task: " + taskId);
+ }
+ final WindowManager wm = preView.mDecorView.getContext()
+ .getSystemService(WindowManager.class);
+ wm.removeView(preView.mDecorView);
+ }
+ mTaskScreenViews.remove(taskId);
+ }
+ }
+
+ private void getWindowResFromContext(Context ctx, Consumer<TypedArray> consumer) {
+ final TypedArray a = ctx.obtainStyledAttributes(R.styleable.Window);
+ consumer.accept(a);
+ a.recycle();
+ }
+
+ /**
+ * Record the views in a starting window.
+ */
+ private static class TaskScreenView {
+ private final View mDecorView;
+
+ TaskScreenView(View decorView) {
+ mDecorView = decorView;
+ }
+ }
+
+ private void addSplashscreenContent(PhoneWindow win, Context ctx,
+ int splashscreenContentResId) {
+ if (splashscreenContentResId == 0) {
+ return;
+ }
+ final Drawable drawable = ctx.getDrawable(splashscreenContentResId);
+ if (drawable == null) {
+ return;
+ }
+
+ // We wrap this into a view so the system insets get applied to the drawable.
+ final View v = new View(ctx);
+ v.setBackground(drawable);
+ win.setContentView(v);
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt
index 33b6902..728cc51 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt
@@ -16,9 +16,10 @@
package com.android.wm.shell.flicker.pip.tv
-import android.os.SystemClock
import androidx.test.filters.RequiresDevice
-import org.junit.Assert.assertNotNull
+import androidx.test.uiautomator.UiObject2
+import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME
+import com.android.wm.shell.flicker.wait
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
@@ -34,21 +35,27 @@
class TvPipMenuTests(rotationName: String, rotation: Int)
: TvPipTestBase(rotationName, rotation) {
+ private val systemUiResources =
+ packageManager.getResourcesForApplication(SYSTEM_UI_PACKAGE_NAME)
+ private val playButtonDescription = systemUiResources.run {
+ getString(getIdentifier("pip_play", "string", SYSTEM_UI_PACKAGE_NAME))
+ }
+ private val pauseButtonDescription = systemUiResources.run {
+ getString(getIdentifier("pip_pause", "string", SYSTEM_UI_PACKAGE_NAME))
+ }
+
@Before
override fun setUp() {
super.setUp()
// Launch the app and go to PiP
testApp.launchViaIntent()
- testApp.clickEnterPipButton()
}
@Test
fun pipMenu_open() {
- // Pressing the Window key should bring up Pip menu
- uiDevice.pressWindowKey()
- val pipMenu = uiDevice.waitForTvPipMenu()
- ?: fail("Pip notification should have been dismissed")
+ val pipMenu = enterPip_openMenu_assertShown()
+ // Make sure it's fullscreen
assertTrue("Pip menu should be shown fullscreen", pipMenu.isFullscreen(uiDevice))
testApp.closePipWindow()
@@ -56,22 +63,29 @@
@Test
fun pipMenu_backButton() {
- // Pressing the Window key should bring up Pip menu
- uiDevice.pressWindowKey()
- assertNotNull("Pip notification should have been dismissed", uiDevice.waitForTvPipMenu())
+ enterPip_openMenu_assertShown()
// Pressing the Back key should close the Pip menu
uiDevice.pressBack()
- assertTrue("Pip notification should have closed", uiDevice.waitForTvPipMenuToClose())
+ assertTrue("Pip menu should have closed", uiDevice.waitForTvPipMenuToClose())
+
+ testApp.closePipWindow()
+ }
+
+ @Test
+ fun pipMenu_homeButton() {
+ enterPip_openMenu_assertShown()
+
+ // Pressing the Home key should close the Pip menu
+ uiDevice.pressHome()
+ assertTrue("Pip menu should have closed", uiDevice.waitForTvPipMenuToClose())
testApp.closePipWindow()
}
@Test
fun pipMenu_closeButton() {
- // Pressing the Window key should bring up Pip menu
- uiDevice.pressWindowKey()
- assertNotNull("Pip notification should have been dismissed", uiDevice.waitForTvPipMenu())
+ enterPip_openMenu_assertShown()
// PiP menu should contain the Close button
val closeButton = uiDevice.findTvPipMenuCloseButton()
@@ -84,26 +98,53 @@
@Test
fun pipMenu_fullscreenButton() {
- // Pressing the Window key should bring up Pip menu
- uiDevice.pressWindowKey()
- assertNotNull("Pip notification should have been dismissed", uiDevice.waitForTvPipMenu())
+ enterPip_openMenu_assertShown()
// PiP menu should contain the Fullscreen button
val fullscreenButton = uiDevice.findTvPipMenuFullscreenButton()
?: fail("\"Full screen\" button should be shown in Pip menu")
// Clicking on the fullscreen button should return app to the fullscreen mode.
- // Click, wait for 3 seconds, check the app is fullscreen
+ // Click, wait for the app to go fullscreen
fullscreenButton.click()
- SystemClock.sleep(3_000L)
assertTrue("\"Full screen\" button should open the app fullscreen",
- testApp.ui?.isFullscreen(uiDevice) ?: false)
+ wait { testApp.ui?.isFullscreen(uiDevice) ?: false })
// Close the app
uiDevice.pressBack()
testApp.waitUntilClosed()
}
+ @Test
+ fun pipMenu_mediaPlayPauseButtons() {
+ // Start media session before entering PiP
+ testApp.clickStartMediaSessionButton()
+
+ enterPip_openMenu_assertShown()
+
+ // PiP menu should contain the Pause button
+ val pauseButton = uiDevice.findTvPipMenuElementWithDescription(pauseButtonDescription)
+ ?: fail("\"Pause\" button should be shown in Pip menu if there is an active " +
+ "playing media session.")
+
+ // When we pause media, the button should change from Pause to Play
+ pauseButton.click()
+
+ // PiP menu should contain the Play button now
+ uiDevice.waitForTvPipMenuElementWithDescription(playButtonDescription)
+ ?: fail("\"Play\" button should be shown in Pip menu if there is an active " +
+ "paused media session.")
+
+ testApp.closePipWindow()
+ }
+
+ private fun enterPip_openMenu_assertShown(): UiObject2 {
+ testApp.clickEnterPipButton()
+ // Pressing the Window key should bring up Pip menu
+ uiDevice.pressWindowKey()
+ return uiDevice.waitForTvPipMenu() ?: fail("Pip menu should have been shown")
+ }
+
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt
index d9e6ff3..8db8bc67 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt
@@ -45,6 +45,19 @@
fun UiDevice.findTvPipMenuFullscreenButton(): UiObject2? = findObject(
By.res(SYSTEM_UI_PACKAGE_NAME, TV_PIP_MENU_FULLSCREEN_BUTTON_ID))
+fun UiDevice.findTvPipMenuElementWithDescription(desc: String): UiObject2? {
+ val buttonSelector = By.desc(desc)
+ val menuWithButtonSelector = By.copy(tvPipMenuSelector).hasDescendant(buttonSelector)
+ return findObject(menuWithButtonSelector)?.findObject(buttonSelector)
+}
+
+fun UiDevice.waitForTvPipMenuElementWithDescription(desc: String): UiObject2? {
+ val buttonSelector = By.desc(desc)
+ val menuWithButtonSelector = By.copy(tvPipMenuSelector).hasDescendant(buttonSelector)
+ return wait(Until.findObject(menuWithButtonSelector), WAIT_TIME_MS)
+ ?.findObject(buttonSelector)
+}
+
fun UiObject2.isFullscreen(uiDevice: UiDevice): Boolean = visibleBounds.run {
height() == uiDevice.displayHeight && width() == uiDevice.displayWidth
}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java
index f70603e..b60068a 100644
--- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java
@@ -17,7 +17,8 @@
package com.android.wm.shell.flicker.testapp;
import static android.media.MediaMetadata.METADATA_KEY_TITLE;
-import static android.media.session.PlaybackState.ACTION_PLAY_PAUSE;
+import static android.media.session.PlaybackState.ACTION_PAUSE;
+import static android.media.session.PlaybackState.ACTION_PLAY;
import static android.media.session.PlaybackState.ACTION_STOP;
import static android.media.session.PlaybackState.STATE_PAUSED;
import static android.media.session.PlaybackState.STATE_PLAYING;
@@ -48,7 +49,7 @@
private MediaSession mMediaSession;
private final PlaybackState.Builder mPlaybackStateBuilder = new PlaybackState.Builder()
- .setActions(ACTION_PLAY_PAUSE | ACTION_STOP)
+ .setActions(ACTION_PLAY | ACTION_PAUSE | ACTION_STOP)
.setState(STATE_STOPPED, 0, 1f);
private PlaybackState mPlaybackState = mPlaybackStateBuilder.build();
private final MediaMetadata.Builder mMediaMetadataBuilder = new MediaMetadata.Builder();
diff --git a/libs/WindowManager/Shell/tests/unittest/Android.bp b/libs/WindowManager/Shell/tests/unittest/Android.bp
index 9940ea5..dca2732 100644
--- a/libs/WindowManager/Shell/tests/unittest/Android.bp
+++ b/libs/WindowManager/Shell/tests/unittest/Android.bp
@@ -30,6 +30,7 @@
"mockito-target-extended-minus-junit4",
"truth-prebuilt",
"testables",
+ "platform-test-annotations",
],
libs: [
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
index e4155a2..fdf4d31 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
@@ -36,6 +36,7 @@
import static org.mockito.Mockito.verify;
import android.app.ActivityManager.RunningTaskInfo;
+import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.graphics.Rect;
import android.os.Binder;
@@ -71,6 +72,8 @@
@Mock
private ITaskOrganizerController mTaskOrganizerController;
+ @Mock
+ private Context mContext;
ShellTaskOrganizer mOrganizer;
private final SyncTransactionQueue mSyncTransactionQueue = mock(SyncTransactionQueue.class);
@@ -106,7 +109,7 @@
.when(mTaskOrganizerController).registerTaskOrganizer(any());
} catch (RemoteException e) {}
mOrganizer = spy(new ShellTaskOrganizer(mTaskOrganizerController, mSyncTransactionQueue,
- mTransactionPool, mTestExecutor, mTestExecutor));
+ mTransactionPool, mTestExecutor, mTestExecutor, mContext));
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
index 7adc411..7c9b9c3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
@@ -35,6 +35,7 @@
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.Pair;
+import android.view.WindowManager;
import androidx.test.filters.SmallTest;
@@ -135,8 +136,9 @@
mBubbleB2 = new Bubble(mEntryB2, mSuppressionListener, mPendingIntentCanceledListener);
mBubbleB3 = new Bubble(mEntryB3, mSuppressionListener, mPendingIntentCanceledListener);
mBubbleC1 = new Bubble(mEntryC1, mSuppressionListener, mPendingIntentCanceledListener);
-
- mBubbleData = new BubbleData(getContext(), mBubbleLogger);
+ TestableBubblePositioner positioner = new TestableBubblePositioner(mContext,
+ mock(WindowManager.class));
+ mBubbleData = new BubbleData(getContext(), mBubbleLogger, positioner);
// Used by BubbleData to set lastAccessedTime
when(mTimeSource.currentTimeMillis()).thenReturn(1000L);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleFlyoutViewTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleFlyoutViewTest.java
index 5b77e4a..69d5244 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleFlyoutViewTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleFlyoutViewTest.java
@@ -19,7 +19,9 @@
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotSame;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.graphics.Color;
import android.graphics.PointF;
@@ -36,7 +38,7 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Mockito;
+import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
@@ -48,11 +50,16 @@
private TextView mSenderName;
private float[] mDotCenter = new float[2];
private Bubble.FlyoutMessage mFlyoutMessage;
+ @Mock
+ private BubblePositioner mPositioner;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
+ when(mPositioner.getBubbleBitmapSize()).thenReturn(40);
+ when(mPositioner.getBubbleSize()).thenReturn(60);
+
mFlyoutMessage = new Bubble.FlyoutMessage();
mFlyoutMessage.senderName = "Josh";
mFlyoutMessage.message = "Hello";
@@ -70,7 +77,8 @@
mFlyout.setupFlyoutStartingAsDot(
mFlyoutMessage,
new PointF(100, 100), 500, true, Color.WHITE, null, null, mDotCenter,
- false);
+ false,
+ mPositioner);
mFlyout.setVisibility(View.VISIBLE);
assertEquals("Hello", mFlyoutText.getText());
@@ -80,10 +88,11 @@
@Test
public void testFlyoutHide_runsCallback() {
- Runnable after = Mockito.mock(Runnable.class);
+ Runnable after = mock(Runnable.class);
mFlyout.setupFlyoutStartingAsDot(mFlyoutMessage,
new PointF(100, 100), 500, true, Color.WHITE, null, after, mDotCenter,
- false);
+ false,
+ mPositioner);
mFlyout.hideFlyout();
verify(after).run();
@@ -93,7 +102,8 @@
public void testSetCollapsePercent() {
mFlyout.setupFlyoutStartingAsDot(mFlyoutMessage,
new PointF(100, 100), 500, true, Color.WHITE, null, null, mDotCenter,
- false);
+ false,
+ mPositioner);
mFlyout.setVisibility(View.VISIBLE);
mFlyout.setCollapsePercent(1f);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/TestableBubblePositioner.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/TestableBubblePositioner.java
new file mode 100644
index 0000000..96bc533
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/TestableBubblePositioner.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 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.Context;
+import android.content.res.Configuration;
+import android.graphics.Insets;
+import android.graphics.Rect;
+import android.view.WindowManager;
+
+public class TestableBubblePositioner extends BubblePositioner {
+
+ public TestableBubblePositioner(Context context,
+ WindowManager windowManager) {
+ super(context, windowManager);
+
+ updateInternal(Configuration.ORIENTATION_PORTRAIT,
+ Insets.of(0, 0, 0, 0),
+ new Rect(0, 0, 500, 1000));
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationControllerTest.java
index 9c4f341..1eba3c2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationControllerTest.java
@@ -64,7 +64,7 @@
super.setUp();
BubblePositioner positioner = new BubblePositioner(getContext(), mock(WindowManager.class));
- positioner.update(Configuration.ORIENTATION_PORTRAIT,
+ positioner.updateInternal(Configuration.ORIENTATION_PORTRAIT,
Insets.of(0, 0, 0, 0),
new Rect(0, 0, mDisplayWidth, mDisplayHeight));
mExpandedController = new ExpandedAnimationController(positioner, mExpandedViewPadding,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/StackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/StackAnimationControllerTest.java
index 6b01462..f36dcbe 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/StackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/StackAnimationControllerTest.java
@@ -27,6 +27,7 @@
import android.graphics.PointF;
import android.testing.AndroidTestingRunner;
import android.view.View;
+import android.view.WindowManager;
import android.widget.FrameLayout;
import androidx.dynamicanimation.animation.DynamicAnimation;
@@ -34,7 +35,7 @@
import androidx.test.filters.SmallTest;
import com.android.wm.shell.R;
-import com.android.wm.shell.bubbles.BubblePositioner;
+import com.android.wm.shell.bubbles.TestableBubblePositioner;
import com.android.wm.shell.common.FloatingContentCoordinator;
import org.junit.Before;
@@ -310,7 +311,7 @@
super(floatingContentCoordinator,
bubbleCountSupplier,
onBubbleAnimatedOutAction,
- mock(BubblePositioner.class));
+ new TestableBubblePositioner(mContext, mock(WindowManager.class)));
}
@Override
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutControllerTest.java
new file mode 100644
index 0000000..595440f
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutControllerTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 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.hidedisplaycutout;
+
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+
+import android.platform.test.annotations.Presubmit;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableContext;
+import android.testing.TestableLooper;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@Presubmit
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class HideDisplayCutoutControllerTest {
+ private TestableContext mContext = new TestableContext(
+ InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
+
+ private HideDisplayCutoutController mHideDisplayCutoutController;
+ @Mock
+ private HideDisplayCutoutOrganizer mMockDisplayAreaOrganizer;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mHideDisplayCutoutController = new HideDisplayCutoutController(
+ mContext, mMockDisplayAreaOrganizer);
+ }
+
+ @Test
+ public void testToggleHideDisplayCutout_On() {
+ mHideDisplayCutoutController.mEnabled = false;
+ mContext.getOrCreateTestableResources().addOverride(
+ com.android.internal.R.bool.config_hideDisplayCutoutWithDisplayArea, true);
+ reset(mMockDisplayAreaOrganizer);
+ mHideDisplayCutoutController.updateStatus();
+ verify(mMockDisplayAreaOrganizer).enableHideDisplayCutout();
+ }
+
+ @Test
+ public void testToggleHideDisplayCutout_Off() {
+ mHideDisplayCutoutController.mEnabled = true;
+ mContext.getOrCreateTestableResources().addOverride(
+ com.android.internal.R.bool.config_hideDisplayCutoutWithDisplayArea, false);
+ mHideDisplayCutoutController.updateStatus();
+ verify(mMockDisplayAreaOrganizer).disableHideDisplayCutout();
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizerTest.java
new file mode 100644
index 0000000..2e4fd6a
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizerTest.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2020 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.hidedisplaycutout;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.window.DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.res.Configuration;
+import android.graphics.Insets;
+import android.graphics.Rect;
+import android.os.Binder;
+import android.platform.test.annotations.Presubmit;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableContext;
+import android.testing.TestableLooper;
+import android.view.Display;
+import android.view.Surface;
+import android.view.SurfaceControl;
+import android.window.DisplayAreaAppearedInfo;
+import android.window.DisplayAreaInfo;
+import android.window.DisplayAreaOrganizer;
+import android.window.IWindowContainerToken;
+import android.window.WindowContainerToken;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.R;
+import com.android.wm.shell.common.DisplayController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+
+@Presubmit
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class HideDisplayCutoutOrganizerTest {
+ private TestableContext mContext = new TestableContext(
+ InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
+
+ @Mock
+ private DisplayController mMockDisplayController;
+ private HideDisplayCutoutOrganizer mOrganizer;
+
+ private DisplayAreaInfo mDisplayAreaInfo;
+ private SurfaceControl mLeash;
+
+ @Mock
+ private Display mDisplay;
+ @Mock
+ private IWindowContainerToken mMockRealToken;
+ private WindowContainerToken mToken;
+
+ private final Rect mFakeDefaultBounds = new Rect(0, 0, 100, 200);
+ private final Insets mFakeDefaultCutoutInsets = Insets.of(0, 10, 0, 0);
+ private final int mFakeStatusBarHeightPortrait = 15;
+ private final int mFakeStatusBarHeightLandscape = 10;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ when(mMockDisplayController.getDisplay(anyInt())).thenReturn(mDisplay);
+
+ HideDisplayCutoutOrganizer organizer = new HideDisplayCutoutOrganizer(
+ mContext, mMockDisplayController);
+ mOrganizer = Mockito.spy(organizer);
+ doNothing().when(mOrganizer).unregisterOrganizer();
+ doNothing().when(mOrganizer).applyBoundsAndOffsets(any(), any(), any(), any());
+ doNothing().when(mOrganizer).applyTransaction(any(), any());
+
+ // It will be called when mDisplayAreaMap.containKey(token) is called.
+ Binder binder = new Binder();
+ doReturn(binder).when(mMockRealToken).asBinder();
+ mToken = new WindowContainerToken(mMockRealToken);
+ mLeash = new SurfaceControl();
+ mDisplayAreaInfo = new DisplayAreaInfo(
+ mToken, DEFAULT_DISPLAY, FEATURE_HIDE_DISPLAY_CUTOUT);
+ mDisplayAreaInfo.configuration.orientation = Configuration.ORIENTATION_PORTRAIT;
+ DisplayAreaAppearedInfo info = new DisplayAreaAppearedInfo(mDisplayAreaInfo, mLeash);
+ ArrayList<DisplayAreaAppearedInfo> infoList = new ArrayList<>();
+ infoList.add(info);
+ doReturn(infoList).when(mOrganizer).registerOrganizer(
+ DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT);
+ }
+
+ @Test
+ public void testEnableHideDisplayCutout() {
+ mOrganizer.enableHideDisplayCutout();
+
+ verify(mOrganizer).registerOrganizer(DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT);
+ verify(mOrganizer).addDisplayAreaInfoAndLeashToMap(mDisplayAreaInfo, mLeash);
+ verify(mOrganizer).updateBoundsAndOffsets(true);
+ assertThat(mOrganizer.mDisplayAreaMap.containsKey(mDisplayAreaInfo.token)).isTrue();
+ assertThat(mOrganizer.mDisplayAreaMap.containsValue(mLeash)).isTrue();
+ }
+
+ @Test
+ public void testOnDisplayAreaAppeared() {
+ mOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
+
+ assertThat(mOrganizer.mDisplayAreaMap.containsKey(mToken)).isTrue();
+ assertThat(mOrganizer.mDisplayAreaMap.containsValue(mLeash)).isTrue();
+ }
+
+ @Test
+ public void testOnDisplayAreaVanished() {
+ mOrganizer.mDisplayAreaMap.put(mDisplayAreaInfo.token, mLeash);
+ mOrganizer.onDisplayAreaVanished(mDisplayAreaInfo);
+
+ assertThat(mOrganizer.mDisplayAreaMap.containsKey(mDisplayAreaInfo.token)).isFalse();
+ }
+
+ @Test
+ public void testToggleHideDisplayCutout_enable_rot0() {
+ doReturn(mFakeDefaultBounds).when(mOrganizer).getDisplayBoundsOfNaturalOrientation();
+ doReturn(mFakeDefaultCutoutInsets).when(mOrganizer)
+ .getDisplayCutoutInsetsOfNaturalOrientation();
+ mContext.getOrCreateTestableResources().addOverride(
+ R.dimen.status_bar_height_portrait, mFakeStatusBarHeightPortrait);
+ doReturn(Surface.ROTATION_0).when(mDisplay).getRotation();
+ mOrganizer.enableHideDisplayCutout();
+
+ verify(mOrganizer).registerOrganizer(DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT);
+ verify(mOrganizer).addDisplayAreaInfoAndLeashToMap(mDisplayAreaInfo, mLeash);
+ verify(mOrganizer).updateBoundsAndOffsets(true);
+ assertThat(mOrganizer.mCurrentDisplayBounds).isEqualTo(new Rect(0, 15, 100, 200));
+ assertThat(mOrganizer.mOffsetX).isEqualTo(0);
+ assertThat(mOrganizer.mOffsetY).isEqualTo(15);
+ assertThat(mOrganizer.mRotation).isEqualTo(Surface.ROTATION_0);
+ }
+
+ @Test
+ public void testToggleHideDisplayCutout_enable_rot90() {
+ doReturn(mFakeDefaultBounds).when(mOrganizer).getDisplayBoundsOfNaturalOrientation();
+ doReturn(mFakeDefaultCutoutInsets).when(mOrganizer)
+ .getDisplayCutoutInsetsOfNaturalOrientation();
+ mContext.getOrCreateTestableResources().addOverride(
+ R.dimen.status_bar_height_landscape, mFakeStatusBarHeightLandscape);
+ doReturn(Surface.ROTATION_90).when(mDisplay).getRotation();
+ mOrganizer.enableHideDisplayCutout();
+
+ verify(mOrganizer).registerOrganizer(DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT);
+ verify(mOrganizer).addDisplayAreaInfoAndLeashToMap(mDisplayAreaInfo, mLeash);
+ verify(mOrganizer).updateBoundsAndOffsets(true);
+ assertThat(mOrganizer.mCurrentDisplayBounds).isEqualTo(new Rect(10, 0, 200, 100));
+ assertThat(mOrganizer.mOffsetX).isEqualTo(10);
+ assertThat(mOrganizer.mOffsetY).isEqualTo(0);
+ assertThat(mOrganizer.mRotation).isEqualTo(Surface.ROTATION_90);
+ }
+
+ @Test
+ public void testToggleHideDisplayCutout_enable_rot270() {
+ doReturn(mFakeDefaultBounds).when(mOrganizer).getDisplayBoundsOfNaturalOrientation();
+ doReturn(mFakeDefaultCutoutInsets).when(mOrganizer)
+ .getDisplayCutoutInsetsOfNaturalOrientation();
+ mContext.getOrCreateTestableResources().addOverride(
+ R.dimen.status_bar_height_landscape, mFakeStatusBarHeightLandscape);
+ doReturn(Surface.ROTATION_270).when(mDisplay).getRotation();
+ mOrganizer.enableHideDisplayCutout();
+
+ verify(mOrganizer).registerOrganizer(DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT);
+ verify(mOrganizer).addDisplayAreaInfoAndLeashToMap(mDisplayAreaInfo, mLeash);
+ verify(mOrganizer).updateBoundsAndOffsets(true);
+ assertThat(mOrganizer.mCurrentDisplayBounds).isEqualTo(new Rect(0, 0, 190, 100));
+ assertThat(mOrganizer.mOffsetX).isEqualTo(0);
+ assertThat(mOrganizer.mOffsetY).isEqualTo(0);
+ assertThat(mOrganizer.mRotation).isEqualTo(Surface.ROTATION_270);
+ }
+
+ @Test
+ public void testToggleHideDisplayCutout_disable() {
+ doReturn(mFakeDefaultBounds).when(mOrganizer).getDisplayBoundsOfNaturalOrientation();
+ doReturn(mFakeDefaultCutoutInsets).when(mOrganizer)
+ .getDisplayCutoutInsetsOfNaturalOrientation();
+ mContext.getOrCreateTestableResources().addOverride(
+ R.dimen.status_bar_height_portrait, mFakeStatusBarHeightPortrait);
+ mOrganizer.enableHideDisplayCutout();
+
+ // disable hide display cutout
+ mOrganizer.disableHideDisplayCutout();
+ verify(mOrganizer).updateBoundsAndOffsets(false);
+ verify(mOrganizer).unregisterOrganizer();
+ assertThat(mOrganizer.mCurrentDisplayBounds).isEqualTo(new Rect(0, 0, 0, 0));
+ assertThat(mOrganizer.mOffsetX).isEqualTo(0);
+ assertThat(mOrganizer.mOffsetY).isEqualTo(0);
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
new file mode 100644
index 0000000..f5628ab
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2020 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 unittest.src.com.android.wm.shell.startingsurface;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+
+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.spy;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.testing.TestableContext;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowMetrics;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.wm.shell.startingsurface.StartingSurfaceDrawer;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for the starting surface drawer.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class StartingSurfaceDrawerTests {
+ @Mock
+ private IBinder mBinder;
+ @Mock
+ private WindowManager mMockWindowManager;
+
+ TestStartingSurfaceDrawer mStartingSurfaceDrawer;
+
+ static final class TestStartingSurfaceDrawer extends StartingSurfaceDrawer{
+ int mAddWindowForTask = 0;
+
+ TestStartingSurfaceDrawer(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected void postAddWindow(int taskId, IBinder appToken,
+ View view, WindowManager wm, WindowManager.LayoutParams params) {
+ // listen for addView
+ mAddWindowForTask = taskId;
+ }
+
+ @Override
+ protected void removeWindowSynced(int taskId) {
+ // listen for removeView
+ if (mAddWindowForTask == taskId) {
+ mAddWindowForTask = 0;
+ }
+ }
+ }
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ final TestableContext context = new TestableContext(
+ InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
+ final WindowManager realWindowManager = context.getSystemService(WindowManager.class);
+ final WindowMetrics metrics = realWindowManager.getMaximumWindowMetrics();
+ context.addMockSystemService(WindowManager.class, mMockWindowManager);
+
+ spyOn(context);
+ spyOn(realWindowManager);
+ try {
+ doReturn(context).when(context).createPackageContext(anyString(), anyInt());
+ } catch (PackageManager.NameNotFoundException e) {
+ //
+ }
+ doReturn(metrics).when(mMockWindowManager).getMaximumWindowMetrics();
+ doNothing().when(mMockWindowManager).addView(any(), any());
+
+ mStartingSurfaceDrawer = spy(new TestStartingSurfaceDrawer(context));
+ }
+
+ @Test
+ public void testAddSplashScreenSurface() {
+ final int taskId = 1;
+ final Handler mainLoop = new Handler(Looper.getMainLooper());
+ final ActivityManager.RunningTaskInfo taskInfo =
+ createTaskInfo(taskId, WINDOWING_MODE_FULLSCREEN);
+ mStartingSurfaceDrawer.addStartingWindow(taskInfo, mBinder);
+ waitHandlerIdle(mainLoop);
+ verify(mStartingSurfaceDrawer).postAddWindow(eq(taskId), eq(mBinder), any(), any(), any());
+ assertEquals(mStartingSurfaceDrawer.mAddWindowForTask, taskId);
+
+ mStartingSurfaceDrawer.removeStartingWindow(taskInfo);
+ waitHandlerIdle(mainLoop);
+ verify(mStartingSurfaceDrawer).removeWindowSynced(eq(taskId));
+ assertEquals(mStartingSurfaceDrawer.mAddWindowForTask, 0);
+ }
+
+ private ActivityManager.RunningTaskInfo createTaskInfo(int taskId, int windowingMode) {
+ ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
+ final ActivityInfo info = new ActivityInfo();
+ info.applicationInfo = new ApplicationInfo();
+ info.packageName = "test";
+ info.theme = android.R.style.Theme;
+ taskInfo.topActivityInfo = info;
+ taskInfo.taskId = taskId;
+ taskInfo.configuration.windowConfiguration.setWindowingMode(windowingMode);
+ return taskInfo;
+ }
+
+ private static void waitHandlerIdle(Handler handler) {
+ handler.runWithScissors(() -> { }, 0 /* timeout */);
+ }
+}
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index b2c39c9..ccce403 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -183,7 +183,6 @@
ALOGI("%s", ss.str().c_str());
// Just so we have something that counts up, the value is largely irrelevant
ATRACE_INT(ss.str().c_str(), ++sDaveyCount);
- android::util::stats_write(android::util::DAVEY_OCCURRED, getuid(), ns2ms(totalDuration));
}
}
diff --git a/libs/hwui/canvas/CanvasOpTypes.h b/libs/hwui/canvas/CanvasOpTypes.h
index 895c6d0..efcb373 100644
--- a/libs/hwui/canvas/CanvasOpTypes.h
+++ b/libs/hwui/canvas/CanvasOpTypes.h
@@ -37,13 +37,19 @@
// Drawing ops
DrawColor,
DrawRect,
+ DrawRegion,
DrawRoundRect,
DrawRoundRectProperty,
+ DrawDoubleRoundRect,
DrawCircleProperty,
DrawCircle,
DrawOval,
DrawArc,
DrawPaint,
+ DrawPoint,
+ DrawPath,
+ DrawLine,
+ DrawVertices,
// TODO: Rest
diff --git a/libs/hwui/canvas/CanvasOps.h b/libs/hwui/canvas/CanvasOps.h
index afd88c0..6a76539 100644
--- a/libs/hwui/canvas/CanvasOps.h
+++ b/libs/hwui/canvas/CanvasOps.h
@@ -19,6 +19,8 @@
#include <SkAndroidFrameworkUtils.h>
#include <SkCanvas.h>
#include <SkPath.h>
+#include <SkRegion.h>
+#include <SkVertices.h>
#include <log/log.h>
#include "CanvasProperty.h"
@@ -150,6 +152,15 @@
};
template <>
+struct CanvasOp<CanvasOpType::DrawPoint> {
+ float x;
+ float y;
+ SkPaint paint;
+ void draw(SkCanvas* canvas) const { canvas->drawPoint(x, y, paint); }
+ ASSERT_DRAWABLE()
+};
+
+template <>
struct CanvasOp<CanvasOpType::DrawRect> {
SkRect rect;
SkPaint paint;
@@ -157,6 +168,14 @@
ASSERT_DRAWABLE()
};
+template <>
+struct CanvasOp<CanvasOpType::DrawRegion> {
+ SkRegion region;
+ SkPaint paint;
+ void draw(SkCanvas* canvas) const { canvas->drawRegion(region, paint); }
+ ASSERT_DRAWABLE()
+};
+
template<>
struct CanvasOp<CanvasOpType::DrawRoundRect> {
SkRect rect;
@@ -170,6 +189,17 @@
};
template<>
+struct CanvasOp<CanvasOpType::DrawDoubleRoundRect> {
+ SkRRect outer;
+ SkRRect inner;
+ SkPaint paint;
+ void draw(SkCanvas* canvas) const {
+ canvas->drawDRRect(outer, inner, paint);
+ }
+ ASSERT_DRAWABLE()
+};
+
+template<>
struct CanvasOp<CanvasOpType::DrawCircle> {
SkScalar cx;
SkScalar cy;
@@ -205,7 +235,41 @@
ASSERT_DRAWABLE()
};
+template<>
+struct CanvasOp<CanvasOpType::DrawPath> {
+ SkPath path;
+ SkPaint paint;
+
+ void draw(SkCanvas* canvas) const { canvas->drawPath(path, paint); }
+ ASSERT_DRAWABLE()
+};
+
+template<>
+struct CanvasOp<CanvasOpType::DrawLine> {
+ float startX;
+ float startY;
+ float endX;
+ float endY;
+ SkPaint paint;
+
+ void draw(SkCanvas* canvas) const {
+ canvas->drawLine(startX, startY, endX, endY, paint);
+ }
+ ASSERT_DRAWABLE()
+};
+
+template<>
+struct CanvasOp<CanvasOpType::DrawVertices> {
+ sk_sp<SkVertices> vertices;
+ SkBlendMode mode;
+ SkPaint paint;
+ void draw(SkCanvas* canvas) const {
+ canvas->drawVertices(vertices, mode, paint);
+ }
+ ASSERT_DRAWABLE()
+};
+
// cleanup our macros
#undef ASSERT_DRAWABLE
-} // namespace android::uirenderer
\ No newline at end of file
+} // namespace android::uirenderer
diff --git a/libs/hwui/tests/common/CallCountingCanvas.h b/libs/hwui/tests/common/CallCountingCanvas.h
index a965571..594afd0 100644
--- a/libs/hwui/tests/common/CallCountingCanvas.h
+++ b/libs/hwui/tests/common/CallCountingCanvas.h
@@ -80,7 +80,7 @@
int drawPathCount = 0;
void onDrawPath(const SkPath& path, const SkPaint& paint) override {
- drawPaintCount++;
+ drawPathCount++;
}
int drawRegionCount = 0;
@@ -159,6 +159,12 @@
drawPictureCount++;
}
+ int drawVerticesCount = 0;
+ void onDrawVerticesObject (const SkVertices *vertices, SkBlendMode mode,
+ const SkPaint &paint) override {
+ drawVerticesCount++;
+ }
+
private:
int END_MARKER;
};
diff --git a/libs/hwui/tests/unit/CanvasOpTests.cpp b/libs/hwui/tests/unit/CanvasOpTests.cpp
index 2311924..60c8628 100644
--- a/libs/hwui/tests/unit/CanvasOpTests.cpp
+++ b/libs/hwui/tests/unit/CanvasOpTests.cpp
@@ -196,6 +196,40 @@
EXPECT_EQ(1, canvas.sumTotalDrawCalls());
}
+TEST(CanvasOp, simpleDrawPoint) {
+ CanvasOpBuffer buffer;
+ EXPECT_EQ(buffer.size(), 0);
+ buffer.push(CanvasOp<Op::DrawPoint> {
+ .x = 12,
+ .y = 42,
+ .paint = SkPaint{}
+ });
+
+ CallCountingCanvas canvas;
+ EXPECT_EQ(0, canvas.sumTotalDrawCalls());
+ rasterizeCanvasBuffer(buffer, &canvas);
+ EXPECT_EQ(1, canvas.drawPoints);
+ EXPECT_EQ(1, canvas.sumTotalDrawCalls());
+}
+
+TEST(CanvasOp, simpleDrawLine) {
+ CanvasOpBuffer buffer;
+ EXPECT_EQ(buffer.size(), 0);
+ buffer.push(CanvasOp<Op::DrawLine> {
+ .startX = 16,
+ .startY = 28,
+ .endX = 12,
+ .endY = 30,
+ .paint = SkPaint{}
+ });
+
+ CallCountingCanvas canvas;
+ EXPECT_EQ(0, canvas.sumTotalDrawCalls());
+ rasterizeCanvasBuffer(buffer, &canvas);
+ EXPECT_EQ(1, canvas.drawPoints);
+ EXPECT_EQ(1, canvas.sumTotalDrawCalls());
+}
+
TEST(CanvasOp, simpleDrawRect) {
CanvasOpBuffer buffer;
EXPECT_EQ(buffer.size(), 0);
@@ -211,6 +245,45 @@
EXPECT_EQ(1, canvas.sumTotalDrawCalls());
}
+TEST(CanvasOp, simpleDrawRegionRect) {
+ CanvasOpBuffer buffer;
+ EXPECT_EQ(buffer.size(), 0);
+ SkRegion region;
+ region.setRect(SkIRect::MakeWH(12, 50));
+ buffer.push(CanvasOp<Op::DrawRegion> {
+ .paint = SkPaint{},
+ .region = region
+ });
+
+ CallCountingCanvas canvas;
+ EXPECT_EQ(0, canvas.sumTotalDrawCalls());
+ rasterizeCanvasBuffer(buffer, &canvas);
+ // If the region is a rectangle, drawRegion calls into drawRect as a fast path
+ EXPECT_EQ(1, canvas.drawRectCount);
+ EXPECT_EQ(1, canvas.sumTotalDrawCalls());
+}
+
+TEST(CanvasOp, simpleDrawRegionPath) {
+ CanvasOpBuffer buffer;
+ EXPECT_EQ(buffer.size(), 0);
+ SkPath path;
+ path.addCircle(50, 50, 50);
+ SkRegion clip;
+ clip.setRect(SkIRect::MakeWH(100, 100));
+ SkRegion region;
+ region.setPath(path, clip);
+ buffer.push(CanvasOp<Op::DrawRegion> {
+ .paint = SkPaint{},
+ .region = region
+ });
+
+ CallCountingCanvas canvas;
+ EXPECT_EQ(0, canvas.sumTotalDrawCalls());
+ rasterizeCanvasBuffer(buffer, &canvas);
+ EXPECT_EQ(1, canvas.drawRegionCount);
+ EXPECT_EQ(1, canvas.sumTotalDrawCalls());
+}
+
TEST(CanvasOp, simpleDrawRoundRect) {
CanvasOpBuffer buffer;
EXPECT_EQ(buffer.size(), 0);
@@ -228,6 +301,44 @@
EXPECT_EQ(1, canvas.sumTotalDrawCalls());
}
+TEST(CanvasOp, simpleDrawDoubleRoundRect) {
+ CanvasOpBuffer buffer;
+ EXPECT_EQ(buffer.size(), 0);
+ SkRect outer = SkRect::MakeLTRB(0, 0, 100, 100);
+ SkRect inner = SkRect::MakeLTRB(20, 20, 80, 80);
+
+ const int numPts = 4;
+ SkRRect outerRRect;
+
+ auto outerPts = std::make_unique<SkVector[]>(numPts);
+ outerPts[0].set(32, 16);
+ outerPts[1].set(48, 48);
+ outerPts[2].set(16, 32);
+ outerPts[3].set(20, 20);
+ outerRRect.setRectRadii(outer, outerPts.get());
+ outerRRect.setRect(outer);
+
+ SkRRect innerRRect;
+ auto innerPts = std::make_unique<SkVector[]>(numPts);
+ innerPts[0].set(16, 8);
+ innerPts[1].set(24, 24);
+ innerPts[2].set(8, 16);
+ innerPts[3].set(10, 10);
+ innerRRect.setRectRadii(inner, innerPts.get());
+
+ buffer.push(CanvasOp<Op::DrawDoubleRoundRect> {
+ .outer = outerRRect,
+ .inner = innerRRect,
+ .paint = SkPaint{}
+ });
+
+ CallCountingCanvas canvas;
+ EXPECT_EQ(0, canvas.sumTotalDrawCalls());
+ rasterizeCanvasBuffer(buffer, &canvas);
+ EXPECT_EQ(1, canvas.drawDRRectCount);
+ EXPECT_EQ(1, canvas.sumTotalDrawCalls());
+}
+
TEST(CanvasOp, simpleDrawCircle) {
CanvasOpBuffer buffer;
EXPECT_EQ(buffer.size(), 0);
@@ -278,6 +389,23 @@
EXPECT_EQ(1, canvas.sumTotalDrawCalls());
}
+TEST(CanvasOp, simpleDrawPath) {
+ CanvasOpBuffer buffer;
+ EXPECT_EQ(buffer.size(), 0);
+ SkPath path;
+ path.addCircle(50, 50, 30);
+ buffer.push(CanvasOp<Op::DrawPath> {
+ .path = path,
+ .paint = SkPaint{}
+ });
+
+ CallCountingCanvas canvas;
+ EXPECT_EQ(0, canvas.sumTotalDrawCalls());
+ rasterizeCanvasBuffer(buffer, &canvas);
+ EXPECT_EQ(1, canvas.drawPathCount);
+ EXPECT_EQ(1, canvas.sumTotalDrawCalls());
+}
+
TEST(CanvasOp, simpleDrawRoundRectProperty) {
CanvasOpBuffer buffer;
EXPECT_EQ(buffer.size(), 0);
@@ -332,6 +460,27 @@
EXPECT_EQ(1, canvas.sumTotalDrawCalls());
}
+TEST(CanvasOp, simpleDrawVertices) {
+ CanvasOpBuffer buffer;
+ EXPECT_EQ(buffer.size(), 0);
+
+ SkPoint pts[3] = {{64, 32}, {0, 224}, {128, 224}};
+ SkColor colors[3] = {SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN};
+ sk_sp<SkVertices> vertices = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode, 3, pts,
+ nullptr, colors);
+ buffer.push(CanvasOp<Op::DrawVertices> {
+ .vertices = vertices,
+ .mode = SkBlendMode::kSrcOver,
+ .paint = SkPaint{}
+ });
+
+ CallCountingCanvas canvas;
+ EXPECT_EQ(0, canvas.sumTotalDrawCalls());
+ rasterizeCanvasBuffer(buffer, &canvas);
+ EXPECT_EQ(1, canvas.drawVerticesCount);
+ EXPECT_EQ(1, canvas.sumTotalDrawCalls());
+}
+
TEST(CanvasOp, immediateRendering) {
auto canvas = std::make_shared<CallCountingCanvas>();
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 4fbcfe1..047b809 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -202,6 +202,7 @@
*
* @hide
*/
+ @SystemApi
@TestApi
public static final String FUSED_PROVIDER = "fused";
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 44890be..f216c8c 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -79,7 +79,8 @@
/**
* This is a class for reading and writing Exif tags in various image file formats.
* <p>
- * Supported for reading: JPEG, PNG, WebP, HEIF, DNG, CR2, NEF, NRW, ARW, RW2, ORF, PEF, SRW, RAF.
+ * Supported for reading: JPEG, PNG, WebP, HEIF, DNG, CR2, NEF, NRW, ARW, RW2, ORF, PEF, SRW, RAF,
+ * AVIF.
* <p>
* Supported for writing: JPEG, PNG, WebP.
* <p>
@@ -543,6 +544,8 @@
private static final byte[] HEIF_TYPE_FTYP = new byte[] {'f', 't', 'y', 'p'};
private static final byte[] HEIF_BRAND_MIF1 = new byte[] {'m', 'i', 'f', '1'};
private static final byte[] HEIF_BRAND_HEIC = new byte[] {'h', 'e', 'i', 'c'};
+ private static final byte[] HEIF_BRAND_AVIF = new byte[] {'a', 'v', 'i', 'f'};
+ private static final byte[] HEIF_BRAND_AVIS = new byte[] {'a', 'v', 'i', 's'};
// See http://fileformats.archiveteam.org/wiki/Olympus_ORF
private static final short ORF_SIGNATURE_1 = 0x4f52;
@@ -2662,6 +2665,7 @@
byte[] brand = new byte[4];
boolean isMif1 = false;
boolean isHeic = false;
+ boolean isAvif = false;
for (long i = 0; i < chunkDataSize / 4; ++i) {
if (signatureInputStream.read(brand) != brand.length) {
return false;
@@ -2674,8 +2678,11 @@
isMif1 = true;
} else if (Arrays.equals(brand, HEIF_BRAND_HEIC)) {
isHeic = true;
+ } else if (Arrays.equals(brand, HEIF_BRAND_AVIF)
+ || Arrays.equals(brand, HEIF_BRAND_AVIS)) {
+ isAvif = true;
}
- if (isMif1 && isHeic) {
+ if (isMif1 && (isHeic || isAvif)) {
return true;
}
}
diff --git a/media/java/android/media/ThumbnailUtils.java b/media/java/android/media/ThumbnailUtils.java
index fbf38dc..e6d95eb6 100644
--- a/media/java/android/media/ThumbnailUtils.java
+++ b/media/java/android/media/ThumbnailUtils.java
@@ -272,7 +272,8 @@
if (mimeType.equals("image/heif")
|| mimeType.equals("image/heif-sequence")
|| mimeType.equals("image/heic")
- || mimeType.equals("image/heic-sequence")) {
+ || mimeType.equals("image/heic-sequence")
+ || mimeType.equals("image/avif")) {
try (MediaMetadataRetriever retriever = new MediaMetadataRetriever()) {
retriever.setDataSource(file.getAbsolutePath());
bitmap = retriever.getThumbnailImageAtIndex(-1,
diff --git a/media/java/android/media/soundtrigger/SoundTriggerManager.java b/media/java/android/media/soundtrigger/SoundTriggerManager.java
index 00e3bce..f60c708 100644
--- a/media/java/android/media/soundtrigger/SoundTriggerManager.java
+++ b/media/java/android/media/soundtrigger/SoundTriggerManager.java
@@ -41,6 +41,7 @@
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
+import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.provider.Settings;
@@ -69,6 +70,7 @@
private final Context mContext;
private final ISoundTriggerSession mSoundTriggerSession;
+ private final IBinder mBinderToken = new Binder();
// Stores a mapping from the sound model UUID to the SoundTriggerInstance created by
// the createSoundTriggerDetector() call.
@@ -90,7 +92,8 @@
originatorIdentity.packageName = ActivityThread.currentOpPackageName();
try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
- mSoundTriggerSession = soundTriggerService.attachAsOriginator(originatorIdentity);
+ mSoundTriggerSession = soundTriggerService.attachAsOriginator(originatorIdentity,
+ mBinderToken);
}
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index aa3143f..97161e5 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -61,6 +61,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -369,6 +370,28 @@
mTunerResourceManager.setFrontendInfoList(infos);
}
+ /**
+ * Get frontend info list from native and build them into a {@link FrontendInfo} list. Any
+ * {@code null} FrontendInfo element would be removed.
+ */
+ private FrontendInfo[] getFrontendInfoListInternal() {
+ List<Integer> ids = getFrontendIds();
+ if (ids == null) {
+ return null;
+ }
+ FrontendInfo[] infos = new FrontendInfo[ids.size()];
+ for (int i = 0; i < ids.size(); i++) {
+ int id = ids.get(i);
+ FrontendInfo frontendInfo = getFrontendInfoById(id);
+ if (frontendInfo == null) {
+ Log.e(TAG, "Failed to get a FrontendInfo on frontend id:" + id + "!");
+ continue;
+ }
+ infos[i] = frontendInfo;
+ }
+ return Arrays.stream(infos).filter(Objects::nonNull).toArray(FrontendInfo[]::new);
+ }
+
/** @hide */
public static int getTunerVersion() {
return sTunerVersion;
@@ -932,7 +955,7 @@
}
/**
- * Gets the frontend information.
+ * Gets the initialized frontend information.
*
* @return The frontend information. {@code null} if the operation failed.
*/
@@ -950,6 +973,16 @@
return mFrontendInfo;
}
+ /**
+ * Get a list all the existed frontend information.
+ *
+ * @return The list of all the frontend information. {@code null} if the operation failed.
+ */
+ @Nullable
+ public List<FrontendInfo> getFrontendInfoList() {
+ return Arrays.asList(getFrontendInfoListInternal());
+ }
+
/** @hide */
public FrontendInfo getFrontendInfoById(int id) {
return nativeGetFrontendInfo(id);
diff --git a/media/java/android/media/tv/tuner/filter/Filter.java b/media/java/android/media/tv/tuner/filter/Filter.java
index 2f2d8f7..82cc78d 100644
--- a/media/java/android/media/tv/tuner/filter/Filter.java
+++ b/media/java/android/media/tv/tuner/filter/Filter.java
@@ -25,6 +25,7 @@
import android.media.tv.tuner.Tuner;
import android.media.tv.tuner.Tuner.Result;
import android.media.tv.tuner.TunerUtils;
+import android.media.tv.tuner.TunerVersionChecker;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -148,7 +149,6 @@
public static final int SUBTYPE_PTP = 16;
-
/** @hide */
@IntDef(flag = true, prefix = "STATUS_", value = {STATUS_DATA_READY, STATUS_LOW_WATER,
STATUS_HIGH_WATER, STATUS_OVERFLOW})
@@ -180,6 +180,31 @@
*/
public static final int STATUS_OVERFLOW = Constants.DemuxFilterStatus.OVERFLOW;
+ /** @hide */
+ @IntDef(flag = true,
+ prefix = "SCRAMBLING_STATUS_",
+ value = {SCRAMBLING_STATUS_UNKNOWN, SCRAMBLING_STATUS_NOT_SCRAMBLED,
+ SCRAMBLING_STATUS_SCRAMBLED})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ScramblingStatusMask {}
+
+ /**
+ * Content’s scrambling status is unknown
+ */
+ public static final int SCRAMBLING_STATUS_UNKNOWN =
+ android.hardware.tv.tuner.V1_1.Constants.ScramblingStatus.UNKNOWN;
+ /**
+ * Content is not scrambled.
+ */
+ public static final int SCRAMBLING_STATUS_NOT_SCRAMBLED =
+ android.hardware.tv.tuner.V1_1.Constants.ScramblingStatus.NOT_SCRAMBLED;
+ /**
+ * Content is scrambled.
+ */
+ public static final int SCRAMBLING_STATUS_SCRAMBLED =
+ android.hardware.tv.tuner.V1_1.Constants.ScramblingStatus.SCRAMBLED;
+
+
private static final String TAG = "Filter";
private long mNativeContext;
@@ -197,6 +222,7 @@
int type, int subType, FilterConfiguration settings);
private native int nativeGetId();
private native long nativeGetId64Bit();
+ private native int nativeconfigureScramblingEvent(int scramblingStatusMask);
private native int nativeSetDataSource(Filter source);
private native int nativeStartFilter();
private native int nativeStopFilter();
@@ -280,6 +306,38 @@
}
/**
+ * Configure the Filter to monitor specific Scrambling Status through
+ * {@link ScramblingStatusEvent}.
+ *
+ * <p>{@link ScramblingStatusEvent} should be sent at the following two scenarios:
+ *
+ * <ul>
+ * <li>When this method is called, the first detected scrambling status should be sent.
+ * <li>When the filter transits into the monitored statuses configured in
+ * {@code scramblingStatusMask}, event should be sent.
+ * <ul/>
+ *
+ * <p>This configuration is only supported in Tuner 1.1 or higher version. Unsupported version
+ * will cause no-op. Use {@link TunerVersionChecker.getTunerVersion()} to get the version
+ * information.
+ *
+ * @param scramblingStatusMask Scrambling Statuses to be monitored. Set corresponding bit to
+ * monitor it. Reset to stop monitoring.
+ * @return result status of the operation.
+ */
+ @Result
+ public int configureScramblingStatusEvent(@ScramblingStatusMask int scramblingStatusMask) {
+ synchronized (mLock) {
+ TunerUtils.checkResourceState(TAG, mIsClosed);
+ if (!TunerVersionChecker.checkHigherOrEqualVersionTo(
+ TunerVersionChecker.TUNER_VERSION_1_1, "configureScramblingStatusEvent")) {
+ return Tuner.RESULT_UNAVAILABLE;
+ }
+ return nativeconfigureScramblingEvent(scramblingStatusMask);
+ }
+ }
+
+ /**
* Sets the filter's data source.
*
* A filter uses demux as data source by default. If the data was packetized
diff --git a/media/java/android/media/tv/tuner/filter/MmtpRecordEvent.java b/media/java/android/media/tv/tuner/filter/MmtpRecordEvent.java
index 1031e33..1bbd6e3 100644
--- a/media/java/android/media/tv/tuner/filter/MmtpRecordEvent.java
+++ b/media/java/android/media/tv/tuner/filter/MmtpRecordEvent.java
@@ -94,7 +94,7 @@
* {@link android.media.tv.tuner.TunerVersionChecker.getTunerVersion()} to get the version
* information.
*/
- public int getFirstMbInSlice() {
+ public int getFirstMacroblockInSlice() {
return mFirstMbInSlice;
}
diff --git a/media/java/android/media/tv/tuner/filter/ScramblingStatusEvent.java b/media/java/android/media/tv/tuner/filter/ScramblingStatusEvent.java
new file mode 100644
index 0000000..a78b96e
--- /dev/null
+++ b/media/java/android/media/tv/tuner/filter/ScramblingStatusEvent.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2020 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.media.tv.tuner.filter;
+
+import android.annotation.SystemApi;
+
+/**
+ * Scrambling Status event sent from {@link Filter} objects with Scrambling Status type.
+ *
+ * <p>This event is only sent in Tuner 1.1 or higher version. Use
+ * {@link TunerVersionChecker.getTunerVersion()} to get the version information.
+ *
+ * @hide
+ */
+@SystemApi
+public final class ScramblingStatusEvent extends FilterEvent {
+ private final int mScramblingStatus;
+
+ private ScramblingStatusEvent(@Filter.ScramblingStatusMask int scramblingStatus) {
+ mScramblingStatus = scramblingStatus;
+ }
+
+ /**
+ * Gets Scrambling Status Type.
+ *
+ * <p>This event field is only sent in Tuner 1.1 or higher version. Unsupported version returns
+ * default value 0. Use {@link TunerVersionChecker.getTunerVersion()} to get the version
+ * information.
+ */
+ @Filter.ScramblingStatusMask
+ public int getScramblingStatus() {
+ return mScramblingStatus;
+ }
+}
diff --git a/media/java/android/media/tv/tuner/filter/TsRecordEvent.java b/media/java/android/media/tv/tuner/filter/TsRecordEvent.java
index 6ea3bf8..2816199 100644
--- a/media/java/android/media/tv/tuner/filter/TsRecordEvent.java
+++ b/media/java/android/media/tv/tuner/filter/TsRecordEvent.java
@@ -99,7 +99,7 @@
* {@link android.media.tv.tuner.TunerVersionChecker.getTunerVersion()} to get the version
* information.
*/
- public int getFirstMbInSlice() {
+ public int getFirstMacroblockInSlice() {
return mFirstMbInSlice;
}
}
diff --git a/media/java/android/media/tv/tuner/frontend/FrontendInfo.java b/media/java/android/media/tv/tuner/frontend/FrontendInfo.java
index 68c0c96..f3e9476 100644
--- a/media/java/android/media/tv/tuner/frontend/FrontendInfo.java
+++ b/media/java/android/media/tv/tuner/frontend/FrontendInfo.java
@@ -22,6 +22,9 @@
import android.media.tv.tuner.frontend.FrontendStatus.FrontendStatusType;
import android.util.Range;
+import java.util.Arrays;
+import java.util.Objects;
+
/**
* This class is used to specify meta information of a frontend.
*
@@ -118,4 +121,30 @@
public FrontendCapabilities getFrontendCapabilities() {
return mFrontendCap;
}
+
+
+ /** @hide */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || !(o instanceof FrontendInfo)) {
+ return false;
+ }
+ // TODO: compare FrontendCapabilities
+ FrontendInfo info = (FrontendInfo) o;
+ return mId == info.getId() && mType == info.getType()
+ && Objects.equals(mFrequencyRange, info.getFrequencyRange())
+ && Objects.equals(mSymbolRateRange, info.getSymbolRateRange())
+ && mAcquireRange == info.getAcquireRange()
+ && mExclusiveGroupId == info.getExclusiveGroupId()
+ && Arrays.equals(mStatusCaps, info.getStatusCapabilities());
+ }
+
+ /** @hide */
+ @Override
+ public int hashCode() {
+ return mId;
+ }
}
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 2541750..b9e7848 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -4024,6 +4024,28 @@
::android::hardware::tv::tuner::V1_1::Constant64Bit::INVALID_FILTER_ID_64BIT);
}
+static jint android_media_tv_Tuner_configure_scrambling_status_event(
+ JNIEnv* env, jobject filter, int scramblingStatusMask) {
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ if (iFilterSp == NULL) {
+ ALOGD("Failed to configure scrambling event: filter not found");
+ return (jint) Result::NOT_INITIALIZED;
+ }
+
+ sp<::android::hardware::tv::tuner::V1_1::IFilter> iFilterSp_1_1;
+ iFilterSp_1_1 = ::android::hardware::tv::tuner::V1_1::IFilter::castFrom(iFilterSp);
+ Result res;
+
+ if (iFilterSp_1_1 != NULL) {
+ res = iFilterSp_1_1->configureScramblingEvent(scramblingStatusMask);
+ } else {
+ ALOGW("configureScramblingEvent is not supported with the current HAL implementation.");
+ return (jint) Result::INVALID_STATE;
+ }
+
+ return (jint) res;
+}
+
static jint android_media_tv_Tuner_set_filter_data_source(
JNIEnv* env, jobject filter, jobject srcFilter) {
sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
@@ -4695,6 +4717,8 @@
{ "nativeGetId", "()I", (void *)android_media_tv_Tuner_get_filter_id },
{ "nativeGetId64Bit", "()J",
(void *)android_media_tv_Tuner_get_filter_64bit_id },
+ { "nativeconfigureScramblingEvent", "(I)I",
+ (void *)android_media_tv_Tuner_configure_scrambling_status_event },
{ "nativeSetDataSource", "(Landroid/media/tv/tuner/filter/Filter;)I",
(void *)android_media_tv_Tuner_set_filter_data_source },
{ "nativeStartFilter", "()I", (void *)android_media_tv_Tuner_start_filter },
diff --git a/packages/CarSystemUI/Android.bp b/packages/CarSystemUI/Android.bp
deleted file mode 100644
index 08dd799..0000000
--- a/packages/CarSystemUI/Android.bp
+++ /dev/null
@@ -1,165 +0,0 @@
-//
-// Copyright (C) 2018 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.
-//
-android_library {
- name: "CarSystemUI-core",
-
- srcs: [
- "src/**/*.java",
- "src/**/I*.aidl",
- ],
-
- resource_dirs: [
- "res-keyguard",
- "res",
- ],
-
- static_libs: [
- "SystemUI-core",
- "CarNotificationLib",
- "SystemUIPluginLib",
- "SystemUISharedLib",
- "SettingsLib",
- "car-ui-lib",
- "android.car.userlib",
- "androidx.legacy_legacy-support-v4",
- "androidx.recyclerview_recyclerview",
- "androidx.preference_preference",
- "androidx.appcompat_appcompat",
- "androidx.mediarouter_mediarouter",
- "androidx.palette_palette",
- "androidx.legacy_legacy-preference-v14",
- "androidx.leanback_leanback",
- "androidx.slice_slice-core",
- "androidx.slice_slice-view",
- "androidx.slice_slice-builders",
- "androidx.arch.core_core-runtime",
- "androidx.lifecycle_lifecycle-extensions",
- "SystemUI-tags",
- "SystemUI-proto",
- "dagger2",
- "//external/kotlinc:kotlin-annotations",
- ],
-
- libs: [
- "android.car",
- ],
-
- manifest: "AndroidManifest.xml",
-
- plugins: ["dagger2-compiler"],
-
-}
-
-android_library {
- name: "CarSystemUI-tests",
- manifest: "tests/AndroidManifest.xml",
- resource_dirs: [
- "tests/res",
- "res-keyguard",
- "res",
- ],
- srcs: [
- "tests/src/**/*.java",
- "src/**/*.java",
- "src/**/I*.aidl",
- ],
- static_libs: [
- "SystemUI-tests",
- "CarNotificationLib",
- "SystemUIPluginLib",
- "SystemUISharedLib",
- "SettingsLib",
- "android.car.userlib",
- "androidx.legacy_legacy-support-v4",
- "androidx.recyclerview_recyclerview",
- "androidx.preference_preference",
- "androidx.appcompat_appcompat",
- "androidx.mediarouter_mediarouter",
- "androidx.palette_palette",
- "androidx.legacy_legacy-preference-v14",
- "androidx.leanback_leanback",
- "androidx.slice_slice-core",
- "androidx.slice_slice-view",
- "androidx.slice_slice-builders",
- "androidx.arch.core_core-runtime",
- "androidx.lifecycle_lifecycle-extensions",
- "car-ui-lib",
- "SystemUI-tags",
- "SystemUI-proto",
- "metrics-helper-lib",
- "androidx.test.rules", "hamcrest-library",
- "mockito-target-inline-minus-junit4",
- "testables",
- "truth-prebuilt",
- "dagger2",
- "//external/kotlinc:kotlin-annotations",
- ],
- libs: [
- "android.test.runner",
- "android.test.base",
- "android.car",
- ],
-
- aaptflags: [
- "--extra-packages",
- "com.android.systemui",
- ],
-
- plugins: ["dagger2-compiler"],
-}
-
-android_app {
- name: "CarSystemUI",
-
- static_libs: [
- "CarSystemUI-core",
- ],
-
- export_package_resources: true,
-
- libs: [
- "android.car",
- ],
-
- resource_dirs: [],
-
- overrides: [
- "SystemUI",
- ],
-
- platform_apis: true,
- system_ext_specific: true,
- certificate: "platform",
- privileged: true,
-
- optimize: {
- proguard_flags_files: [
- "proguard.flags",
- ],
- },
- dxflags: ["--multi-dex"],
-
- aaptflags: [
- "--extra-packages",
- "com.android.keyguard",
- ],
-
- kotlincflags: ["-Xjvm-default=enable"],
-
- plugins: ["dagger2-compiler"],
-
- required: ["privapp_whitelist_com.android.systemui"],
-}
diff --git a/packages/CarSystemUI/AndroidManifest.xml b/packages/CarSystemUI/AndroidManifest.xml
deleted file mode 100644
index f0cf2a9..0000000
--- a/packages/CarSystemUI/AndroidManifest.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- package="com.android.systemui"
- android:sharedUserId="android.uid.systemui"
- coreApp="true">
- <!-- This permission is required to monitor car power state. -->
- <uses-permission android:name="android.car.permission.CAR_POWER" />
- <!-- This permission is required to get the trusted device list of a user. -->
- <uses-permission android:name="android.car.permission.CAR_ENROLL_TRUST"/>
- <!-- This permission is required to monitor gear state. -->
- <uses-permission android:name="android.car.permission.CAR_POWERTRAIN" />
- <!-- This permission is required to get bluetooth broadcast. -->
- <uses-permission android:name="android.permission.BLUETOOTH" />
- <!-- These permissions are required to implement icons based on role holders. -->
- <uses-permission android:name="android.permission.OBSERVE_ROLE_HOLDERS"/>
- <uses-permission android:name="android.permission.MANAGE_ROLE_HOLDERS"/>
- <!-- This permission is required to access app information from other users. -->
- <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"/>
- <!-- This permission is required to check the foreground user id. -->
- <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
-</manifest>
diff --git a/packages/CarSystemUI/CleanSpec.mk b/packages/CarSystemUI/CleanSpec.mk
deleted file mode 100644
index ceac67c..0000000
--- a/packages/CarSystemUI/CleanSpec.mk
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (C) 2019 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.
-#
-
-# If you don't need to do a full clean build but would like to touch
-# a file or delete some intermediate files, add a clean step to the end
-# of the list. These steps will only be run once, if they haven't been
-# run before.
-#
-# E.g.:
-# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
-# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
-#
-# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
-# files that are missing or have been moved.
-#
-# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
-# Use $(OUT_DIR) to refer to the "out" directory.
-#
-# If you need to re-do something that's already mentioned, just copy
-# the command and add it to the bottom of the list. E.g., if a change
-# that you made last week required touching a file and a change you
-# made today requires touching the same file, just copy the old
-# touch step and add it to the end of the list.
-#
-# *****************************************************************
-# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THE BANNER
-# *****************************************************************
-
-# For example:
-#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
-#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
-#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
-#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
-$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product/priv-app/CarSystemUI)
-$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product/priv-app/CarSystemUI)
-# ******************************************************************
-# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
-# ******************************************************************
diff --git a/packages/CarSystemUI/TEST_MAPPING b/packages/CarSystemUI/TEST_MAPPING
deleted file mode 100644
index 54afb90..0000000
--- a/packages/CarSystemUI/TEST_MAPPING
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "auto-end-to-end-presubmit": [
- {
- "name": "AndroidAutoUiTests",
- "options" : [
- {
- "include-filter": "android.test.functional.auto.apps.HomeHelperTest"
- }
- ]
- }
- ],
- "auto-end-to-end-postsubmit": [
- {
- "name": "AndroidAutoUiTests",
- "options" : [
- {
- "include-filter": "android.test.functional.auto.apps.NotificationHelperTest"
- }
- ]
- }
- ],
- "carsysui-presubmit": [
- {
- "name": "CarSystemUITests",
- "options" : [
- {
- "include-annotation": "com.android.systemui.car.CarSystemUiTest"
- }
- ]
- }
- ]
-}
diff --git a/packages/CarSystemUI/proguard.flags b/packages/CarSystemUI/proguard.flags
deleted file mode 100644
index f0b20c1..0000000
--- a/packages/CarSystemUI/proguard.flags
+++ /dev/null
@@ -1,7 +0,0 @@
--keep class com.android.systemui.CarSystemUIFactory
--keep class com.android.car.notification.headsup.animationhelper.**
-
--keep class com.android.systemui.DaggerCarGlobalRootComponent { *; }
--keep class com.android.systemui.DaggerCarGlobalRootComponent$CarSysUIComponentImpl { *; }
-
--include ../SystemUI/proguard.flags
diff --git a/packages/CarSystemUI/res-keyguard/drawable/ic_backspace.xml b/packages/CarSystemUI/res-keyguard/drawable/ic_backspace.xml
deleted file mode 100644
index f3a2f0f..0000000
--- a/packages/CarSystemUI/res-keyguard/drawable/ic_backspace.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2018, The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License")
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="36dp"
- android:height="36dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#FF000000"
- android:pathData="M9,15.59L12.59,12L9,8.41L10.41,7L14,10.59L17.59,7L19,8.41L15.41,12L19,15.59L17.59,17L14,13.41L10.41,17L9,15.59zM21,6H8l-4.5,6L8,18h13V6M21,4c1.1,0 2,0.9 2,2v12c0,1.1 -0.9,2 -2,2H8c-0.63,0 -1.22,-0.3 -1.6,-0.8L1,12l5.4,-7.2C6.78,4.3 7.37,4 8,4H21L21,4z"/>
-</vector>
diff --git a/packages/CarSystemUI/res-keyguard/drawable/ic_done.xml b/packages/CarSystemUI/res-keyguard/drawable/ic_done.xml
deleted file mode 100644
index ef0aac2..0000000
--- a/packages/CarSystemUI/res-keyguard/drawable/ic_done.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2018, The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License")
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="36dp"
- android:height="36dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#FF000000"
- android:pathData="M9,16.2l-3.5,-3.5a0.984,0.984 0,0 0,-1.4 0,0.984 0.984,0 0,0 0,1.4l4.19,4.19c0.39,0.39 1.02,0.39 1.41,0L20.3,7.7a0.984,0.984 0,0 0,0 -1.4,0.984 0.984,0 0,0 -1.4,0L9,16.2z"/>
-</vector>
diff --git a/packages/CarSystemUI/res-keyguard/drawable/keyguard_button_background.xml b/packages/CarSystemUI/res-keyguard/drawable/keyguard_button_background.xml
deleted file mode 100644
index 8b2779d..0000000
--- a/packages/CarSystemUI/res-keyguard/drawable/keyguard_button_background.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2018, 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true">
- <shape android:shape="rectangle">
- <corners android:radius="@*android:dimen/car_button_radius"/>
- <solid android:color="#131315"/>
- </shape>
- </item>
- <item>
- <shape android:shape="rectangle">
- <corners android:radius="@*android:dimen/car_button_radius"/>
- <solid android:color="@color/button_background"/>
- </shape>
- </item>
-</selector>
diff --git a/packages/CarSystemUI/res-keyguard/layout-land/keyguard_pattern_view.xml b/packages/CarSystemUI/res-keyguard/layout-land/keyguard_pattern_view.xml
deleted file mode 100644
index a465254..0000000
--- a/packages/CarSystemUI/res-keyguard/layout-land/keyguard_pattern_view.xml
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2018, 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.
-*/
--->
-
-<!-- Car customizations
- - Added title "Enter your Pattern" at the top
- - Hid the emergency call at the bottom
--->
-
-<com.android.keyguard.KeyguardPatternView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/keyguard_pattern_view"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingHorizontal="@*android:dimen/car_margin">
-
- <FrameLayout
- android:layout_height="match_parent"
- android:layout_width="0dp"
- android:layout_weight="1">
-
- <com.android.internal.widget.LockPatternView
- android:id="@+id/lockPatternView"
- android:layout_width="@dimen/keyguard_pattern_dimension"
- android:layout_height="@dimen/keyguard_pattern_dimension"
- android:layout_gravity="center"/>
- </FrameLayout>
-
- <LinearLayout
- android:id="@+id/container"
- android:layout_height="match_parent"
- android:layout_width="0dp"
- android:layout_weight="1"
- android:orientation="vertical"
- android:gravity="center_vertical">
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_margin="@*android:dimen/car_padding_2"
- android:gravity="center"
- android:textColor="@android:color/white"
- android:textSize="@*android:dimen/car_body1_size"
- android:text="@string/keyguard_enter_your_pattern" />
-
- <include layout="@layout/keyguard_message_area" />
-
- <Button
- android:id="@+id/cancel_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- style="@style/KeyguardButton"
- android:text="@string/cancel"/>
-
- <include layout="@layout/keyguard_eca"
- android:id="@+id/keyguard_selector_fade_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:layout_gravity="bottom|center_horizontal"
- android:gravity="center_horizontal"
- android:visibility="gone" />
- </LinearLayout>
-
-</com.android.keyguard.KeyguardPatternView>
diff --git a/packages/CarSystemUI/res-keyguard/layout-land/keyguard_pin_view.xml b/packages/CarSystemUI/res-keyguard/layout-land/keyguard_pin_view.xml
deleted file mode 100644
index 5746102..0000000
--- a/packages/CarSystemUI/res-keyguard/layout-land/keyguard_pin_view.xml
+++ /dev/null
@@ -1,126 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2018, 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.
--->
-
-<!-- Car customizations
- - Added title "Enter your PIN" under the entry field
- - Put backspace and enter buttons in row 4
- - PIN pad is on start side while entry field and title are on the end side
- - Hid the emergency call at the bottom
--->
-
-<com.android.keyguard.KeyguardPINView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/keyguard_pin_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal"
- android:paddingHorizontal="@*android:dimen/car_margin">
-
- <FrameLayout
- android:layout_width="0dp"
- android:layout_weight="1"
- android:layout_height="match_parent">
-
- <GridLayout
- android:id="@+id/container"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:gravity="center"
- android:columnCount="3">
-
- <include layout="@layout/num_pad_keys"/>
- </GridLayout>
- </FrameLayout>
-
- <LinearLayout
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:gravity="center"
- android:orientation="vertical">
-
- <com.android.keyguard.PasswordTextView
- android:id="@+id/pinEntry"
- android:layout_width="@dimen/keyguard_security_width"
- android:layout_height="@dimen/pin_entry_height"
- android:gravity="center"
- app:scaledTextSize="@integer/password_text_view_scale"
- android:contentDescription="@string/keyguard_accessibility_pin_area" />
-
- <View
- android:id="@+id/divider"
- android:layout_width="@dimen/keyguard_security_width"
- android:layout_height="@dimen/divider_height"
- android:background="@android:color/white" />
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="@*android:dimen/car_padding_2"
- android:gravity="center"
- android:textColor="@android:color/white"
- android:textSize="@*android:dimen/car_body1_size"
- android:text="@string/keyguard_enter_your_pin" />
-
- <include layout="@layout/keyguard_message_area" />
-
- <Button
- android:id="@+id/cancel_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- style="@style/KeyguardButton"
- android:text="@string/cancel"/>
- </LinearLayout>
-
- <!-- KeyguardPinView references these resources ids in code so removing them will cause the
- keyguard to crash. Instead put them down here where they are out of the way and set their
- visibility to gone. -->
- <com.android.keyguard.AlphaOptimizedRelativeLayout
- android:id="@+id/row0"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:visibility="gone" />
- <LinearLayout
- android:id="@+id/row1"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:visibility="gone" />
- <LinearLayout
- android:id="@+id/row2"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:visibility="gone" />
- <LinearLayout
- android:id="@+id/row3"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:visibility="gone" />
- <LinearLayout
- android:id="@+id/row4"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:visibility="gone" />
-
- <include layout="@layout/keyguard_eca"
- android:id="@+id/keyguard_selector_fade_container"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:visibility="gone" />
-</com.android.keyguard.KeyguardPINView>
diff --git a/packages/CarSystemUI/res-keyguard/layout/keyguard_bouncer.xml b/packages/CarSystemUI/res-keyguard/layout/keyguard_bouncer.xml
deleted file mode 100644
index d105e44..0000000
--- a/packages/CarSystemUI/res-keyguard/layout/keyguard_bouncer.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2018 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
- -->
-
-<!-- Car customizations
- Car has solid black background instead of a transparent one
--->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@android:color/black"
- android:fitsSystemWindows="true">
-
- <include
- style="@style/BouncerSecurityContainer"
- layout="@layout/keyguard_host_view"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-</FrameLayout>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res-keyguard/layout/keyguard_container.xml b/packages/CarSystemUI/res-keyguard/layout/keyguard_container.xml
deleted file mode 100644
index 3e35df9..0000000
--- a/packages/CarSystemUI/res-keyguard/layout/keyguard_container.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2020 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.
- -->
-
-<!-- Car customizations
- Car has solid black background instead of a transparent one
--->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/keyguard_container"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center"/>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res-keyguard/layout/keyguard_message_area.xml b/packages/CarSystemUI/res-keyguard/layout/keyguard_message_area.xml
deleted file mode 100644
index 09cf472..0000000
--- a/packages/CarSystemUI/res-keyguard/layout/keyguard_message_area.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2018, 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.
-*/
--->
-
-<com.android.keyguard.KeyguardMessageArea
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- style="@style/Keyguard.TextView"
- android:id="@+id/keyguard_message_area"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:focusable="true"
- android:layout_marginBottom="@*android:dimen/car_padding_4"
- android:textSize="@*android:dimen/car_body2_size" />
diff --git a/packages/CarSystemUI/res-keyguard/layout/keyguard_num_pad_key.xml b/packages/CarSystemUI/res-keyguard/layout/keyguard_num_pad_key.xml
deleted file mode 100644
index c7eda38..0000000
--- a/packages/CarSystemUI/res-keyguard/layout/keyguard_num_pad_key.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2018 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
- -->
-
-<!-- Car customizations
- The mnemonics is not shown for car but KeyguardPinView references the resource id in code.
- Removing it will cause the keyguard to crash. Hide them instead
--->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <TextView
- android:id="@+id/digit_text"
- style="@style/Widget.TextView.NumPadKey"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
- <!-- The mnemonics is not shown for car but KeyguardPinView references the resource id in code.
- Removing it will cause the keyguard to crash. Hide them instead -->
- <TextView
- android:id="@+id/klondike_text"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:visibility="gone"
- />
-</merge>
-
diff --git a/packages/CarSystemUI/res-keyguard/layout/keyguard_password_view.xml b/packages/CarSystemUI/res-keyguard/layout/keyguard_password_view.xml
deleted file mode 100644
index d57875f..0000000
--- a/packages/CarSystemUI/res-keyguard/layout/keyguard_password_view.xml
+++ /dev/null
@@ -1,102 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2018, 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.
-*/
--->
-
-<!-- Car customizations
- - Added title "Enter your Password" below the password field
- - Hid the emergency call at the bottom
--->
-
-<com.android.keyguard.KeyguardPasswordView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/res-auto"
- android:id="@+id/keyguard_password_view"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center">
-
- <include layout="@layout/keyguard_message_area" />
-
- <!-- Password entry field -->
- <LinearLayout
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_gravity="center_horizontal"
- android:orientation="vertical"
- android:theme="?attr/passwordStyle">
-
- <EditText
- android:id="@+id/passwordEntry"
- android:layout_width="@dimen/password_field_width"
- android:layout_height="wrap_content"
- android:gravity="center_horizontal"
- android:singleLine="true"
- android:textStyle="normal"
- android:inputType="textPassword"
- android:textSize="@*android:dimen/car_body1_size"
- android:textColor="?attr/wallpaperTextColor"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:imeOptions="flagForceAscii|actionDone"
- android:maxLength="@integer/password_max_length"
- />
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_margin="@*android:dimen/car_padding_2"
- android:gravity="center"
- android:textColor="@android:color/white"
- android:textSize="@*android:dimen/car_body1_size"
- android:text="@string/keyguard_enter_your_password" />
-
- <Button
- android:id="@+id/cancel_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- style="@style/KeyguardButton"
- android:text="@string/cancel"/>
-
- <ImageView android:id="@+id/switch_ime_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="12dp"
- android:src="@drawable/ic_lockscreen_ime"
- android:contentDescription="@string/accessibility_ime_switch_button"
- android:clickable="true"
- android:padding="8dp"
- android:tint="@color/background_protected"
- android:layout_gravity="end|center_vertical"
- android:background="?android:attr/selectableItemBackground"
- android:visibility="gone"
- />
- </LinearLayout>
-
- <include layout="@layout/keyguard_eca"
- android:id="@+id/keyguard_selector_fade_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="12dp"
- android:orientation="vertical"
- android:layout_gravity="bottom|center_horizontal"
- android:gravity="center_horizontal"
- android:visibility="gone"
- />
-
-</com.android.keyguard.KeyguardPasswordView>
diff --git a/packages/CarSystemUI/res-keyguard/layout/keyguard_pattern_view.xml b/packages/CarSystemUI/res-keyguard/layout/keyguard_pattern_view.xml
deleted file mode 100644
index bb69d44..0000000
--- a/packages/CarSystemUI/res-keyguard/layout/keyguard_pattern_view.xml
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2018, 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.
-*/
--->
-
-<!-- Car customizations
- - Added title "Enter your Pattern" at the top
- - Hid the emergency call at the bottom
--->
-
-<com.android.keyguard.KeyguardPatternView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/res-auto"
- android:id="@+id/keyguard_pattern_view"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- androidprv:layout_maxWidth="@dimen/keyguard_security_width"
- android:gravity="center_horizontal">
-
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <LinearLayout
- android:id="@+id/container"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:orientation="vertical"
- android:layout_gravity="center">
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_margin="@*android:dimen/car_padding_2"
- android:gravity="center"
- android:textColor="@android:color/white"
- android:textSize="@*android:dimen/car_body1_size"
- android:text="@string/keyguard_enter_your_pattern" />
-
- <include layout="@layout/keyguard_message_area" />
-
- <com.android.internal.widget.LockPatternView
- android:id="@+id/lockPatternView"
- android:layout_width="@dimen/keyguard_pattern_dimension"
- android:layout_height="@dimen/keyguard_pattern_dimension"
- android:layout_marginVertical="@dimen/pin_pattern_pad_margin_vertical"
- android:layout_gravity="center_horizontal"
- android:gravity="center" />
-
- <Button
- android:id="@+id/cancel_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- style="@style/KeyguardButton"
- android:text="@string/cancel"/>
-
- <include layout="@layout/keyguard_eca"
- android:id="@+id/keyguard_selector_fade_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:layout_gravity="bottom|center_horizontal"
- android:gravity="center_horizontal"
- android:visibility="gone" />
- </LinearLayout>
- </FrameLayout>
-
-</com.android.keyguard.KeyguardPatternView>
diff --git a/packages/CarSystemUI/res-keyguard/layout/keyguard_pin_view.xml b/packages/CarSystemUI/res-keyguard/layout/keyguard_pin_view.xml
deleted file mode 100644
index 815e67d..0000000
--- a/packages/CarSystemUI/res-keyguard/layout/keyguard_pin_view.xml
+++ /dev/null
@@ -1,127 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2018, 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.
--->
-
-<!-- Car customizations
- - Added title "Enter your PIN" under the entry field
- - Put backspace and enter buttons in row 4
- - Hid the emergency call at the bottom
--->
-
-<com.android.keyguard.KeyguardPINView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/keyguard_pin_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginLeft="@dimen/num_pad_margin_left"
- android:layout_marginRight="@dimen/num_pad_margin_right"
- android:orientation="vertical"
- android:gravity="center">
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:orientation="vertical">
-
- <com.android.keyguard.PasswordTextView
- android:id="@+id/pinEntry"
- android:layout_width="@dimen/keyguard_security_width"
- android:layout_height="@dimen/pin_entry_height"
- android:gravity="center"
- app:scaledTextSize="@integer/password_text_view_scale"
- android:contentDescription="@string/keyguard_accessibility_pin_area" />
-
- <View
- android:id="@+id/divider"
- android:layout_width="@dimen/keyguard_security_width"
- android:layout_height="@dimen/divider_height"
- android:background="@android:color/white" />
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="@*android:dimen/car_padding_2"
- android:gravity="center"
- android:textColor="@android:color/white"
- android:textSize="@*android:dimen/car_body1_size"
- android:text="@string/keyguard_enter_your_pin" />
-
- <include layout="@layout/keyguard_message_area" />
-
- </LinearLayout>
-
- <GridLayout
- android:id="@+id/container"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginVertical="@dimen/pin_pattern_pad_margin_vertical"
- android:columnCount="3">
-
- <include layout="@layout/num_pad_keys"/>
- </GridLayout>
-
- <Button
- android:id="@+id/cancel_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- style="@style/KeyguardButton"
- android:text="@string/cancel"/>
-
- </LinearLayout>
-
- <!-- KeyguardPinView references these resources ids in code so removing them will cause the
- keyguard to crash. Instead put them down here where they are out of the way and set their
- visibility to gone. -->
- <com.android.keyguard.AlphaOptimizedRelativeLayout
- android:id="@+id/row0"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:visibility="gone" />
- <LinearLayout
- android:id="@+id/row1"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:visibility="gone" />
- <LinearLayout
- android:id="@+id/row2"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:visibility="gone" />
- <LinearLayout
- android:id="@+id/row3"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:visibility="gone" />
- <LinearLayout
- android:id="@+id/row4"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:visibility="gone" />
-
- <include
- layout="@layout/keyguard_eca"
- android:id="@+id/keyguard_selector_fade_container"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:visibility="gone" />
-</com.android.keyguard.KeyguardPINView>
diff --git a/packages/CarSystemUI/res-keyguard/layout/num_pad_keys.xml b/packages/CarSystemUI/res-keyguard/layout/num_pad_keys.xml
deleted file mode 100644
index 8306cb4..0000000
--- a/packages/CarSystemUI/res-keyguard/layout/num_pad_keys.xml
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2018 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
- -->
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto">
- <!-- Row 1 -->
- <com.android.keyguard.NumPadKey
- android:id="@+id/key1"
- style="@style/NumPadKeyButton"
- app:digit="1" />
- <com.android.keyguard.NumPadKey
- android:id="@+id/key2"
- style="@style/NumPadKeyButton.MiddleColumn"
- app:digit="2" />
- <com.android.keyguard.NumPadKey
- android:id="@+id/key3"
- style="@style/NumPadKeyButton"
- app:digit="3" />
-
- <!-- Row 2 -->
- <com.android.keyguard.NumPadKey
- android:id="@+id/key4"
- style="@style/NumPadKeyButton"
- app:digit="4" />
- <com.android.keyguard.NumPadKey
- android:id="@+id/key5"
- style="@style/NumPadKeyButton.MiddleColumn"
- app:digit="5" />
- <com.android.keyguard.NumPadKey
- android:id="@+id/key6"
- style="@style/NumPadKeyButton"
- app:digit="6" />
-
- <!-- Row 3 -->
- <com.android.keyguard.NumPadKey
- android:id="@+id/key7"
- style="@style/NumPadKeyButton"
- app:digit="7" />
- <com.android.keyguard.NumPadKey
- android:id="@+id/key8"
- style="@style/NumPadKeyButton.MiddleColumn"
- app:digit="8" />
- <com.android.keyguard.NumPadKey
- android:id="@+id/key9"
- style="@style/NumPadKeyButton"
- app:digit="9" />
-
- <!-- Row 4 -->
- <ImageButton
- android:id="@+id/delete_button"
- style="@style/NumPadKeyButton.LastRow"
- android:gravity="center_vertical"
- android:src="@drawable/ic_backspace"
- android:clickable="true"
- android:tint="@android:color/white"
- android:background="@drawable/ripple_drawable"
- android:contentDescription="@string/keyboardview_keycode_delete" />
- <com.android.keyguard.NumPadKey
- android:id="@+id/key0"
- style="@style/NumPadKeyButton.LastRow.MiddleColumn"
- app:digit="0" />
- <ImageButton
- android:id="@+id/key_enter"
- style="@style/NumPadKeyButton.LastRow"
- android:src="@drawable/ic_done"
- android:tint="@android:color/white"
- android:background="@drawable/ripple_drawable"
- android:contentDescription="@string/keyboardview_keycode_enter" />
-</merge>
-
diff --git a/packages/CarSystemUI/res-keyguard/values-h1000dp/dimens.xml b/packages/CarSystemUI/res-keyguard/values-h1000dp/dimens.xml
deleted file mode 100644
index d055efa..0000000
--- a/packages/CarSystemUI/res-keyguard/values-h1000dp/dimens.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2018, 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>
- <dimen name="pin_pattern_pad_margin_vertical">178dp</dimen>
-</resources>
diff --git a/packages/CarSystemUI/res-keyguard/values-land/dimens.xml b/packages/CarSystemUI/res-keyguard/values-land/dimens.xml
deleted file mode 100644
index c39e0e4..0000000
--- a/packages/CarSystemUI/res-keyguard/values-land/dimens.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2018, 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>
- <dimen name="num_pad_key_margin_horizontal">@*android:dimen/car_padding_5</dimen>
- <dimen name="num_pad_key_margin_bottom">@*android:dimen/car_padding_4</dimen>
-</resources>
diff --git a/packages/CarSystemUI/res-keyguard/values/colors.xml b/packages/CarSystemUI/res-keyguard/values/colors.xml
deleted file mode 100644
index ba9f060..0000000
--- a/packages/CarSystemUI/res-keyguard/values/colors.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2018, The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License")
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <color name="button_background">@*android:color/car_dark_blue_grey_600</color>
- <color name="button_text">@android:color/white</color>
-</resources>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res-keyguard/values/dimens.xml b/packages/CarSystemUI/res-keyguard/values/dimens.xml
deleted file mode 100644
index 8dfe171..0000000
--- a/packages/CarSystemUI/res-keyguard/values/dimens.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2017, 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>
- <dimen name="num_pad_margin_left">112dp</dimen>
- <dimen name="num_pad_margin_right">144dp</dimen>
- <dimen name="num_pad_key_width">80dp</dimen>
- <dimen name="num_pad_key_height">80dp</dimen>
- <dimen name="num_pad_key_margin_horizontal">@*android:dimen/car_padding_5</dimen>
- <dimen name="num_pad_key_margin_bottom">@*android:dimen/car_padding_5</dimen>
- <dimen name="pin_entry_height">@dimen/num_pad_key_height</dimen>
- <dimen name="divider_height">1dp</dimen>
- <dimen name="key_enter_margin_top">128dp</dimen>
- <dimen name="keyguard_pattern_dimension">400dp</dimen>
- <dimen name="password_field_width">350dp</dimen>
- <dimen name="pin_pattern_pad_margin_vertical">0dp</dimen>
-</resources>
diff --git a/packages/CarSystemUI/res-keyguard/values/integers.xml b/packages/CarSystemUI/res-keyguard/values/integers.xml
deleted file mode 100644
index bad1346..0000000
--- a/packages/CarSystemUI/res-keyguard/values/integers.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2017, 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>
- <integer name="password_text_view_scale">40</integer>
- <integer name="password_max_length">500</integer>
-</resources>
diff --git a/packages/CarSystemUI/res-keyguard/values/styles.xml b/packages/CarSystemUI/res-keyguard/values/styles.xml
deleted file mode 100644
index ecea30a..0000000
--- a/packages/CarSystemUI/res-keyguard/values/styles.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2017, 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 xmlns:android="http://schemas.android.com/apk/res/android">
-
- <!-- The style for the volume icons in the volume dialog. This style makes the icon scale to
- fit its container since auto wants the icon to be larger. The padding is added to make it
- so the icon does not press along the edges of the dialog. -->
- <style name="NumPadKeyButton">
- <item name="android:layout_width">@dimen/num_pad_key_width</item>
- <item name="android:layout_height">@dimen/num_pad_key_height</item>
- <item name="android:layout_marginBottom">@dimen/num_pad_key_margin_bottom</item>
- <item name="textView">@id/pinEntry</item>
- </style>
-
- <style name="NumPadKeyButton.MiddleColumn">
- <item name="android:layout_marginStart">@dimen/num_pad_key_margin_horizontal</item>
- <item name="android:layout_marginEnd">@dimen/num_pad_key_margin_horizontal</item>
- </style>
-
- <style name="NumPadKeyButton.LastRow">
- <item name="android:layout_marginBottom">0dp</item>
- </style>
-
- <style name="NumPadKeyButton.LastRow.MiddleColumn">
- <item name="android:layout_marginStart">@dimen/num_pad_key_margin_horizontal</item>
- <item name="android:layout_marginEnd">@dimen/num_pad_key_margin_horizontal</item>
- </style>
-
- <style name="KeyguardButton" parent="@android:style/Widget.DeviceDefault.Button">
- <item name="android:background">@drawable/keyguard_button_background</item>
- <item name="android:textColor">@color/button_text</item>
- <item name="android:textAllCaps">false</item>
- </style>
-
- <style name="Widget.TextView.NumPadKey" parent="@android:style/Widget.TextView">
- <!-- Only replaces the text size. -->
- <item name="android:textSize">@*android:dimen/car_body1_size</item>
- </style>
-</resources>
diff --git a/packages/CarSystemUI/res/anim/car_arrow_fade_in_rotate_down.xml b/packages/CarSystemUI/res/anim/car_arrow_fade_in_rotate_down.xml
deleted file mode 100644
index 74f38d4..0000000
--- a/packages/CarSystemUI/res/anim/car_arrow_fade_in_rotate_down.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2018, 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.
-*/
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:ordering="together">
- <objectAnimator
- android:propertyName="rotation"
- android:duration="0"
- android:valueFrom="180"
- android:valueTo="0"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
- <objectAnimator
- android:propertyName="alpha"
- android:valueFrom="0.0"
- android:valueTo="1.0"
- android:valueType="floatType"
- android:duration="300"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
- <objectAnimator
- android:propertyName="scaleX"
- android:valueFrom="0.8"
- android:valueTo="1.0"
- android:valueType="floatType"
- android:duration="300"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
- <objectAnimator
- android:propertyName="scaleY"
- android:valueFrom="0.8"
- android:valueTo="1.0"
- android:valueType="floatType"
- android:duration="300"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/anim/car_arrow_fade_in_rotate_up.xml b/packages/CarSystemUI/res/anim/car_arrow_fade_in_rotate_up.xml
deleted file mode 100644
index 0f28297..0000000
--- a/packages/CarSystemUI/res/anim/car_arrow_fade_in_rotate_up.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2018, 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.
-*/
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:ordering="together">
- <objectAnimator
- android:propertyName="rotation"
- android:duration="0"
- android:valueFrom="0"
- android:valueTo="180"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
- <objectAnimator
- android:propertyName="alpha"
- android:valueFrom="0.0"
- android:valueTo="1.0"
- android:valueType="floatType"
- android:duration="300"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
- <objectAnimator
- android:propertyName="scaleX"
- android:valueFrom="0.8"
- android:valueTo="1.0"
- android:valueType="floatType"
- android:duration="300"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
- <objectAnimator
- android:propertyName="scaleY"
- android:valueFrom="0.8"
- android:valueTo="1.0"
- android:valueType="floatType"
- android:duration="300"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/anim/car_arrow_fade_out.xml b/packages/CarSystemUI/res/anim/car_arrow_fade_out.xml
deleted file mode 100644
index e6757d2..0000000
--- a/packages/CarSystemUI/res/anim/car_arrow_fade_out.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2018, 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.
-*/
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:ordering="together">
- <objectAnimator
- android:propertyName="alpha"
- android:valueFrom="1.0"
- android:valueTo="0.0"
- android:valueType="floatType"
- android:duration="300"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
- <objectAnimator
- android:propertyName="scaleX"
- android:valueFrom="1.0"
- android:valueTo="0.8"
- android:valueType="floatType"
- android:duration="300"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
- <objectAnimator
- android:propertyName="scaleY"
- android:valueFrom="1.0"
- android:valueTo="0.8"
- android:valueType="floatType"
- android:duration="300"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/anim/car_user_switcher_close_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_close_animation.xml
deleted file mode 100644
index 6f12338..0000000
--- a/packages/CarSystemUI/res/anim/car_user_switcher_close_animation.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<!-- Copyright (C) 2018 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.
--->
-<animator xmlns:android="http://schemas.android.com/apk/res/android"
- android:duration="133"
- android:valueType="intType"
- android:valueFrom="@dimen/car_user_switcher_container_height"
- android:valueTo="0"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
diff --git a/packages/CarSystemUI/res/anim/car_user_switcher_close_icon_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_close_icon_animation.xml
deleted file mode 100644
index 9f8c12e..0000000
--- a/packages/CarSystemUI/res/anim/car_user_switcher_close_icon_animation.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!-- Copyright (C) 2018 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
- <objectAnimator
- android:duration="167"
- android:propertyName="rotation"
- android:valueType="floatType"
- android:valueFrom="180"
- android:valueTo="0"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/anim/car_user_switcher_close_name_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_close_name_animation.xml
deleted file mode 100644
index adc1f72..0000000
--- a/packages/CarSystemUI/res/anim/car_user_switcher_close_name_animation.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<!-- Copyright (C) 2018 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
- <objectAnimator
- android:duration="83"
- android:propertyName="alpha"
- android:valueType="floatType"
- android:valueFrom="0"
- android:valueTo="1" />
-</set>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/anim/car_user_switcher_close_pages_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_close_pages_animation.xml
deleted file mode 100644
index dec5c05..0000000
--- a/packages/CarSystemUI/res/anim/car_user_switcher_close_pages_animation.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<!-- Copyright (C) 2018 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
- <objectAnimator
- android:duration="83"
- android:propertyName="alpha"
- android:valueType="floatType"
- android:valueFrom="1"
- android:valueTo="0" />
-</set>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/anim/car_user_switcher_close_pod_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_close_pod_animation.xml
deleted file mode 100644
index 986a9cb..0000000
--- a/packages/CarSystemUI/res/anim/car_user_switcher_close_pod_animation.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!-- Copyright (C) 2018 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:ordering="together" >
-
- <objectAnimator
- android:duration="50"
- android:propertyName="alpha"
- android:valueType="floatType"
- android:valueFrom="1"
- android:valueTo="0" />
-</set>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/anim/car_user_switcher_open_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_open_animation.xml
deleted file mode 100644
index 80b38b3..0000000
--- a/packages/CarSystemUI/res/anim/car_user_switcher_open_animation.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<!-- Copyright (C) 2018 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.
--->
-<animator xmlns:android="http://schemas.android.com/apk/res/android"
- android:duration="200"
- android:valueType="intType"
- android:valueFrom="0"
- android:valueTo="@dimen/car_user_switcher_container_height"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
diff --git a/packages/CarSystemUI/res/anim/car_user_switcher_open_icon_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_open_icon_animation.xml
deleted file mode 100644
index 721376c..0000000
--- a/packages/CarSystemUI/res/anim/car_user_switcher_open_icon_animation.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!-- Copyright (C) 2018 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
- <objectAnimator
- android:duration="167"
- android:propertyName="rotation"
- android:valueType="floatType"
- android:valueFrom="0"
- android:valueTo="180"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/anim/car_user_switcher_open_name_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_open_name_animation.xml
deleted file mode 100644
index 246099e..0000000
--- a/packages/CarSystemUI/res/anim/car_user_switcher_open_name_animation.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!-- Copyright (C) 2018 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
- <objectAnimator
- android:duration="83"
- android:startOffset="83"
- android:propertyName="alpha"
- android:valueType="floatType"
- android:valueFrom="1"
- android:valueTo="0" />
-</set>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/anim/car_user_switcher_open_pages_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_open_pages_animation.xml
deleted file mode 100644
index 9a1c642..0000000
--- a/packages/CarSystemUI/res/anim/car_user_switcher_open_pages_animation.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!-- Copyright (C) 2018 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
- <objectAnimator
- android:duration="83"
- android:startOffset="83"
- android:propertyName="alpha"
- android:valueType="floatType"
- android:valueFrom="0"
- android:valueTo="1" />
-</set>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/anim/car_user_switcher_open_pod_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_open_pod_animation.xml
deleted file mode 100644
index 1414b66..0000000
--- a/packages/CarSystemUI/res/anim/car_user_switcher_open_pod_animation.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!-- Copyright (C) 2018 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:ordering="together" >
-
- <objectAnimator
- android:duration="167"
- android:startOffset="67"
- android:propertyName="translationY"
- android:valueType="floatType"
- android:valueFrom="@dimen/car_user_switcher_container_anim_height"
- android:valueTo="0"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
- <objectAnimator
- android:duration="83"
- android:startOffset="117"
- android:propertyName="alpha"
- android:valueType="floatType"
- android:valueFrom="0"
- android:valueTo="1" />
-</set>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/car_add_circle_round.xml b/packages/CarSystemUI/res/drawable/car_add_circle_round.xml
deleted file mode 100644
index 13c7dd1..0000000
--- a/packages/CarSystemUI/res/drawable/car_add_circle_round.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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.
--->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item>
- <shape android:shape="oval">
- <solid
- android:color="@color/car_user_switcher_add_user_background_color"/>
- <size
- android:width="@dimen/car_user_switcher_image_avatar_size"
- android:height="@dimen/car_user_switcher_image_avatar_size"/>
- </shape>
- </item>
- <item
- android:drawable="@drawable/car_ic_add_white"
- android:gravity="center"/>
-</layer-list>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/car_ic_add_white.xml b/packages/CarSystemUI/res/drawable/car_ic_add_white.xml
deleted file mode 100644
index 9d5ca26..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_add_white.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<!-- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@*android:dimen/car_touch_target_size"
- android:height="@*android:dimen/car_touch_target_size"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="@color/car_user_switcher_add_user_add_sign_color"
- android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/car_ic_apps.xml b/packages/CarSystemUI/res/drawable/car_ic_apps.xml
deleted file mode 100644
index e028a0e..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_apps.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size"
- android:viewportWidth="44"
- android:viewportHeight="44">
- <path
- android:pathData="M7.33333333 14.6666667L14.6666667 14.6666667L14.6666667 7.33333333L7.33333333 7.33333333L7.33333333 14.6666667ZM18.3333333 36.6666667L25.6666667 36.6666667L25.6666667 29.3333333L18.3333333 29.3333333L18.3333333 36.6666667ZM7.33333333 36.6666667L14.6666667 36.6666667L14.6666667 29.3333333L7.33333333 29.3333333L7.33333333 36.6666667ZM7.33333333 25.6666667L14.6666667 25.6666667L14.6666667 18.3333333L7.33333333 18.3333333L7.33333333 25.6666667ZM18.3333333 25.6666667L25.6666667 25.6666667L25.6666667 18.3333333L18.3333333 18.3333333L18.3333333 25.6666667ZM29.3333333 7.33333333L29.3333333 14.6666667L36.6666667 14.6666667L36.6666667 7.33333333L29.3333333 7.33333333ZM18.3333333 14.6666667L25.6666667 14.6666667L25.6666667 7.33333333L18.3333333 7.33333333L18.3333333 14.6666667ZM29.3333333 25.6666667L36.6666667 25.6666667L36.6666667 18.3333333L29.3333333 18.3333333L29.3333333 25.6666667ZM29.3333333 36.6666667L36.6666667 36.6666667L36.6666667 29.3333333L29.3333333 29.3333333L29.3333333 36.6666667Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/car_ic_apps_selected.xml b/packages/CarSystemUI/res/drawable/car_ic_apps_selected.xml
deleted file mode 100644
index 9504e61..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_apps_selected.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size"
- android:viewportWidth="44"
- android:viewportHeight="44">
- <path
- android:pathData="M7.33333333 14.6666667L14.6666667 14.6666667L14.6666667 7.33333333L7.33333333 7.33333333L7.33333333 14.6666667ZM18.3333333 36.6666667L25.6666667 36.6666667L25.6666667 29.3333333L18.3333333 29.3333333L18.3333333 36.6666667ZM7.33333333 36.6666667L14.6666667 36.6666667L14.6666667 29.3333333L7.33333333 29.3333333L7.33333333 36.6666667ZM7.33333333 25.6666667L14.6666667 25.6666667L14.6666667 18.3333333L7.33333333 18.3333333L7.33333333 25.6666667ZM18.3333333 25.6666667L25.6666667 25.6666667L25.6666667 18.3333333L18.3333333 18.3333333L18.3333333 25.6666667ZM29.3333333 7.33333333L29.3333333 14.6666667L36.6666667 14.6666667L36.6666667 7.33333333L29.3333333 7.33333333ZM18.3333333 14.6666667L25.6666667 14.6666667L25.6666667 7.33333333L18.3333333 7.33333333L18.3333333 14.6666667ZM29.3333333 25.6666667L36.6666667 25.6666667L36.6666667 18.3333333L29.3333333 18.3333333L29.3333333 25.6666667ZM29.3333333 36.6666667L36.6666667 36.6666667L36.6666667 29.3333333L29.3333333 29.3333333L29.3333333 36.6666667Z"
- android:fillColor="@color/car_nav_icon_fill_color_selected" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/car_ic_arrow.xml b/packages/CarSystemUI/res/drawable/car_ic_arrow.xml
deleted file mode 100644
index cfacbf9..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_arrow.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
- ~ Copyright (C) 2018 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="48.0dp"
- android:height="48.0dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M14.0,20.0l10.0,10.0 10.0,-10.0z"/>
-</vector>
diff --git a/packages/CarSystemUI/res/drawable/car_ic_arrow_drop_up.xml b/packages/CarSystemUI/res/drawable/car_ic_arrow_drop_up.xml
deleted file mode 100644
index 81e7262..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_arrow_drop_up.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
- ~ Copyright (C) 2018 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="48.0dp"
- android:height="48.0dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M14 28l10-10 10 10z"/>
-</vector>
diff --git a/packages/CarSystemUI/res/drawable/car_ic_home.xml b/packages/CarSystemUI/res/drawable/car_ic_home.xml
deleted file mode 100644
index c78f0ed..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_home.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/car_ic_home_selected.xml b/packages/CarSystemUI/res/drawable/car_ic_home_selected.xml
deleted file mode 100644
index 16192df..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_home_selected.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z"
- android:fillColor="@color/car_nav_icon_fill_color_selected" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/car_ic_hvac.xml b/packages/CarSystemUI/res/drawable/car_ic_hvac.xml
deleted file mode 100644
index 55c968e..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_hvac.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:pathData="M16.34,8.36l-2.29,0.82c-0.18,-0.13 -0.38,-0.25 -0.58,-0.34c0.17,-0.83 0.63,-1.58 1.36,-2.06C16.85,5.44 16.18,2 13.39,2C9,2 7.16,5.01 8.36,7.66l0.82,2.29c-0.13,0.18 -0.25,0.38 -0.34,0.58c-0.83,-0.17 -1.58,-0.63 -2.06,-1.36C5.44,7.15 2,7.82 2,10.61c0,4.4 3.01,6.24 5.66,5.03l2.29,-0.82c0.18,0.13 0.38,0.25 0.58,0.34c-0.17,0.83 -0.63,1.58 -1.36,2.06C7.15,18.56 7.82,22 10.61,22c4.4,0 6.24,-3.01 5.03,-5.66l-0.82,-2.29c0.13,-0.18 0.25,-0.38 0.34,-0.58c0.83,0.17 1.58,0.63 2.06,1.36c1.34,2.01 4.77,1.34 4.77,-1.45C22,9 18.99,7.16 16.34,8.36zM12,13.5c-0.83,0 -1.5,-0.67 -1.5,-1.5c0,-0.83 0.67,-1.5 1.5,-1.5c0.83,0 1.5,0.67 1.5,1.5C13.5,12.83 12.83,13.5 12,13.5zM10.24,5.22C10.74,4.44 11.89,4 13.39,4c0.79,0 0.71,0.86 0.34,1.11c-1.22,0.81 -2,2.06 -2.25,3.44c-0.21,0.03 -0.42,0.08 -0.62,0.15l-0.68,-1.88C10,6.42 9.86,5.81 10.24,5.22zM6.83,13.82c-0.4,0.18 -1.01,0.32 -1.61,-0.06C4.44,13.26 4,12.11 4,10.61c0,-0.79 0.86,-0.71 1.11,-0.34c0.81,1.22 2.06,2 3.44,2.25c0.03,0.21 0.08,0.42 0.15,0.62L6.83,13.82zM13.76,18.78c-0.5,0.77 -1.65,1.22 -3.15,1.22c-0.79,0 -0.71,-0.86 -0.34,-1.11c1.22,-0.81 2,-2.06 2.25,-3.44c0.21,-0.03 0.42,-0.08 0.62,-0.15l0.68,1.88C14,17.58 14.14,18.18 13.76,18.78zM18.89,13.73c-0.81,-1.22 -2.06,-2 -3.44,-2.25c-0.03,-0.21 -0.08,-0.42 -0.15,-0.62l1.88,-0.68c0.4,-0.18 1.01,-0.32 1.61,0.06c0.77,0.5 1.22,1.65 1.22,3.15C20,14.19 19.14,14.11 18.89,13.73z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
diff --git a/packages/CarSystemUI/res/drawable/car_ic_hvac_selected.xml b/packages/CarSystemUI/res/drawable/car_ic_hvac_selected.xml
deleted file mode 100644
index 817b714..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_hvac_selected.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:pathData="M16.34,8.36l-2.29,0.82c-0.18,-0.13 -0.38,-0.25 -0.58,-0.34c0.17,-0.83 0.63,-1.58 1.36,-2.06C16.85,5.44 16.18,2 13.39,2C9,2 7.16,5.01 8.36,7.66l0.82,2.29c-0.13,0.18 -0.25,0.38 -0.34,0.58c-0.83,-0.17 -1.58,-0.63 -2.06,-1.36C5.44,7.15 2,7.82 2,10.61c0,4.4 3.01,6.24 5.66,5.03l2.29,-0.82c0.18,0.13 0.38,0.25 0.58,0.34c-0.17,0.83 -0.63,1.58 -1.36,2.06C7.15,18.56 7.82,22 10.61,22c4.4,0 6.24,-3.01 5.03,-5.66l-0.82,-2.29c0.13,-0.18 0.25,-0.38 0.34,-0.58c0.83,0.17 1.58,0.63 2.06,1.36c1.34,2.01 4.77,1.34 4.77,-1.45C22,9 18.99,7.16 16.34,8.36zM12,13.5c-0.83,0 -1.5,-0.67 -1.5,-1.5c0,-0.83 0.67,-1.5 1.5,-1.5c0.83,0 1.5,0.67 1.5,1.5C13.5,12.83 12.83,13.5 12,13.5zM10.24,5.22C10.74,4.44 11.89,4 13.39,4c0.79,0 0.71,0.86 0.34,1.11c-1.22,0.81 -2,2.06 -2.25,3.44c-0.21,0.03 -0.42,0.08 -0.62,0.15l-0.68,-1.88C10,6.42 9.86,5.81 10.24,5.22zM6.83,13.82c-0.4,0.18 -1.01,0.32 -1.61,-0.06C4.44,13.26 4,12.11 4,10.61c0,-0.79 0.86,-0.71 1.11,-0.34c0.81,1.22 2.06,2 3.44,2.25c0.03,0.21 0.08,0.42 0.15,0.62L6.83,13.82zM13.76,18.78c-0.5,0.77 -1.65,1.22 -3.15,1.22c-0.79,0 -0.71,-0.86 -0.34,-1.11c1.22,-0.81 2,-2.06 2.25,-3.44c0.21,-0.03 0.42,-0.08 0.62,-0.15l0.68,1.88C14,17.58 14.14,18.18 13.76,18.78zM18.89,13.73c-0.81,-1.22 -2.06,-2 -3.44,-2.25c-0.03,-0.21 -0.08,-0.42 -0.15,-0.62l1.88,-0.68c0.4,-0.18 1.01,-0.32 1.61,0.06c0.77,0.5 1.22,1.65 1.22,3.15C20,14.19 19.14,14.11 18.89,13.73z"
- android:fillColor="@color/car_nav_icon_fill_color_selected" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/car_ic_keyboard_arrow_down.xml b/packages/CarSystemUI/res/drawable/car_ic_keyboard_arrow_down.xml
deleted file mode 100644
index 3709aa5..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_keyboard_arrow_down.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~
- ~ Copyright (C) 2018 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.
- ~
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="44dp"
- android:height="44dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
- <path
- android:pathData="M14.83 16.42L24 25.59l9.17-9.17L36 19.25l-12 12-12-12z"
- android:fillColor="#ffffff"/>
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/car_ic_music.xml b/packages/CarSystemUI/res/drawable/car_ic_music.xml
deleted file mode 100644
index 6339ebb..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_music.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M22 5.5L22 24.8416667C20.9183333 24.2183333 19.6716667 23.8333333 18.3333333 23.8333333C14.2816667 23.8333333 11 27.115 11 31.1666667C11 35.2183333 14.2816667 38.5 18.3333333 38.5C22.385 38.5 25.6666667 35.2183333 25.6666667 31.1666667L25.6666667 12.8333333L33 12.8333333L33 5.5L22 5.5Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/car_ic_music_selected.xml b/packages/CarSystemUI/res/drawable/car_ic_music_selected.xml
deleted file mode 100644
index a56bcb3..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_music_selected.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M22 5.5L22 24.8416667C20.9183333 24.2183333 19.6716667 23.8333333 18.3333333 23.8333333C14.2816667 23.8333333 11 27.115 11 31.1666667C11 35.2183333 14.2816667 38.5 18.3333333 38.5C22.385 38.5 25.6666667 35.2183333 25.6666667 31.1666667L25.6666667 12.8333333L33 12.8333333L33 5.5L22 5.5Z"
- android:fillColor="@color/car_nav_icon_fill_color_selected" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/car_ic_navigation.xml b/packages/CarSystemUI/res/drawable/car_ic_navigation.xml
deleted file mode 100644
index e1fabe0..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_navigation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M39.8016667 20.6983333L23.3016667 4.19833333C22.5866667 3.48333333 21.4316667 3.48333333 20.7166667 4.19833333L4.21666667 20.6983333C3.50166667 21.4133333 3.50166667 22.5683333 4.21666667 23.2833333L20.7166667 39.7833333C21.4316667 40.4983333 22.5866667 40.4983333 23.3016667 39.7833333L39.8016667 23.2833333C40.5166667 22.5866667 40.5166667 21.4316667 39.8016667 20.6983333ZM25.6666667 26.5833333L25.6666667 22L18.3333333 22L18.3333333 27.5L14.6666667 27.5L14.6666667 20.1666667C14.6666667 19.1583333 15.4916667 18.3333333 16.5 18.3333333L25.6666667 18.3333333L25.6666667 13.75L32.0833333 20.1666667L25.6666667 26.5833333Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/car_ic_navigation_selected.xml b/packages/CarSystemUI/res/drawable/car_ic_navigation_selected.xml
deleted file mode 100644
index d11cf28..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_navigation_selected.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M39.8016667 20.6983333L23.3016667 4.19833333C22.5866667 3.48333333 21.4316667 3.48333333 20.7166667 4.19833333L4.21666667 20.6983333C3.50166667 21.4133333 3.50166667 22.5683333 4.21666667 23.2833333L20.7166667 39.7833333C21.4316667 40.4983333 22.5866667 40.4983333 23.3016667 39.7833333L39.8016667 23.2833333C40.5166667 22.5866667 40.5166667 21.4316667 39.8016667 20.6983333ZM25.6666667 26.5833333L25.6666667 22L18.3333333 22L18.3333333 27.5L14.6666667 27.5L14.6666667 20.1666667C14.6666667 19.1583333 15.4916667 18.3333333 16.5 18.3333333L25.6666667 18.3333333L25.6666667 13.75L32.0833333 20.1666667L25.6666667 26.5833333Z"
- android:fillColor="@color/car_nav_icon_fill_color_selected" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/car_ic_notification.xml b/packages/CarSystemUI/res/drawable/car_ic_notification.xml
deleted file mode 100644
index aabf916..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_notification.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size"
- android:viewportWidth="44"
- android:viewportHeight="44">
- <path
- android:pathData="M22 39.125C23.925 39.125 25.5 37.55 25.5 35.625L18.5 35.625C18.5 37.55 20.0575 39.125 22 39.125ZM32.5 28.625L32.5 19.875C32.5 14.5025 29.63 10.005 24.625 8.815L24.625 7.625C24.625 6.1725 23.4525 5 22 5C20.5475 5 19.375 6.1725 19.375 7.625L19.375 8.815C14.3525 10.005 11.5 14.485 11.5 19.875L11.5 28.625L8 32.125L8 33.875L36 33.875L36 32.125L32.5 28.625Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/car_ic_overview.xml b/packages/CarSystemUI/res/drawable/car_ic_overview.xml
deleted file mode 100644
index f185eb9..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_overview.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M36.92857 22.39286A14.53571 14.53571 0 0 1 7.857143 22.39286A14.53571 14.53571 0 0 1 36.92857 22.39286Z"
- android:strokeColor="@color/car_nav_icon_fill_color"
- android:strokeWidth="4" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/car_ic_overview_selected.xml b/packages/CarSystemUI/res/drawable/car_ic_overview_selected.xml
deleted file mode 100644
index 19b5583..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_overview_selected.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M36.92857 22.39286A14.53571 14.53571 0 0 1 7.857143 22.39286A14.53571 14.53571 0 0 1 36.92857 22.39286Z"
- android:strokeColor="@color/car_nav_icon_fill_color_selected"
- android:strokeWidth="4" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/car_ic_phone.xml b/packages/CarSystemUI/res/drawable/car_ic_phone.xml
deleted file mode 100644
index 50e36b5..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_phone.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M12.1366667 19.7816667C14.7766667 24.97 19.03 29.205 24.2183333 31.8633333L28.2516667 27.83C28.7466667 27.335 29.48 27.17 30.1216667 27.39C32.175 28.0683333 34.3933333 28.435 36.6666667 28.435C37.675 28.435 38.5 29.26 38.5 30.2683333L38.5 36.6666667C38.5 37.675 37.675 38.5 36.6666667 38.5C19.4516667 38.5 5.5 24.5483333 5.5 7.33333333C5.5 6.325 6.325 5.5 7.33333333 5.5L13.75 5.5C14.7583333 5.5 15.5833333 6.325 15.5833333 7.33333333C15.5833333 9.625 15.95 11.825 16.6283333 13.8783333C16.83 14.52 16.6833333 15.235 16.17 15.7483333L12.1366667 19.7816667Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/car_ic_phone_selected.xml b/packages/CarSystemUI/res/drawable/car_ic_phone_selected.xml
deleted file mode 100644
index 11b1687..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_phone_selected.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M12.1366667 19.7816667C14.7766667 24.97 19.03 29.205 24.2183333 31.8633333L28.2516667 27.83C28.7466667 27.335 29.48 27.17 30.1216667 27.39C32.175 28.0683333 34.3933333 28.435 36.6666667 28.435C37.675 28.435 38.5 29.26 38.5 30.2683333L38.5 36.6666667C38.5 37.675 37.675 38.5 36.6666667 38.5C19.4516667 38.5 5.5 24.5483333 5.5 7.33333333C5.5 6.325 6.325 5.5 7.33333333 5.5L13.75 5.5C14.7583333 5.5 15.5833333 6.325 15.5833333 7.33333333C15.5833333 9.625 15.95 11.825 16.6283333 13.8783333C16.83 14.52 16.6833333 15.235 16.17 15.7483333L12.1366667 19.7816667Z"
- android:fillColor="@color/car_nav_icon_fill_color_selected" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/car_ic_selection_bg.xml b/packages/CarSystemUI/res/drawable/car_ic_selection_bg.xml
deleted file mode 100644
index 12993f5..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_selection_bg.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="70dp"
- android:height="70dp"
- android:viewportHeight="70.0"
- android:viewportWidth="70.0">
- <path
- android:fillColor="?android:attr/colorAccent"
- android:fillType="evenOdd"
- android:pathData="M4,0L66,0A4,4 0,0 1,70 4L70,66A4,4 0,0 1,66 70L4,70A4,4 0,0 1,0 66L0,4A4,4 0,0 1,4 0z"
- android:strokeColor="#00000000"
- android:strokeWidth="1"/>
-</vector>
diff --git a/packages/CarSystemUI/res/drawable/car_ic_settings_icon.xml b/packages/CarSystemUI/res/drawable/car_ic_settings_icon.xml
deleted file mode 100644
index 147f539..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_settings_icon.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@*android:dimen/status_bar_system_icon_size"
- android:height="@*android:dimen/status_bar_system_icon_size"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:fillColor="@color/system_bar_icon_color"
- android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4C9.75,2 9.54,2.18 9.51,2.42L9.13,5.07C8.52,5.32 7.96,5.66 7.44,6.05l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46C2.21,8.95 2.27,9.22 2.46,9.37l2.11,1.65C4.53,11.34 4.5,11.67 4.5,12s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65C9.54,21.82 9.75,22 10,22h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64L19.43,12.98zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5s3.5,1.57 3.5,3.5S13.93,15.5 12,15.5z"/>
-</vector>
diff --git a/packages/CarSystemUI/res/drawable/car_ic_unseen_indicator.xml b/packages/CarSystemUI/res/drawable/car_ic_unseen_indicator.xml
deleted file mode 100644
index 025fc9c..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_unseen_indicator.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <group
- android:translateX="30"
- android:translateY="2">
- <path
- android:fillColor="@color/car_nav_unseen_indicator_color"
- android:strokeWidth="1"
- android:pathData="M 6 0 C 9.31370849898 0 12 2.68629150102 12 6 C 12 9.31370849898 9.31370849898 12 6 12 C 2.68629150102 12 0 9.31370849898 0 6 C 0 2.68629150102 2.68629150102 0 6 0 Z" />
- </group>
-</vector>
diff --git a/packages/CarSystemUI/res/drawable/car_ic_user_icon.xml b/packages/CarSystemUI/res/drawable/car_ic_user_icon.xml
deleted file mode 100644
index 270d932..0000000
--- a/packages/CarSystemUI/res/drawable/car_ic_user_icon.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"
- android:fillColor="@color/system_bar_icon_color"/>
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/car_rounded_bg_bottom.xml b/packages/CarSystemUI/res/drawable/car_rounded_bg_bottom.xml
deleted file mode 100644
index 07227fb..0000000
--- a/packages/CarSystemUI/res/drawable/car_rounded_bg_bottom.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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
- -->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="?android:attr/colorBackgroundFloating" />
- <corners
- android:bottomLeftRadius="@*android:dimen/car_radius_3"
- android:topLeftRadius="0dp"
- android:bottomRightRadius="@*android:dimen/car_radius_3"
- android:topRightRadius="0dp"
- />
-</shape>
diff --git a/packages/CarSystemUI/res/drawable/car_seekbar_thumb.xml b/packages/CarSystemUI/res/drawable/car_seekbar_thumb.xml
deleted file mode 100644
index 2649a00..0000000
--- a/packages/CarSystemUI/res/drawable/car_seekbar_thumb.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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
- -->
-
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item>
- <shape android:shape="oval">
- <padding
- android:bottom="@*android:dimen/car_padding_1"
- android:left="@*android:dimen/car_padding_1"
- android:right="@*android:dimen/car_padding_1"
- android:top="@*android:dimen/car_padding_1"/>
- <solid android:color="@android:color/black"/>
- </shape>
- </item>
- <item>
- <shape android:shape="oval">
- <solid android:color="@*android:color/car_accent"/>
- <size
- android:width="@*android:dimen/car_seekbar_thumb_size"
- android:height="@*android:dimen/car_seekbar_thumb_size"/>
- </shape>
- </item>
-</layer-list>
diff --git a/packages/CarSystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml b/packages/CarSystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml
deleted file mode 100644
index 34578fe..0000000
--- a/packages/CarSystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="17dp"
- android:height="17dp"
- android:viewportWidth="18.0"
- android:viewportHeight="18.0">
- <group
- android:translateY="0.5"
- android:translateX="0.5" >
- <path
- android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
- android:fillColor="#FFFFFF"/>
- </group>
-</vector>
diff --git a/packages/CarSystemUI/res/drawable/headsup_scrim_bottom.xml b/packages/CarSystemUI/res/drawable/headsup_scrim_bottom.xml
deleted file mode 100644
index 1724ef0..0000000
--- a/packages/CarSystemUI/res/drawable/headsup_scrim_bottom.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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.
- -->
-<shape
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <gradient
- android:startColor="@android:color/black"
- android:endColor="@android:color/transparent"
- android:angle="90" />
-</shape>
diff --git a/packages/CarSystemUI/res/drawable/hvac_decrease_button.xml b/packages/CarSystemUI/res/drawable/hvac_decrease_button.xml
deleted file mode 100644
index 656e94a..0000000
--- a/packages/CarSystemUI/res/drawable/hvac_decrease_button.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- ~ Copyright (C) 2020 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.
- -->
-
-<layer-list
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:aapt="http://schemas.android.com/aapt">
- <item android:gravity="center"
- android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size">
- <aapt:attr name="android:drawable">
- <shape android:shape="oval">
- <size
- android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size"/>
- <solid
- android:color="@color/hvac_temperature_adjust_button_color"/>
- </shape>
- </aapt:attr>
- </item>
- <item android:gravity="center"
- android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size">
- <aapt:attr name="android:drawable">
- <vector android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="@color/hvac_temperature_decrease_arrow_color"
- android:pathData="M14,7l-5,5 5,5V7z"/>
- </vector>
- </aapt:attr>
- </item>
- <item>
- <aapt:attr name="android:drawable">
- <ripple android:color="?android:attr/colorControlHighlight"/>
- </aapt:attr>
- </item>
-</layer-list>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/hvac_increase_button.xml b/packages/CarSystemUI/res/drawable/hvac_increase_button.xml
deleted file mode 100644
index 57c07c8..0000000
--- a/packages/CarSystemUI/res/drawable/hvac_increase_button.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- ~ Copyright (C) 2020 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.
- -->
-
-<layer-list
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:aapt="http://schemas.android.com/aapt">
- <item android:gravity="center"
- android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size">
- <aapt:attr name="android:drawable">
- <shape android:shape="oval">
- <size
- android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size"/>
- <solid
- android:color="@color/hvac_temperature_adjust_button_color"/>
- </shape>
- </aapt:attr>
- </item>
- <item android:gravity="center"
- android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size">
- <aapt:attr name="android:drawable">
- <vector android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="@color/hvac_temperature_increase_arrow_color"
- android:pathData="M10,17l5,-5 -5,-5v10z"/>
- </vector>
- </aapt:attr>
- </item>
- <item>
- <aapt:attr name="android:drawable">
- <ripple android:color="?android:attr/colorControlHighlight"/>
- </aapt:attr>
- </item>
-</layer-list>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/ic_mic_white.xml b/packages/CarSystemUI/res/drawable/ic_mic_white.xml
deleted file mode 100644
index 71fcc53..0000000
--- a/packages/CarSystemUI/res/drawable/ic_mic_white.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size"
- android:viewportWidth="44"
- android:viewportHeight="44">
-<path
- android:pathData="M22 25.6666667C25.0433333 25.6666667 27.4816667 23.21 27.4816667 20.1666667L27.5 9.16666667C27.5 6.12333333 25.0433333 3.66666667 22 3.66666667C18.9566667 3.66666667 16.5 6.12333333 16.5 9.16666667L16.5 20.1666667C16.5 23.21 18.9566667 25.6666667 22 25.6666667ZM31.7166667 20.1666667C31.7166667 25.6666667 27.06 29.5166667 22 29.5166667C16.94 29.5166667 12.2833333 25.6666667 12.2833333 20.1666667L9.16666667 20.1666667C9.16666667 26.4183333 14.1533333 31.5883333 20.1666667 32.4866667L20.1666667 38.5L23.8333333 38.5L23.8333333 32.4866667C29.8466667 31.6066667 34.8333333 26.4366667 34.8333333 20.1666667L31.7166667 20.1666667Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/notification_handle_bar.xml b/packages/CarSystemUI/res/drawable/notification_handle_bar.xml
deleted file mode 100644
index 5ed7499..0000000
--- a/packages/CarSystemUI/res/drawable/notification_handle_bar.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2019 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.
--->
-<ripple
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:color="@android:color/white">
- <item>
- <shape android:shape="rectangle">
- <corners android:radius="@dimen/clear_all_button_radius"/>
- <solid android:color="@android:color/white"/>
- </shape>
- </item>
-</ripple>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/drawable/notification_material_bg.xml b/packages/CarSystemUI/res/drawable/notification_material_bg.xml
deleted file mode 100644
index 03746c8..0000000
--- a/packages/CarSystemUI/res/drawable/notification_material_bg.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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
- -->
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
- android:color="@color/notification_ripple_untinted_color">
- <item>
- <shape xmlns:android="http://schemas.android.com/apk/res/android">
- <solid android:color="@color/notification_material_background_color"/>
- <corners
- android:radius="@dimen/notification_shadow_radius"/>
- </shape>
- </item>
-</ripple>
diff --git a/packages/CarSystemUI/res/drawable/notification_material_bg_dim.xml b/packages/CarSystemUI/res/drawable/notification_material_bg_dim.xml
deleted file mode 100644
index 03746c8..0000000
--- a/packages/CarSystemUI/res/drawable/notification_material_bg_dim.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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
- -->
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
- android:color="@color/notification_ripple_untinted_color">
- <item>
- <shape xmlns:android="http://schemas.android.com/apk/res/android">
- <solid android:color="@color/notification_material_background_color"/>
- <corners
- android:radius="@dimen/notification_shadow_radius"/>
- </shape>
- </item>
-</ripple>
diff --git a/packages/CarSystemUI/res/drawable/stat_sys_signal_null.xml b/packages/CarSystemUI/res/drawable/stat_sys_signal_null.xml
deleted file mode 100644
index 2b487f9e..0000000
--- a/packages/CarSystemUI/res/drawable/stat_sys_signal_null.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:autoMirrored="true"
- android:width="17dp"
- android:height="17dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="?attr/backgroundColor"
- android:pathData="M2.000000,22.000000l20.000000,0.000000L22.000000,2.000000L2.000000,22.000000zM20.000000,20.000000L6.800000,20.000000L20.000000,6.800000L20.000000,20.000000z"/>
-</vector>
diff --git a/packages/CarSystemUI/res/drawable/system_bar_background_pill.xml b/packages/CarSystemUI/res/drawable/system_bar_background_pill.xml
deleted file mode 100644
index 51d2b9d..0000000
--- a/packages/CarSystemUI/res/drawable/system_bar_background_pill.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- ~ Copyright (C) 2020 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.
- -->
-<layer-list
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:aapt="http://schemas.android.com/aapt">
- <item>
- <aapt:attr name="android:drawable">
- <shape android:shape="rectangle">
- <solid android:color="@color/system_bar_background_pill_color"/>
- <corners android:radius="30dp"/>
- </shape>
- </aapt:attr>
- </item>
- <item>
- <aapt:attr name="android:drawable">
- <ripple android:color="?android:attr/colorControlHighlight"/>
- </aapt:attr>
- </item>
-</layer-list>
diff --git a/packages/CarSystemUI/res/drawable/volume_dialog_background.xml b/packages/CarSystemUI/res/drawable/volume_dialog_background.xml
deleted file mode 100644
index fa3ca8f..0000000
--- a/packages/CarSystemUI/res/drawable/volume_dialog_background.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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
- -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
- <solid android:color="?android:attr/colorBackgroundFloating"/>
- <padding
- android:bottom="5dp"
- android:left="5dp"
- android:right="5dp"
- android:top="5dp"/>
- <corners android:bottomLeftRadius="20dp"
- android:bottomRightRadius="20dp"/>
-</shape>
diff --git a/packages/CarSystemUI/res/layout/adjustable_temperature_view.xml b/packages/CarSystemUI/res/layout/adjustable_temperature_view.xml
deleted file mode 100644
index d197409..0000000
--- a/packages/CarSystemUI/res/layout/adjustable_temperature_view.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- ~ Copyright (C) 2020 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:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:gravity="center_vertical"
- android:paddingEnd="@dimen/hvac_container_padding"
- android:paddingStart="@dimen/hvac_container_padding">
-
- <ImageView
- android:id="@+id/hvac_decrease_button"
- android:layout_width="@dimen/hvac_temperature_button_size"
- android:layout_height="@dimen/hvac_temperature_button_size"
- android:scaleType="center"
- android:src="@drawable/hvac_decrease_button"/>
-
- <TextView
- android:id="@+id/hvac_temperature_text"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:textSize="@dimen/hvac_temperature_text_size"
- android:textColor="@color/system_bar_text_color"
- android:paddingStart="@dimen/hvac_temperature_text_padding"
- android:paddingEnd="@dimen/hvac_temperature_text_padding"
- android:gravity="center"/>
-
- <ImageView
- android:id="@+id/hvac_increase_button"
- android:layout_width="@dimen/hvac_temperature_button_size"
- android:layout_height="@dimen/hvac_temperature_button_size"
- android:scaleType="center"
- android:src="@drawable/hvac_increase_button" />
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/layout/car_fullscreen_user_pod.xml b/packages/CarSystemUI/res/layout/car_fullscreen_user_pod.xml
deleted file mode 100644
index a2a628d..0000000
--- a/packages/CarSystemUI/res/layout/car_fullscreen_user_pod.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (C) 2018 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:clipChildren="false"
- android:alpha="0"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:orientation="vertical"
- android:gravity="center">
-
- <ImageView
- android:id="@+id/user_avatar"
- android:layout_width="@dimen/car_user_switcher_image_avatar_size"
- android:layout_height="@dimen/car_user_switcher_image_avatar_size"
- android:background="?android:attr/selectableItemBackground"
- android:gravity="center"/>
-
- <TextView
- android:id="@+id/user_name"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/car_user_switcher_vertical_spacing_between_name_and_avatar"
- android:textSize="@dimen/car_user_switcher_name_text_size"
- android:textColor="@color/car_user_switcher_name_text_color"
- android:ellipsize="end"
- android:singleLine="true"
- android:gravity="center"/>
-
-</LinearLayout>
diff --git a/packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml b/packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml
deleted file mode 100644
index 534c51e..0000000
--- a/packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2018 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.
--->
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/fullscreen_user_switcher"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/car_user_switcher_background_color">
-
- <LinearLayout
- android:id="@+id/container"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_alignParentTop="true"
- android:orientation="vertical">
-
- <include
- layout="@layout/car_status_bar_header"
- android:layout_alignParentTop="true"
- android:theme="@android:style/Theme"/>
-
-
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <com.android.systemui.car.userswitcher.UserGridRecyclerView
- android:id="@+id/user_grid"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_marginTop="@dimen/car_user_switcher_margin_top"/>
- </FrameLayout>
-
- </LinearLayout>
-</FrameLayout>
diff --git a/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml
deleted file mode 100644
index 94816f8..0000000
--- a/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml
+++ /dev/null
@@ -1,112 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2018, 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.
-*/
--->
-
-<com.android.systemui.car.navigationbar.CarNavigationBarView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:orientation="vertical"
- android:background="@drawable/system_bar_background">
-
- <LinearLayout
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:id="@+id/nav_buttons"
- android:orientation="vertical"
- android:gravity="top"
- android:paddingTop="30dp"
- android:layout_weight="1"
- android:animateLayoutChanges="true">
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/home"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
- android:src="@drawable/car_ic_overview"
- android:background="?android:attr/selectableItemBackground"
- android:paddingTop="30dp"
- android:paddingBottom="30dp"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/grid"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- systemui:intent="intent:#Intent;component=com.android.car.home/.AppGridActivity;end"
- systemui:longIntent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
- android:src="@drawable/car_ic_apps"
- android:background="?android:attr/selectableItemBackground"
- android:paddingTop="30dp"
- android:paddingBottom="30dp"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/hvac"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
- systemui:broadcast="true"
- android:src="@drawable/car_ic_hvac"
- android:background="?android:attr/selectableItemBackground"
- android:paddingTop="30dp"
- android:paddingBottom="30dp"
- />
-
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:gravity="bottom"
- android:orientation="vertical">
-
- <com.android.systemui.statusbar.AlphaOptimizedImageView
- android:id="@+id/note"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:src="@drawable/car_ic_notification"
- android:background="?android:attr/selectableItemBackground"
- android:paddingTop="20dp"
- android:paddingBottom="20dp"
- android:alpha="0.7"
- />
-
-
- <com.android.systemui.statusbar.policy.Clock
- android:id="@+id/clock"
- android:textAppearance="@style/TextAppearance.StatusBar.Clock"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:singleLine="true"
- android:paddingStart="@dimen/status_bar_clock_starting_padding"
- android:paddingEnd="@dimen/status_bar_clock_end_padding"
- android:gravity="center_horizontal"
- android:paddingBottom="20dp"
- />
-
- <Space
- android:layout_height="10dp"
- android:layout_width="match_parent"/>
-
- </LinearLayout>
-
-</com.android.systemui.car.navigationbar.CarNavigationBarView>
diff --git a/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
deleted file mode 100644
index 9e6dd11..0000000
--- a/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2018, 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.
-*/
--->
-
-<com.android.systemui.car.navigationbar.CarNavigationBarView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:orientation="vertical"
- android:background="@drawable/system_bar_background">
-
- <LinearLayout
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:id="@+id/nav_buttons"
- android:orientation="vertical"
- android:gravity="top"
- android:paddingTop="30dp"
- android:layout_weight="1"
- android:animateLayoutChanges="true">
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/home"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
- android:src="@drawable/car_ic_overview"
- android:background="?android:attr/selectableItemBackground"
- android:paddingTop="30dp"
- android:paddingBottom="30dp"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/hvac"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
- systemui:broadcast="true"
- android:src="@drawable/car_ic_hvac"
- android:background="?android:attr/selectableItemBackground"
- android:paddingTop="30dp"
- android:paddingBottom="30dp"
- />
- </LinearLayout>
-</com.android.systemui.car.navigationbar.CarNavigationBarView>
diff --git a/packages/CarSystemUI/res/layout/car_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_navigation_bar.xml
deleted file mode 100644
index 8314ba5..0000000
--- a/packages/CarSystemUI/res/layout/car_navigation_bar.xml
+++ /dev/null
@@ -1,122 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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.
- -->
-
-<com.android.systemui.car.navigationbar.CarNavigationBarView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/system_bar_background"
- android:gravity="center"
- android:orientation="horizontal">
-
- <RelativeLayout
- android:id="@+id/nav_buttons"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layoutDirection="ltr">
-
- <com.android.systemui.car.hvac.AdjustableTemperatureView
- android:id="@+id/driver_hvac"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:gravity="center_vertical"
- systemui:hvacAreaId="49"
- systemui:hvacTempFormat="%.0f\u00B0" />
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_centerInParent="true"
- android:layout_weight="1"
- android:gravity="center"
- android:layoutDirection="ltr"
- android:paddingEnd="@dimen/system_bar_button_group_padding"
- android:paddingStart="@dimen/system_bar_button_group_padding">
-
- <Space
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"/>
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/home"
- style="@style/NavigationBarButton"
- systemui:componentNames="com.android.car.carlauncher/.CarLauncher"
- systemui:highlightWhenSelected="true"
- systemui:icon="@drawable/car_ic_home"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"/>
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/phone_nav"
- style="@style/NavigationBarButton"
- systemui:highlightWhenSelected="true"
- systemui:icon="@drawable/car_ic_phone"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;package=com.android.car.dialer;launchFlags=0x10000000;end"
- systemui:packages="com.android.car.dialer"/>
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/grid_nav"
- style="@style/NavigationBarButton"
- systemui:componentNames="com.android.car.carlauncher/.AppGridActivity"
- systemui:highlightWhenSelected="true"
- systemui:icon="@drawable/car_ic_apps"
- systemui:intent="intent:#Intent;component=com.android.car.carlauncher/.AppGridActivity;launchFlags=0x24000000;end"/>
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/hvac"
- style="@style/NavigationBarButton"
- systemui:highlightWhenSelected="true"
- systemui:icon="@drawable/car_ic_hvac"
- systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
- systemui:broadcast="true"/>
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/notifications"
- style="@style/NavigationBarButton"
- systemui:highlightWhenSelected="true"
- systemui:icon="@drawable/car_ic_notification"
- systemui:longIntent="intent:#Intent;component=com.android.car.bugreport/.BugReportActivity;end"/>
-
- <Space
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"/>
- </LinearLayout>
-
- <com.android.systemui.car.hvac.AdjustableTemperatureView
- android:id="@+id/passenger_hvac"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentEnd="true"
- android:gravity="center_vertical"
- systemui:hvacAreaId="68"
- systemui:hvacTempFormat="%.0f\u00B0" />
- </RelativeLayout>
-
- <LinearLayout
- android:id="@+id/lock_screen_nav_buttons"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:gravity="center"
- android:layoutDirection="ltr"
- android:paddingEnd="@dimen/car_keyline_1"
- android:paddingStart="@dimen/car_keyline_1"
- android:visibility="gone"
- />
-</com.android.systemui.car.navigationbar.CarNavigationBarView>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/layout/car_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_navigation_bar_unprovisioned.xml
deleted file mode 100644
index a040e80..0000000
--- a/packages/CarSystemUI/res/layout/car_navigation_bar_unprovisioned.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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
- -->
-
-<com.android.systemui.car.navigationbar.CarNavigationBarView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/system_bar_background"
- android:orientation="vertical">
-
- <LinearLayout
- android:id="@+id/nav_buttons"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:paddingStart="@*android:dimen/car_padding_5"
- android:paddingEnd="@*android:dimen/car_padding_5">
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/home"
- android:layout_width="@*android:dimen/car_touch_target_size"
- android:layout_height="match_parent"
- android:background="?android:attr/selectableItemBackground"
- systemui:icon="@drawable/car_ic_overview"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
- systemui:selectedIcon="@drawable/car_ic_overview_selected"
- systemui:highlightWhenSelected="true"
- />
- </LinearLayout>
-</com.android.systemui.car.navigationbar.CarNavigationBarView>
-
diff --git a/packages/CarSystemUI/res/layout/car_navigation_button.xml b/packages/CarSystemUI/res/layout/car_navigation_button.xml
deleted file mode 100644
index 9f79023..0000000
--- a/packages/CarSystemUI/res/layout/car_navigation_button.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2018, 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.
-*/
--->
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/car_nav_button_icon"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:animateLayoutChanges="true"
- android:orientation="vertical">
-
- <com.android.systemui.statusbar.AlphaOptimizedImageView
- android:id="@+id/car_nav_button_icon_image"
- android:layout_height="@dimen/car_navigation_button_icon_height"
- android:layout_width="match_parent"
- android:layout_gravity="center"
- android:animateLayoutChanges="true"
- android:background="@android:color/transparent"
- android:scaleType="fitCenter"
- android:tintMode="src_in"
- android:tint="@color/car_nav_icon_fill_color_selected"
- android:clickable="false"
- />
-
- <com.android.systemui.statusbar.AlphaOptimizedImageView
- android:id="@+id/car_nav_button_more_icon"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:layout_gravity="center"
- android:animateLayoutChanges="true"
- android:src="@drawable/car_ic_arrow"
- android:background="@android:color/transparent"
- android:scaleType="fitCenter"
- android:clickable="false"
- android:visibility="gone"
- />
-
- <ImageView
- android:id="@+id/car_nav_button_unseen_icon"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:layout_gravity="center"
- android:src="@drawable/car_ic_unseen_indicator"
- android:background="@android:color/transparent"
- android:scaleType="fitCenter"
- android:clickable="false"
- />
-
- </FrameLayout>
-</merge>
diff --git a/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml
deleted file mode 100644
index dc95833..0000000
--- a/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml
+++ /dev/null
@@ -1,115 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2018, 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.
-*/
--->
-
-<com.android.systemui.car.navigationbar.CarNavigationBarView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:orientation="vertical"
- android:background="@drawable/system_bar_background">
-
- <!-- phone.NavigationBarView has rot0 and rot90 but we expect the car head unit to have a fixed
- rotation so skip this level of the hierarchy.
- -->
- <LinearLayout
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:id="@+id/nav_buttons"
- android:orientation="vertical"
- android:gravity="top"
- android:paddingTop="30dp"
- android:layout_weight="1"
- android:animateLayoutChanges="true">
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/home"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
- android:src="@drawable/car_ic_overview"
- android:background="?android:attr/selectableItemBackground"
- android:paddingTop="30dp"
- android:paddingBottom="30dp"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/grid"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- systemui:intent="intent:#Intent;component=com.android.car.home/.AppGridActivity;launchFlags=0x14000000;end"
- systemui:longIntent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
- android:src="@drawable/car_ic_apps"
- android:background="?android:attr/selectableItemBackground"
- android:paddingTop="30dp"
- android:paddingBottom="30dp"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/hvac"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
- systemui:broadcast="true"
- android:src="@drawable/car_ic_hvac"
- android:background="?android:attr/selectableItemBackground"
- android:paddingTop="30dp"
- android:paddingBottom="30dp"
- />
-
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:gravity="bottom"
- android:orientation="vertical">
-
- <com.android.systemui.statusbar.AlphaOptimizedImageView
- android:id="@+id/note"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:src="@drawable/car_ic_notification"
- android:background="?android:attr/selectableItemBackground"
- android:paddingTop="20dp"
- android:paddingBottom="20dp"
- android:alpha="0.7"
- />
-
-
- <com.android.systemui.statusbar.policy.Clock
- android:id="@+id/clock"
- android:textAppearance="@style/TextAppearance.StatusBar.Clock"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:singleLine="true"
- android:paddingStart="@dimen/status_bar_clock_starting_padding"
- android:paddingEnd="@dimen/status_bar_clock_end_padding"
- android:gravity="center_horizontal"
- android:paddingBottom="20dp"
- />
-
- <Space
- android:layout_height="10dp"
- android:layout_width="match_parent"/>
-
- </LinearLayout>
-
-</com.android.systemui.car.navigationbar.CarNavigationBarView>
diff --git a/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
deleted file mode 100644
index 9e6dd11..0000000
--- a/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2018, 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.
-*/
--->
-
-<com.android.systemui.car.navigationbar.CarNavigationBarView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:orientation="vertical"
- android:background="@drawable/system_bar_background">
-
- <LinearLayout
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:id="@+id/nav_buttons"
- android:orientation="vertical"
- android:gravity="top"
- android:paddingTop="30dp"
- android:layout_weight="1"
- android:animateLayoutChanges="true">
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/home"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
- android:src="@drawable/car_ic_overview"
- android:background="?android:attr/selectableItemBackground"
- android:paddingTop="30dp"
- android:paddingBottom="30dp"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/hvac"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
- systemui:broadcast="true"
- android:src="@drawable/car_ic_hvac"
- android:background="?android:attr/selectableItemBackground"
- android:paddingTop="30dp"
- android:paddingBottom="30dp"
- />
- </LinearLayout>
-</com.android.systemui.car.navigationbar.CarNavigationBarView>
diff --git a/packages/CarSystemUI/res/layout/car_status_bar_header.xml b/packages/CarSystemUI/res/layout/car_status_bar_header.xml
deleted file mode 100644
index 12c9f11..0000000
--- a/packages/CarSystemUI/res/layout/car_status_bar_header.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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
- -->
-<!-- Extends LinearLayout -->
-<com.android.systemui.car.userswitcher.CarStatusBarHeader
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/header"
- android:layout_width="match_parent"
- android:layout_height="@dimen/status_bar_height">
-
- <include layout="@layout/car_top_navigation_bar"
- android:id="@+id/qs_car_top_bar"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- />
-</com.android.systemui.car.userswitcher.CarStatusBarHeader>
diff --git a/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml
deleted file mode 100644
index 7994b19..0000000
--- a/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml
+++ /dev/null
@@ -1,135 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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
- -->
-
-<com.android.systemui.car.navigationbar.CarNavigationBarView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:id="@+id/car_top_bar"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/system_bar_background"
- android:orientation="vertical">
-
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:layoutDirection="ltr">
-
- <FrameLayout
- android:id="@+id/system_icon_area"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentStart="true"
- android:layout_marginTop="@dimen/car_padding_2"
- android:layout_marginStart="@dimen/car_padding_2"
- android:layout_centerVertical="true"
- android:gravity="center_vertical"
- >
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:background="@drawable/system_bar_background_pill"
- android:layout_weight="1"
- android:gravity="center_vertical"
- systemui:intent="intent:#Intent;component=com.android.car.settings/.common.CarSettingActivities$QuickSettingActivity;launchFlags=0x24000000;end">
-
- <include
- layout="@layout/system_icons"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:layout_marginStart="@dimen/car_padding_2"
- android:layout_marginEnd="@dimen/car_padding_2"
- android:gravity="center_vertical"
- />
- </com.android.systemui.car.navigationbar.CarNavigationButton>
- </FrameLayout>
-
- <FrameLayout
- android:id="@+id/clock_container"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_centerInParent="true"
- >
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/qs"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@null"
- systemui:intent="intent:#Intent;component=com.android.car.settings/.common.CarSettingActivities$QuickSettingActivity;launchFlags=0x24000000;end"
- />
- <com.android.systemui.statusbar.policy.Clock
- android:id="@+id/clock"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:elevation="5dp"
- android:singleLine="true"
- android:textAppearance="@style/TextAppearance.SystemBar.Clock"
- systemui:amPmStyle="normal"
- />
- </FrameLayout>
-
- <FrameLayout
- android:id="@+id/user_name_container"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentEnd="true"
- android:layout_centerVertical="true"
- android:layout_marginTop="@dimen/car_padding_2"
- >
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/user_name"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_marginEnd="@dimen/car_padding_2"
- android:background="@drawable/system_bar_background_pill"
- android:gravity="center_vertical"
- systemui:intent="intent:#Intent;component=com.android.car.settings/.users.UserSwitcherActivity;launchFlags=0x24000000;end"
- >
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal"
- android:layout_marginStart="@dimen/car_padding_2"
- android:layout_marginEnd="@dimen/car_padding_2"
- android:gravity="center_vertical"
- >
- <ImageView
- android:id="@+id/user_avatar"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:src="@drawable/car_ic_user_icon"
- android:layout_marginEnd="@dimen/system_bar_user_icon_padding"
- />
- <TextView
- android:id="@+id/user_name_text"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:gravity="center_vertical"
- android:textAppearance="@style/TextAppearance.SystemBar.Username"
- android:maxLines="1"
- android:maxLength="10"
- android:layout_marginEnd="@dimen/system_bar_user_icon_padding"
- />
- </LinearLayout>
- </com.android.systemui.car.navigationbar.CarNavigationButton>
- </FrameLayout>
- </RelativeLayout>
-
-</com.android.systemui.car.navigationbar.CarNavigationBarView>
diff --git a/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml
deleted file mode 100644
index b8ac2b4..0000000
--- a/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml
+++ /dev/null
@@ -1,135 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 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
- -->
-
-<com.android.systemui.car.navigationbar.CarNavigationBarView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:id="@+id/car_top_bar"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/system_bar_background"
- android:orientation="vertical">
-
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1">
-
- <FrameLayout
- android:id="@+id/left_hvac_container"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentStart="true"
- >
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/hvacleft"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@null"
- systemui:broadcast="true"
- systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
- />
-
- <com.android.systemui.car.hvac.AnimatedTemperatureView
- android:id="@+id/lefttext"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:paddingStart="@*android:dimen/car_padding_4"
- android:paddingEnd="16dp"
- android:gravity="center_vertical|start"
- android:minEms="4"
- android:textAppearance="@style/TextAppearance.CarStatus"
- systemui:hvacAreaId="49"
- systemui:hvacPivotOffset="60dp"
- />
- </FrameLayout>
-
- <FrameLayout
- android:id="@+id/clock_container"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_centerInParent="true">
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/qs"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@null"/>
- <com.android.systemui.statusbar.policy.Clock
- android:id="@+id/clock"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:elevation="5dp"
- android:singleLine="true"
- android:textAppearance="@style/TextAppearance.StatusBar.Clock"/>
- </FrameLayout>
-
- <LinearLayout
- android:id="@+id/system_icon_area"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_centerHorizontal="true"
- android:layout_centerVertical="true"
- android:layout_toEndOf="@+id/clock_container"
- android:paddingStart="@*android:dimen/car_padding_1"
- android:gravity="center_vertical"
- android:orientation="horizontal"
- >
-
- <include
- layout="@layout/system_icons"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:paddingStart="4dp"
- android:gravity="center_vertical"
- />
- </LinearLayout>
-
- <FrameLayout
- android:id="@+id/right_hvac_container"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentEnd="true"
- >
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/hvacright"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@null"
- systemui:broadcast="true"
- systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
- />
-
- <com.android.systemui.car.hvac.AnimatedTemperatureView
- android:id="@+id/righttext"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:paddingStart="16dp"
- android:paddingEnd="@*android:dimen/car_padding_4"
- android:gravity="center_vertical|end"
- android:minEms="4"
- android:textAppearance="@style/TextAppearance.CarStatus"
- systemui:hvacAreaId="68"
- systemui:hvacPivotOffset="60dp"
- />
- </FrameLayout>
- </RelativeLayout>
-
-</com.android.systemui.car.navigationbar.CarNavigationBarView>
diff --git a/packages/CarSystemUI/res/layout/car_user_switching_dialog.xml b/packages/CarSystemUI/res/layout/car_user_switching_dialog.xml
deleted file mode 100644
index 09fbf7a..0000000
--- a/packages/CarSystemUI/res/layout/car_user_switching_dialog.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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.
- -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:background="@color/car_user_switching_dialog_background_color">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:layout_gravity="center"
- android:gravity="center_horizontal">
- <ImageView
- android:id="@+id/user_loading_avatar"
- android:layout_width="@dimen/car_fullscreen_user_pod_image_avatar_width"
- android:layout_height="@dimen/car_fullscreen_user_pod_image_avatar_height"/>
-
- <TextView
- android:id="@+id/user_loading"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/car_user_switching_dialog_loading_text_margin_top"
- android:textSize="@dimen/car_user_switching_dialog_loading_text_font_size"
- android:textColor="@color/car_user_switching_dialog_loading_text_color"
- android:layout_below="@id/user_loading_avatar"/>
- </LinearLayout>
-</FrameLayout>
diff --git a/packages/CarSystemUI/res/layout/car_volume_dialog.xml b/packages/CarSystemUI/res/layout/car_volume_dialog.xml
deleted file mode 100644
index 35551ea..0000000
--- a/packages/CarSystemUI/res/layout/car_volume_dialog.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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
- -->
-<androidx.recyclerview.widget.RecyclerView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/volume_list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minWidth="@dimen/volume_dialog_panel_width"/>
diff --git a/packages/CarSystemUI/res/layout/car_volume_item.xml b/packages/CarSystemUI/res/layout/car_volume_item.xml
deleted file mode 100644
index 0b42904..0000000
--- a/packages/CarSystemUI/res/layout/car_volume_item.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2019 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.
--->
-
-<RelativeLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@color/car_volume_dialog_background_color"
- android:paddingStart="@dimen/car_volume_item_padding_start"
- android:paddingEnd="@dimen/car_volume_item_padding_end"
- android:minHeight="@dimen/car_volume_item_height">
-
- <!-- Primary Action. -->
- <ImageView
- android:id="@+id/primary_icon"
- android:layout_width="@dimen/car_volume_item_icon_size"
- android:layout_centerVertical="true"
- android:layout_alignParentStart="true"
- android:layout_height="@dimen/car_volume_item_icon_size"/>
-
- <!-- Note: the horizontal padding and offset are set to 0 so that the track and thumb
- aligns with the proper keylines. -->
- <SeekBar
- android:id="@+id/seek_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="@dimen/car_volume_item_seekbar_margin_vertical"
- android:layout_marginTop="@dimen/car_volume_item_seekbar_margin_vertical"
- android:min="0"
- android:paddingBottom="@dimen/car_volume_item_seekbar_padding_vertical"
- android:layout_centerVertical="true"
- android:paddingEnd="0dp"
- android:paddingStart="0dp"
- android:paddingTop="@dimen/car_volume_item_seekbar_padding_vertical"
- android:splitTrack="false"
- android:layout_toStartOf="@id/supplemental_icon_divider"
- android:layout_marginStart="@dimen/car_volume_item_seekbar_margin_start"
- android:layout_marginEnd="@dimen/car_volume_item_seekbar_margin_end"
- android:thumbOffset="0dp"/>
-
- <!-- Supplemental action. -->
- <View
- android:id="@+id/supplemental_icon_divider"
- android:layout_width="@dimen/car_volume_item_divider_width"
- android:layout_height="@dimen/car_volume_item_divider_height"
- android:layout_marginEnd="@dimen/car_volume_item_divider_margin_end"
- android:layout_centerVertical="true"
- android:layout_toStartOf="@id/supplemental_icon"
- android:background="@color/car_volume_item_divider_color"/>
- <ImageView
- android:id="@+id/supplemental_icon"
- android:layout_width="@dimen/car_volume_item_icon_size"
- android:layout_height="@dimen/car_volume_item_icon_size"
- android:background="?android:attr/selectableItemBackground"
- android:layout_centerVertical="true"
- android:layout_alignParentEnd="true"
- android:scaleType="fitCenter"/>
-</RelativeLayout>
diff --git a/packages/CarSystemUI/res/layout/headsup_container_bottom.xml b/packages/CarSystemUI/res/layout/headsup_container_bottom.xml
deleted file mode 100644
index 5aab0a1..0000000
--- a/packages/CarSystemUI/res/layout/headsup_container_bottom.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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.
- -->
-
-<androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/notification_headsup"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <androidx.constraintlayout.widget.Guideline
- android:id="@+id/gradient_edge"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- app:layout_constraintGuide_begin="@dimen/headsup_scrim_height"/>
-
- <!-- Include a FocusParkingView at the beginning. The rotary controller "parks" the focus here
- when the user navigates to another window. This is also used to prevent wrap-around. -->
- <com.android.car.ui.FocusParkingView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"/>
-
- <View
- android:id="@+id/scrim"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:background="@drawable/headsup_scrim_bottom"
- app:layout_constraintBottom_toBottomOf="@+id/gradient_edge"
- app:layout_constraintTop_toTopOf="parent"/>
-
- <FrameLayout
- android:id="@+id/headsup_content"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/headsup_notification_top_margin"
- app:layout_constraintEnd_toStartOf="parent"
- app:layout_constraintStart_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- />
-
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/layout/notification_center_activity.xml b/packages/CarSystemUI/res/layout/notification_center_activity.xml
deleted file mode 100644
index 0e45e43..0000000
--- a/packages/CarSystemUI/res/layout/notification_center_activity.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2018 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.
--->
-<com.android.car.notification.CarNotificationView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/notification_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/notification_shade_background_color">
-
- <com.android.car.ui.FocusParkingView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
-
- <View
- android:id="@+id/glass_pane"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:translationZ="2dp"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- />
-
- <com.android.car.ui.FocusArea
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:orientation="vertical"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent">
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/notifications"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingBottom="@dimen/notification_shade_list_padding_bottom"/>
- </com.android.car.ui.FocusArea>
-
- <include layout="@layout/notification_handle_bar"/>
-
-</com.android.car.notification.CarNotificationView>
diff --git a/packages/CarSystemUI/res/layout/notification_handle_bar.xml b/packages/CarSystemUI/res/layout/notification_handle_bar.xml
deleted file mode 100644
index 99c3a02..0000000
--- a/packages/CarSystemUI/res/layout/notification_handle_bar.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2019, 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.
-*/
--->
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <View
- android:id="@+id/handle_bar"
- android:layout_width="match_parent"
- android:layout_height="@dimen/notification_shade_handle_bar_height"
- android:layout_marginBottom="@dimen/notification_shade_handle_bar_margin_bottom"
- android:layout_marginEnd="@dimen/notification_shade_handle_bar_margin_start"
- android:layout_marginStart="@dimen/notification_shade_handle_bar_margin_end"
- android:layout_marginTop="@dimen/notification_shade_handle_bar_margin_top"
- android:background="@drawable/notification_handle_bar"/>
-</merge>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/layout/notification_panel_container.xml b/packages/CarSystemUI/res/layout/notification_panel_container.xml
deleted file mode 100644
index 3b53c6a..0000000
--- a/packages/CarSystemUI/res/layout/notification_panel_container.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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.
- -->
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/notification_container"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="invisible"/>
diff --git a/packages/CarSystemUI/res/layout/rear_view_camera.xml b/packages/CarSystemUI/res/layout/rear_view_camera.xml
deleted file mode 100644
index 9b9898c..0000000
--- a/packages/CarSystemUI/res/layout/rear_view_camera.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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/rear_view_camera_container"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@android:color/transparent"
- android:orientation="vertical">
- <Button
- android:id="@+id/close_button"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@color/rear_view_camera_button_background"
- android:text="@string/rear_view_camera_close_button_text"
- android:textAppearance="?android:attr/textAppearanceLarge"/>
-</LinearLayout>
diff --git a/packages/CarSystemUI/res/layout/status_bar_wifi_group.xml b/packages/CarSystemUI/res/layout/status_bar_wifi_group.xml
deleted file mode 100644
index 531e577..0000000
--- a/packages/CarSystemUI/res/layout/status_bar_wifi_group.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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
- -->
-<com.android.systemui.statusbar.StatusBarWifiView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:id="@+id/wifi_combo"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:gravity="center_vertical">
-
- <com.android.keyguard.AlphaOptimizedLinearLayout
- android:id="@+id/wifi_group"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:paddingStart="2dp"
- android:gravity="center_vertical"
- >
- <FrameLayout
- android:id="@+id/inout_container"
- android:layout_width="wrap_content"
- android:layout_height="17dp"
- android:gravity="center_vertical">
- <ImageView
- android:id="@+id/wifi_in"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingEnd="2dp"
- android:src="@drawable/ic_activity_down"
- android:visibility="gone"
- />
- <ImageView
- android:id="@+id/wifi_out"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingEnd="2dp"
- android:src="@drawable/ic_activity_up"
- android:visibility="gone"
- />
- </FrameLayout>
- <FrameLayout
- android:id="@+id/wifi_combo"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center_vertical">
- <com.android.systemui.statusbar.AlphaOptimizedImageView
- android:id="@+id/wifi_signal"
- android:layout_width="@*android:dimen/status_bar_system_icon_size"
- android:layout_height="@*android:dimen/status_bar_system_icon_size"
- android:theme="?attr/lightIconTheme"/>
- </FrameLayout>
-
- <View
- android:id="@+id/wifi_signal_spacer"
- android:layout_width="@dimen/status_bar_wifi_signal_spacer_width"
- android:layout_height="4dp"
- android:visibility="gone"/>
-
- <ViewStub
- android:id="@+id/connected_device_signals_stub"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout="@layout/connected_device_signal"/>
-
- <View
- android:id="@+id/wifi_airplane_spacer"
- android:layout_width="@dimen/status_bar_airplane_spacer_width"
- android:layout_height="4dp"
- android:visibility="gone"
- />
- </com.android.keyguard.AlphaOptimizedLinearLayout>
-</com.android.systemui.statusbar.StatusBarWifiView>
diff --git a/packages/CarSystemUI/res/layout/system_icons.xml b/packages/CarSystemUI/res/layout/system_icons.xml
deleted file mode 100644
index f6ffcc8..0000000
--- a/packages/CarSystemUI/res/layout/system_icons.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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/system_icons"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center_vertical"
- android:orientation="horizontal">
-
- <com.android.systemui.statusbar.phone.StatusIconContainer
- android:id="@+id/statusIcons"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:scaleType="fitCenter"
- android:gravity="center_vertical"
- android:orientation="horizontal"
- />
-
- <ImageView
- android:id="@+id/settingsIcon"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_marginStart="@dimen/car_padding_2"
- android:src="@drawable/car_ic_settings_icon"
- />
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/layout/sysui_overlay_window.xml b/packages/CarSystemUI/res/layout/sysui_overlay_window.xml
deleted file mode 100644
index 980265e..0000000
--- a/packages/CarSystemUI/res/layout/sysui_overlay_window.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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.
- -->
-
-<!-- Fullscreen views in sysui should be listed here in increasing Z order. -->
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:background="@android:color/transparent"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <ViewStub android:id="@+id/notification_panel_stub"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout="@layout/notification_panel_container"/>
-
- <ViewStub android:id="@+id/keyguard_stub"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout="@layout/keyguard_container" />
-
- <ViewStub android:id="@+id/fullscreen_user_switcher_stub"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout="@layout/car_fullscreen_user_switcher"/>
-
- <ViewStub android:id="@+id/user_switching_dialog_stub"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout="@layout/car_user_switching_dialog"/>
-
- <!-- Should be at bottom to get the highest Z-order. -->
- <ViewStub android:id="@+id/rear_view_camera_stub"
- android:layout_width="@dimen/rear_view_camera_width"
- android:layout_height="@dimen/rear_view_camera_height"
- android:layout_gravity="center"
- android:layout="@layout/rear_view_camera"/>
-</FrameLayout>
diff --git a/packages/CarSystemUI/res/values-af/strings.xml b/packages/CarSystemUI/res/values-af/strings.xml
deleted file mode 100644
index cf288d7..0000000
--- a/packages/CarSystemUI/res/values-af/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Stemherkenning nou deur gekoppelde Bluetooth-toestel hanteer"</string>
- <string name="car_guest" msgid="318393171202663722">"Gas"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Gas"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Voeg gebruiker by"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Nuwe gebruiker"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Wanneer jy \'n nuwe gebruiker byvoeg, moet daardie persoon hul spasie opstel."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Enige gebruiker kan programme vir al die ander gebruikers opdateer."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Laai tans"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Laai tans gebruiker (van <xliff:g id="FROM_USER">%1$d</xliff:g> na <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Maak toe"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-am/strings.xml b/packages/CarSystemUI/res/values-am/strings.xml
deleted file mode 100644
index 8281631..0000000
--- a/packages/CarSystemUI/res/values-am/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"ዝቅተኛ"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"ከፍተኛ"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"የድምፅ ለይቶ ማወቅ አሁን በተገናኘ የብሉቱዝ መሣሪያ ይስተናገዳል"</string>
- <string name="car_guest" msgid="318393171202663722">"እንግዳ"</string>
- <string name="start_guest_session" msgid="497784785761754874">"እንግዳ"</string>
- <string name="car_add_user" msgid="4067337059622483269">"ተጠቃሚ አክል"</string>
- <string name="car_new_user" msgid="6637442369728092473">"አዲስ ተጠቃሚ"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"አዲስ ተጠቃሚ ሲያክሉ ያ ሰው የራሳቸውን ቦታ ማቀናበር አለባቸው።"</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"ማንኛውም ተጠቃሚ መተግበሪያዎችን ለሌሎች ተጠቃሚዎች ሁሉ ማዘመን ይችላል።"</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"በመጫን ላይ"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"ተጠቃሚን (ከ<xliff:g id="FROM_USER">%1$d</xliff:g> ወደ <xliff:g id="TO_USER">%2$d</xliff:g>) በመጫን ላይ"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"ዝጋ"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-ar/strings.xml b/packages/CarSystemUI/res/values-ar/strings.xml
deleted file mode 100644
index d9abb0a..0000000
--- a/packages/CarSystemUI/res/values-ar/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"حد أدنى"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"حد أقصى"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"تتم معالجة التعرّف على الصوت الآن من خلال جهاز بلوتوث متصل."</string>
- <string name="car_guest" msgid="318393171202663722">"ضيف"</string>
- <string name="start_guest_session" msgid="497784785761754874">"ضيف"</string>
- <string name="car_add_user" msgid="4067337059622483269">"إضافة مستخدم"</string>
- <string name="car_new_user" msgid="6637442369728092473">"مستخدم جديد"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"عند إضافة مستخدم جديد، على هذا المستخدم إعداد مساحته."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"يمكن لأي مستخدم تحديث التطبيقات لجميع المستخدمين الآخرين."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"جارٍ التحميل"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"جارٍ تحميل الملف الشخصي الجديد للمستخدم (من <xliff:g id="FROM_USER">%1$d</xliff:g> إلى <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"إغلاق"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-as/strings.xml b/packages/CarSystemUI/res/values-as/strings.xml
deleted file mode 100644
index d871055..0000000
--- a/packages/CarSystemUI/res/values-as/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"সর্বনিম্ন"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"সৰ্বাধিক"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"কণ্ঠস্বৰৰ চিনাক্তকৰণ এতিয়া সংযুক্ত ব্লুটুথ ডিভাইচে নিয়ন্ত্ৰণ কৰে"</string>
- <string name="car_guest" msgid="318393171202663722">"অতিথি"</string>
- <string name="start_guest_session" msgid="497784785761754874">"অতিথি"</string>
- <string name="car_add_user" msgid="4067337059622483269">"ব্যৱহাৰকাৰী যোগ দিয়ক"</string>
- <string name="car_new_user" msgid="6637442369728092473">"নতুন ব্যৱহাৰকাৰী"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"আপুনি যেতিয়া এজন নতুন ব্যৱহাৰকাৰীক যোগ কৰে, তেতিয়া তেওঁ নিজৰ ঠাই ছেট আপ কৰাটো প্ৰয়োজন হয়।"</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"যিকোনো ব্যৱহাৰকাৰীয়ে অন্য ব্যৱহাৰকাৰীৰ বাবে এপ্সমূহ আপডে’ট কৰিব পাৰে।"</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"ল’ড হৈ আছে"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"ব্যৱহাৰকাৰী ল’ড হৈ আছে (<xliff:g id="FROM_USER">%1$d</xliff:g>ৰ পৰা to <xliff:g id="TO_USER">%2$d</xliff:g>লৈ)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"বন্ধ কৰক"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-az/strings.xml b/packages/CarSystemUI/res/values-az/strings.xml
deleted file mode 100644
index 89c9eb4..0000000
--- a/packages/CarSystemUI/res/values-az/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Maks"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Səs tanınması qoşulmuş Bluetooth cihazı ilə icra edilir"</string>
- <string name="car_guest" msgid="318393171202663722">"Qonaq"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Qonaq"</string>
- <string name="car_add_user" msgid="4067337059622483269">"İstifadəçi əlavə edin"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Yeni İstifadəçi"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Yeni istifadəçi əlavə etdiyinizdə həmin şəxs öz yerini təyin etməlidir."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"İstənilən istifadəçi digər bütün istifadəçilər üçün tətbiqləri güncəlləyə bilər."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Yüklənir"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"İstifadəçi yüklənir (<xliff:g id="FROM_USER">%1$d</xliff:g>-<xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Qapadın"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-b+sr+Latn/strings.xml b/packages/CarSystemUI/res/values-b+sr+Latn/strings.xml
deleted file mode 100644
index 6aee013..0000000
--- a/packages/CarSystemUI/res/values-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Prepoznavanjem glasa sada upravlja povezani Bluetooth uređaj"</string>
- <string name="car_guest" msgid="318393171202663722">"Gost"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Gost"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Dodaj korisnika"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Novi korisnik"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kada dodate novog korisnika, ta osoba treba da podesi svoj prostor."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Svaki korisnik može da ažurira aplikacije za sve ostale korisnike."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Učitava se"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Profil korisnika se učitava (iz<xliff:g id="FROM_USER">%1$d</xliff:g> u <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Zatvori"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-be/strings.xml b/packages/CarSystemUI/res/values-be/strings.xml
deleted file mode 100644
index fde4273..0000000
--- a/packages/CarSystemUI/res/values-be/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Мін"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Макс"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Распазнаванне голасу выконвае падключаная прылада Bluetooth"</string>
- <string name="car_guest" msgid="318393171202663722">"Госць"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Госць"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Дадаць карыстальніка"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Новы карыстальнік"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Калі вы дадаяце новага карыстальніка, яму трэба наладзіць свой профіль."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Кожны карыстальнік прылады можа абнаўляць праграмы для ўсіх іншых карыстальнікаў."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Ідзе загрузка"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Ідзе загрузка профілю карыстальніка (ад <xliff:g id="FROM_USER">%1$d</xliff:g> да <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Закрыць"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-bg/strings.xml b/packages/CarSystemUI/res/values-bg/strings.xml
deleted file mode 100644
index 25f2845..0000000
--- a/packages/CarSystemUI/res/values-bg/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Мин."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Макс."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Гл. разпознаване се обработва от свързаното у-во с Bluetooth"</string>
- <string name="car_guest" msgid="318393171202663722">"Гост"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Гост"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Добавяне на потребител"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Нов потребител"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Когато добавите нов потребител, той трябва да настрои работната си област."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Всеки потребител може да актуализира приложенията за всички останали потребители."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Зарежда се"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Потребителят се зарежда (от <xliff:g id="FROM_USER">%1$d</xliff:g> до <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Затваряне"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-bn/strings.xml b/packages/CarSystemUI/res/values-bn/strings.xml
deleted file mode 100644
index 5664cc1..0000000
--- a/packages/CarSystemUI/res/values-bn/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"সর্বনিম্ন"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"সর্বাধিক"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"কানেক্ট করা ব্লুটুথ ডিভাইস এখন ভয়েস শনাক্তকরণ ম্যানেজ করছে"</string>
- <string name="car_guest" msgid="318393171202663722">"অতিথি"</string>
- <string name="start_guest_session" msgid="497784785761754874">"অতিথি"</string>
- <string name="car_add_user" msgid="4067337059622483269">"ব্যবহারকারীকে যোগ করুন"</string>
- <string name="car_new_user" msgid="6637442369728092473">"নতুন ব্যবহারকারী"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"নতুন ব্যবহারকারী যোগ করলে, তার স্পেস তাকে সেট-আপ করে নিতে হবে।"</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"যেকোনও ব্যবহারকারী বাকি সব ব্যবহারকারীর জন্য অ্যাপ আপডেট করতে পারবেন।"</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"লোড হচ্ছে"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"ব্যবহারকারীর প্রোফাইল লোড করা হচ্ছে (<xliff:g id="FROM_USER">%1$d</xliff:g> থেকে <xliff:g id="TO_USER">%2$d</xliff:g>-এ)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"বন্ধ করুন"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-bs/strings.xml b/packages/CarSystemUI/res/values-bs/strings.xml
deleted file mode 100644
index 588771e..0000000
--- a/packages/CarSystemUI/res/values-bs/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Prepoznavanjem glasa sada upravlja povezani Bluetooth uređaj"</string>
- <string name="car_guest" msgid="318393171202663722">"Gost"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Gost"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Dodaj korisnika"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Novi korisnik"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kada dodate novog korisnika, ta osoba treba postaviti svoj prostor."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Bilo koji korisnik može ažurirati aplikacije za sve druge korisnike."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Učitavanje"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Učitavanje korisnika (od korisnika <xliff:g id="FROM_USER">%1$d</xliff:g> do korisnika <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Zatvori"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-ca/strings.xml b/packages/CarSystemUI/res/values-ca/strings.xml
deleted file mode 100644
index c151d48..0000000
--- a/packages/CarSystemUI/res/values-ca/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Mín."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Màx."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Reconeixement de veu gestionat per disp. Bluetooth connectat"</string>
- <string name="car_guest" msgid="318393171202663722">"Convidat"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Convidat"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Afegeix un usuari"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Usuari nou"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Quan s\'afegeix un usuari nou, aquesta persona ha de configurar el seu espai."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Qualsevol usuari pot actualitzar les aplicacions de la resta d\'usuaris."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"S\'està carregant"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"S\'està carregant l\'usuari (de <xliff:g id="FROM_USER">%1$d</xliff:g> a <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Tanca"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-cs/strings.xml b/packages/CarSystemUI/res/values-cs/strings.xml
deleted file mode 100644
index 7657e32..0000000
--- a/packages/CarSystemUI/res/values-cs/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Rozpoznávání hlasu teď provádí připojené zařízení Bluetooth"</string>
- <string name="car_guest" msgid="318393171202663722">"Host"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Host"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Přidat uživatele"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Nový uživatel"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Každý nově přidaný uživatel si musí nastavit vlastní prostor."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Každý uživatel může aktualizovat aplikace všech ostatních uživatelů."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Načítání"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Načítání uživatele (předchozí: <xliff:g id="FROM_USER">%1$d</xliff:g>, následující: <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Zavřít"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-da/strings.xml b/packages/CarSystemUI/res/values-da/strings.xml
deleted file mode 100644
index 120929e..0000000
--- a/packages/CarSystemUI/res/values-da/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Talegenkendelse sker nu med den forbundne Blutetooth-enhed"</string>
- <string name="car_guest" msgid="318393171202663722">"Gæst"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Gæst"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Tilføj bruger"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Ny bruger"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Når du tilføjer en ny bruger, skal vedkommende konfigurere sit område."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Alle brugere kan opdatere apps for alle andre brugere."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Indlæser"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Indlæser bruger (fra <xliff:g id="FROM_USER">%1$d</xliff:g> til <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Luk"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-de/strings.xml b/packages/CarSystemUI/res/values-de/strings.xml
deleted file mode 100644
index e2437f0..0000000
--- a/packages/CarSystemUI/res/values-de/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Max."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Spracherkennung jetzt über das verbundene Bluetooth-Gerät"</string>
- <string name="car_guest" msgid="318393171202663722">"Gast"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Gast"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Nutzer hinzufügen"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Neuer Nutzer"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Wenn du einen neuen Nutzer hinzufügst, muss dieser seinen Bereich einrichten."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Jeder Nutzer kann Apps für alle anderen Nutzer aktualisieren."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Wird geladen"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Nutzer wird geladen (von <xliff:g id="FROM_USER">%1$d</xliff:g> bis <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Schließen"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-el/strings.xml b/packages/CarSystemUI/res/values-el/strings.xml
deleted file mode 100644
index 9b24fa4..0000000
--- a/packages/CarSystemUI/res/values-el/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Ελάχ."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Μεγ."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Φωνητική αναγνωση από συνδεδεμένη συσκευή Bluetooth"</string>
- <string name="car_guest" msgid="318393171202663722">"Επισκέπτης"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Επισκέπτης"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Προσθήκη χρήστη"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Νέος χρήστης"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Κατά την προσθήκη ενός νέου χρήστη, αυτός θα πρέπει να ρυθμίσει τον χώρο του."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Οποιοσδήποτε χρήστης μπορεί να ενημερώσει τις εφαρμογές για όλους τους άλλους χρήστες."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Φόρτωση"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Φόρτωση χρήστη (από <xliff:g id="FROM_USER">%1$d</xliff:g> έως <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Κλείσιμο"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-en-rAU/strings.xml b/packages/CarSystemUI/res/values-en-rAU/strings.xml
deleted file mode 100644
index 8eb76c2..0000000
--- a/packages/CarSystemUI/res/values-en-rAU/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Voice recognition now handled by connected Bluetooth device"</string>
- <string name="car_guest" msgid="318393171202663722">"Guest"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Guest"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Add user"</string>
- <string name="car_new_user" msgid="6637442369728092473">"New user"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"When you add a new user, that person needs to set up their space."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Loading"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Loading user (from <xliff:g id="FROM_USER">%1$d</xliff:g> to <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Close"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-en-rCA/strings.xml b/packages/CarSystemUI/res/values-en-rCA/strings.xml
deleted file mode 100644
index 8eb76c2..0000000
--- a/packages/CarSystemUI/res/values-en-rCA/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Voice recognition now handled by connected Bluetooth device"</string>
- <string name="car_guest" msgid="318393171202663722">"Guest"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Guest"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Add user"</string>
- <string name="car_new_user" msgid="6637442369728092473">"New user"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"When you add a new user, that person needs to set up their space."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Loading"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Loading user (from <xliff:g id="FROM_USER">%1$d</xliff:g> to <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Close"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-en-rGB/strings.xml b/packages/CarSystemUI/res/values-en-rGB/strings.xml
deleted file mode 100644
index 8eb76c2..0000000
--- a/packages/CarSystemUI/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Voice recognition now handled by connected Bluetooth device"</string>
- <string name="car_guest" msgid="318393171202663722">"Guest"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Guest"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Add user"</string>
- <string name="car_new_user" msgid="6637442369728092473">"New user"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"When you add a new user, that person needs to set up their space."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Loading"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Loading user (from <xliff:g id="FROM_USER">%1$d</xliff:g> to <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Close"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-en-rIN/strings.xml b/packages/CarSystemUI/res/values-en-rIN/strings.xml
deleted file mode 100644
index 8eb76c2..0000000
--- a/packages/CarSystemUI/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Voice recognition now handled by connected Bluetooth device"</string>
- <string name="car_guest" msgid="318393171202663722">"Guest"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Guest"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Add user"</string>
- <string name="car_new_user" msgid="6637442369728092473">"New user"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"When you add a new user, that person needs to set up their space."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Loading"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Loading user (from <xliff:g id="FROM_USER">%1$d</xliff:g> to <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Close"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-en-rXC/strings.xml b/packages/CarSystemUI/res/values-en-rXC/strings.xml
deleted file mode 100644
index 37a568b..0000000
--- a/packages/CarSystemUI/res/values-en-rXC/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Voice recognition now handled by connected Bluetooth device"</string>
- <string name="car_guest" msgid="318393171202663722">"Guest"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Guest"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Add User"</string>
- <string name="car_new_user" msgid="6637442369728092473">"New User"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"When you add a new user, that person needs to set up their space."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Loading"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Loading user (from <xliff:g id="FROM_USER">%1$d</xliff:g> to <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Close"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-es-rUS/strings.xml b/packages/CarSystemUI/res/values-es-rUS/strings.xml
deleted file mode 100644
index e067594..0000000
--- a/packages/CarSystemUI/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Mín."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Máx."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"El dispositivo Bluetooth administra el reconocimiento de voz"</string>
- <string name="car_guest" msgid="318393171202663722">"Invitado"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Invitado"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Agregar usuario"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Usuario nuevo"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Cuando agregues un usuario nuevo, esa persona deberá configurar su espacio."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Cualquier usuario puede actualizar las aplicaciones del resto de los usuarios."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Cargando"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Cargando usuario (de <xliff:g id="FROM_USER">%1$d</xliff:g> a <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Cerrar"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-es/strings.xml b/packages/CarSystemUI/res/values-es/strings.xml
deleted file mode 100644
index 8aad2ca..0000000
--- a/packages/CarSystemUI/res/values-es/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Mín."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Máx."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"El dispositivo Bluetooth gestiona el reconocimiento de voz"</string>
- <string name="car_guest" msgid="318393171202663722">"Invitado"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Invitado"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Añadir usuario"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Nuevo usuario"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Cuando añades un usuario, esa persona debe configurar su espacio."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Cualquier usuario puede actualizar las aplicaciones del resto de los usuarios."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Cargando"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Cargando usuario (de <xliff:g id="FROM_USER">%1$d</xliff:g> a <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Cerrar"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-et/strings.xml b/packages/CarSystemUI/res/values-et/strings.xml
deleted file mode 100644
index 14ec9df..0000000
--- a/packages/CarSystemUI/res/values-et/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Häältuvastust haldab nüüd ühendatud Bluetoothi seade"</string>
- <string name="car_guest" msgid="318393171202663722">"Külaline"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Külaline"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Lisa kasutaja"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Uus kasutaja"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kui lisate uue kasutaja, siis peab ta seadistama oma ruumi."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Iga kasutaja saab rakendusi värskendada kõigi teiste kasutajate jaoks."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Laadimine"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Kasutaja laadimine (<xliff:g id="FROM_USER">%1$d</xliff:g> > <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Sule"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-eu/strings.xml b/packages/CarSystemUI/res/values-eu/strings.xml
deleted file mode 100644
index 9139e65..0000000
--- a/packages/CarSystemUI/res/values-eu/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Max."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Konektatutako Bluetooth bidezko gailuak kudeatzen du ahotsa ezagutzeko eginbidea"</string>
- <string name="car_guest" msgid="318393171202663722">"Gonbidatua"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Gonbidatua"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Gehitu erabiltzaile bat"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Erabiltzaile berria"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Erabiltzaile bat gehitzen duzunean, bere eremua konfiguratu beharko du."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Edozein erabiltzailek egunera ditzake beste erabiltzaile guztien aplikazioak."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Kargatzen"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Erabiltzailea kargatzen (<xliff:g id="FROM_USER">%1$d</xliff:g> izatetik<xliff:g id="TO_USER">%2$d</xliff:g> izatera igaroko da)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Itxi"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-fa/strings.xml b/packages/CarSystemUI/res/values-fa/strings.xml
deleted file mode 100644
index 3f53b11..0000000
--- a/packages/CarSystemUI/res/values-fa/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"حداقل"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"حداکثر"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"اکنون تشخیص صدا را دستگاه بلوتوث متصل کنترل میکند"</string>
- <string name="car_guest" msgid="318393171202663722">"مهمان"</string>
- <string name="start_guest_session" msgid="497784785761754874">"مهمان"</string>
- <string name="car_add_user" msgid="4067337059622483269">"افزودن کاربر"</string>
- <string name="car_new_user" msgid="6637442369728092473">"کاربر جدید"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"وقتی کاربر جدیدی اضافه میکنید، آن فرد باید فضای خود را تنظیم کند."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"هر کاربری میتواند برنامهها را برای همه کاربران دیگر بهروزرسانی کند."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"درحال بارگیری"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"بارگیری کاربر (از <xliff:g id="FROM_USER">%1$d</xliff:g> تا <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"بستن"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-fi/strings.xml b/packages/CarSystemUI/res/values-fi/strings.xml
deleted file mode 100644
index 4c20f85..0000000
--- a/packages/CarSystemUI/res/values-fi/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Alin"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Ylin"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Äänentunnistus tehdään nyt yhdistetyllä Bluetooth-laitteella"</string>
- <string name="car_guest" msgid="318393171202663722">"Vieras"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Vieras"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Lisää käyttäjä"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Uusi käyttäjä"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kun lisäät uuden käyttäjän, hänen on valittava oman tilansa asetukset."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Kaikki käyttäjät voivat päivittää sovelluksia muille käyttäjille."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Ladataan"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Ladataan käyttäjäprofiilia (<xliff:g id="FROM_USER">%1$d</xliff:g>–<xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Sulje"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-fr-rCA/strings.xml b/packages/CarSystemUI/res/values-fr-rCA/strings.xml
deleted file mode 100644
index b190549..0000000
--- a/packages/CarSystemUI/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"La reconn. voc. est gérée par l\'appareil Bluetooth connecté"</string>
- <string name="car_guest" msgid="318393171202663722">"Invité"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Invité"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Ajouter un utilisateur"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Nouvel utilisateur"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Lorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Tout utilisateur peut mettre à jour les applications pour tous les autres utilisateurs."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Chargement en cours…"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Chargement de l\'utilisateur (de <xliff:g id="FROM_USER">%1$d</xliff:g> vers <xliff:g id="TO_USER">%2$d</xliff:g>) en cours…"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Fermer"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-fr/strings.xml b/packages/CarSystemUI/res/values-fr/strings.xml
deleted file mode 100644
index 5a905a0..0000000
--- a/packages/CarSystemUI/res/values-fr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"L\'appareil Bluetooth connecté gère la reconnaissance vocale"</string>
- <string name="car_guest" msgid="318393171202663722">"Invité"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Invité"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Ajouter un utilisateur"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Nouvel utilisateur"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Lorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"N\'importe quel utilisateur peut mettre à jour les applications pour tous les autres utilisateurs."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Chargement…"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Chargement de l\'utilisateur (de <xliff:g id="FROM_USER">%1$d</xliff:g> à <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Fermer"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-gl/strings.xml b/packages/CarSystemUI/res/values-gl/strings.xml
deleted file mode 100644
index e77df4f..0000000
--- a/packages/CarSystemUI/res/values-gl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Mín."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Máx."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"O dispositivo Bluetooth xestionará o recoñecemento de voz"</string>
- <string name="car_guest" msgid="318393171202663722">"Convidado"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Convidado"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Engadir usuario"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Novo usuario"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Cando engadas un novo usuario, este deberá configurar o seu espazo."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Calquera usuario pode actualizar as aplicacións para o resto dos usuarios."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Cargando"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Cargando usuario (do <xliff:g id="FROM_USER">%1$d</xliff:g> ao <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Pechar"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-gu/strings.xml b/packages/CarSystemUI/res/values-gu/strings.xml
deleted file mode 100644
index 174d7a7..0000000
--- a/packages/CarSystemUI/res/values-gu/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"ન્યૂનતમ"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"મહત્તમ"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"અવાજની ઓળખ હવે કનેક્ટેડ બ્લૂટૂથ ડિવાઇસ વડે નિયંત્રિત થશે"</string>
- <string name="car_guest" msgid="318393171202663722">"અતિથિ"</string>
- <string name="start_guest_session" msgid="497784785761754874">"અતિથિ"</string>
- <string name="car_add_user" msgid="4067337059622483269">"વપરાશકર્તા ઉમેરો"</string>
- <string name="car_new_user" msgid="6637442369728092473">"નવા વપરાશકર્તા"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"જ્યારે તમે કોઈ નવા વપરાશકર્તાને ઉમેરો છો, ત્યારે તે વ્યક્તિએ તેમની સ્પેસ સેટ કરવાની જરૂર રહે છે."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"કોઈપણ વપરાશકર્તા અન્ય બધા વપરાશકર્તાઓ માટે ઍપને અપડેટ કરી શકે છે."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"લોડ કરી રહ્યાં છીએ"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"વપરાશકર્તાને લોડ કરી રહ્યાં છીએ (<xliff:g id="FROM_USER">%1$d</xliff:g>માંથી <xliff:g id="TO_USER">%2$d</xliff:g>માં)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"બંધ કરો"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-hi/strings.xml b/packages/CarSystemUI/res/values-hi/strings.xml
deleted file mode 100644
index 83321fd..0000000
--- a/packages/CarSystemUI/res/values-hi/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"कम से कम"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"ज़्यादा से ज़्यादा"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"अब आवाज़ पहचानने का काम, कनेक्ट किए गए ब्लूटूथ डिवाइस करते हैं"</string>
- <string name="car_guest" msgid="318393171202663722">"मेहमान प्रोफ़ाइल"</string>
- <string name="start_guest_session" msgid="497784785761754874">"मेहमान के तौर पर सेशन शुरू करें"</string>
- <string name="car_add_user" msgid="4067337059622483269">"उपयोगकर्ता जोड़ें"</string>
- <string name="car_new_user" msgid="6637442369728092473">"नया उपयोगकर्ता"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"जब आप कोई नया उपयोगकर्ता जोड़ते हैं, तब उसे अपनी जगह सेट करनी होती है."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"कोई भी उपयोगकर्ता, बाकी सभी उपयोगकर्ताओं के लिए ऐप्लिकेशन अपडेट कर सकता है."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"लोड हो रही है"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"उपयोगकर्ता को लोड किया जा रहा है (<xliff:g id="FROM_USER">%1$d</xliff:g> से <xliff:g id="TO_USER">%2$d</xliff:g> पर)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"बंद करें"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-hr/strings.xml b/packages/CarSystemUI/res/values-hr/strings.xml
deleted file mode 100644
index 872fc69..0000000
--- a/packages/CarSystemUI/res/values-hr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Prepoznavanjem glasa rukuje se s povezanog Bluetooth uređaja"</string>
- <string name="car_guest" msgid="318393171202663722">"Gost"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Gost"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Dodajte korisnika"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Novi korisnik"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kada dodate novog korisnika, ta osoba mora postaviti vlastiti prostor."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Svaki korisnik može ažurirati aplikacije za ostale korisnike."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Učitavanje"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Učitavanje korisnika (od <xliff:g id="FROM_USER">%1$d</xliff:g> do <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Zatvori"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-hu/strings.xml b/packages/CarSystemUI/res/values-hu/strings.xml
deleted file mode 100644
index 63328f3..0000000
--- a/packages/CarSystemUI/res/values-hu/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Max."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"A hangfelismerést a csatlakoztatott Bluetooth-eszköz kezeli"</string>
- <string name="car_guest" msgid="318393171202663722">"Vendég"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Vendég"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Felhasználó hozzáadása"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Új felhasználó"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Ha új felhasználót ad hozzá, az illetőnek be kell állítania saját felületét."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Bármely felhasználó frissítheti az alkalmazásokat az összes felhasználó számára."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Betöltés"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Felhasználó betöltése (<xliff:g id="FROM_USER">%1$d</xliff:g> → <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Bezárás"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-hy/strings.xml b/packages/CarSystemUI/res/values-hy/strings.xml
deleted file mode 100644
index 778f695..0000000
--- a/packages/CarSystemUI/res/values-hy/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Նվազ․"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Առավ․"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Ձայնի ճանաչումը մշակվում է միացված Bluetooth սարքի կողմից"</string>
- <string name="car_guest" msgid="318393171202663722">"Հյուր"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Հյուրի ռեժիմ"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Ավելացնել օգտատեր"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Նոր օգտատեր"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Երբ դուք նոր օգտատեր եք ավելացնում, նա պետք է կարգավորի իր պրոֆիլը։"</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Ցանկացած օգտատեր կարող է թարմացնել հավելվածները բոլոր մյուս հաշիվների համար։"</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Բեռնում"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Օգտատերը բեռնվում է (<xliff:g id="FROM_USER">%1$d</xliff:g> – <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Փակել"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-in/strings.xml b/packages/CarSystemUI/res/values-in/strings.xml
deleted file mode 100644
index 60525ad..0000000
--- a/packages/CarSystemUI/res/values-in/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Maks"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Pengenalan suara ditangani perangkat Bluetooth terhubung"</string>
- <string name="car_guest" msgid="318393171202663722">"Tamu"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Tamu"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Tambahkan Pengguna"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Pengguna Baru"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Jika ditambahkan, pengguna baru harus menyiapkan ruangnya sendiri."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Setiap pengguna dapat mengupdate aplikasi untuk semua pengguna lain."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Memuat"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Memuat pengguna (dari <xliff:g id="FROM_USER">%1$d</xliff:g> menjadi <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Tutup"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-is/strings.xml b/packages/CarSystemUI/res/values-is/strings.xml
deleted file mode 100644
index 5a927aa0..0000000
--- a/packages/CarSystemUI/res/values-is/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Lágm."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Hám."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Raddgreiningu er nú stjórnað af tengdu Bluetooth-tæki"</string>
- <string name="car_guest" msgid="318393171202663722">"Gestur"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Gestur"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Bæta notanda við"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Nýr notandi"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Þegar þú bætir nýjum notanda við þarf viðkomandi að setja upp sitt eigið svæði."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Allir notendur geta uppfært forrit fyrir alla aðra notendur."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Hleður"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Hleður notanda (frá <xliff:g id="FROM_USER">%1$d</xliff:g> til <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Loka"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-it/strings.xml b/packages/CarSystemUI/res/values-it/strings.xml
deleted file mode 100644
index 41d7ad4..0000000
--- a/packages/CarSystemUI/res/values-it/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Riconoscimento vocale gestito da dispos. Bluetooth connesso"</string>
- <string name="car_guest" msgid="318393171202663722">"Ospite"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Ospite"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Aggiungi utente"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Nuovo utente"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Il nuovo utente, una volta aggiunto, dovrà configurare il suo spazio."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Qualsiasi utente può aggiornare le app per tutti gli altri."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Caricamento"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Caricamento dell\'utente (da <xliff:g id="FROM_USER">%1$d</xliff:g> a <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Chiudi"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-iw/strings.xml b/packages/CarSystemUI/res/values-iw/strings.xml
deleted file mode 100644
index f419cac..0000000
--- a/packages/CarSystemUI/res/values-iw/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"מינ\'"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"מקס\'"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"הזיהוי הקולי מתבצע עכשיו במכשיר Bluetooth מחובר"</string>
- <string name="car_guest" msgid="318393171202663722">"אורח"</string>
- <string name="start_guest_session" msgid="497784785761754874">"אורח"</string>
- <string name="car_add_user" msgid="4067337059622483269">"הוספת משתמש"</string>
- <string name="car_new_user" msgid="6637442369728092473">"משתמש חדש"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"בעת הוספת משתמש חדש, על משתמש זה להגדיר את המרחב שלו."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"כל משתמש יכול לעדכן אפליקציות לכל שאר המשתמשים."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"בטעינה"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"המשתמש בטעינה (מהמשתמש <xliff:g id="FROM_USER">%1$d</xliff:g> אל <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"סגירה"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-ja/strings.xml b/packages/CarSystemUI/res/values-ja/strings.xml
deleted file mode 100644
index 9cf056fd..0000000
--- a/packages/CarSystemUI/res/values-ja/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"最小"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"最大"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Bluetooth 接続デバイスで音声認識が処理されるようになりました"</string>
- <string name="car_guest" msgid="318393171202663722">"ゲスト"</string>
- <string name="start_guest_session" msgid="497784785761754874">"ゲスト"</string>
- <string name="car_add_user" msgid="4067337059622483269">"ユーザーを追加"</string>
- <string name="car_new_user" msgid="6637442369728092473">"新しいユーザー"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"新しいユーザーを追加したら、そのユーザーは自分のスペースをセットアップする必要があります。"</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"どのユーザーも他のすべてのユーザーに代わってアプリを更新できます。"</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"読み込んでいます"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"ユーザーを読み込んでいます(<xliff:g id="FROM_USER">%1$d</xliff:g>~<xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"閉じる"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-ka/strings.xml b/packages/CarSystemUI/res/values-ka/strings.xml
deleted file mode 100644
index 7d62c62..0000000
--- a/packages/CarSystemUI/res/values-ka/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"მინ"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"მაქს"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"ხმის ამოცნობა დამუშავდება დაკავშირებული Bluetooth-მოწყობილობით"</string>
- <string name="car_guest" msgid="318393171202663722">"სტუმარი"</string>
- <string name="start_guest_session" msgid="497784785761754874">"სტუმარი"</string>
- <string name="car_add_user" msgid="4067337059622483269">"მომხმარებლის დამატება"</string>
- <string name="car_new_user" msgid="6637442369728092473">"ახალი მომხმარებელი"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"ახალი მომხმარებლის დამატებისას, ამ მომხმარებელს საკუთარი სივრცის გამართვა მოუწევს."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"ნებისმიერ მომხმარებელს შეუძლია აპები ყველა სხვა მომხმარებლისათვის განაახლოს."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"იტვირთება"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"იტვირთება მომხმარებელი (<xliff:g id="FROM_USER">%1$d</xliff:g>-დან <xliff:g id="TO_USER">%2$d</xliff:g>-მდე)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"დახურვა"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-kk/strings.xml b/packages/CarSystemUI/res/values-kk/strings.xml
deleted file mode 100644
index 313fe81..0000000
--- a/packages/CarSystemUI/res/values-kk/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Мин."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Макс."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Дауысты тану үшін Bluetooth құрылғысы пайдаланылады."</string>
- <string name="car_guest" msgid="318393171202663722">"Қонақ"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Қонақ"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Пайдаланушыны енгізу"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Жаңа пайдаланушы"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Қосылған жаңа пайдаланушы өз профилін реттеуі керек."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Кез келген пайдаланушы қолданбаларды басқа пайдаланушылар үшін жаңарта алады."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Жүктелуде"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Пайдаланушы профилі жүктелуде (<xliff:g id="FROM_USER">%1$d</xliff:g> – <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Жабу"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-km/strings.xml b/packages/CarSystemUI/res/values-km/strings.xml
deleted file mode 100644
index 709cfe5..0000000
--- a/packages/CarSystemUI/res/values-km/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"អប្បបរមា"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"អតិបរិមា"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"ឥឡូវនេះ ការសម្គាល់សំឡេងត្រូវបានចាត់ចែងដោយឧបករណ៍ដែលបានភ្ជាប់ប៊្លូធូស"</string>
- <string name="car_guest" msgid="318393171202663722">"ភ្ញៀវ"</string>
- <string name="start_guest_session" msgid="497784785761754874">"ភ្ញៀវ"</string>
- <string name="car_add_user" msgid="4067337059622483269">"បញ្ចូលអ្នកប្រើប្រាស់"</string>
- <string name="car_new_user" msgid="6637442369728092473">"អ្នកប្រើប្រាស់ថ្មី"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"នៅពេលដែលអ្នកបញ្ចូលអ្នកប្រើប្រាស់ថ្មី បុគ្គលនោះត្រូវតែរៀបចំទំហំផ្ទុករបស់គេ។"</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"អ្នកប្រើប្រាស់ណាក៏អាចដំឡើងកំណែកម្មវិធីសម្រាប់អ្នកប្រើប្រាស់ទាំងអស់ផ្សេងទៀតបានដែរ។"</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"កំពុងផ្ទុក"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"កំពុងផ្ទុកអ្នកប្រើប្រាស់ (ពី <xliff:g id="FROM_USER">%1$d</xliff:g> ដល់ <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"បិទ"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-kn/strings.xml b/packages/CarSystemUI/res/values-kn/strings.xml
deleted file mode 100644
index b9667df..0000000
--- a/packages/CarSystemUI/res/values-kn/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"ಕನಿಷ್ಠ"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"ಗರಿಷ್ಠ"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"ಇದೀಗ ಕನೆಕ್ಟ್ ಆದ ಬ್ಲೂಟೂತ್ ಸಾಧನ ಧ್ವನಿ ಗುರುತಿಸುವಿಕೆ ನಿರ್ವಹಿಸಿದೆ"</string>
- <string name="car_guest" msgid="318393171202663722">"ಅತಿಥಿ"</string>
- <string name="start_guest_session" msgid="497784785761754874">"ಅತಿಥಿ"</string>
- <string name="car_add_user" msgid="4067337059622483269">"ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿ"</string>
- <string name="car_new_user" msgid="6637442369728092473">"ಹೊಸ ಬಳಕೆದಾರ"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"ನೀವು ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ಅವರ ಸ್ಥಳವನ್ನು ಸೆಟಪ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"ಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗಾಗಿ ಆ್ಯಪ್ಗಳನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಬಹುದು."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"ಲೋಡ್ ಆಗುತ್ತಿದೆ"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"ಬಳಕೆದಾರರನ್ನು ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ (<xliff:g id="FROM_USER">%1$d</xliff:g> ನಿಂದ <xliff:g id="TO_USER">%2$d</xliff:g> ವರೆಗೆ)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"ಮುಚ್ಚಿರಿ"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-ko/strings.xml b/packages/CarSystemUI/res/values-ko/strings.xml
deleted file mode 100644
index 17a2466..0000000
--- a/packages/CarSystemUI/res/values-ko/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"최소"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"최대"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"이제 연결된 블루투스 기기에서 음성 인식이 처리됩니다."</string>
- <string name="car_guest" msgid="318393171202663722">"게스트"</string>
- <string name="start_guest_session" msgid="497784785761754874">"게스트"</string>
- <string name="car_add_user" msgid="4067337059622483269">"사용자 추가"</string>
- <string name="car_new_user" msgid="6637442369728092473">"신규 사용자"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"추가된 신규 사용자는 자신만의 공간을 설정해야 합니다."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"누구나 다른 모든 사용자를 위해 앱을 업데이트할 수 있습니다."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"로드 중"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"사용자 로드 중(<xliff:g id="FROM_USER">%1$d</xliff:g>님에서 <xliff:g id="TO_USER">%2$d</xliff:g>님으로)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"닫기"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-ky/strings.xml b/packages/CarSystemUI/res/values-ky/strings.xml
deleted file mode 100644
index 74150d0..0000000
--- a/packages/CarSystemUI/res/values-ky/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Мин."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Макс."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Үндү эми туташкан Bluetooth түзмөгү менен тааныса болот"</string>
- <string name="car_guest" msgid="318393171202663722">"Конок"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Конок"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Колдонуучу кошуу"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Жаңы колдонуучу"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Жаңы колдонуучу кошулганда, ал өзүнүн профилин жөндөп алышы керек."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Колдонмолорду бир колдонуучу жаңыртканда, ал калган бардык колдонуучулар үчүн да жаңырат."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Жүктөлүүдө"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Колдонуучу тууралуу маалымат жүктөлүүдө (<xliff:g id="FROM_USER">%1$d</xliff:g> – <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Жабуу"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-lo/strings.xml b/packages/CarSystemUI/res/values-lo/strings.xml
deleted file mode 100644
index bc94a51..0000000
--- a/packages/CarSystemUI/res/values-lo/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"ນທ"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"ສູງສຸດ"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"ການຈຳແນກສຽງເວົ້າດຽວນີ້ຈັດການໂດຍອຸປະກອນ Bluetooth ທີ່ເຊື່ອມຕໍ່"</string>
- <string name="car_guest" msgid="318393171202663722">"ແຂກ"</string>
- <string name="start_guest_session" msgid="497784785761754874">"ແຂກ"</string>
- <string name="car_add_user" msgid="4067337059622483269">"ເພີ່ມຜູ້ໃຊ້"</string>
- <string name="car_new_user" msgid="6637442369728092473">"ຜູ້ໃຊ້ໃໝ່"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"ເມື່ອທ່ານເພີ່ມຜູ້ໃຊ້ໃໝ່, ບຸກຄົນນັ້ນຈຳເປັນຕ້ອງຕັ້ງຄ່າພື້ນທີ່ຂອງເຂົາເຈົ້າ."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"ຜູ້ໃຊ້ຕ່າງໆສາມາດອັບເດດແອັບສຳລັບຜູ້ໃຊ້ອື່ນທັງໝົດໄດ້."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"ກຳລັງໂຫຼດ"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"ກຳລັງໂຫຼດຜູ້ໃຊ້ (ຈາກ <xliff:g id="FROM_USER">%1$d</xliff:g> ໄປຍັງ <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"ປິດ"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-lt/strings.xml b/packages/CarSystemUI/res/values-lt/strings.xml
deleted file mode 100644
index a47ad59..0000000
--- a/packages/CarSystemUI/res/values-lt/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Didž."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Balso atpažinimą dabar tvarko susietas „Bluetooth“ įrenginys"</string>
- <string name="car_guest" msgid="318393171202663722">"Svečias"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Svečias"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Pridėti naudotoją"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Naujas naudotojas"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kai pridedate naują naudotoją, šis asmuo turi nustatyti savo vietą."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Bet kuris naudotojas gali atnaujinti visų kitų naudotojų programas."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Įkeliama"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Įkeliamas naudotojo profilis (<xliff:g id="FROM_USER">%1$d</xliff:g> – <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Uždaryti"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-lv/strings.xml b/packages/CarSystemUI/res/values-lv/strings.xml
deleted file mode 100644
index cb7c8b9..0000000
--- a/packages/CarSystemUI/res/values-lv/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Balss atpazīšanu tagad nodrošina pievienotā Bluetooth ierīce"</string>
- <string name="car_guest" msgid="318393171202663722">"Viesis"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Viesis"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Pievienot lietotāju"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Jauns lietotājs"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kad pievienojat jaunu lietotāju, viņam ir jāizveido savs profils."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Ikviens lietotājs var atjaunināt lietotnes visu lietotāju vārdā."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Notiek ielāde…"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Notiek lietotāja profila ielāde (<xliff:g id="FROM_USER">%1$d</xliff:g>–<xliff:g id="TO_USER">%2$d</xliff:g>)…"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Aizvērt"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-mk/strings.xml b/packages/CarSystemUI/res/values-mk/strings.xml
deleted file mode 100644
index cd2ae97..0000000
--- a/packages/CarSystemUI/res/values-mk/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Мин."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Макс."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Поврзаниот уред со Bluetooth управува со препознавањето глас"</string>
- <string name="car_guest" msgid="318393171202663722">"Гостин"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Гостин"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Додај корисник"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Нов корисник"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Кога додавате нов корисник, тоа лице треба да го постави својот простор."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Секој корисник може да ажурира апликации за сите други корисници."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Се вчитува"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Се вчитува корисникот (од <xliff:g id="FROM_USER">%1$d</xliff:g> до <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Затвори"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-ml/strings.xml b/packages/CarSystemUI/res/values-ml/strings.xml
deleted file mode 100644
index 613ea59..0000000
--- a/packages/CarSystemUI/res/values-ml/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"മിനിമം"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"മാക്സിമം"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"കണക്റ്റ് ചെയ്ത Bluetooth ഉപകരണം വഴി ഇപ്പോൾ വോയ്സ് തിരിച്ചറിയൽ കെെകാര്യം ചെയ്യുന്നു"</string>
- <string name="car_guest" msgid="318393171202663722">"അതിഥി"</string>
- <string name="start_guest_session" msgid="497784785761754874">"അതിഥി"</string>
- <string name="car_add_user" msgid="4067337059622483269">"ഉപയോക്താവിനെ ചേർക്കുക"</string>
- <string name="car_new_user" msgid="6637442369728092473">"പുതിയ ഉപയോക്താവ്"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"നിങ്ങളൊരു പുതിയ ഉപയോക്താവിനെ ചേർക്കുമ്പോൾ, ആ വ്യക്തി സ്വന്തം ഇടം സജ്ജീകരിക്കേണ്ടതുണ്ട്."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"ഏതൊരു ഉപയോക്താവിനും മറ്റെല്ലാ ഉപയോക്താക്കൾക്കുമായി ആപ്പുകൾ അപ്ഡേറ്റ് ചെയ്യാനാവും."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"ലോഡ് ചെയ്യുന്നു"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"ഉപയോക്തൃ പ്രൊഫൈൽ ലോഡ് ചെയ്യുന്നു (<xliff:g id="FROM_USER">%1$d</xliff:g> എന്നതിൽ നിന്ന് <xliff:g id="TO_USER">%2$d</xliff:g> എന്നതിലേക്ക്)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"അടയ്ക്കുക"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-mn/strings.xml b/packages/CarSystemUI/res/values-mn/strings.xml
deleted file mode 100644
index 33bcd27..0000000
--- a/packages/CarSystemUI/res/values-mn/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Бага"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Их"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Одоо дуугаар танихыг холбогдсон Bluetooth төхөөрөмж удирдана"</string>
- <string name="car_guest" msgid="318393171202663722">"Зочин"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Зочин"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Хэрэглэгч нэмэх"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Шинэ хэрэглэгч"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Та шинэ хэрэглэгч нэмэх үед тухайн хэрэглэгч хувийн орон зайгаа тохируулах шаардлагатай."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Бусад бүх хэрэглэгчийн аппыг дурын хэрэглэгч шинэчлэх боломжтой."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Ачаалж байна"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Хэрэглэгчийг ачаалж байна (<xliff:g id="FROM_USER">%1$d</xliff:g>-с <xliff:g id="TO_USER">%2$d</xliff:g> хүртэл)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Хаах"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-mr/strings.xml b/packages/CarSystemUI/res/values-mr/strings.xml
deleted file mode 100644
index b1c8a72..0000000
--- a/packages/CarSystemUI/res/values-mr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"मि"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"कमाल"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"आता कनेक्ट केलेले ब्लूटूथ डिव्हाइस व्हॉइस रेकग्निशन हाताळते"</string>
- <string name="car_guest" msgid="318393171202663722">"अतिथी"</string>
- <string name="start_guest_session" msgid="497784785761754874">"अतिथी"</string>
- <string name="car_add_user" msgid="4067337059622483269">"वापरकर्ता जोडा"</string>
- <string name="car_new_user" msgid="6637442369728092473">"नवीन वापरकर्ता"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"तुम्ही नवीन वापरकर्ता जोडता तेव्हा त्या व्यक्तीने त्यांची जागा सेट करणे आवश्यक असते."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"कोणताही वापरकर्ता इतर सर्व वापरकर्त्यांसाठी अॅप्स अपडेट करू शकतो."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"लोड करत आहे"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"वापरकर्ता लोड करत आहे (<xliff:g id="FROM_USER">%1$d</xliff:g> पासून <xliff:g id="TO_USER">%2$d</xliff:g> पर्यंत)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"बंद करा"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-ms/strings.xml b/packages/CarSystemUI/res/values-ms/strings.xml
deleted file mode 100644
index 0bb683b..0000000
--- a/packages/CarSystemUI/res/values-ms/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Maks"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Pengecaman suara kini dikendalikan peranti Bluetooth tersmbg"</string>
- <string name="car_guest" msgid="318393171202663722">"Tetamu"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Tetamu"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Tambah Pengguna"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Pengguna Baharu"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Apabila anda menambahkan pengguna baharu, orang itu perlu menyediakan ruang mereka."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Mana-mana pengguna boleh mengemas kini apl untuk semua pengguna lain."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Memuatkan"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Memuatkan pengguna (daripada <xliff:g id="FROM_USER">%1$d</xliff:g> hingga <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Tutup"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-my/strings.xml b/packages/CarSystemUI/res/values-my/strings.xml
deleted file mode 100644
index 4e7ca39..0000000
--- a/packages/CarSystemUI/res/values-my/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"နိမ့်"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"မြင့်"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"ချိတ်ထားသော ဘလူးတုသ်စက်ဖြင့် အသံမှတ်သားမှုကို ထိန်းချုပ်သည်"</string>
- <string name="car_guest" msgid="318393171202663722">"ဧည့်သည်"</string>
- <string name="start_guest_session" msgid="497784785761754874">"ဧည့်သည်"</string>
- <string name="car_add_user" msgid="4067337059622483269">"အသုံးပြုသူ ထည့်ရန်"</string>
- <string name="car_new_user" msgid="6637442369728092473">"အသုံးပြုသူ အသစ်"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"အသုံးပြုသူအသစ် ထည့်သည့်အခါ ထိုသူသည် မိမိ၏ နေရာကို စနစ်ထည့်သွင်းရပါမည်။"</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"မည်သူမဆို အသုံးပြုသူအားလုံးအတွက် အက်ပ်များကို အပ်ဒိတ်လုပ်နိုင်သည်။"</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"ဖွင့်နေသည်"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"အသုံးပြုသူကို ဖွင့်နေသည် (<xliff:g id="FROM_USER">%1$d</xliff:g> မှ <xliff:g id="TO_USER">%2$d</xliff:g> သို့)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"ပိတ်ရန်"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-nb/strings.xml b/packages/CarSystemUI/res/values-nb/strings.xml
deleted file mode 100644
index 0b2856f..0000000
--- a/packages/CarSystemUI/res/values-nb/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Talegjenkjenning håndteres nå av tilkoblet Bluetooth-enhet"</string>
- <string name="car_guest" msgid="318393171202663722">"Gjest"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Gjest"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Legg til bruker"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Ny bruker"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Når du legger til en ny bruker, må vedkommende konfigurere sitt eget område."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Alle brukere kan oppdatere apper for alle andre brukere."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Laster inn"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Laster inn brukeren (fra <xliff:g id="FROM_USER">%1$d</xliff:g> til <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Lukk"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-ne/strings.xml b/packages/CarSystemUI/res/values-ne/strings.xml
deleted file mode 100644
index 3a25d6e0..0000000
--- a/packages/CarSystemUI/res/values-ne/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"न्यूनतम"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"अधिकतम"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"अब ब्लुटुथ मार्फत जोडिएको यन्त्रले आवाज पहिचान गर्ने कार्य सम्हाल्छ"</string>
- <string name="car_guest" msgid="318393171202663722">"अतिथि"</string>
- <string name="start_guest_session" msgid="497784785761754874">"अतिथि"</string>
- <string name="car_add_user" msgid="4067337059622483269">"प्रयोगकर्ता थप्नुहोस्"</string>
- <string name="car_new_user" msgid="6637442369728092473">"नयाँ प्रयोगकर्ता"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"तपाईंले नयाँ प्रयोगकर्ता थप्दा ती व्यक्तिले आफ्नो स्थान सेटअप गर्नु पर्छ।"</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"सबै प्रयोगकर्ताले अन्य प्रयोगकर्ताका अनुप्रयोगहरू अद्यावधिक गर्न सक्छन्।"</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"लोड गरिँदै"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"प्रयोगकर्तासम्बन्धी जानकारी लोड गरिँदै (<xliff:g id="FROM_USER">%1$d</xliff:g> बाट <xliff:g id="TO_USER">%2$d</xliff:g> मा)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"बन्द गर्नुहोस्"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-night/colors.xml b/packages/CarSystemUI/res/values-night/colors.xml
deleted file mode 100644
index a2edd7dc..0000000
--- a/packages/CarSystemUI/res/values-night/colors.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android">
- <color name="car_accent">#356FE5</color>
- <color name="status_bar_background_color">#ff000000</color>
- <color name="system_bar_background_opaque">#ff0c1013</color>
-
- <!-- The background color of the notification shade -->
- <color name="notification_shade_background_color">#E0000000</color>
-
- <!-- The color of the ripples on the untinted notifications -->
- <color name="notification_ripple_untinted_color">@color/ripple_material_dark</color>
-</resources>
diff --git a/packages/CarSystemUI/res/values-nl/strings.xml b/packages/CarSystemUI/res/values-nl/strings.xml
deleted file mode 100644
index 4765f71..0000000
--- a/packages/CarSystemUI/res/values-nl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Max."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Spraakherkenning actief via een verbonden bluetooth-apparaat"</string>
- <string name="car_guest" msgid="318393171202663722">"Gast"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Gast"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Gebruiker toevoegen"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Nieuwe gebruiker"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Als je een nieuwe gebruiker toevoegt, moet die persoon een eigen profiel instellen."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Elke gebruiker kan apps updaten voor alle andere gebruikers"</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Laden"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Gebruiker laden (van <xliff:g id="FROM_USER">%1$d</xliff:g> naar <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Sluiten"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-or/strings.xml b/packages/CarSystemUI/res/values-or/strings.xml
deleted file mode 100644
index 4168d5a..0000000
--- a/packages/CarSystemUI/res/values-or/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"ସର୍ବନିମ୍ନ"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"ସର୍ବାଧିକ"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"ଭଏସ ଚିହ୍ନଟକରଣ ଏବେ ସଂଯୁକ୍ତ ଥିବା ବ୍ଲୁଟୁଥ ଡିଭାଇସ ଦ୍ୱାରା ପରିଚାଳିତ"</string>
- <string name="car_guest" msgid="318393171202663722">"ଅତିଥି"</string>
- <string name="start_guest_session" msgid="497784785761754874">"ଅତିଥି"</string>
- <string name="car_add_user" msgid="4067337059622483269">"ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରନ୍ତୁ"</string>
- <string name="car_new_user" msgid="6637442369728092473">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"ଜଣେ ନୂଆ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରିବା ବେଳେ ସେହି ବ୍ୟକ୍ତିଙ୍କୁ ତାଙ୍କ ସ୍ଥାନ ସେଟ୍ ଅପ୍ କରିବାର ଆବଶ୍ୟକତା ଅଛି।"</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"ଯେ କୌଣସି ଉପଯୋଗକର୍ତ୍ତା ଅନ୍ୟ ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଆପଗୁଡ଼ିକୁ ଅପଡେଟ୍ କରିପାରିବେ।"</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"ଲୋଡ୍ କରାଯାଉଛି"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଲୋଡ୍ କରାଯାଉଛି (<xliff:g id="FROM_USER">%1$d</xliff:g>ଙ୍କ ଠାରୁ <xliff:g id="TO_USER">%2$d</xliff:g> ପର୍ଯ୍ୟନ୍ତ)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"ବନ୍ଦ କରନ୍ତୁ"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-pa/strings.xml b/packages/CarSystemUI/res/values-pa/strings.xml
deleted file mode 100644
index 3d9d3a597..0000000
--- a/packages/CarSystemUI/res/values-pa/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"ਨਿਊਨਤਮ"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"ਅਧਿਕਤਮ"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"ਅਵਾਜ਼ ਦੀ ਪਛਾਣ ਨੂੰ ਹੁਣ ਕਨੈਕਟ ਕੀਤਾ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸ ਸੰਭਾਲਦਾ ਹੈ"</string>
- <string name="car_guest" msgid="318393171202663722">"ਮਹਿਮਾਨ"</string>
- <string name="start_guest_session" msgid="497784785761754874">"ਮਹਿਮਾਨ"</string>
- <string name="car_add_user" msgid="4067337059622483269">"ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰੋ"</string>
- <string name="car_new_user" msgid="6637442369728092473">"ਨਵਾਂ ਵਰਤੋਂਕਾਰ"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"ਜਦੋਂ ਤੁਸੀਂ ਕੋਈ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਦੇ ਹੋ, ਤਾਂ ਉਸ ਵਿਅਕਤੀ ਨੂੰ ਆਪਣੀ ਜਗ੍ਹਾ ਸੈੱਟਅੱਪ ਕਰਨ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ।"</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"ਕੋਈ ਵੀ ਵਰਤੋਂਕਾਰ ਹੋਰ ਸਾਰੇ ਵਰਤੋਂਕਾਰਾਂ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਅੱਪਡੇਟ ਕਰ ਸਕਦਾ ਹੈ।"</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"ਵਰਤੋਂਕਾਰ ਨੂੰ ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ (<xliff:g id="FROM_USER">%1$d</xliff:g> ਤੋਂ <xliff:g id="TO_USER">%2$d</xliff:g> ਤੱਕ)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"ਬੰਦ ਕਰੋ"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-pl/strings.xml b/packages/CarSystemUI/res/values-pl/strings.xml
deleted file mode 100644
index 52b90f1..0000000
--- a/packages/CarSystemUI/res/values-pl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Rozpoznawanie mowy przez połączone urządzenie Bluetooth"</string>
- <string name="car_guest" msgid="318393171202663722">"Gość"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Gość"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Dodaj użytkownika"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Nowy użytkownik"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Gdy dodasz nowego użytkownika, musi on skonfigurować swój profil."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Każdy użytkownik może aktualizować aplikacje wszystkich innych użytkowników."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Ładuję"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Ładuję użytkownika (od <xliff:g id="FROM_USER">%1$d</xliff:g> do <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Zamknij"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-pt-rPT/strings.xml b/packages/CarSystemUI/res/values-pt-rPT/strings.xml
deleted file mode 100644
index 2dffa17..0000000
--- a/packages/CarSystemUI/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Mín."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Máx."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Reconhecimento de voz agora através do disp. Bluetooth lig."</string>
- <string name="car_guest" msgid="318393171202663722">"Convidado"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Convidado"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Adicionar utilizador"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Novo utilizador"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Ao adicionar um novo utilizador, essa pessoa tem de configurar o respetivo espaço."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Qualquer utilizador pode atualizar apps para todos os outros utilizadores."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"A carregar…"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"A carregar o utilizador (de <xliff:g id="FROM_USER">%1$d</xliff:g> para <xliff:g id="TO_USER">%2$d</xliff:g>)…"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Fechar"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-pt/strings.xml b/packages/CarSystemUI/res/values-pt/strings.xml
deleted file mode 100644
index a7c44d2..0000000
--- a/packages/CarSystemUI/res/values-pt/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Mín"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Máx"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Reconhecimento de voz com dispositivo Bluetooth conectado"</string>
- <string name="car_guest" msgid="318393171202663722">"Convidado"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Convidado"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Adicionar usuário"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Novo usuário"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Quando você adiciona um usuário novo, essa pessoa precisa configurar o espaço dela."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Qualquer usuário pode atualizar apps para os demais usuários."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Carregando"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Carregando usuário (de <xliff:g id="FROM_USER">%1$d</xliff:g> para <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Fechar"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-ro/strings.xml b/packages/CarSystemUI/res/values-ro/strings.xml
deleted file mode 100644
index 1a4e71d..0000000
--- a/packages/CarSystemUI/res/values-ro/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Recunoașterea vocală acum gestionată de dispozitivul Bluetooth conectat"</string>
- <string name="car_guest" msgid="318393171202663722">"Invitat"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Invitat"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Adăugați un utilizator"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Utilizator nou"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Când adăugați un utilizator nou, acesta trebuie să-și configureze spațiul."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Orice utilizator poate actualiza aplicațiile pentru toți ceilalți utilizatori."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Se încarcă"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Se încarcă utilizatorul (de la <xliff:g id="FROM_USER">%1$d</xliff:g> la <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Închideți"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-ru/strings.xml b/packages/CarSystemUI/res/values-ru/strings.xml
deleted file mode 100644
index 330ba2f..0000000
--- a/packages/CarSystemUI/res/values-ru/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Мин."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Макс."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Для распознавания речи используется Bluetooth-устройство."</string>
- <string name="car_guest" msgid="318393171202663722">"Гость"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Гость"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Добавить пользователя"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Новый пользователь"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Когда вы добавите пользователя, ему потребуется настроить профиль."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Любой пользователь устройства может обновлять приложения для всех аккаунтов."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Загрузка…"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Загрузка профиля пользователя (с <xliff:g id="FROM_USER">%1$d</xliff:g> по <xliff:g id="TO_USER">%2$d</xliff:g>)…"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Закрыть"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-si/strings.xml b/packages/CarSystemUI/res/values-si/strings.xml
deleted file mode 100644
index 6391d28..0000000
--- a/packages/CarSystemUI/res/values-si/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"අවම"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"උපරිම"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"හඬ හැඳුනුම දැන් සම්බන්ධ බ්ලූටූත් උපාංගය මගින් හසුරුවනු ලැබේ"</string>
- <string name="car_guest" msgid="318393171202663722">"අමුත්තා"</string>
- <string name="start_guest_session" msgid="497784785761754874">"අමුත්තා"</string>
- <string name="car_add_user" msgid="4067337059622483269">"පරිශීලක එක් කරන්න"</string>
- <string name="car_new_user" msgid="6637442369728092473">"නව පරිශීලක"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"ඔබ අලුත් පරිශීලකයෙකු එක් කරන විට, එම පුද්ගලයා තමන්ගේ ඉඩ සකසා ගැනීමට අවශ්ය වේ."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"සියලුම අනෙක් පරිශීලකයින් සඳහා ඕනෑම පරිශීලකයෙකුට යෙදුම් යාවත්කාලීන කළ හැක."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"පූරණය වෙමින්"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"පරිශීලකයා පූරණය වෙමින් (<xliff:g id="FROM_USER">%1$d</xliff:g> සිට <xliff:g id="TO_USER">%2$d</xliff:g> වෙත)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"වසන්න"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-sk/strings.xml b/packages/CarSystemUI/res/values-sk/strings.xml
deleted file mode 100644
index 80b9b5e..0000000
--- a/packages/CarSystemUI/res/values-sk/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"min."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"max."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Rozpoznávanie hlasu teraz prebieha v pripoj. zar. Bluetooth"</string>
- <string name="car_guest" msgid="318393171202663722">"Hosť"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Hosť"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Pridať používateľa"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Nový používateľ"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Keď pridáte nového používateľa, musí si nastaviť vlastný priestor."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Každý používateľ môže aktualizovať aplikácie pre všetkých ostatných používateľov."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Načítava sa"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Načítava sa používateľ (predchádzajúci: <xliff:g id="FROM_USER">%1$d</xliff:g>, nasledujúci: <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Zavrieť"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-sl/strings.xml b/packages/CarSystemUI/res/values-sl/strings.xml
deleted file mode 100644
index b67002b..0000000
--- a/packages/CarSystemUI/res/values-sl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Najn."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Najv."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Prepoznavanje glasu zdaj izvaja povezana naprava Bluetooth"</string>
- <string name="car_guest" msgid="318393171202663722">"Gost"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Gost"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Dodaj uporabnika"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Nov uporabnik"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Ko dodate novega uporabnika, mora ta nastaviti svoj prostor."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Vsak uporabnik lahko posodobi aplikacije za vse druge uporabnike."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Nalaganje"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Nalaganje uporabnika (od uporabnika <xliff:g id="FROM_USER">%1$d</xliff:g> do uporabnika <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Zapri"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-sq/strings.xml b/packages/CarSystemUI/res/values-sq/strings.xml
deleted file mode 100644
index d19e158..0000000
--- a/packages/CarSystemUI/res/values-sq/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Njohja zanore trajtohet nga pajisja me Bluetooth-in e lidhur"</string>
- <string name="car_guest" msgid="318393171202663722">"I ftuar"</string>
- <string name="start_guest_session" msgid="497784785761754874">"I ftuar"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Shto përdorues"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Përdorues i ri"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kur shton një përdorues të ri, ai person duhet të konfigurojë hapësirën e vet."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Çdo përdorues mund t\'i përditësojë aplikacionet për të gjithë përdoruesit e tjerë."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Po ngarkohet"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Përdoruesi po ngarkohet (nga <xliff:g id="FROM_USER">%1$d</xliff:g> te <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Mbyll"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-sr/strings.xml b/packages/CarSystemUI/res/values-sr/strings.xml
deleted file mode 100644
index a5fb5b4..0000000
--- a/packages/CarSystemUI/res/values-sr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Мин."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Maкс."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Препознавањем гласа сада управља повезани Bluetooth уређај"</string>
- <string name="car_guest" msgid="318393171202663722">"Гост"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Гост"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Додај корисника"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Нови корисник"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Када додате новог корисника, та особа треба да подеси свој простор."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Сваки корисник може да ажурира апликације за све остале кориснике."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Учитава се"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Профил корисника се учитава (из<xliff:g id="FROM_USER">%1$d</xliff:g> у <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Затвори"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-sv/strings.xml b/packages/CarSystemUI/res/values-sv/strings.xml
deleted file mode 100644
index 8a942d6..0000000
--- a/packages/CarSystemUI/res/values-sv/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Nu hanteras röstigenkänning via en anstluten Bluetooth-enhet"</string>
- <string name="car_guest" msgid="318393171202663722">"Gäst"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Gäst"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Lägg till användare"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Ny användare"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"När du lägger till en ny användare måste den personen konfigurera sitt utrymme."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Alla användare kan uppdatera appar för andra användare."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Läser in"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Läser in användare (från <xliff:g id="FROM_USER">%1$d</xliff:g> till <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Stäng"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-sw/strings.xml b/packages/CarSystemUI/res/values-sw/strings.xml
deleted file mode 100644
index be03373..0000000
--- a/packages/CarSystemUI/res/values-sw/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Chini"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Juu"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Utambuzi wa sauti sasa unashughulikiwa na kifaa kilichounganishwa cha Bluetooth"</string>
- <string name="car_guest" msgid="318393171202663722">"Mgeni"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Mgeni"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Ongeza Mtumiaji"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Mtumiaji Mpya"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Ukiongeza mtumiaji mpya, ni lazima aweke kikundi chake."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Mtumiaji yeyote anaweza kusasisha programu za watumiaji wengine."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Inapakia"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Inapakia wasifu wa mtumiaji (kutoka <xliff:g id="FROM_USER">%1$d</xliff:g> kuwa <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Funga"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-ta/strings.xml b/packages/CarSystemUI/res/values-ta/strings.xml
deleted file mode 100644
index a82a2f8..0000000
--- a/packages/CarSystemUI/res/values-ta/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"குறைந்தபட்சம்"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"அதிகபட்சம்"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"இணைக்கப்பட்ட புளூடூத் சாதனத்தால் \'குரல் அறிதல்\' கையாளப்படுகிறது"</string>
- <string name="car_guest" msgid="318393171202663722">"கெஸ்ட்"</string>
- <string name="start_guest_session" msgid="497784785761754874">"கெஸ்ட்"</string>
- <string name="car_add_user" msgid="4067337059622483269">"பயனரைச் சேருங்கள்"</string>
- <string name="car_new_user" msgid="6637442369728092473">"புதிய பயனர்"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"புதிய பயனரைச் சேர்க்கும்போது அவர் தனக்கான சேமிப்பிடத்தை அமைக்க வேண்டும்."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"எந்தப் பயனரும் பிற பயனர்கள் சார்பாக ஆப்ஸைப் புதுப்பிக்க முடியும்."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"ஏற்றுகிறது"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"பயனர் தகவலை ஏற்றுகிறது (<xliff:g id="FROM_USER">%1$d</xliff:g>லிருந்து <xliff:g id="TO_USER">%2$d</xliff:g> வரை)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"மூடுக"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-te/strings.xml b/packages/CarSystemUI/res/values-te/strings.xml
deleted file mode 100644
index cf74f80..0000000
--- a/packages/CarSystemUI/res/values-te/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"కని."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"గరి."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"నేడు వాయిస్ గుర్తింపును కనెక్ట్ అయిన బ్లూటూత్ నిర్వహిస్తోంది"</string>
- <string name="car_guest" msgid="318393171202663722">"గెస్ట్"</string>
- <string name="start_guest_session" msgid="497784785761754874">"గెస్ట్"</string>
- <string name="car_add_user" msgid="4067337059622483269">"యూజర్ను జోడించండి"</string>
- <string name="car_new_user" msgid="6637442369728092473">"కొత్త యూజర్"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"మీరు కొత్త యూజర్ను జోడించినప్పుడు, ఆ వ్యక్తి తన స్పేస్ను సెటప్ చేసుకోవాలి."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"ఏ యూజర్ అయినా మిగతా యూజర్ల కోసం యాప్లను అప్డేట్ చేయవచ్చు."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"లోడ్ అవుతోంది"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"యూజర్ను లోడ్ చేస్తోంది (<xliff:g id="FROM_USER">%1$d</xliff:g> నుండి <xliff:g id="TO_USER">%2$d</xliff:g> వరకు)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"మూసివేయి"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-th/strings.xml b/packages/CarSystemUI/res/values-th/strings.xml
deleted file mode 100644
index dacf605..0000000
--- a/packages/CarSystemUI/res/values-th/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"ตอนนี้อุปกรณ์บลูทูธที่เชื่อมต่อจะจัดการการจดจำเสียง"</string>
- <string name="car_guest" msgid="318393171202663722">"ผู้ใช้ชั่วคราว"</string>
- <string name="start_guest_session" msgid="497784785761754874">"ผู้ใช้ชั่วคราว"</string>
- <string name="car_add_user" msgid="4067337059622483269">"เพิ่มผู้ใช้"</string>
- <string name="car_new_user" msgid="6637442369728092473">"ผู้ใช้ใหม่"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"เมื่อคุณเพิ่มผู้ใช้ใหม่ ผู้ใช้ดังกล่าวจะต้องตั้งค่าพื้นที่ของตนเอง"</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"ผู้ใช้ทุกคนจะอัปเดตแอปให้แก่ผู้ใช้คนอื่นๆ ได้"</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"กำลังโหลด"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"กำลังโหลดผู้ใช้ (จาก <xliff:g id="FROM_USER">%1$d</xliff:g> ถึง <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"ปิด"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-tl/strings.xml b/packages/CarSystemUI/res/values-tl/strings.xml
deleted file mode 100644
index 89d8cd2..0000000
--- a/packages/CarSystemUI/res/values-tl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Minuto"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Hawak na ngayon ng Bluetooth device ang Pagkilala ng boses"</string>
- <string name="car_guest" msgid="318393171202663722">"Bisita"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Bisita"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Magdagdag ng User"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Bagong User"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kapag nagdagdag ka ng bagong user, kailangang i-set up ng taong iyon ang kanyang espasyo."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Puwedeng i-update ng sinumang user ang mga app para sa lahat ng iba pang user."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Naglo-load"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Nilo-load ang user (mula kay <xliff:g id="FROM_USER">%1$d</xliff:g> papunta kay <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Isara"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-tr/strings.xml b/packages/CarSystemUI/res/values-tr/strings.xml
deleted file mode 100644
index 36bf694..0000000
--- a/packages/CarSystemUI/res/values-tr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Artık ses tanıma, bağlı Bluetooth cihazı tarafından işleniyor"</string>
- <string name="car_guest" msgid="318393171202663722">"Misafir"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Misafir"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Kullanıcı Ekle"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Yeni Kullanıcı"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Yeni kullanıcı eklediğinizde, bu kişinin alanını ayarlaması gerekir."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Herhangi bir kullanıcı, diğer tüm kullanıcılar için uygulamaları güncelleyebilir."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Yükleniyor"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Kullanıcı yükleniyor (<xliff:g id="FROM_USER">%1$d</xliff:g> kullanıcısından <xliff:g id="TO_USER">%2$d</xliff:g> kullanıcısına)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Kapat"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-uk/strings.xml b/packages/CarSystemUI/res/values-uk/strings.xml
deleted file mode 100644
index 391513f..0000000
--- a/packages/CarSystemUI/res/values-uk/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Мін."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Макс."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Голос розпізнається через підключений пристрій Bluetooth"</string>
- <string name="car_guest" msgid="318393171202663722">"Гість"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Гість"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Додати користувача"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Новий користувач"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Коли ви додаєте нового користувача, він має налаштувати свій профіль."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Усі користувачі можуть оновлювати додатки для решти людей."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Завантаження"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Завантаження профілю користувача (від <xliff:g id="FROM_USER">%1$d</xliff:g> до <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Закрити"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-ur/strings.xml b/packages/CarSystemUI/res/values-ur/strings.xml
deleted file mode 100644
index abe9214..0000000
--- a/packages/CarSystemUI/res/values-ur/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"کم از کم"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"زیادہ سے زیادہ"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"آواز کی شناخت اب منسلک کردہ بلوٹوتھ آلے سے ہوتی ہے"</string>
- <string name="car_guest" msgid="318393171202663722">"مہمان"</string>
- <string name="start_guest_session" msgid="497784785761754874">"مہمان"</string>
- <string name="car_add_user" msgid="4067337059622483269">"صارف شامل کریں"</string>
- <string name="car_new_user" msgid="6637442369728092473">"نیا صارف"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"جب آپ ایک نیا صارف شامل کرتے ہیں تو اس شخص کو اپنی جگہ سیٹ کرنی ہوتی ہے۔"</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"کوئی بھی صارف دیگر سبھی صارفین کے لیے ایپس کو اپ ڈیٹ کر سکتا ہے۔"</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"لوڈ ہو رہی ہے"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"صارف کی نئی پروفائل لوڈ ہو رہی ہے (<xliff:g id="FROM_USER">%1$d</xliff:g> سے <xliff:g id="TO_USER">%2$d</xliff:g> کو)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"بند کریں"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-uz/strings.xml b/packages/CarSystemUI/res/values-uz/strings.xml
deleted file mode 100644
index 398d1f5..0000000
--- a/packages/CarSystemUI/res/values-uz/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Daq."</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Endi ovozni tanish Bluetooth qurilma ulanganda amalga oshadi"</string>
- <string name="car_guest" msgid="318393171202663722">"Mehmon"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Mehmon"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Foydalanuvchi kiritish"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Yangi foydalanuvchi"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Yangi profil kiritilgach, uni sozlash lozim."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Qurilmaning istalgan foydalanuvchisi ilovalarni barcha hisoblar uchun yangilashi mumkin."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Yuklanmoqda"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Foydalanuvchi profili yuklanmoqda (<xliff:g id="FROM_USER">%1$d</xliff:g> – <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Yopish"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-vi/strings.xml b/packages/CarSystemUI/res/values-vi/strings.xml
deleted file mode 100644
index f15320f..0000000
--- a/packages/CarSystemUI/res/values-vi/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Tối thiểu"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Tối đa"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Thiết bị Bluetooth được kết nối đang xử lý vấn đề nhận dạng giọng nói"</string>
- <string name="car_guest" msgid="318393171202663722">"Khách"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Khách"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Thêm người dùng"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Người dùng mới"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Khi bạn thêm một người dùng mới, người đó cần thiết lập không gian của mình."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Bất kỳ người dùng nào cũng có thể cập nhật ứng dụng cho tất cả những người dùng khác."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Đang tải"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Đang tải hồ sơ người dùng (từ <xliff:g id="FROM_USER">%1$d</xliff:g> sang <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Đóng"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-zh-rCN/strings.xml b/packages/CarSystemUI/res/values-zh-rCN/strings.xml
deleted file mode 100644
index a91f48c..0000000
--- a/packages/CarSystemUI/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"最小"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"最大"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"现在由已连接的蓝牙设备处理语音识别操作"</string>
- <string name="car_guest" msgid="318393171202663722">"访客"</string>
- <string name="start_guest_session" msgid="497784785761754874">"访客"</string>
- <string name="car_add_user" msgid="4067337059622483269">"添加用户"</string>
- <string name="car_new_user" msgid="6637442369728092473">"新用户"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"当您添加新用户时,该用户需要自行设置个人空间。"</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"任何用户均可为所有其他用户更新应用。"</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"正在加载"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"正在加载用户(从 <xliff:g id="FROM_USER">%1$d</xliff:g> 到 <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"关闭"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-zh-rHK/strings.xml b/packages/CarSystemUI/res/values-zh-rHK/strings.xml
deleted file mode 100644
index 7aa6116..0000000
--- a/packages/CarSystemUI/res/values-zh-rHK/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"最小"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"最大"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"現在由已連線的藍牙裝置處理語音辨識作業"</string>
- <string name="car_guest" msgid="318393171202663722">"訪客"</string>
- <string name="start_guest_session" msgid="497784785761754874">"訪客"</string>
- <string name="car_add_user" msgid="4067337059622483269">"新增使用者"</string>
- <string name="car_new_user" msgid="6637442369728092473">"新使用者"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"新增的使用者需要自行設定個人空間。"</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"任何使用者都可以為所有其他使用者更新應用程式。"</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"正在載入"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"正在載入使用者 (由 <xliff:g id="FROM_USER">%1$d</xliff:g> 至 <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"關閉"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-zh-rTW/strings.xml b/packages/CarSystemUI/res/values-zh-rTW/strings.xml
deleted file mode 100644
index c062463..0000000
--- a/packages/CarSystemUI/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"最小"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"最大"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"現在由已連線的藍牙裝置處理語音辨識作業"</string>
- <string name="car_guest" msgid="318393171202663722">"訪客"</string>
- <string name="start_guest_session" msgid="497784785761754874">"訪客"</string>
- <string name="car_add_user" msgid="4067337059622483269">"新增使用者"</string>
- <string name="car_new_user" msgid="6637442369728092473">"新使用者"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"新使用者必須自行設定個人空間。"</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"任何使用者都能為所有其他使用者更新應用程式。"</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"載入中"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"正在載入使用者 (從 <xliff:g id="FROM_USER">%1$d</xliff:g> 到 <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"關閉"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values-zu/strings.xml b/packages/CarSystemUI/res/values-zu/strings.xml
deleted file mode 100644
index 2dd33d8..0000000
--- a/packages/CarSystemUI/res/values-zu/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="hvac_min_text" msgid="8167124789068494624">"Okuncane"</string>
- <string name="hvac_max_text" msgid="3669693372074755551">"Okuningi"</string>
- <string name="voice_recognition_toast" msgid="1149934534584052842">"Ukubonwa kwezwi manje kuphethwe idivayisi exhunyiwe ye-Bluetooth"</string>
- <string name="car_guest" msgid="318393171202663722">"Isihambeli"</string>
- <string name="start_guest_session" msgid="497784785761754874">"Isihambeli"</string>
- <string name="car_add_user" msgid="4067337059622483269">"Engeza umsebenzisi"</string>
- <string name="car_new_user" msgid="6637442369728092473">"Umsebenzisi omusha"</string>
- <string name="user_add_user_message_setup" msgid="1035578846007352323">"Uma ungeza umsebenzisi omusha, loyo muntu udinga ukusetha izikhala zakhe."</string>
- <string name="user_add_user_message_update" msgid="7061671307004867811">"Noma yimuphi umsebenzisi angabuyekeza izinhlelo zokusebenza zabanye abasebenzisi."</string>
- <string name="car_loading_profile" msgid="4507385037552574474">"Iyalayisha"</string>
- <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Ilayisha umsebenzisi (kusuka ku-<xliff:g id="FROM_USER">%1$d</xliff:g> kuya ku-<xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
- <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Vala"</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values/attrs.xml b/packages/CarSystemUI/res/values/attrs.xml
deleted file mode 100644
index 7883764..0000000
--- a/packages/CarSystemUI/res/values/attrs.xml
+++ /dev/null
@@ -1,113 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 2018 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>
- <attr name="icon" format="reference"/>
- <attr name="selectedIcon" format="reference"/>
- <attr name="intent" format="string"/>
- <attr name="longIntent" format="string"/>
- <attr name="selectedAlpha" format="float" />
- <attr name="unselectedAlpha" format="float" />
-
- <!-- Custom attributes to configure hvac values -->
- <declare-styleable name="AnimatedTemperatureView">
- <attr name="hvacAreaId" format="integer"/>
- <attr name="hvacPropertyId" format="integer"/>
- <attr name="hvacTempFormat" format="string"/>
- <!-- how far away the animations should center around -->
- <attr name="hvacPivotOffset" format="dimension"/>
- <attr name="hvacMinValue" format="float"/>
- <attr name="hvacMaxValue" format="float"/>
- <attr name="hvacMinText" format="string|reference"/>
- <attr name="hvacMaxText" format="string|reference"/>
- <attr name="android:gravity"/>
- <attr name="android:minEms"/>
- <attr name="android:textAppearance"/>
- </declare-styleable>
-
- <!-- Allow for custom attribs to be added to a nav button -->
- <declare-styleable name="CarNavigationButton">
- <!-- intent to start when button is click -->
- <attr name="intent" />
- <!-- intent to start when a long press has happened -->
- <attr name="longIntent" />
- <!-- start the intent as a broad cast instead of an activity if true-->
- <attr name="broadcast" format="boolean"/>
- <!-- Alpha value to used when in selected state. Defaults 1f -->
- <attr name="selectedAlpha" />
- <!-- Alpha value to used when in un-selected state. Defaults 0.7f -->
- <attr name="unselectedAlpha" />
- <!-- icon to be rendered when in selected state -->
- <attr name="selectedIcon" />
- <!-- icon to be rendered (drawable) -->
- <attr name="icon"/>
- <!-- categories that will be added as extras to the fired intents -->
- <attr name="categories" format="string"/>
- <!-- package names that will be added as extras to the fired intents -->
- <attr name="packages" format="string" />
- <!-- componentName names that will be used for detecting selected state -->
- <attr name="componentNames" format="string" />
- <!-- whether to highlight the button when selected. Defaults false -->
- <attr name="showMoreWhenSelected" format="boolean" />
- <!-- whether to highlight the button when selected. Defaults false -->
- <attr name="highlightWhenSelected" format="boolean" />
- <!-- whether to show the icon of the app currently associated this button's role. Only
- relevant for buttons associated to specific roles (e.g.: AssistantButton).
- Defaults false -->
- <attr name="useDefaultAppIconForRole" format="boolean"/>
- </declare-styleable>
-
- <!-- Custom attributes to configure hvac values -->
- <declare-styleable name="TemperatureView">
- <attr name="hvacAreaId" format="integer"/>
- <attr name="hvacPropertyId" format="integer"/>
- <attr name="hvacTempFormat" format="string"/>
- </declare-styleable>
-
- <declare-styleable name="carVolumeItems"/>
- <declare-styleable name="carVolumeItems_item">
- <!-- Align with AudioAttributes.USAGE_* -->
- <attr name="usage">
- <enum name="unknown" value="0"/>
- <enum name="media" value="1"/>
- <enum name="voice_communication" value="2"/>
- <enum name="voice_communication_signalling" value="3"/>
- <enum name="alarm" value="4"/>
- <enum name="notification" value="5"/>
- <enum name="notification_ringtone" value="6"/>
- <enum name="notification_communication_request" value="7"/>
- <enum name="notification_communication_instant" value="8"/>
- <enum name="notification_communication_delayed" value="9"/>
- <enum name="notification_event" value="10"/>
- <enum name="assistance_accessibility" value="11"/>
- <enum name="assistance_navigation_guidance" value="12"/>
- <enum name="assistance_sonification" value="13"/>
- <enum name="game" value="14"/>
- <!-- hidden, do not use -->
- <!-- enum name="virtual_source" value="15"/ -->
- <enum name="assistant" value="16"/>
- <enum name="call_assistant" value="17"/>
- <enum name="emergency" value="1000"/>
- <enum name="safety" value="1001"/>
- <enum name="vehicle_status" value="1002"/>
- <enum name="announcement" value="1003"/>
- </attr>
-
- <!-- Icon resource ids to render on UI -->
- <attr name="icon" />
- </declare-styleable>
-</resources>
diff --git a/packages/CarSystemUI/res/values/colors.xml b/packages/CarSystemUI/res/values/colors.xml
deleted file mode 100644
index 91d4166..0000000
--- a/packages/CarSystemUI/res/values/colors.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- colors for user switcher -->
- <color name="car_user_switcher_background_color">#000000</color>
- <color name="car_user_switcher_name_text_color">@*android:color/car_body1_light</color>
- <color name="car_user_switcher_add_user_background_color">#131313</color>
- <color name="car_user_switcher_add_user_add_sign_color">@*android:color/car_body1_light</color>
- <color name="car_nav_icon_fill_color">#8F8F8F</color>
- <color name="car_nav_icon_fill_color_selected">#ffffff</color>
- <!-- colors for seekbar -->
- <color name="car_seekbar_track_background">#131315</color>
- <color name="car_seekbar_track_secondary_progress">@*android:color/car_accent</color>
- <!-- colors for volume dialog tint -->
- <color name="car_volume_dialog_tint">@*android:color/car_tint</color>
-
- <color name="docked_divider_background">@*android:color/car_grey_50</color>
- <color name="system_bar_background_opaque">#ff172026</color>
-
- <!-- colors for status bar -->
- <color name="system_bar_background_pill_color">#282A2D</color>
- <color name="system_bar_icon_color">#FFFFFF</color>
- <color name="system_bar_text_color">#FFFFFF</color>
- <color name="status_bar_background_color">#33000000</color>
- <drawable name="system_bar_background">@color/status_bar_background_color</drawable>
-
- <!-- colors for hvac temperature view -->
- <color name="hvac_temperature_adjust_button_color">#3C4043</color>
- <color name="hvac_temperature_decrease_arrow_color">#8AB4F8</color>
- <color name="hvac_temperature_increase_arrow_color">#F28B82</color>
-
- <!-- The background color of the notification shade -->
- <color name="notification_shade_background_color">#D6000000</color>
-
- <!-- The background color of the car volume dialog -->
- <color name="car_volume_dialog_background_color">@color/system_bar_background_opaque</color>
-
- <!-- The color of the dividing line between grouped notifications. -->
- <color name="notification_divider_color">@*android:color/notification_action_list</color>
-
- <!-- The color for the unseen indicator. -->
- <color name="car_nav_unseen_indicator_color">#e25142</color>
-
- <!-- The color of the ripples on the untinted notifications -->
- <color name="notification_ripple_untinted_color">@color/ripple_material_light</color>
-
- <color name="keyguard_button_text_color">@android:color/black</color>
-
- <color name="list_divider_color">@*android:color/car_list_divider_light</color>
- <color name="car_volume_item_divider_color">@*android:color/car_list_divider</color>
- <color name="car_volume_item_background_color">@*android:color/car_card_dark</color>
-
- <color name="car_user_switching_dialog_background_color">@android:color/black</color>
- <color name="car_user_switching_dialog_loading_text_color">@*android:color/car_body1</color>
-
- <color name="rear_view_camera_button_background">@*android:color/car_card_dark</color>
-</resources>
diff --git a/packages/CarSystemUI/res/values/config.xml b/packages/CarSystemUI/res/values/config.xml
deleted file mode 100644
index b6179ed..0000000
--- a/packages/CarSystemUI/res/values/config.xml
+++ /dev/null
@@ -1,166 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<resources>
- <string name="config_statusBarComponent" translatable="false">
- com.android.systemui.statusbar.car.CarStatusBar
- </string>
- <string name="config_systemUIFactoryComponent" translatable="false">
- com.android.systemui.CarSystemUIFactory
- </string>
-
- <bool name="config_enableFullscreenUserSwitcher">true</bool>
-
- <!-- Configure which system bars should be displayed. -->
- <bool name="config_enableTopNavigationBar">true</bool>
- <bool name="config_enableLeftNavigationBar">false</bool>
- <bool name="config_enableRightNavigationBar">false</bool>
- <bool name="config_enableBottomNavigationBar">true</bool>
-
- <!-- Configure the type of each system bar. Each system bar must have a unique type. -->
- <!-- STATUS_BAR = 0-->
- <!-- NAVIGATION_BAR = 1-->
- <!-- STATUS_BAR_EXTRA = 2-->
- <!-- NAVIGATION_BAR_EXTRA = 3-->
- <integer name="config_topSystemBarType">0</integer>
- <integer name="config_leftSystemBarType">2</integer>
- <integer name="config_rightSystemBarType">3</integer>
- <integer name="config_bottomSystemBarType">1</integer>
-
- <!-- Configure the relative z-order among the system bars. When two system bars overlap (e.g.
- if both top bar and left bar are enabled, it creates an overlapping space in the upper left
- corner), the system bar with the higher z-order takes the overlapping space and padding is
- applied to the other bar.-->
- <!-- NOTE: If two overlapping system bars have the same z-order, SystemBarConfigs will throw a
- RuntimeException, since their placing order cannot be determined. Bars that do not overlap
- are allowed to have the same z-order. -->
- <!-- NOTE: If the z-order of a bar is 10 or above, it will also appear on top of HUN's. -->
- <integer name="config_topSystemBarZOrder">1</integer>
- <integer name="config_leftSystemBarZOrder">0</integer>
- <integer name="config_rightSystemBarZOrder">0</integer>
- <integer name="config_bottomSystemBarZOrder">10</integer>
-
- <!-- If set to true, the corresponding system bar will be hidden when Keyboard (IME) appears.
- NOTE: hideBottomSystemBarKeyboard must not be overlaid directly here. To change its value,
- overlay config_automotiveHideNavBarForKeyboard in framework/base/core/res/res. -->
- <bool name="config_hideTopSystemBarForKeyboard">false</bool>
- <bool name="config_hideBottomSystemBarForKeyboard">@*android:bool/config_automotiveHideNavBarForKeyboard</bool>
- <bool name="config_hideLeftSystemBarForKeyboard">false</bool>
- <bool name="config_hideRightSystemBarForKeyboard">false</bool>
-
- <!-- Disable normal notification rendering; we handle that ourselves -->
- <bool name="config_renderNotifications">false</bool>
-
- <!-- Whether navigationBar touch events should be consumed before reaching the CarFacetButton \
- when the notification panel is open. -->
- <bool name="config_consumeNavigationBarTouchWhenNotificationPanelOpen">false</bool>
-
- <!-- Whether heads-up notifications should be shown when shade is open. -->
- <bool name="config_enableHeadsUpNotificationWhenNotificationShadeOpen">true</bool>
- <!-- Whether heads-up notifications should be shown on the bottom. If false, heads-up
- notifications will be shown pushed to the top of their parent container. If true, they will
- be shown pushed to the bottom of their parent container. If true, then should override
- config_headsUpNotificationAnimationHelper to use a different AnimationHelper, such as
- com.android.car.notification.headsup.animationhelper.
- CarHeadsUpNotificationBottomAnimationHelper. -->
- <bool name="config_showHeadsUpNotificationOnBottom">false</bool>
-
- <bool name="config_hideNavWhenKeyguardBouncerShown">true</bool>
- <bool name="config_enablePersistentDockedActivity">false</bool>
- <string name="config_persistentDockedActivityIntentUri" translatable="false"></string>
-
- <!-- How many icons may be shown at once in the system bar. Includes any
- slots that may be reused for things like IME control. -->
- <integer name="config_maxNotificationIcons">0</integer>
-
- <!--
- Initial alpha percent value for the background when the notification
- shade is open. Should be a number between, and inclusive, 0 and 100.
- If the number is 0, then the background alpha starts off fully
- transparent. If the number if 100, then the background alpha starts off
- fully opaque. -->
- <integer name="config_initialNotificationBackgroundAlpha">0</integer>
- <!--
- Final alpha percent value for the background when the notification
- shade is fully open. Should be a number between, and inclusive, 0 and
- 100. If this value is smaller than
- config_initialNotificationBackgroundAlpha, the background will default
- to a constant alpha percent value using the initial alpha. -->
- <integer name="config_finalNotificationBackgroundAlpha">100</integer>
-
- <!-- Car System UI's OverlayViewsMediator.
- Whenever a new class is added, make sure to also add that class to OverlayWindowModule. -->
- <string-array name="config_carSystemUIOverlayViewsMediators" translatable="false">
- <item>@string/config_notificationPanelViewMediator</item>
- <item>com.android.systemui.car.keyguard.CarKeyguardViewMediator</item>
- <item>com.android.systemui.car.userswitcher.FullscreenUserSwitcherViewMediator</item>
- <item>com.android.systemui.car.userswitcher.UserSwitchTransitionViewMediator</item>
- <item>com.android.systemui.car.rvc.RearViewCameraViewMediator</item>
- </string-array>
-
- <!--
- Car SystemUI's notification mediator. Replace with other notification mediators to have
- the notification panel show from another system bar. The system bar should be enabled to
- use the mediator with that system bar.
- Example: config_enableBottomNavigationBar=true
- config_notificationPanelViewMediator=
- com.android.systemui.car.notification.BottomNotificationPanelViewMediator -->
- <string name="config_notificationPanelViewMediator" translatable="false">
- com.android.systemui.car.notification.TopNotificationPanelViewMediator</string>
-
- <!-- List of package names that are allowed sources of app installation. -->
- <string-array name="config_allowedAppInstallSources" translatable="false">
- <item>com.android.vending</item>
- </string-array>
-
- <!-- The list of components to exclude from config_systemUIServiceComponents. -->
- <string-array name="config_systemUIServiceComponentsExclude" translatable="false">
- <item>com.android.systemui.recents.Recents</item>
- <item>com.android.systemui.volume.VolumeUI</item>
- <item>com.android.systemui.statusbar.phone.StatusBar</item>
- <item>com.android.systemui.keyboard.KeyboardUI</item>
- <item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>
- <item>com.android.systemui.LatencyTester</item>
- <item>com.android.systemui.globalactions.GlobalActionsComponent</item>
- <item>com.android.systemui.SliceBroadcastRelayHandler</item>
- <item>com.android.systemui.statusbar.notification.InstantAppNotifier</item>
- <item>com.android.systemui.accessibility.WindowMagnification</item>
- <item>com.android.systemui.accessibility.SystemActions</item>
- </string-array>
-
- <!-- The list of components to append to config_systemUIServiceComponents. -->
- <string-array name="config_systemUIServiceComponentsInclude" translatable="false">
- <item>com.android.systemui.car.navigationbar.CarNavigationBar</item>
- <item>com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier</item>
- <item>com.android.systemui.car.window.SystemUIOverlayWindowManager</item>
- <item>com.android.systemui.car.volume.VolumeUI</item>
- </string-array>
-
- <!-- How many milliseconds to wait before force hiding the UserSwitchTransitionView -->
- <integer name="config_userSwitchTransitionViewShownTimeoutMs" translatable="false">5000</integer>
-
- <!-- The Activity name for the Rear View Camera, if empty, the feature will be disabled. -->
- <string name="config_rearViewCameraActivity" translatable="false"></string>
-
- <!-- Whether the Notification Panel should be inset by the top system bar. -->
- <bool name="config_notif_panel_inset_by_top_systembar" translatable="false">false</bool>
- <!-- Whether the Notification Panel should be inset by the bottom system bar. -->
- <bool name="config_notif_panel_inset_by_bottom_systembar" translatable="false">true</bool>
- <!-- Whether the Notification Panel should be inset by the left system bar. -->
- <bool name="config_notif_panel_inset_by_left_systembar" translatable="false">false</bool>
- <!-- Whether the Notification Panel should be inset by the right system bar. -->
- <bool name="config_notif_panel_inset_by_right_systembar" translatable="false">false</bool>
-</resources>
diff --git a/packages/CarSystemUI/res/values/dimens.xml b/packages/CarSystemUI/res/values/dimens.xml
deleted file mode 100644
index a7d8ab5..0000000
--- a/packages/CarSystemUI/res/values/dimens.xml
+++ /dev/null
@@ -1,234 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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>
- <!-- Text size for car -->
- <dimen name="car_title_size">32sp</dimen>
- <dimen name="car_title2_size">32sp</dimen>
- <dimen name="car_headline1_size">45sp</dimen>
- <dimen name="car_headline2_size">32sp</dimen>
- <dimen name="car_headline3_size">24sp</dimen>
- <dimen name="car_headline4_size">20sp</dimen>
- <dimen name="car_body1_size">32sp</dimen>
- <dimen name="car_body2_size">28sp</dimen>
- <dimen name="car_body3_size">26sp</dimen>
- <dimen name="car_body4_size">24sp</dimen>
- <!-- car_body5_size is deprecated -->
- <dimen name="car_body5_size">18sp</dimen>
- <dimen name="car_label1_size">26sp</dimen>
- <dimen name="car_label2_size">64sp</dimen>
- <dimen name="car_action1_size">26sp</dimen>
- <dimen name="car_action2_size">26sp</dimen>
- <!-- Paddings -->
- <dimen name="car_padding_0">4dp</dimen>
- <dimen name="car_padding_1">8dp</dimen>
- <dimen name="car_padding_2">16dp</dimen>
- <dimen name="car_padding_3">24dp</dimen>
- <dimen name="car_padding_4">32dp</dimen>
- <dimen name="car_padding_5">64dp</dimen>
- <dimen name="car_padding_6">96dp</dimen>
-
- <!--
- Note: status bar height and navigation bar heights are defined
- in frameworks/base/core package and thus will have no effect if
- set here. See car_product overlay for car specific defaults-->
-
- <!-- Overrides the space between each status icon in the system bar -->
- <dimen name="status_bar_system_icon_spacing">16dp</dimen>
- <!-- Overrides the size of the network signal icon -->
- <dimen name="signal_icon_size">32dp</dimen>
- <dimen name="system_bar_user_icon_padding">16dp</dimen>
- <dimen name="system_bar_user_icon_drawing_size">36dp</dimen>
- <!-- Padding on either side of the group of all system bar buttons -->
- <dimen name="system_bar_button_group_padding">64dp</dimen>
- <dimen name="system_bar_icon_drawing_size">44dp</dimen>
- <dimen name="system_bar_button_size">76dp</dimen>
- <!-- Margin between the system bar buttons -->
- <dimen name="system_bar_button_margin">32dp</dimen>
- <!-- Padding between the system bar button and the icon within it -->
- <dimen name="system_bar_button_padding">16dp</dimen>
-
- <!-- The amount by which to scale up the status bar icons. -->
- <item name="status_bar_icon_scale_factor" format="float" type="dimen">1.75</item>
-
- <dimen name="car_primary_icon_size">@*android:dimen/car_primary_icon_size</dimen>
-
- <dimen name="hvac_container_padding">16dp</dimen>
- <dimen name="hvac_temperature_text_size">56sp</dimen>
- <dimen name="hvac_temperature_text_padding">8dp</dimen>
- <dimen name="hvac_temperature_button_size">76dp</dimen>
- <!--These values represent MIN and MAX for hvac-->
- <item name="hvac_min_value_celsius" format="float" type="dimen">10</item>
- <item name="hvac_max_value_celsius" format="float" type="dimen">35</item>
-
- <!-- Largest size an avatar might need to be drawn in the user picker, status bar, or
- quick settings header -->
- <dimen name="max_avatar_size">128dp</dimen>
-
- <!-- Standard image button size for volume dialog buttons -->
- <dimen name="volume_button_size">84dp</dimen>
- <!-- The maximum width allowed for the volume dialog. For auto, we allow this to span a good
- deal of the screen. This value accounts for the side margins. -->
- <dimen name="volume_dialog_panel_width">1920dp</dimen>
- <dimen name="volume_dialog_side_margin">@dimen/side_margin</dimen>
-
- <dimen name="volume_dialog_elevation">6dp</dimen>
-
- <dimen name="volume_dialog_row_margin_end">@*android:dimen/car_keyline_3</dimen>
-
- <dimen name="volume_dialog_row_padding_end">0dp</dimen>
-
- <dimen name="line_item_height">128dp</dimen>
- <dimen name="volume_icon_size">96dp</dimen>
- <dimen name="side_margin">148dp</dimen>
- <dimen name="car_keyline_1">24dp</dimen>
- <dimen name="car_keyline_2">96dp</dimen>
- <dimen name="car_keyline_3">128dp</dimen>
-
- <!-- Height of icons in Ongoing App Ops dialog. Both App Op icon and application icon -->
- <dimen name="ongoing_appops_dialog_icon_height">48dp</dimen>
- <!-- Margin between text lines in Ongoing App Ops dialog -->
- <dimen name="ongoing_appops_dialog_text_margin">15dp</dimen>
- <!-- Padding around Ongoing App Ops dialog content -->
- <dimen name="ongoing_appops_dialog_content_padding">24dp</dimen>
- <!-- Margins around the Ongoing App Ops chip. In landscape, the side margins are 0 -->
- <dimen name="ongoing_appops_chip_margin">12dp</dimen>
- <!-- Start and End padding for Ongoing App Ops chip -->
- <dimen name="ongoing_appops_chip_side_padding">6dp</dimen>
- <!-- Padding between background of Ongoing App Ops chip and content -->
- <dimen name="ongoing_appops_chip_bg_padding">4dp</dimen>
- <!-- Radius of Ongoing App Ops chip corners -->
- <dimen name="ongoing_appops_chip_bg_corner_radius">12dp</dimen>
-
- <!-- Car volume dimens. -->
- <dimen name="car_volume_item_icon_size">@dimen/car_primary_icon_size</dimen>
- <dimen name="car_volume_item_height">@*android:dimen/car_single_line_list_item_height</dimen>
- <dimen name="car_volume_item_padding_start">@*android:dimen/car_keyline_1</dimen>
- <dimen name="car_volume_item_padding_end">@*android:dimen/car_keyline_1</dimen>
- <dimen name="car_volume_item_seekbar_margin_vertical">@*android:dimen/car_padding_1</dimen>
- <dimen name="car_volume_item_seekbar_margin_start">@*android:dimen/car_keyline_3</dimen>
- <dimen name="car_volume_item_seekbar_margin_end">@*android:dimen/car_padding_4</dimen>
- <dimen name="car_volume_item_seekbar_padding_vertical">@*android:dimen/car_seekbar_padding</dimen>
- <dimen name="car_volume_item_divider_height">60dp</dimen>
- <dimen name="car_volume_item_divider_width">1dp</dimen>
- <dimen name="car_volume_item_divider_margin_end">@*android:dimen/car_padding_4</dimen>
- <dimen name="car_volume_item_corner_radius">@*android:dimen/car_radius_3</dimen>
-
- <!-- Car notification shade-->
- <dimen name="notification_shade_handle_bar_height">10dp</dimen>
- <dimen name="notification_shade_handle_bar_radius">20dp</dimen>
- <dimen name="notification_shade_handle_bar_margin_start">200dp</dimen>
- <dimen name="notification_shade_handle_bar_margin_end">200dp</dimen>
- <dimen name="notification_shade_handle_bar_margin_top">20dp</dimen>
- <dimen name="notification_shade_handle_bar_margin_bottom">10dp</dimen>
- <dimen name="notification_shade_list_padding_bottom">50dp</dimen>
-
- <!-- The alpha for the scrim behind the notification shade. This value is 1 so that the
- scrim has no transparency. -->
- <item name="scrim_behind_alpha" format="float" type="dimen">1.0</item>
-
- <!-- The width of panel holding the notification card. -->
- <dimen name="notification_panel_width">522dp</dimen>
-
- <!-- Height of a small notification in the status bar-->
- <dimen name="notification_min_height">192dp</dimen>
-
- <!-- Height of a small notification in the status bar which was used before android N -->
- <dimen name="notification_min_height_legacy">192dp</dimen>
-
- <!-- Height of a large notification in the status bar -->
- <dimen name="notification_max_height">400dp</dimen>
-
- <!-- Height of a heads up notification in the status bar for legacy custom views -->
- <dimen name="notification_max_heads_up_height_legacy">400dp</dimen>
-
- <!-- Height of a heads up notification in the status bar -->
- <dimen name="notification_max_heads_up_height">400dp</dimen>
-
- <!-- Height of the status bar header bar -->
- <dimen name="status_bar_header_height">54dp</dimen>
-
- <!-- The height of the divider between the individual notifications. -->
- <dimen name="notification_divider_height">16dp</dimen>
-
- <!-- The height of the divider between the individual notifications when the notification
- wants it to be increased. This value is the same as notification_divider_height so that
- the spacing between all notifications will always be the same. -->
- <dimen name="notification_divider_height_increased">@dimen/notification_divider_height</dimen>
-
- <!-- The alpha of the dividing line between child notifications of a notification group. -->
- <item name="notification_divider_alpha" format="float" type="dimen">1.0</item>
-
- <!-- The width of each individual notification card. -->
- <dimen name="notification_child_width">522dp</dimen>
-
- <!-- The top margin of the notification panel. -->
- <dimen name="notification_panel_margin_top">32dp</dimen>
-
- <!-- The bottom margin of the panel that holds the list of notifications. -->
- <dimen name="notification_panel_margin_bottom">@dimen/notification_divider_height</dimen>
-
- <!-- The corner radius of the shadow behind the notification. -->
- <dimen name="notification_shadow_radius">16dp</dimen>
-
- <!-- The amount of space below the notification list. This value is 0 so the list scrolls
- all the way to the bottom. -->
- <dimen name="close_handle_underlap">0dp</dimen>
-
- <!-- The height of the divider between the individual notifications in a notification group. -->
- <dimen name="notification_children_container_divider_height">1dp</dimen>
-
- <!-- The height of the header for a container containing child notifications. -->
- <dimen name="notification_children_container_header_height">76dp</dimen>
-
- <!-- The top margin for the notification children container in its non-expanded form. This
- value is smaller than notification_children_container_header_height to bring the first
- child closer so there is less wasted space. -->
- <dimen name="notification_children_container_margin_top">68dp</dimen>
-
- <!-- dimensions for the car user switcher -->
- <dimen name="car_user_switcher_name_text_size">@*android:dimen/car_body1_size</dimen>
- <dimen name="car_user_switcher_image_avatar_size">@*android:dimen/car_large_avatar_size</dimen>
- <dimen name="car_user_switcher_vertical_spacing_between_users">@*android:dimen/car_padding_5</dimen>
- <dimen name="car_user_switcher_vertical_spacing_between_name_and_avatar">@*android:dimen/car_padding_4</dimen>
- <dimen name="car_user_switcher_margin_top">@*android:dimen/car_padding_4</dimen>
-
- <dimen name="car_navigation_button_width">64dp</dimen>
- <dimen name="car_navigation_button_icon_height">44dp</dimen>
- <dimen name="car_navigation_bar_width">760dp</dimen>
- <dimen name="car_left_navigation_bar_width">96dp</dimen>
- <dimen name="car_right_navigation_bar_width">96dp</dimen>
- <!-- In order to change the height of the bottom nav bar, overlay navigation_bar_height in
- frameworks/base/core/res/res instead. -->
- <dimen name="car_bottom_navigation_bar_height">@*android:dimen/navigation_bar_height</dimen>
- <!-- In order to change the height of the top nav bar, overlay status_bar_height in
- frameworks/base/core/res/res instead. -->
- <dimen name="car_top_navigation_bar_height">@*android:dimen/status_bar_height</dimen>
-
- <dimen name="car_user_switcher_container_height">420dp</dimen>
- <!-- This must be the negative of car_user_switcher_container_height for the animation. -->
- <dimen name="car_user_switcher_container_anim_height">-420dp</dimen>
-
- <!-- dimensions for car user switching dialog -->
- <dimen name="car_fullscreen_user_pod_image_avatar_width">96dp</dimen>
- <dimen name="car_fullscreen_user_pod_image_avatar_height">96dp</dimen>
- <dimen name="car_user_switching_dialog_loading_text_margin_top">@*android:dimen/car_padding_4</dimen>
- <dimen name="car_user_switching_dialog_loading_text_font_size">@*android:dimen/car_body1_size</dimen>
-
- <!-- dimensions for rear view camera -->
- <dimen name="rear_view_camera_width">600dp</dimen>
- <dimen name="rear_view_camera_height">500dp</dimen>
-</resources>
diff --git a/packages/CarSystemUI/res/values/ids.xml b/packages/CarSystemUI/res/values/ids.xml
deleted file mode 100644
index 05194a4..0000000
--- a/packages/CarSystemUI/res/values/ids.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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>
- <!-- Values used for finding elements on the system ui nav bars -->
- <item type="id" name="lock_screen_nav_buttons"/>
-</resources>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/values/integers.xml b/packages/CarSystemUI/res/values/integers.xml
deleted file mode 100644
index 5ae5555..0000000
--- a/packages/CarSystemUI/res/values/integers.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (c) 2018, 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>
- <!-- Full screen user switcher column number -->
- <integer name="user_fullscreen_switcher_num_col">3</integer>
-
- <!--Percentage of the screen height, from the bottom, that a notification panel being
- partially closed at will result in it remaining open if released-->
- <integer name="notification_settle_open_percentage">20</integer>
- <!--Percentage of the screen height, from the bottom, that a notification panel being peeked
- at will result in remaining closed the panel if released-->
- <integer name="notification_settle_close_percentage">80</integer>
-
- <!-- Timeout values in milliseconds for displaying volume dialog-->
- <integer name="car_volume_dialog_display_normal_timeout">3000</integer>
- <integer name="car_volume_dialog_display_hovering_timeout">16000</integer>
- <integer name="car_volume_dialog_display_expanded_normal_timeout">6000</integer>
- <integer name="car_volume_dialog_display_expanded_hovering_timeout">32000</integer>
-</resources>
diff --git a/packages/CarSystemUI/res/values/strings.xml b/packages/CarSystemUI/res/values/strings.xml
deleted file mode 100644
index 2644565..0000000
--- a/packages/CarSystemUI/res/values/strings.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (c) 2018 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Format for HVAC temperature (No decimal and the degree symbol) -->
- <string name="hvac_temperature_format" translatable="false">%.0f\u00B0</string>
- <!-- String to represent lowest setting of an HVAC system [CHAR LIMIT=10]-->
- <string name="hvac_min_text">Min</string>
- <!-- String to represent largest setting of an HVAC system [CHAR LIMIT=10]-->
- <string name="hvac_max_text">Max</string>
- <!-- String to display when no HVAC temperature is available -->
- <string name="hvac_null_temp_text" translatable="false">--</string>
- <!-- Text for voice recognition toast. [CHAR LIMIT=60] -->
- <string name="voice_recognition_toast">Voice recognition now handled by connected Bluetooth device</string>
- <!-- Name of Guest Profile. [CHAR LIMIT=35] -->
- <string name="car_guest">Guest</string>
- <!-- Title for button that starts a guest session. [CHAR LIMIT=35] -->
- <string name="start_guest_session">Guest</string>
- <!-- Title for button that adds a new user. [CHAR LIMIT=30] -->
- <string name="car_add_user">Add User</string>
- <!-- Default name of the new user created. [CHAR LIMIT=30] -->
- <string name="car_new_user">New User</string>
- <!-- Message to inform user that creation of new user requires that user to set up their space. [CHAR LIMIT=100] -->
- <string name="user_add_user_message_setup">When you add a new user, that person needs to set up their space.</string>
- <!-- Message to inform user that the newly created user will have permissions to update apps for all other users. [CHAR LIMIT=100] -->
- <string name="user_add_user_message_update">Any user can update apps for all other users.</string>
- <!-- Message to inform user that the new user profile is loading. [CHAR LIMIT=20] -->
- <string name="car_loading_profile">Loading</string>
- <!-- Message to inform user that the new user profile is loading with additional information on the previous and the next user. [CHAR LIMIT=100] -->
- <string name="car_loading_profile_developer_message">Loading user (from <xliff:g id="from_user" example="10">%1$d</xliff:g> to <xliff:g id="to_user" example="12">%2$d</xliff:g>)</string>
- <!-- Text for the close button in Rear View Camera [CHAR LIMIT=30] -->
- <string name="rear_view_camera_close_button_text">Close</string>
-</resources>
diff --git a/packages/CarSystemUI/res/values/styles.xml b/packages/CarSystemUI/res/values/styles.xml
deleted file mode 100644
index f5de2fd..0000000
--- a/packages/CarSystemUI/res/values/styles.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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 xmlns:android="http://schemas.android.com/apk/res/android">
-
- <!-- The style for the volume icons in the volume dialog. This style makes the icon scale to
- fit its container since auto wants the icon to be larger. The padding is added to make it
- so the icon does not press along the edges of the dialog. -->
- <style name="VolumeButtons" parent="@android:style/Widget.Material.Button.Borderless">
- <item name="android:background">@drawable/btn_borderless_rect</item>
- <item name="android:scaleType">fitCenter</item>
- <item name="android:padding">22dp</item>
- </style>
-
- <style name="TextAppearance.SystemBar.Clock"
- parent="@*android:style/TextAppearance.StatusBar.Icon">
- <item name="android:textSize">@dimen/car_body1_size</item>
- <item name="android:textColor">@*android:color/car_headline3</item>
- </style>
-
- <style name="TextAppearance.SystemBar.Username"
- parent="@android:style/TextAppearance.DeviceDefault">
- <item name="android:textSize">@dimen/car_body3_size</item>
- <item name="android:textColor">@color/system_bar_text_color</item>
- </style>
-
- <style name="TextAppearance.CarStatus" parent="@android:style/TextAppearance.DeviceDefault">
- <item name="android:textSize">@*android:dimen/car_body2_size</item>
- <item name="android:textColor">@color/system_bar_text_color</item>
- </style>
-
- <style name="NavigationBarButton">
- <item name="android:layout_height">@dimen/system_bar_button_size</item>
- <item name="android:layout_width">@dimen/system_bar_button_size</item>
- <item name="android:layout_marginEnd">@dimen/system_bar_button_margin</item>
- <item name="android:padding">@dimen/system_bar_button_padding</item>
- <item name="android:gravity">center</item>
- <item name="android:background">?android:attr/selectableItemBackground</item>
- <item name="unselectedAlpha">0.56</item>
- </style>
-</resources>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/xml/car_volume_items.xml b/packages/CarSystemUI/res/xml/car_volume_items.xml
deleted file mode 100644
index d371a64..0000000
--- a/packages/CarSystemUI/res/xml/car_volume_items.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 2018 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.
- -->
-
-<!--
- Defines all possible items on car volume settings UI, keyed by usage.
--->
-<carVolumeItems xmlns:car="http://schemas.android.com/apk/res-auto">
- <item car:usage="unknown"
- car:icon="@drawable/car_ic_music"/>
- <item car:usage="media"
- car:icon="@drawable/car_ic_music"/>
- <item car:usage="assistance_navigation_guidance"
- car:icon="@drawable/car_ic_navigation"/>
- <item car:usage="voice_communication_signalling"
- car:icon="@*android:drawable/ic_audio_ring_notif"/>
- <item car:usage="alarm"
- car:icon="@drawable/ic_volume_alarm"/>
- <item car:usage="notification"
- car:icon="@drawable/car_ic_notification"/>
- <item car:usage="notification_ringtone"
- car:icon="@drawable/car_ic_notification"/>
- <item car:usage="notification_communication_request"
- car:icon="@drawable/car_ic_notification"/>
- <item car:usage="notification_communication_instant"
- car:icon="@drawable/car_ic_notification"/>
- <item car:usage="notification_communication_delayed"
- car:icon="@drawable/car_ic_notification"/>
- <item car:usage="notification_event"
- car:icon="@drawable/car_ic_notification"/>
- <item car:usage="assistance_accessibility"
- car:icon="@drawable/car_ic_notification"/>
- <item car:usage="voice_communication"
- car:icon="@*android:drawable/ic_audio_ring_notif"/>
- <item car:usage="assistance_sonification"
- car:icon="@drawable/car_ic_notification"/>
- <item car:usage="game"
- car:icon="@drawable/car_ic_music"/>
- <item car:usage="assistant"
- car:icon="@drawable/car_ic_music"/>
- <item car:usage="call_assistant"
- car:icon="@*android:drawable/ic_audio_ring_notif"/>
- <item car:usage="emergency"
- car:icon="@drawable/ic_volume_alarm"/>
- <item car:usage="safety"
- car:icon="@drawable/ic_volume_alarm"/>
- <item car:usage="vehicle_status"
- car:icon="@drawable/car_ic_notification"/>
- <item car:usage="announcement"
- car:icon="@drawable/car_ic_notification"/>
-</carVolumeItems>
-
diff --git a/packages/CarSystemUI/samples/sample1/rro/Android.bp b/packages/CarSystemUI/samples/sample1/rro/Android.bp
deleted file mode 100644
index 5b0347f..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/Android.bp
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// Copyright (C) 2020 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.
-//
-
-android_app {
- name: "CarSystemUISampleOneRRO",
- resource_dirs: ["res"],
- certificate: "platform",
- platform_apis: true,
- manifest: "AndroidManifest.xml",
- aaptflags: [
- "--no-resource-deduping",
- "--no-resource-removal",
- ]
-}
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample1/rro/AndroidManifest.xml b/packages/CarSystemUI/samples/sample1/rro/AndroidManifest.xml
deleted file mode 100644
index 5c25056..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/AndroidManifest.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.systemui.rro">
- <overlay
- android:targetPackage="com.android.systemui"
- android:isStatic="false"
- android:resourcesMap="@xml/car_sysui_overlays"
- />
-</manifest>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_apps.xml b/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_apps.xml
deleted file mode 100644
index a8d8a2f..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_apps.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
-<path
- android:pathData="M7.33333333 14.6666667L14.6666667 14.6666667L14.6666667 7.33333333L7.33333333 7.33333333L7.33333333 14.6666667ZM18.3333333 36.6666667L25.6666667 36.6666667L25.6666667 29.3333333L18.3333333 29.3333333L18.3333333 36.6666667ZM7.33333333 36.6666667L14.6666667 36.6666667L14.6666667 29.3333333L7.33333333 29.3333333L7.33333333 36.6666667ZM7.33333333 25.6666667L14.6666667 25.6666667L14.6666667 18.3333333L7.33333333 18.3333333L7.33333333 25.6666667ZM18.3333333 25.6666667L25.6666667 25.6666667L25.6666667 18.3333333L18.3333333 18.3333333L18.3333333 25.6666667ZM29.3333333 7.33333333L29.3333333 14.6666667L36.6666667 14.6666667L36.6666667 7.33333333L29.3333333 7.33333333ZM18.3333333 14.6666667L25.6666667 14.6666667L25.6666667 7.33333333L18.3333333 7.33333333L18.3333333 14.6666667ZM29.3333333 25.6666667L36.6666667 25.6666667L36.6666667 18.3333333L29.3333333 18.3333333L29.3333333 25.6666667ZM29.3333333 36.6666667L36.6666667 36.6666667L36.6666667 29.3333333L29.3333333 29.3333333L29.3333333 36.6666667Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_apps_selected.xml b/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_apps_selected.xml
deleted file mode 100644
index 2a4e91a..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_apps_selected.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M7.33333333 14.6666667L14.6666667 14.6666667L14.6666667 7.33333333L7.33333333 7.33333333L7.33333333 14.6666667ZM18.3333333 36.6666667L25.6666667 36.6666667L25.6666667 29.3333333L18.3333333 29.3333333L18.3333333 36.6666667ZM7.33333333 36.6666667L14.6666667 36.6666667L14.6666667 29.3333333L7.33333333 29.3333333L7.33333333 36.6666667ZM7.33333333 25.6666667L14.6666667 25.6666667L14.6666667 18.3333333L7.33333333 18.3333333L7.33333333 25.6666667ZM18.3333333 25.6666667L25.6666667 25.6666667L25.6666667 18.3333333L18.3333333 18.3333333L18.3333333 25.6666667ZM29.3333333 7.33333333L29.3333333 14.6666667L36.6666667 14.6666667L36.6666667 7.33333333L29.3333333 7.33333333ZM18.3333333 14.6666667L25.6666667 14.6666667L25.6666667 7.33333333L18.3333333 7.33333333L18.3333333 14.6666667ZM29.3333333 25.6666667L36.6666667 25.6666667L36.6666667 18.3333333L29.3333333 18.3333333L29.3333333 25.6666667ZM29.3333333 36.6666667L36.6666667 36.6666667L36.6666667 29.3333333L29.3333333 29.3333333L29.3333333 36.6666667Z"
- android:fillColor="@color/car_nav_icon_fill_color_selected" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_music.xml b/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_music.xml
deleted file mode 100644
index 6339ebb..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_music.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M22 5.5L22 24.8416667C20.9183333 24.2183333 19.6716667 23.8333333 18.3333333 23.8333333C14.2816667 23.8333333 11 27.115 11 31.1666667C11 35.2183333 14.2816667 38.5 18.3333333 38.5C22.385 38.5 25.6666667 35.2183333 25.6666667 31.1666667L25.6666667 12.8333333L33 12.8333333L33 5.5L22 5.5Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_music_selected.xml b/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_music_selected.xml
deleted file mode 100644
index a56bcb3..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_music_selected.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M22 5.5L22 24.8416667C20.9183333 24.2183333 19.6716667 23.8333333 18.3333333 23.8333333C14.2816667 23.8333333 11 27.115 11 31.1666667C11 35.2183333 14.2816667 38.5 18.3333333 38.5C22.385 38.5 25.6666667 35.2183333 25.6666667 31.1666667L25.6666667 12.8333333L33 12.8333333L33 5.5L22 5.5Z"
- android:fillColor="@color/car_nav_icon_fill_color_selected" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_navigation.xml b/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_navigation.xml
deleted file mode 100644
index e1fabe0..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_navigation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M39.8016667 20.6983333L23.3016667 4.19833333C22.5866667 3.48333333 21.4316667 3.48333333 20.7166667 4.19833333L4.21666667 20.6983333C3.50166667 21.4133333 3.50166667 22.5683333 4.21666667 23.2833333L20.7166667 39.7833333C21.4316667 40.4983333 22.5866667 40.4983333 23.3016667 39.7833333L39.8016667 23.2833333C40.5166667 22.5866667 40.5166667 21.4316667 39.8016667 20.6983333ZM25.6666667 26.5833333L25.6666667 22L18.3333333 22L18.3333333 27.5L14.6666667 27.5L14.6666667 20.1666667C14.6666667 19.1583333 15.4916667 18.3333333 16.5 18.3333333L25.6666667 18.3333333L25.6666667 13.75L32.0833333 20.1666667L25.6666667 26.5833333Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_navigation_selected.xml b/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_navigation_selected.xml
deleted file mode 100644
index d11cf28..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_navigation_selected.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M39.8016667 20.6983333L23.3016667 4.19833333C22.5866667 3.48333333 21.4316667 3.48333333 20.7166667 4.19833333L4.21666667 20.6983333C3.50166667 21.4133333 3.50166667 22.5683333 4.21666667 23.2833333L20.7166667 39.7833333C21.4316667 40.4983333 22.5866667 40.4983333 23.3016667 39.7833333L39.8016667 23.2833333C40.5166667 22.5866667 40.5166667 21.4316667 39.8016667 20.6983333ZM25.6666667 26.5833333L25.6666667 22L18.3333333 22L18.3333333 27.5L14.6666667 27.5L14.6666667 20.1666667C14.6666667 19.1583333 15.4916667 18.3333333 16.5 18.3333333L25.6666667 18.3333333L25.6666667 13.75L32.0833333 20.1666667L25.6666667 26.5833333Z"
- android:fillColor="@color/car_nav_icon_fill_color_selected" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_overview.xml b/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_overview.xml
deleted file mode 100644
index f185eb9..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_overview.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M36.92857 22.39286A14.53571 14.53571 0 0 1 7.857143 22.39286A14.53571 14.53571 0 0 1 36.92857 22.39286Z"
- android:strokeColor="@color/car_nav_icon_fill_color"
- android:strokeWidth="4" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_overview_selected.xml b/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_overview_selected.xml
deleted file mode 100644
index 19b5583..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_overview_selected.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M36.92857 22.39286A14.53571 14.53571 0 0 1 7.857143 22.39286A14.53571 14.53571 0 0 1 36.92857 22.39286Z"
- android:strokeColor="@color/car_nav_icon_fill_color_selected"
- android:strokeWidth="4" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_phone.xml b/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_phone.xml
deleted file mode 100644
index 50e36b5..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_phone.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M12.1366667 19.7816667C14.7766667 24.97 19.03 29.205 24.2183333 31.8633333L28.2516667 27.83C28.7466667 27.335 29.48 27.17 30.1216667 27.39C32.175 28.0683333 34.3933333 28.435 36.6666667 28.435C37.675 28.435 38.5 29.26 38.5 30.2683333L38.5 36.6666667C38.5 37.675 37.675 38.5 36.6666667 38.5C19.4516667 38.5 5.5 24.5483333 5.5 7.33333333C5.5 6.325 6.325 5.5 7.33333333 5.5L13.75 5.5C14.7583333 5.5 15.5833333 6.325 15.5833333 7.33333333C15.5833333 9.625 15.95 11.825 16.6283333 13.8783333C16.83 14.52 16.6833333 15.235 16.17 15.7483333L12.1366667 19.7816667Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_phone_selected.xml b/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_phone_selected.xml
deleted file mode 100644
index 11b1687..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/drawable/car_ic_phone_selected.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M12.1366667 19.7816667C14.7766667 24.97 19.03 29.205 24.2183333 31.8633333L28.2516667 27.83C28.7466667 27.335 29.48 27.17 30.1216667 27.39C32.175 28.0683333 34.3933333 28.435 36.6666667 28.435C37.675 28.435 38.5 29.26 38.5 30.2683333L38.5 36.6666667C38.5 37.675 37.675 38.5 36.6666667 38.5C19.4516667 38.5 5.5 24.5483333 5.5 7.33333333C5.5 6.325 6.325 5.5 7.33333333 5.5L13.75 5.5C14.7583333 5.5 15.5833333 6.325 15.5833333 7.33333333C15.5833333 9.625 15.95 11.825 16.6283333 13.8783333C16.83 14.52 16.6833333 15.235 16.17 15.7483333L12.1366667 19.7816667Z"
- android:fillColor="@color/car_nav_icon_fill_color_selected" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/drawable/system_bar_background.xml b/packages/CarSystemUI/samples/sample1/rro/res/drawable/system_bar_background.xml
deleted file mode 100644
index 6161ad9..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/drawable/system_bar_background.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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.
- -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
- <corners
- android:topLeftRadius="0dp"
- android:topRightRadius="10dp"
- android:bottomLeftRadius="0dp"
- android:bottomRightRadius="0dp"
- />
- <solid
- android:color="#404040"
- />
- <padding
- android:left="0dp"
- android:top="0dp"
- android:right="0dp"
- android:bottom="0dp"
- />
-</shape>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/drawable/system_bar_background_2.xml b/packages/CarSystemUI/samples/sample1/rro/res/drawable/system_bar_background_2.xml
deleted file mode 100644
index 3582142..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/drawable/system_bar_background_2.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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.
- -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
- <corners
- android:topLeftRadius="10dp"
- android:topRightRadius="0dp"
- android:bottomLeftRadius="0dp"
- android:bottomRightRadius="0dp"
- />
- <solid
- android:color="#404040"
- />
- <padding
- android:left="0dp"
- android:top="0dp"
- android:right="0dp"
- android:bottom="0dp"
- />
-</shape>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/drawable/system_bar_background_3.xml b/packages/CarSystemUI/samples/sample1/rro/res/drawable/system_bar_background_3.xml
deleted file mode 100644
index afa5b32..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/drawable/system_bar_background_3.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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.
- -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
- <corners
- android:topLeftRadius="0dp"
- android:topRightRadius="0dp"
- android:bottomLeftRadius="10dp"
- android:bottomRightRadius="0dp"
- />
- <solid
- android:color="#404040"
- />
- <padding
- android:left="0dp"
- android:top="0dp"
- android:right="0dp"
- android:bottom="0dp"
- />
-</shape>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/layout/car_navigation_bar.xml b/packages/CarSystemUI/samples/sample1/rro/res/layout/car_navigation_bar.xml
deleted file mode 100644
index 4358d97..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/layout/car_navigation_bar.xml
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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.
- -->
-<com.android.systemui.car.navigationbar.CarNavigationBarView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@android:color/transparent"
- android:orientation="horizontal">
- <!--The 20dp padding is the difference between the background selected icon size and the ripple
- that was chosen, thus it's a hack to make it look pretty and not an official margin value-->
- <LinearLayout
- android:id="@+id/nav_buttons"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@drawable/system_bar_background"
- android:gravity="center"
- android:layoutDirection="ltr"
- android:paddingEnd="20dp"
- android:paddingStart="20dp">
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/home"
- style="@style/NavigationBarButton"
- systemui:componentNames="com.android.car.carlauncher/.CarLauncher"
- systemui:icon="@drawable/car_ic_overview"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
- systemui:selectedIcon="@drawable/car_ic_overview_selected"
- systemui:highlightWhenSelected="true"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/maps_nav"
- style="@style/NavigationBarButton"
- systemui:categories="android.intent.category.APP_MAPS"
- systemui:icon="@drawable/car_ic_navigation"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MAPS;launchFlags=0x14000000;end"
- systemui:selectedIcon="@drawable/car_ic_navigation_selected"
- systemui:highlightWhenSelected="true"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/music_nav"
- style="@style/NavigationBarButton"
- systemui:categories="android.intent.category.APP_MUSIC"
- systemui:icon="@drawable/car_ic_music"
- systemui:intent="intent:#Intent;action=android.car.intent.action.MEDIA_TEMPLATE;launchFlags=0x10000000;end"
- systemui:packages="com.android.car.media"
- systemui:selectedIcon="@drawable/car_ic_music_selected"
- systemui:highlightWhenSelected="true"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/phone_nav"
- style="@style/NavigationBarButton"
- systemui:icon="@drawable/car_ic_phone"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;package=com.android.car.dialer;launchFlags=0x10000000;end"
- systemui:packages="com.android.car.dialer"
- systemui:selectedIcon="@drawable/car_ic_phone_selected"
- systemui:highlightWhenSelected="true"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/grid_nav"
- style="@style/NavigationBarButton"
- systemui:componentNames="com.android.car.carlauncher/.AppGridActivity"
- systemui:icon="@drawable/car_ic_apps"
- systemui:intent="intent:#Intent;component=com.android.car.carlauncher/.AppGridActivity;launchFlags=0x24000000;end"
- systemui:selectedIcon="@drawable/car_ic_apps_selected"
- systemui:highlightWhenSelected="true"
- />
-
- </LinearLayout>
-</com.android.systemui.car.navigationbar.CarNavigationBarView>
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/layout/car_right_navigation_bar.xml b/packages/CarSystemUI/samples/sample1/rro/res/layout/car_right_navigation_bar.xml
deleted file mode 100644
index dc1d0d64..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/layout/car_right_navigation_bar.xml
+++ /dev/null
@@ -1,141 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2018, 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.
-*/
--->
-
-<com.android.systemui.car.navigationbar.CarNavigationBarView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:orientation="vertical"
- android:baselineAligned="false"
- android:background="@android:color/transparent">
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="110dp"
- android:background="@drawable/system_bar_background_3">
- <FrameLayout
- android:id="@+id/clock_container"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_centerInParent="true">
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/qs"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@null"
- systemui:intent="intent:#Intent;component=com.android.car.settings/.common.CarSettingActivities$QuickSettingActivity;launchFlags=0x24000000;end"
- />
- <com.android.systemui.statusbar.policy.Clock
- android:id="@+id/clock"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:elevation="5dp"
- android:singleLine="true"
- android:textAppearance="@style/TextAppearance.StatusBar.Clock"
- />
- </FrameLayout>
- </RelativeLayout>
- <View
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"
- />
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="110dp"
- android:layout_gravity="bottom"
- android:orientation="horizontal"
- android:background="@drawable/system_bar_background_2">
-
- <FrameLayout
- android:id="@+id/left_hvac_container"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentStart="true">
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/hvacleft"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@null"
- systemui:broadcast="true"
- systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
- />
-
- <com.android.systemui.car.hvac.AnimatedTemperatureView
- android:id="@+id/lefttext"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:paddingStart="@*android:dimen/car_padding_4"
- android:paddingEnd="16dp"
- android:gravity="center_vertical|start"
- android:minEms="4"
- android:textAppearance="@style/TextAppearance.CarStatus"
- systemui:hvacAreaId="49"
- systemui:hvacMaxText="Max"
- systemui:hvacMaxValue="126"
- systemui:hvacMinText="Min"
- systemui:hvacMinValue="0"
- systemui:hvacPivotOffset="60dp"
- systemui:hvacPropertyId="358614275"
- systemui:hvacTempFormat="%.0f\u00B0"
- />
- </FrameLayout>
- <View
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"
- />
- <FrameLayout
- android:id="@+id/right_hvac_container"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentEnd="true">
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/hvacright"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@null"
- systemui:broadcast="true"
- systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
- />
-
- <com.android.systemui.car.hvac.AnimatedTemperatureView
- android:id="@+id/righttext"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:paddingStart="16dp"
- android:paddingEnd="@*android:dimen/car_padding_4"
- android:gravity="center_vertical|end"
- android:minEms="4"
- android:textAppearance="@style/TextAppearance.CarStatus"
- systemui:hvacAreaId="68"
- systemui:hvacMaxText="Max"
- systemui:hvacMaxValue="126"
- systemui:hvacMinText="Min"
- systemui:hvacMinValue="0"
- systemui:hvacPivotOffset="60dp"
- systemui:hvacPropertyId="358614275"
- systemui:hvacTempFormat="%.0f\u00B0"
- />
- </FrameLayout>
- </LinearLayout>
-</com.android.systemui.car.navigationbar.CarNavigationBarView>
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/layout/system_icons.xml b/packages/CarSystemUI/samples/sample1/rro/res/layout/system_icons.xml
deleted file mode 100644
index d235792..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/layout/system_icons.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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/system_icons"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center_vertical">
-
- <com.android.systemui.statusbar.phone.StatusIconContainer
- android:id="@+id/statusIcons"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:paddingEnd="4dp"
- android:gravity="center_vertical"
- android:orientation="horizontal"
- />
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/values/attrs.xml b/packages/CarSystemUI/samples/sample1/rro/res/values/attrs.xml
deleted file mode 100644
index e02f9e6..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/values/attrs.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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>
- <attr name="broadcast" format="boolean"/>
- <attr name="icon" format="reference"/>
- <attr name="selectedIcon" format="reference"/>
- <attr name="intent" format="string"/>
- <attr name="longIntent" format="string"/>
- <attr name="componentNames" format="string" />
- <attr name="highlightWhenSelected" format="boolean" />
- <attr name="categories" format="string"/>
- <attr name="packages" format="string" />
-
- <!-- Custom attributes to configure hvac values -->
- <declare-styleable name="AnimatedTemperatureView">
- <attr name="hvacAreaId" format="integer"/>
- <attr name="hvacPropertyId" format="integer"/>
- <attr name="hvacTempFormat" format="string"/>
- <!-- how far away the animations should center around -->
- <attr name="hvacPivotOffset" format="dimension"/>
- <attr name="hvacMinValue" format="float"/>
- <attr name="hvacMaxValue" format="float"/>
- <attr name="hvacMinText" format="string|reference"/>
- <attr name="hvacMaxText" format="string|reference"/>
- <attr name="android:gravity"/>
- <attr name="android:minEms"/>
- <attr name="android:textAppearance"/>
- </declare-styleable>
-</resources>
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/values/colors.xml b/packages/CarSystemUI/samples/sample1/rro/res/values/colors.xml
deleted file mode 100644
index c32d638..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/values/colors.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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 xmlns:android="http://schemas.android.com/apk/res/android">
- <color name="car_nav_icon_fill_color">#8F8F8F</color>
- <color name="car_nav_icon_fill_color_selected">#FFFFFF</color>
-</resources>
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/values/config.xml b/packages/CarSystemUI/samples/sample1/rro/res/values/config.xml
deleted file mode 100644
index 2ec90e9..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/values/config.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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>
- <!-- Configure which system bars should be displayed. -->
- <bool name="config_enableTopNavigationBar">false</bool>
- <bool name="config_enableLeftNavigationBar">false</bool>
- <bool name="config_enableRightNavigationBar">true</bool>
- <bool name="config_enableBottomNavigationBar">true</bool>
-
- <!-- Configure the type of each system bar. Each system bar must have a unique type. -->
- <!-- STATUS_BAR = 0-->
- <!-- NAVIGATION_BAR = 1-->
- <!-- STATUS_BAR_EXTRA = 2-->
- <!-- NAVIGATION_BAR_EXTRA = 3-->
- <integer name="config_topSystemBarType">0</integer>
- <integer name="config_leftSystemBarType">0</integer>
- <integer name="config_rightSystemBarType">0</integer>
- <integer name="config_bottomSystemBarType">1</integer>
-
- <!-- Configure the relative z-order among the system bars. When two system bars overlap (e.g.
- if both top bar and left bar are enabled, it creates an overlapping space in the upper left
- corner), the system bar with the higher z-order takes the overlapping space and padding is
- applied to the other bar.-->
- <!-- NOTE: If two overlapping system bars have the same z-order, SystemBarConfigs will throw a
- RuntimeException, since their placing order cannot be determined. Bars that do not overlap
- are allowed to have the same z-order. -->
- <!-- NOTE: If the z-order of a bar is 10 or above, it will also appear on top of HUN's. -->
- <integer name="config_topSystemBarZOrder">0</integer>
- <integer name="config_leftSystemBarZOrder">0</integer>
- <integer name="config_rightSystemBarZOrder">11</integer>
- <integer name="config_bottomSystemBarZOrder">10</integer>
-
- <!-- Whether heads-up notifications should be shown on the bottom. If false, heads-up
- notifications will be shown pushed to the top of their parent container. If true, they will
- be shown pushed to the bottom of their parent container. If true, then should override
- config_headsUpNotificationAnimationHelper to use a different AnimationHelper, such as
- com.android.car.notification.headsup.animationhelper.
- CarHeadsUpNotificationBottomAnimationHelper. -->
- <bool name="config_showHeadsUpNotificationOnBottom">true</bool>
-
- <string name="config_notificationPanelViewMediator" translatable="false">
- com.android.systemui.car.notification.BottomNotificationPanelViewMediator</string>
-</resources>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/values/dimens.xml b/packages/CarSystemUI/samples/sample1/rro/res/values/dimens.xml
deleted file mode 100644
index cdfed27..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/values/dimens.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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>
- <dimen name="car_right_navigation_bar_width">280dp</dimen>
-</resources>
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/values/styles.xml b/packages/CarSystemUI/samples/sample1/rro/res/values/styles.xml
deleted file mode 100644
index 136dc3b..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/values/styles.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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 xmlns:android="http://schemas.android.com/apk/res/android">
- <style name="TextAppearance.StatusBar.Clock"
- parent="@*android:style/TextAppearance.StatusBar.Icon">
- <item name="android:textSize">40sp</item>
- <item name="android:fontFamily">sans-serif-regular</item>
- <item name="android:textColor">#FFFFFF</item>
- </style>
-
- <style name="NavigationBarButton">
- <item name="android:layout_height">96dp</item>
- <item name="android:layout_width">96dp</item>
- <item name="android:background">?android:attr/selectableItemBackground</item>
- </style>
-
- <style name="TextAppearance.CarStatus" parent="@android:style/TextAppearance.DeviceDefault">
- <item name="android:textSize">30sp</item>
- <item name="android:textColor">#FFFFFF</item>
- </style>
-</resources>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample1/rro/res/xml/car_sysui_overlays.xml b/packages/CarSystemUI/samples/sample1/rro/res/xml/car_sysui_overlays.xml
deleted file mode 100644
index 20aa5f7..0000000
--- a/packages/CarSystemUI/samples/sample1/rro/res/xml/car_sysui_overlays.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-
-<!--
- ~ Copyright (C) 2020 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.
- -->
-
-<overlay>
- <item target="layout/car_navigation_bar" value="@layout/car_navigation_bar"/>
- <item target="layout/system_icons" value="@layout/system_icons"/>
- <item target="layout/car_right_navigation_bar" value="@layout/car_right_navigation_bar"/>
-
- <item target="attr/icon" value="@attr/icon"/>
- <item target="attr/selectedIcon" value="@attr/selectedIcon"/>
- <item target="attr/intent" value="@attr/intent"/>
- <item target="attr/longIntent" value="@attr/longIntent"/>
- <item target="attr/componentNames" value="@attr/componentNames"/>
- <item target="attr/highlightWhenSelected" value="@attr/highlightWhenSelected"/>
- <item target="attr/categories" value="@attr/categories"/>
- <item target="attr/packages" value="@attr/packages"/>
- <item target="attr/hvacAreaId" value="@attr/hvacAreaId"/>
- <item target="attr/hvacPropertyId" value="@attr/hvacPropertyId"/>
- <item target="attr/hvacTempFormat" value="@attr/hvacTempFormat"/>
- <item target="attr/hvacPivotOffset" value="@attr/hvacPivotOffset"/>
- <item target="attr/hvacMinValue" value="@attr/hvacMinValue"/>
- <item target="attr/hvacMaxValue" value="@attr/hvacMaxValue"/>
- <item target="attr/hvacMinText" value="@attr/hvacMinText"/>
- <item target="attr/hvacMaxText" value="@attr/hvacMaxText"/>
- <!-- start the intent as a broad cast instead of an activity if true-->
- <item target="attr/broadcast" value="@attr/broadcast"/>
-
- <item target="drawable/car_ic_overview" value="@drawable/car_ic_overview" />
- <item target="drawable/car_ic_overview_selected" value="@drawable/car_ic_overview_selected" />
- <item target="drawable/car_ic_apps" value="@drawable/car_ic_apps" />
- <item target="drawable/car_ic_apps_selected" value="@drawable/car_ic_apps_selected" />
- <item target="drawable/car_ic_music" value="@drawable/car_ic_music" />
- <item target="drawable/car_ic_music_selected" value="@drawable/car_ic_music_selected" />
- <item target="drawable/car_ic_phone" value="@drawable/car_ic_phone" />
- <item target="drawable/car_ic_phone_selected" value="@drawable/car_ic_phone_selected" />
- <item target="drawable/car_ic_navigation" value="@drawable/car_ic_navigation" />
- <item target="drawable/car_ic_navigation_selected" value="@drawable/car_ic_navigation_selected" />
-
- <item target="dimen/car_right_navigation_bar_width" value="@dimen/car_right_navigation_bar_width" />
-
- <item target="style/NavigationBarButton" value="@style/NavigationBarButton"/>
-
- <item target="color/car_nav_icon_fill_color" value="@color/car_nav_icon_fill_color" />
-
- <item target="bool/config_enableTopNavigationBar" value="@bool/config_enableTopNavigationBar"/>
- <item target="bool/config_enableLeftNavigationBar" value="@bool/config_enableLeftNavigationBar"/>
- <item target="bool/config_enableRightNavigationBar" value="@bool/config_enableRightNavigationBar"/>
- <item target="bool/config_enableBottomNavigationBar" value="@bool/config_enableBottomNavigationBar"/>
- <item target="bool/config_showHeadsUpNotificationOnBottom" value="@bool/config_showHeadsUpNotificationOnBottom"/>
-
- <item target="integer/config_topSystemBarType" value="@integer/config_topSystemBarType"/>
- <item target="integer/config_leftSystemBarType" value="@integer/config_leftSystemBarType"/>
- <item target="integer/config_rightSystemBarType" value="@integer/config_rightSystemBarType"/>
- <item target="integer/config_bottomSystemBarType" value="@integer/config_bottomSystemBarType"/>
-
- <item target="integer/config_topSystemBarZOrder" value="@integer/config_topSystemBarZOrder"/>
- <item target="integer/config_leftSystemBarZOrder" value="@integer/config_leftSystemBarZOrder"/>
- <item target="integer/config_rightSystemBarZOrder" value="@integer/config_rightSystemBarZOrder"/>
- <item target="integer/config_bottomSystemBarZOrder" value="@integer/config_bottomSystemBarZOrder"/>
-
- <item target="string/config_notificationPanelViewMediator" value="@string/config_notificationPanelViewMediator"/>
-</overlay>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample2/rro/Android.bp b/packages/CarSystemUI/samples/sample2/rro/Android.bp
deleted file mode 100644
index bf68e41..0000000
--- a/packages/CarSystemUI/samples/sample2/rro/Android.bp
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// Copyright (C) 2020 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.
-//
-
-android_app {
- name: "CarSystemUISampleTwoRRO",
- resource_dirs: ["res"],
- certificate: "platform",
- platform_apis: true,
- manifest: "AndroidManifest.xml",
- aaptflags: [
- "--no-resource-deduping",
- "--no-resource-removal",
- ]
-}
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample2/rro/AndroidManifest.xml b/packages/CarSystemUI/samples/sample2/rro/AndroidManifest.xml
deleted file mode 100644
index 5c25056..0000000
--- a/packages/CarSystemUI/samples/sample2/rro/AndroidManifest.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.systemui.rro">
- <overlay
- android:targetPackage="com.android.systemui"
- android:isStatic="false"
- android:resourcesMap="@xml/car_sysui_overlays"
- />
-</manifest>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample2/rro/res/drawable/car_ic_apps.xml b/packages/CarSystemUI/samples/sample2/rro/res/drawable/car_ic_apps.xml
deleted file mode 100644
index a8d8a2f..0000000
--- a/packages/CarSystemUI/samples/sample2/rro/res/drawable/car_ic_apps.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
-<path
- android:pathData="M7.33333333 14.6666667L14.6666667 14.6666667L14.6666667 7.33333333L7.33333333 7.33333333L7.33333333 14.6666667ZM18.3333333 36.6666667L25.6666667 36.6666667L25.6666667 29.3333333L18.3333333 29.3333333L18.3333333 36.6666667ZM7.33333333 36.6666667L14.6666667 36.6666667L14.6666667 29.3333333L7.33333333 29.3333333L7.33333333 36.6666667ZM7.33333333 25.6666667L14.6666667 25.6666667L14.6666667 18.3333333L7.33333333 18.3333333L7.33333333 25.6666667ZM18.3333333 25.6666667L25.6666667 25.6666667L25.6666667 18.3333333L18.3333333 18.3333333L18.3333333 25.6666667ZM29.3333333 7.33333333L29.3333333 14.6666667L36.6666667 14.6666667L36.6666667 7.33333333L29.3333333 7.33333333ZM18.3333333 14.6666667L25.6666667 14.6666667L25.6666667 7.33333333L18.3333333 7.33333333L18.3333333 14.6666667ZM29.3333333 25.6666667L36.6666667 25.6666667L36.6666667 18.3333333L29.3333333 18.3333333L29.3333333 25.6666667ZM29.3333333 36.6666667L36.6666667 36.6666667L36.6666667 29.3333333L29.3333333 29.3333333L29.3333333 36.6666667Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample2/rro/res/drawable/car_ic_music.xml b/packages/CarSystemUI/samples/sample2/rro/res/drawable/car_ic_music.xml
deleted file mode 100644
index 6339ebb..0000000
--- a/packages/CarSystemUI/samples/sample2/rro/res/drawable/car_ic_music.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M22 5.5L22 24.8416667C20.9183333 24.2183333 19.6716667 23.8333333 18.3333333 23.8333333C14.2816667 23.8333333 11 27.115 11 31.1666667C11 35.2183333 14.2816667 38.5 18.3333333 38.5C22.385 38.5 25.6666667 35.2183333 25.6666667 31.1666667L25.6666667 12.8333333L33 12.8333333L33 5.5L22 5.5Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample2/rro/res/drawable/car_ic_navigation.xml b/packages/CarSystemUI/samples/sample2/rro/res/drawable/car_ic_navigation.xml
deleted file mode 100644
index e1fabe0..0000000
--- a/packages/CarSystemUI/samples/sample2/rro/res/drawable/car_ic_navigation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M39.8016667 20.6983333L23.3016667 4.19833333C22.5866667 3.48333333 21.4316667 3.48333333 20.7166667 4.19833333L4.21666667 20.6983333C3.50166667 21.4133333 3.50166667 22.5683333 4.21666667 23.2833333L20.7166667 39.7833333C21.4316667 40.4983333 22.5866667 40.4983333 23.3016667 39.7833333L39.8016667 23.2833333C40.5166667 22.5866667 40.5166667 21.4316667 39.8016667 20.6983333ZM25.6666667 26.5833333L25.6666667 22L18.3333333 22L18.3333333 27.5L14.6666667 27.5L14.6666667 20.1666667C14.6666667 19.1583333 15.4916667 18.3333333 16.5 18.3333333L25.6666667 18.3333333L25.6666667 13.75L32.0833333 20.1666667L25.6666667 26.5833333Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample2/rro/res/drawable/car_ic_notification.xml b/packages/CarSystemUI/samples/sample2/rro/res/drawable/car_ic_notification.xml
deleted file mode 100644
index 3c3fefc..0000000
--- a/packages/CarSystemUI/samples/sample2/rro/res/drawable/car_ic_notification.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="44dp"
- android:height="44dp"
- android:viewportWidth="44"
- android:viewportHeight="44">
- <path
- android:pathData="M22 39.125C23.925 39.125 25.5 37.55 25.5 35.625L18.5 35.625C18.5 37.55 20.0575 39.125 22 39.125ZM32.5 28.625L32.5 19.875C32.5 14.5025 29.63 10.005 24.625 8.815L24.625 7.625C24.625 6.1725 23.4525 5 22 5C20.5475 5 19.375 6.1725 19.375 7.625L19.375 8.815C14.3525 10.005 11.5 14.485 11.5 19.875L11.5 28.625L8 32.125L8 33.875L36 33.875L36 32.125L32.5 28.625Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample2/rro/res/drawable/car_ic_overview.xml b/packages/CarSystemUI/samples/sample2/rro/res/drawable/car_ic_overview.xml
deleted file mode 100644
index f185eb9..0000000
--- a/packages/CarSystemUI/samples/sample2/rro/res/drawable/car_ic_overview.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M36.92857 22.39286A14.53571 14.53571 0 0 1 7.857143 22.39286A14.53571 14.53571 0 0 1 36.92857 22.39286Z"
- android:strokeColor="@color/car_nav_icon_fill_color"
- android:strokeWidth="4" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample2/rro/res/drawable/car_ic_phone.xml b/packages/CarSystemUI/samples/sample2/rro/res/drawable/car_ic_phone.xml
deleted file mode 100644
index 50e36b5..0000000
--- a/packages/CarSystemUI/samples/sample2/rro/res/drawable/car_ic_phone.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M12.1366667 19.7816667C14.7766667 24.97 19.03 29.205 24.2183333 31.8633333L28.2516667 27.83C28.7466667 27.335 29.48 27.17 30.1216667 27.39C32.175 28.0683333 34.3933333 28.435 36.6666667 28.435C37.675 28.435 38.5 29.26 38.5 30.2683333L38.5 36.6666667C38.5 37.675 37.675 38.5 36.6666667 38.5C19.4516667 38.5 5.5 24.5483333 5.5 7.33333333C5.5 6.325 6.325 5.5 7.33333333 5.5L13.75 5.5C14.7583333 5.5 15.5833333 6.325 15.5833333 7.33333333C15.5833333 9.625 15.95 11.825 16.6283333 13.8783333C16.83 14.52 16.6833333 15.235 16.17 15.7483333L12.1366667 19.7816667Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample2/rro/res/drawable/system_bar_background.xml b/packages/CarSystemUI/samples/sample2/rro/res/drawable/system_bar_background.xml
deleted file mode 100644
index 6161ad9..0000000
--- a/packages/CarSystemUI/samples/sample2/rro/res/drawable/system_bar_background.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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.
- -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
- <corners
- android:topLeftRadius="0dp"
- android:topRightRadius="10dp"
- android:bottomLeftRadius="0dp"
- android:bottomRightRadius="0dp"
- />
- <solid
- android:color="#404040"
- />
- <padding
- android:left="0dp"
- android:top="0dp"
- android:right="0dp"
- android:bottom="0dp"
- />
-</shape>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample2/rro/res/layout/car_left_navigation_bar.xml b/packages/CarSystemUI/samples/sample2/rro/res/layout/car_left_navigation_bar.xml
deleted file mode 100644
index bd6065c..0000000
--- a/packages/CarSystemUI/samples/sample2/rro/res/layout/car_left_navigation_bar.xml
+++ /dev/null
@@ -1,105 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2018, 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.
-*/
--->
-
-<com.android.systemui.car.navigationbar.CarNavigationBarView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:orientation="vertical"
- android:background="@drawable/system_bar_background">
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/home"
- style="@style/NavigationBarButton"
- systemui:componentNames="com.android.car.carlauncher/.CarLauncher"
- systemui:icon="@drawable/car_ic_overview"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
- systemui:highlightWhenSelected="true"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/maps_nav"
- style="@style/NavigationBarButton"
- systemui:categories="android.intent.category.APP_MAPS"
- systemui:icon="@drawable/car_ic_navigation"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MAPS;launchFlags=0x14000000;end"
- systemui:highlightWhenSelected="true"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/music_nav"
- style="@style/NavigationBarButton"
- systemui:categories="android.intent.category.APP_MUSIC"
- systemui:icon="@drawable/car_ic_music"
- systemui:intent="intent:#Intent;action=android.car.intent.action.MEDIA_TEMPLATE;launchFlags=0x10000000;end"
- systemui:packages="com.android.car.media"
- systemui:highlightWhenSelected="true"
- />
-
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/grid_nav"
- style="@style/NavigationBarButton"
- systemui:componentNames="com.android.car.carlauncher/.AppGridActivity"
- systemui:icon="@drawable/car_ic_apps"
- systemui:intent="intent:#Intent;component=com.android.car.carlauncher/.AppGridActivity;launchFlags=0x24000000;end"
- systemui:highlightWhenSelected="true"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/phone_nav"
- style="@style/NavigationBarButton"
- systemui:icon="@drawable/car_ic_phone"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;package=com.android.car.dialer;launchFlags=0x10000000;end"
- systemui:packages="com.android.car.dialer"
- systemui:highlightWhenSelected="true"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/notifications"
- style="@style/NavigationBarButton"
- systemui:highlightWhenSelected="true"
- systemui:icon="@drawable/car_ic_notification"
- systemui:longIntent="intent:#Intent;component=com.android.car.bugreport/.BugReportActivity;end"/>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:gravity="bottom"
- android:orientation="vertical">
-
- <com.android.systemui.statusbar.policy.Clock
- android:id="@+id/clock"
- android:textAppearance="@style/TextAppearance.StatusBar.Clock"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:singleLine="true"
- android:gravity="center_horizontal"
- android:paddingBottom="20dp"
- />
-
- <Space
- android:layout_height="10dp"
- android:layout_width="match_parent"/>
-
- </LinearLayout>
-
-</com.android.systemui.car.navigationbar.CarNavigationBarView>
diff --git a/packages/CarSystemUI/samples/sample2/rro/res/values/attrs.xml b/packages/CarSystemUI/samples/sample2/rro/res/values/attrs.xml
deleted file mode 100644
index 7ba3334..0000000
--- a/packages/CarSystemUI/samples/sample2/rro/res/values/attrs.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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>
- <attr name="broadcast" format="boolean"/>
- <attr name="icon" format="reference"/>
- <attr name="selectedIcon" format="reference"/>
- <attr name="intent" format="string"/>
- <attr name="longIntent" format="string"/>
- <attr name="componentNames" format="string" />
- <attr name="highlightWhenSelected" format="boolean" />
- <attr name="categories" format="string"/>
- <attr name="packages" format="string" />
-</resources>
diff --git a/packages/CarSystemUI/samples/sample2/rro/res/values/colors.xml b/packages/CarSystemUI/samples/sample2/rro/res/values/colors.xml
deleted file mode 100644
index c32d638..0000000
--- a/packages/CarSystemUI/samples/sample2/rro/res/values/colors.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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 xmlns:android="http://schemas.android.com/apk/res/android">
- <color name="car_nav_icon_fill_color">#8F8F8F</color>
- <color name="car_nav_icon_fill_color_selected">#FFFFFF</color>
-</resources>
diff --git a/packages/CarSystemUI/samples/sample2/rro/res/values/config.xml b/packages/CarSystemUI/samples/sample2/rro/res/values/config.xml
deleted file mode 100644
index 89c7bd4..0000000
--- a/packages/CarSystemUI/samples/sample2/rro/res/values/config.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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>
- <!-- Configure which system bars should be displayed. -->
- <bool name="config_enableTopNavigationBar">false</bool>
- <bool name="config_enableLeftNavigationBar">true</bool>
- <bool name="config_enableRightNavigationBar">false</bool>
- <bool name="config_enableBottomNavigationBar">false</bool>
-
- <!-- Configure the type of each system bar. Each system bar must have a unique type. -->
- <!-- STATUS_BAR = 0-->
- <!-- NAVIGATION_BAR = 1-->
- <!-- STATUS_BAR_EXTRA = 2-->
- <!-- NAVIGATION_BAR_EXTRA = 3-->
- <integer name="config_topSystemBarType">0</integer>
- <integer name="config_leftSystemBarType">1</integer>
- <integer name="config_rightSystemBarType">2</integer>
- <integer name="config_bottomSystemBarType">3</integer>
-
- <!-- Configure the relative z-order among the system bars. When two system bars overlap (e.g.
- if both top bar and left bar are enabled, it creates an overlapping space in the upper left
- corner), the system bar with the higher z-order takes the overlapping space and padding is
- applied to the other bar.-->
- <!-- NOTE: If two overlapping system bars have the same z-order, SystemBarConfigs will throw a
- RuntimeException, since their placing order cannot be determined. Bars that do not overlap
- are allowed to have the same z-order. -->
- <!-- NOTE: If the z-order of a bar is 10 or above, it will also appear on top of HUN's. -->
- <integer name="config_topSystemBarZOrder">0</integer>
- <integer name="config_leftSystemBarZOrder">10</integer>
- <integer name="config_rightSystemBarZOrder">10</integer>
- <integer name="config_bottomSystemBarZOrder">10</integer>
-
- <!-- Whether heads-up notifications should be shown on the bottom. If false, heads-up
- notifications will be shown pushed to the top of their parent container. If true, they will
- be shown pushed to the bottom of their parent container. If true, then should override
- config_headsUpNotificationAnimationHelper to use a different AnimationHelper, such as
- com.android.car.notification.headsup.animationhelper.
- CarHeadsUpNotificationBottomAnimationHelper. -->
- <bool name="config_showHeadsUpNotificationOnBottom">true</bool>
-
- <string name="config_notificationPanelViewMediator" translatable="false">com.android.systemui.car.notification.NotificationPanelViewMediator</string>
-</resources>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample2/rro/res/values/styles.xml b/packages/CarSystemUI/samples/sample2/rro/res/values/styles.xml
deleted file mode 100644
index 136dc3b..0000000
--- a/packages/CarSystemUI/samples/sample2/rro/res/values/styles.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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 xmlns:android="http://schemas.android.com/apk/res/android">
- <style name="TextAppearance.StatusBar.Clock"
- parent="@*android:style/TextAppearance.StatusBar.Icon">
- <item name="android:textSize">40sp</item>
- <item name="android:fontFamily">sans-serif-regular</item>
- <item name="android:textColor">#FFFFFF</item>
- </style>
-
- <style name="NavigationBarButton">
- <item name="android:layout_height">96dp</item>
- <item name="android:layout_width">96dp</item>
- <item name="android:background">?android:attr/selectableItemBackground</item>
- </style>
-
- <style name="TextAppearance.CarStatus" parent="@android:style/TextAppearance.DeviceDefault">
- <item name="android:textSize">30sp</item>
- <item name="android:textColor">#FFFFFF</item>
- </style>
-</resources>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample2/rro/res/xml/car_sysui_overlays.xml b/packages/CarSystemUI/samples/sample2/rro/res/xml/car_sysui_overlays.xml
deleted file mode 100644
index 58a535b..0000000
--- a/packages/CarSystemUI/samples/sample2/rro/res/xml/car_sysui_overlays.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-
-<!--
- ~ Copyright (C) 2020 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.
- -->
-
-<overlay>
- <item target="layout/car_left_navigation_bar" value="@layout/car_left_navigation_bar"/>
-
- <item target="attr/icon" value="@attr/icon"/>
- <item target="attr/selectedIcon" value="@attr/selectedIcon"/>
- <item target="attr/intent" value="@attr/intent"/>
- <item target="attr/longIntent" value="@attr/longIntent"/>
- <item target="attr/componentNames" value="@attr/componentNames"/>
- <item target="attr/highlightWhenSelected" value="@attr/highlightWhenSelected"/>
- <item target="attr/categories" value="@attr/categories"/>
- <item target="attr/packages" value="@attr/packages"/>
- <!-- start the intent as a broad cast instead of an activity if true-->
- <item target="attr/broadcast" value="@attr/broadcast"/>
-
- <item target="drawable/car_ic_overview" value="@drawable/car_ic_overview" />
- <item target="drawable/car_ic_apps" value="@drawable/car_ic_apps" />
- <item target="drawable/car_ic_music" value="@drawable/car_ic_music" />
- <item target="drawable/car_ic_phone" value="@drawable/car_ic_phone" />
- <item target="drawable/car_ic_navigation" value="@drawable/car_ic_navigation" />
-
- <item target="style/NavigationBarButton" value="@style/NavigationBarButton"/>
-
- <item target="color/car_nav_icon_fill_color" value="@color/car_nav_icon_fill_color" />
-
- <item target="bool/config_enableTopNavigationBar" value="@bool/config_enableTopNavigationBar"/>
- <item target="bool/config_enableLeftNavigationBar" value="@bool/config_enableLeftNavigationBar"/>
- <item target="bool/config_enableRightNavigationBar" value="@bool/config_enableRightNavigationBar"/>
- <item target="bool/config_enableBottomNavigationBar" value="@bool/config_enableBottomNavigationBar"/>
- <item target="bool/config_showHeadsUpNotificationOnBottom" value="@bool/config_showHeadsUpNotificationOnBottom"/>
-
- <item target="integer/config_topSystemBarType" value="@integer/config_topSystemBarType"/>
- <item target="integer/config_leftSystemBarType" value="@integer/config_leftSystemBarType"/>
- <item target="integer/config_rightSystemBarType" value="@integer/config_rightSystemBarType"/>
- <item target="integer/config_bottomSystemBarType" value="@integer/config_bottomSystemBarType"/>
-
- <item target="integer/config_topSystemBarZOrder" value="@integer/config_topSystemBarZOrder"/>
- <item target="integer/config_leftSystemBarZOrder" value="@integer/config_leftSystemBarZOrder"/>
- <item target="integer/config_rightSystemBarZOrder" value="@integer/config_rightSystemBarZOrder"/>
- <item target="integer/config_bottomSystemBarZOrder" value="@integer/config_bottomSystemBarZOrder"/>
-
- <item target="string/config_notificationPanelViewMediator" value="@string/config_notificationPanelViewMediator"/>
-
- <item target="id/home" value="@id/home"/>
- <item target="id/maps_nav" value="@id/maps_nav"/>
- <item target="id/music_nav" value="@id/music_nav"/>
- <item target="id/grid_nav" value="@id/grid_nav"/>
- <item target="id/phone_nav" value="@id/phone_nav"/>
- <item target="id/notifications" value="@id/notifications"/>
-</overlay>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample3/rro/Android.bp b/packages/CarSystemUI/samples/sample3/rro/Android.bp
deleted file mode 100644
index 0eae7c2..0000000
--- a/packages/CarSystemUI/samples/sample3/rro/Android.bp
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// Copyright (C) 2020 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.
-//
-
-android_app {
- name: "CarSystemUISampleThreeRRO",
- resource_dirs: ["res"],
- certificate: "platform",
- platform_apis: true,
- manifest: "AndroidManifest.xml",
- aaptflags: [
- "--no-resource-deduping",
- "--no-resource-removal",
- ]
-}
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample3/rro/AndroidManifest.xml b/packages/CarSystemUI/samples/sample3/rro/AndroidManifest.xml
deleted file mode 100644
index 5c25056..0000000
--- a/packages/CarSystemUI/samples/sample3/rro/AndroidManifest.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.systemui.rro">
- <overlay
- android:targetPackage="com.android.systemui"
- android:isStatic="false"
- android:resourcesMap="@xml/car_sysui_overlays"
- />
-</manifest>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_apps.xml b/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_apps.xml
deleted file mode 100644
index a8d8a2f..0000000
--- a/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_apps.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
-<path
- android:pathData="M7.33333333 14.6666667L14.6666667 14.6666667L14.6666667 7.33333333L7.33333333 7.33333333L7.33333333 14.6666667ZM18.3333333 36.6666667L25.6666667 36.6666667L25.6666667 29.3333333L18.3333333 29.3333333L18.3333333 36.6666667ZM7.33333333 36.6666667L14.6666667 36.6666667L14.6666667 29.3333333L7.33333333 29.3333333L7.33333333 36.6666667ZM7.33333333 25.6666667L14.6666667 25.6666667L14.6666667 18.3333333L7.33333333 18.3333333L7.33333333 25.6666667ZM18.3333333 25.6666667L25.6666667 25.6666667L25.6666667 18.3333333L18.3333333 18.3333333L18.3333333 25.6666667ZM29.3333333 7.33333333L29.3333333 14.6666667L36.6666667 14.6666667L36.6666667 7.33333333L29.3333333 7.33333333ZM18.3333333 14.6666667L25.6666667 14.6666667L25.6666667 7.33333333L18.3333333 7.33333333L18.3333333 14.6666667ZM29.3333333 25.6666667L36.6666667 25.6666667L36.6666667 18.3333333L29.3333333 18.3333333L29.3333333 25.6666667ZM29.3333333 36.6666667L36.6666667 36.6666667L36.6666667 29.3333333L29.3333333 29.3333333L29.3333333 36.6666667Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_home.xml b/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_home.xml
deleted file mode 100644
index c78f0ed..0000000
--- a/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_home.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_hvac.xml b/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_hvac.xml
deleted file mode 100644
index 55c968e..0000000
--- a/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_hvac.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:pathData="M16.34,8.36l-2.29,0.82c-0.18,-0.13 -0.38,-0.25 -0.58,-0.34c0.17,-0.83 0.63,-1.58 1.36,-2.06C16.85,5.44 16.18,2 13.39,2C9,2 7.16,5.01 8.36,7.66l0.82,2.29c-0.13,0.18 -0.25,0.38 -0.34,0.58c-0.83,-0.17 -1.58,-0.63 -2.06,-1.36C5.44,7.15 2,7.82 2,10.61c0,4.4 3.01,6.24 5.66,5.03l2.29,-0.82c0.18,0.13 0.38,0.25 0.58,0.34c-0.17,0.83 -0.63,1.58 -1.36,2.06C7.15,18.56 7.82,22 10.61,22c4.4,0 6.24,-3.01 5.03,-5.66l-0.82,-2.29c0.13,-0.18 0.25,-0.38 0.34,-0.58c0.83,0.17 1.58,0.63 2.06,1.36c1.34,2.01 4.77,1.34 4.77,-1.45C22,9 18.99,7.16 16.34,8.36zM12,13.5c-0.83,0 -1.5,-0.67 -1.5,-1.5c0,-0.83 0.67,-1.5 1.5,-1.5c0.83,0 1.5,0.67 1.5,1.5C13.5,12.83 12.83,13.5 12,13.5zM10.24,5.22C10.74,4.44 11.89,4 13.39,4c0.79,0 0.71,0.86 0.34,1.11c-1.22,0.81 -2,2.06 -2.25,3.44c-0.21,0.03 -0.42,0.08 -0.62,0.15l-0.68,-1.88C10,6.42 9.86,5.81 10.24,5.22zM6.83,13.82c-0.4,0.18 -1.01,0.32 -1.61,-0.06C4.44,13.26 4,12.11 4,10.61c0,-0.79 0.86,-0.71 1.11,-0.34c0.81,1.22 2.06,2 3.44,2.25c0.03,0.21 0.08,0.42 0.15,0.62L6.83,13.82zM13.76,18.78c-0.5,0.77 -1.65,1.22 -3.15,1.22c-0.79,0 -0.71,-0.86 -0.34,-1.11c1.22,-0.81 2,-2.06 2.25,-3.44c0.21,-0.03 0.42,-0.08 0.62,-0.15l0.68,1.88C14,17.58 14.14,18.18 13.76,18.78zM18.89,13.73c-0.81,-1.22 -2.06,-2 -3.44,-2.25c-0.03,-0.21 -0.08,-0.42 -0.15,-0.62l1.88,-0.68c0.4,-0.18 1.01,-0.32 1.61,0.06c0.77,0.5 1.22,1.65 1.22,3.15C20,14.19 19.14,14.11 18.89,13.73z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
diff --git a/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_music.xml b/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_music.xml
deleted file mode 100644
index 6339ebb..0000000
--- a/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_music.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M22 5.5L22 24.8416667C20.9183333 24.2183333 19.6716667 23.8333333 18.3333333 23.8333333C14.2816667 23.8333333 11 27.115 11 31.1666667C11 35.2183333 14.2816667 38.5 18.3333333 38.5C22.385 38.5 25.6666667 35.2183333 25.6666667 31.1666667L25.6666667 12.8333333L33 12.8333333L33 5.5L22 5.5Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_navigation.xml b/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_navigation.xml
deleted file mode 100644
index e1fabe0..0000000
--- a/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_navigation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M39.8016667 20.6983333L23.3016667 4.19833333C22.5866667 3.48333333 21.4316667 3.48333333 20.7166667 4.19833333L4.21666667 20.6983333C3.50166667 21.4133333 3.50166667 22.5683333 4.21666667 23.2833333L20.7166667 39.7833333C21.4316667 40.4983333 22.5866667 40.4983333 23.3016667 39.7833333L39.8016667 23.2833333C40.5166667 22.5866667 40.5166667 21.4316667 39.8016667 20.6983333ZM25.6666667 26.5833333L25.6666667 22L18.3333333 22L18.3333333 27.5L14.6666667 27.5L14.6666667 20.1666667C14.6666667 19.1583333 15.4916667 18.3333333 16.5 18.3333333L25.6666667 18.3333333L25.6666667 13.75L32.0833333 20.1666667L25.6666667 26.5833333Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_notification.xml b/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_notification.xml
deleted file mode 100644
index aabf916..0000000
--- a/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_notification.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@dimen/system_bar_icon_drawing_size"
- android:height="@dimen/system_bar_icon_drawing_size"
- android:viewportWidth="44"
- android:viewportHeight="44">
- <path
- android:pathData="M22 39.125C23.925 39.125 25.5 37.55 25.5 35.625L18.5 35.625C18.5 37.55 20.0575 39.125 22 39.125ZM32.5 28.625L32.5 19.875C32.5 14.5025 29.63 10.005 24.625 8.815L24.625 7.625C24.625 6.1725 23.4525 5 22 5C20.5475 5 19.375 6.1725 19.375 7.625L19.375 8.815C14.3525 10.005 11.5 14.485 11.5 19.875L11.5 28.625L8 32.125L8 33.875L36 33.875L36 32.125L32.5 28.625Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_overview.xml b/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_overview.xml
deleted file mode 100644
index f185eb9..0000000
--- a/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_overview.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M36.92857 22.39286A14.53571 14.53571 0 0 1 7.857143 22.39286A14.53571 14.53571 0 0 1 36.92857 22.39286Z"
- android:strokeColor="@color/car_nav_icon_fill_color"
- android:strokeWidth="4" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_phone.xml b/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_phone.xml
deleted file mode 100644
index 50e36b5..0000000
--- a/packages/CarSystemUI/samples/sample3/rro/res/drawable/car_ic_phone.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="44"
- android:viewportHeight="44"
- android:width="44dp"
- android:height="44dp">
- <path
- android:pathData="M12.1366667 19.7816667C14.7766667 24.97 19.03 29.205 24.2183333 31.8633333L28.2516667 27.83C28.7466667 27.335 29.48 27.17 30.1216667 27.39C32.175 28.0683333 34.3933333 28.435 36.6666667 28.435C37.675 28.435 38.5 29.26 38.5 30.2683333L38.5 36.6666667C38.5 37.675 37.675 38.5 36.6666667 38.5C19.4516667 38.5 5.5 24.5483333 5.5 7.33333333C5.5 6.325 6.325 5.5 7.33333333 5.5L13.75 5.5C14.7583333 5.5 15.5833333 6.325 15.5833333 7.33333333C15.5833333 9.625 15.95 11.825 16.6283333 13.8783333C16.83 14.52 16.6833333 15.235 16.17 15.7483333L12.1366667 19.7816667Z"
- android:fillColor="@color/car_nav_icon_fill_color" />
-</vector>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample3/rro/res/layout/car_left_navigation_bar.xml b/packages/CarSystemUI/samples/sample3/rro/res/layout/car_left_navigation_bar.xml
deleted file mode 100644
index 3d1cd08..0000000
--- a/packages/CarSystemUI/samples/sample3/rro/res/layout/car_left_navigation_bar.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2018, 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.
-*/
--->
-
-<com.android.systemui.car.navigationbar.CarNavigationBarView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:orientation="vertical"
- android:background="@android:color/transparent">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:gravity="bottom"
- android:orientation="vertical">
-
- <com.android.systemui.statusbar.policy.Clock
- android:id="@+id/clock"
- android:textAppearance="@style/TextAppearance.StatusBar.Clock"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:singleLine="true"
- android:gravity="center_horizontal"
- android:paddingBottom="20dp"
- />
-
- <Space
- android:layout_height="50dp"
- android:layout_width="match_parent"/>
-
- </LinearLayout>
-
-</com.android.systemui.car.navigationbar.CarNavigationBarView>
diff --git a/packages/CarSystemUI/samples/sample3/rro/res/layout/car_navigation_bar.xml b/packages/CarSystemUI/samples/sample3/rro/res/layout/car_navigation_bar.xml
deleted file mode 100644
index 8314ba5..0000000
--- a/packages/CarSystemUI/samples/sample3/rro/res/layout/car_navigation_bar.xml
+++ /dev/null
@@ -1,122 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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.
- -->
-
-<com.android.systemui.car.navigationbar.CarNavigationBarView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/system_bar_background"
- android:gravity="center"
- android:orientation="horizontal">
-
- <RelativeLayout
- android:id="@+id/nav_buttons"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layoutDirection="ltr">
-
- <com.android.systemui.car.hvac.AdjustableTemperatureView
- android:id="@+id/driver_hvac"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:gravity="center_vertical"
- systemui:hvacAreaId="49"
- systemui:hvacTempFormat="%.0f\u00B0" />
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_centerInParent="true"
- android:layout_weight="1"
- android:gravity="center"
- android:layoutDirection="ltr"
- android:paddingEnd="@dimen/system_bar_button_group_padding"
- android:paddingStart="@dimen/system_bar_button_group_padding">
-
- <Space
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"/>
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/home"
- style="@style/NavigationBarButton"
- systemui:componentNames="com.android.car.carlauncher/.CarLauncher"
- systemui:highlightWhenSelected="true"
- systemui:icon="@drawable/car_ic_home"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"/>
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/phone_nav"
- style="@style/NavigationBarButton"
- systemui:highlightWhenSelected="true"
- systemui:icon="@drawable/car_ic_phone"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;package=com.android.car.dialer;launchFlags=0x10000000;end"
- systemui:packages="com.android.car.dialer"/>
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/grid_nav"
- style="@style/NavigationBarButton"
- systemui:componentNames="com.android.car.carlauncher/.AppGridActivity"
- systemui:highlightWhenSelected="true"
- systemui:icon="@drawable/car_ic_apps"
- systemui:intent="intent:#Intent;component=com.android.car.carlauncher/.AppGridActivity;launchFlags=0x24000000;end"/>
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/hvac"
- style="@style/NavigationBarButton"
- systemui:highlightWhenSelected="true"
- systemui:icon="@drawable/car_ic_hvac"
- systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
- systemui:broadcast="true"/>
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/notifications"
- style="@style/NavigationBarButton"
- systemui:highlightWhenSelected="true"
- systemui:icon="@drawable/car_ic_notification"
- systemui:longIntent="intent:#Intent;component=com.android.car.bugreport/.BugReportActivity;end"/>
-
- <Space
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"/>
- </LinearLayout>
-
- <com.android.systemui.car.hvac.AdjustableTemperatureView
- android:id="@+id/passenger_hvac"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentEnd="true"
- android:gravity="center_vertical"
- systemui:hvacAreaId="68"
- systemui:hvacTempFormat="%.0f\u00B0" />
- </RelativeLayout>
-
- <LinearLayout
- android:id="@+id/lock_screen_nav_buttons"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:gravity="center"
- android:layoutDirection="ltr"
- android:paddingEnd="@dimen/car_keyline_1"
- android:paddingStart="@dimen/car_keyline_1"
- android:visibility="gone"
- />
-</com.android.systemui.car.navigationbar.CarNavigationBarView>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample3/rro/res/values/attrs.xml b/packages/CarSystemUI/samples/sample3/rro/res/values/attrs.xml
deleted file mode 100644
index bc7ded2..0000000
--- a/packages/CarSystemUI/samples/sample3/rro/res/values/attrs.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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>
- <attr name="broadcast" format="boolean"/>
- <attr name="icon" format="reference"/>
- <attr name="intent" format="string"/>
- <attr name="longIntent" format="string"/>
- <attr name="componentNames" format="string" />
- <attr name="highlightWhenSelected" format="boolean" />
- <attr name="categories" format="string"/>
- <attr name="packages" format="string" />
-
- <!-- Custom attributes to configure hvac values -->
- <declare-styleable name="AnimatedTemperatureView">
- <attr name="hvacAreaId" format="integer"/>
- <attr name="hvacPropertyId" format="integer"/>
- <attr name="hvacTempFormat" format="string"/>
- <!-- how far away the animations should center around -->
- <attr name="hvacPivotOffset" format="dimension"/>
- <attr name="hvacMinValue" format="float"/>
- <attr name="hvacMaxValue" format="float"/>
- <attr name="hvacMinText" format="string|reference"/>
- <attr name="hvacMaxText" format="string|reference"/>
- <attr name="android:gravity"/>
- <attr name="android:minEms"/>
- <attr name="android:textAppearance"/>
- </declare-styleable>
-</resources>
diff --git a/packages/CarSystemUI/samples/sample3/rro/res/values/colors.xml b/packages/CarSystemUI/samples/sample3/rro/res/values/colors.xml
deleted file mode 100644
index f98cb96..0000000
--- a/packages/CarSystemUI/samples/sample3/rro/res/values/colors.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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 xmlns:android="http://schemas.android.com/apk/res/android">
- <color name="car_nav_icon_fill_color">#8F8F8F</color>
-</resources>
diff --git a/packages/CarSystemUI/samples/sample3/rro/res/values/config.xml b/packages/CarSystemUI/samples/sample3/rro/res/values/config.xml
deleted file mode 100644
index 2148e7c..0000000
--- a/packages/CarSystemUI/samples/sample3/rro/res/values/config.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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>
- <!-- Configure which system bars should be displayed. -->
- <bool name="config_enableTopNavigationBar">false</bool>
- <bool name="config_enableLeftNavigationBar">true</bool>
- <bool name="config_enableRightNavigationBar">false</bool>
- <bool name="config_enableBottomNavigationBar">true</bool>
-
- <!-- Configure the type of each system bar. Each system bar must have a unique type. -->
- <!-- STATUS_BAR = 0-->
- <!-- NAVIGATION_BAR = 1-->
- <!-- STATUS_BAR_EXTRA = 2-->
- <!-- NAVIGATION_BAR_EXTRA = 3-->
- <integer name="config_topSystemBarType">2</integer>
- <integer name="config_leftSystemBarType">0</integer>
- <integer name="config_rightSystemBarType">3</integer>
- <integer name="config_bottomSystemBarType">1</integer>
-
- <!-- Configure the relative z-order among the system bars. When two system bars overlap (e.g.
- if both top bar and left bar are enabled, it creates an overlapping space in the upper left
- corner), the system bar with the higher z-order takes the overlapping space and padding is
- applied to the other bar.-->
- <!-- NOTE: If two overlapping system bars have the same z-order, SystemBarConfigs will throw a
- RuntimeException, since their placing order cannot be determined. Bars that do not overlap
- are allowed to have the same z-order. -->
- <!-- NOTE: If the z-order of a bar is 10 or above, it will also appear on top of HUN's. -->
- <integer name="config_topSystemBarZOrder">0</integer>
- <integer name="config_leftSystemBarZOrder">10</integer>
- <integer name="config_rightSystemBarZOrder">0</integer>
- <integer name="config_bottomSystemBarZOrder">15</integer>
-
- <!-- Whether heads-up notifications should be shown on the bottom. If false, heads-up
- notifications will be shown pushed to the top of their parent container. If true, they will
- be shown pushed to the bottom of their parent container. If true, then should override
- config_headsUpNotificationAnimationHelper to use a different AnimationHelper, such as
- com.android.car.notification.headsup.animationhelper.
- CarHeadsUpNotificationBottomAnimationHelper. -->
- <bool name="config_showHeadsUpNotificationOnBottom">false</bool>
-
- <string name="config_notificationPanelViewMediator" translatable="false">com.android.systemui.car.notification.BottomNotificationPanelViewMediator</string>
-</resources>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample3/rro/res/values/dimens.xml b/packages/CarSystemUI/samples/sample3/rro/res/values/dimens.xml
deleted file mode 100644
index c89f949..0000000
--- a/packages/CarSystemUI/samples/sample3/rro/res/values/dimens.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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>
- <dimen name="car_left_navigation_bar_width">280dp</dimen>
- <dimen name="car_keyline_1">24dp</dimen>
- <dimen name="system_bar_button_group_padding">64dp</dimen>
- <dimen name="system_bar_icon_drawing_size">44dp</dimen>
-</resources>
diff --git a/packages/CarSystemUI/samples/sample3/rro/res/values/styles.xml b/packages/CarSystemUI/samples/sample3/rro/res/values/styles.xml
deleted file mode 100644
index bad3691..0000000
--- a/packages/CarSystemUI/samples/sample3/rro/res/values/styles.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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 xmlns:android="http://schemas.android.com/apk/res/android">
- <style name="TextAppearance.StatusBar.Clock"
- parent="@*android:style/TextAppearance.StatusBar.Icon">
- <item name="android:textSize">40sp</item>
- <item name="android:fontFamily">sans-serif-regular</item>
- <item name="android:textColor">#FFFFFF</item>
- </style>
-
- <style name="NavigationBarButton">
- <item name="android:layout_height">96dp</item>
- <item name="android:layout_width">96dp</item>
- <item name="android:background">?android:attr/selectableItemBackground</item>
- </style>
-</resources>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample3/rro/res/xml/car_sysui_overlays.xml b/packages/CarSystemUI/samples/sample3/rro/res/xml/car_sysui_overlays.xml
deleted file mode 100644
index f08d968..0000000
--- a/packages/CarSystemUI/samples/sample3/rro/res/xml/car_sysui_overlays.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-
-<!--
- ~ Copyright (C) 2020 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.
- -->
-
-<overlay>
- <item target="layout/car_navigation_bar" value="@layout/car_navigation_bar"/>
- <item target="layout/car_left_navigation_bar" value="@layout/car_left_navigation_bar"/>
-
- <item target="bool/config_enableTopNavigationBar" value="@bool/config_enableTopNavigationBar"/>
- <item target="bool/config_enableLeftNavigationBar" value="@bool/config_enableLeftNavigationBar"/>
- <item target="bool/config_enableRightNavigationBar" value="@bool/config_enableRightNavigationBar"/>
- <item target="bool/config_enableBottomNavigationBar" value="@bool/config_enableBottomNavigationBar"/>
- <item target="bool/config_showHeadsUpNotificationOnBottom" value="@bool/config_showHeadsUpNotificationOnBottom"/>
-
- <item target="attr/icon" value="@attr/icon"/>
- <item target="attr/intent" value="@attr/intent"/>
- <item target="attr/longIntent" value="@attr/longIntent"/>
- <item target="attr/componentNames" value="@attr/componentNames"/>
- <item target="attr/highlightWhenSelected" value="@attr/highlightWhenSelected"/>
- <item target="attr/categories" value="@attr/categories"/>
- <item target="attr/packages" value="@attr/packages"/>
- <item target="attr/hvacAreaId" value="@attr/hvacAreaId"/>
- <item target="attr/hvacPropertyId" value="@attr/hvacPropertyId"/>
- <item target="attr/hvacTempFormat" value="@attr/hvacTempFormat"/>
- <item target="attr/hvacPivotOffset" value="@attr/hvacPivotOffset"/>
- <item target="attr/hvacMinValue" value="@attr/hvacMinValue"/>
- <item target="attr/hvacMaxValue" value="@attr/hvacMaxValue"/>
- <item target="attr/hvacMinText" value="@attr/hvacMinText"/>
- <item target="attr/hvacMaxText" value="@attr/hvacMaxText"/>
- <!-- start the intent as a broad cast instead of an activity if true-->
- <item target="attr/broadcast" value="@attr/broadcast"/>
-
- <item target="color/car_nav_icon_fill_color" value="@color/car_nav_icon_fill_color" />
-
- <item target="drawable/car_ic_overview" value="@drawable/car_ic_overview" />
- <item target="drawable/car_ic_home" value="@drawable/car_ic_home" />
- <item target="drawable/car_ic_hvac" value="@drawable/car_ic_hvac" />
- <item target="drawable/car_ic_apps" value="@drawable/car_ic_apps" />
- <item target="drawable/car_ic_music" value="@drawable/car_ic_music" />
- <item target="drawable/car_ic_notification" value="@drawable/car_ic_notification" />
- <item target="drawable/car_ic_phone" value="@drawable/car_ic_phone" />
- <item target="drawable/car_ic_navigation" value="@drawable/car_ic_navigation" />
-
- <item target="dimen/car_left_navigation_bar_width" value="@dimen/car_left_navigation_bar_width" />
- <item target="dimen/car_keyline_1" value="@dimen/car_keyline_1" />
- <item target="dimen/system_bar_button_group_padding" value="@dimen/system_bar_button_group_padding" />
- <item target="dimen/system_bar_icon_drawing_size" value="@dimen/system_bar_icon_drawing_size" />
-
- <item target="integer/config_topSystemBarType" value="@integer/config_topSystemBarType"/>
- <item target="integer/config_leftSystemBarType" value="@integer/config_leftSystemBarType"/>
- <item target="integer/config_rightSystemBarType" value="@integer/config_rightSystemBarType"/>
- <item target="integer/config_bottomSystemBarType" value="@integer/config_bottomSystemBarType"/>
-
- <item target="integer/config_topSystemBarZOrder" value="@integer/config_topSystemBarZOrder"/>
- <item target="integer/config_leftSystemBarZOrder" value="@integer/config_leftSystemBarZOrder"/>
- <item target="integer/config_rightSystemBarZOrder" value="@integer/config_rightSystemBarZOrder"/>
- <item target="integer/config_bottomSystemBarZOrder" value="@integer/config_bottomSystemBarZOrder"/>
-
- <item target="string/config_notificationPanelViewMediator" value="@string/config_notificationPanelViewMediator"/>
-
- <item target="style/NavigationBarButton" value="@style/NavigationBarButton"/>
-</overlay>
\ No newline at end of file
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarComponentBinder.java b/packages/CarSystemUI/src/com/android/systemui/CarComponentBinder.java
deleted file mode 100644
index d84b2f9..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/CarComponentBinder.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2019 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;
-
-import com.android.systemui.dagger.DefaultActivityBinder;
-import com.android.systemui.dagger.DefaultBroadcastReceiverBinder;
-import com.android.systemui.dagger.DefaultServiceBinder;
-
-import dagger.Module;
-
-/**
- * Supply Activities, Services, and SystemUI Objects for CarSystemUI.
- */
-@Module(includes = {
- DefaultActivityBinder.class,
- DefaultBroadcastReceiverBinder.class,
- DefaultServiceBinder.class})
-public class CarComponentBinder {
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarGlobalRootComponent.java b/packages/CarSystemUI/src/com/android/systemui/CarGlobalRootComponent.java
deleted file mode 100644
index b056dcf..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/CarGlobalRootComponent.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2019 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;
-
-import com.android.systemui.dagger.GlobalModule;
-import com.android.systemui.dagger.GlobalRootComponent;
-import com.android.systemui.dagger.WMModule;
-import com.android.systemui.wmshell.CarWMComponent;
-
-import javax.inject.Singleton;
-
-import dagger.Component;
-
-/** Car subclass for GlobalRootComponent. */
-@Singleton
-@Component(
- modules = {
- GlobalModule.class,
- CarSysUIComponentModule.class,
- WMModule.class
- })
-public interface CarGlobalRootComponent extends GlobalRootComponent {
- /**
- * Builder for a CarGlobalRootComponent.
- */
- @Component.Builder
- interface Builder extends GlobalRootComponent.Builder {
- CarGlobalRootComponent build();
- }
-
- /**
- * Builder for a WMComponent.
- */
- @Override
- CarWMComponent.Builder getWMComponentBuilder();
-
- @Override
- CarSysUIComponent.Builder getSysUIComponent();
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSysUIComponent.java b/packages/CarSystemUI/src/com/android/systemui/CarSysUIComponent.java
deleted file mode 100644
index 51855dc..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/CarSysUIComponent.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2019 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;
-
-import com.android.systemui.dagger.DependencyProvider;
-import com.android.systemui.dagger.SysUIComponent;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.SystemUIModule;
-
-import dagger.Subcomponent;
-
-/**
- * Dagger Subcomponent for Core SysUI.
- */
-@SysUISingleton
-@Subcomponent(modules = {
- CarComponentBinder.class,
- DependencyProvider.class,
- SystemUIModule.class,
- CarSystemUIModule.class,
- CarSystemUIBinder.class})
-public interface CarSysUIComponent extends SysUIComponent {
-
- /**
- * Builder for a CarSysUIComponent.
- */
- @Subcomponent.Builder
- interface Builder extends SysUIComponent.Builder {
- CarSysUIComponent build();
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
deleted file mode 100644
index ec1240f..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2019 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;
-
-import com.android.systemui.biometrics.AuthController;
-import com.android.systemui.car.navigationbar.CarNavigationBar;
-import com.android.systemui.car.notification.CarNotificationModule;
-import com.android.systemui.car.sideloaded.SideLoadedAppController;
-import com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier;
-import com.android.systemui.car.volume.VolumeUI;
-import com.android.systemui.car.window.OverlayWindowModule;
-import com.android.systemui.car.window.SystemUIOverlayWindowManager;
-import com.android.systemui.globalactions.GlobalActionsComponent;
-import com.android.systemui.keyguard.KeyguardViewMediator;
-import com.android.systemui.keyguard.dagger.KeyguardModule;
-import com.android.systemui.power.PowerUI;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsModule;
-import com.android.systemui.shortcut.ShortcutKeyDispatcher;
-import com.android.systemui.statusbar.dagger.StatusBarModule;
-import com.android.systemui.statusbar.notification.InstantAppNotifier;
-import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
-import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.theme.ThemeOverlayController;
-import com.android.systemui.toast.ToastUI;
-import com.android.systemui.util.leak.GarbageMonitor;
-import com.android.systemui.wmshell.WMShell;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.multibindings.ClassKey;
-import dagger.multibindings.IntoMap;
-
-/** Binder for car specific {@link SystemUI} modules. */
-@Module(includes = {RecentsModule.class, StatusBarModule.class, NotificationsModule.class,
- KeyguardModule.class, OverlayWindowModule.class, CarNotificationModule.class})
-public abstract class CarSystemUIBinder {
- /** Inject into AuthController. */
- @Binds
- @IntoMap
- @ClassKey(AuthController.class)
- public abstract SystemUI bindAuthController(AuthController sysui);
-
- /** Inject Car Navigation Bar. */
- @Binds
- @IntoMap
- @ClassKey(CarNavigationBar.class)
- public abstract SystemUI bindCarNavigationBar(CarNavigationBar sysui);
-
- /** Inject into GarbageMonitor.Service. */
- @Binds
- @IntoMap
- @ClassKey(GarbageMonitor.Service.class)
- public abstract SystemUI bindGarbageMonitorService(GarbageMonitor.Service sysui);
-
- /** Inject into GlobalActionsComponent. */
- @Binds
- @IntoMap
- @ClassKey(GlobalActionsComponent.class)
- public abstract SystemUI bindGlobalActionsComponent(GlobalActionsComponent sysui);
-
- /** Inject into InstantAppNotifier. */
- @Binds
- @IntoMap
- @ClassKey(InstantAppNotifier.class)
- public abstract SystemUI bindInstantAppNotifier(InstantAppNotifier sysui);
-
- /** Inject into KeyguardViewMediator. */
- @Binds
- @IntoMap
- @ClassKey(KeyguardViewMediator.class)
- public abstract SystemUI bindKeyguardViewMediator(KeyguardViewMediator sysui);
-
- /** Inject into LatencyTests. */
- @Binds
- @IntoMap
- @ClassKey(LatencyTester.class)
- public abstract SystemUI bindLatencyTester(LatencyTester sysui);
-
- /** Inject into PowerUI. */
- @Binds
- @IntoMap
- @ClassKey(PowerUI.class)
- public abstract SystemUI bindPowerUI(PowerUI sysui);
-
- /** Inject into Recents. */
- @Binds
- @IntoMap
- @ClassKey(Recents.class)
- public abstract SystemUI bindRecents(Recents sysui);
-
- /** Inject into ScreenDecorations. */
- @Binds
- @IntoMap
- @ClassKey(ScreenDecorations.class)
- public abstract SystemUI bindScreenDecorations(ScreenDecorations sysui);
-
- /** Inject into ShortcutKeyDispatcher. */
- @Binds
- @IntoMap
- @ClassKey(ShortcutKeyDispatcher.class)
- public abstract SystemUI bindsShortcutKeyDispatcher(ShortcutKeyDispatcher sysui);
-
- /** Inject into SizeCompatModeActivityController. */
- @Binds
- @IntoMap
- @ClassKey(SizeCompatModeActivityController.class)
- public abstract SystemUI bindsSizeCompatModeActivityController(
- SizeCompatModeActivityController sysui);
-
- /** Inject into SliceBroadcastRelayHandler. */
- @Binds
- @IntoMap
- @ClassKey(SliceBroadcastRelayHandler.class)
- public abstract SystemUI bindSliceBroadcastRelayHandler(SliceBroadcastRelayHandler sysui);
-
- /** Inject into ThemeOverlayController. */
- @Binds
- @IntoMap
- @ClassKey(ThemeOverlayController.class)
- public abstract SystemUI bindThemeOverlayController(ThemeOverlayController sysui);
-
- /** Inject into StatusBar. */
- @Binds
- @IntoMap
- @ClassKey(StatusBar.class)
- public abstract SystemUI bindsStatusBar(StatusBar sysui);
-
- /** Inject into VolumeUI. */
- @Binds
- @IntoMap
- @ClassKey(VolumeUI.class)
- public abstract SystemUI bindVolumeUI(VolumeUI sysui);
-
- /** Inject into ToastUI. */
- @Binds
- @IntoMap
- @ClassKey(ToastUI.class)
- public abstract SystemUI bindToastUI(ToastUI service);
-
- /** Inject into ConnectedDeviceVoiceRecognitionNotifier. */
- @Binds
- @IntoMap
- @ClassKey(ConnectedDeviceVoiceRecognitionNotifier.class)
- public abstract SystemUI bindConnectedDeviceVoiceRecognitionNotifier(
- ConnectedDeviceVoiceRecognitionNotifier sysui);
-
- /** Inject into SystemUIOverlayWindowManager. */
- @Binds
- @IntoMap
- @ClassKey(SystemUIOverlayWindowManager.class)
- public abstract SystemUI bindSystemUIPrimaryWindowManager(SystemUIOverlayWindowManager sysui);
-
- /** Inject into SideLoadedAppController. */
- @Binds
- @IntoMap
- @ClassKey(SideLoadedAppController.class)
- public abstract SystemUI bindSideLoadedAppController(SideLoadedAppController sysui);
-
- /** Inject into WMShell. */
- @Binds
- @IntoMap
- @ClassKey(WMShell.class)
- public abstract SystemUI bindWMShell(WMShell sysui);
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
deleted file mode 100644
index a65edc5..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2018 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;
-
-import android.content.Context;
-import android.content.res.Resources;
-
-import com.android.systemui.dagger.GlobalRootComponent;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Class factory to provide car specific SystemUI components.
- */
-public class CarSystemUIFactory extends SystemUIFactory {
-
- @Override
- protected GlobalRootComponent buildGlobalRootComponent(Context context) {
- return DaggerCarGlobalRootComponent.builder()
- .context(context)
- .build();
- }
-
- @Override
- public String[] getSystemUIServiceComponents(Resources resources) {
- Set<String> names = new HashSet<>();
-
- for (String s : super.getSystemUIServiceComponents(resources)) {
- names.add(s);
- }
-
- for (String s : resources.getStringArray(R.array.config_systemUIServiceComponentsExclude)) {
- names.remove(s);
- }
-
- for (String s : resources.getStringArray(R.array.config_systemUIServiceComponentsInclude)) {
- names.add(s);
- }
-
- String[] finalNames = new String[names.size()];
- names.toArray(finalNames);
-
- return finalNames;
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
deleted file mode 100644
index 1d35bbb..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2019 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;
-
-import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
-import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.PowerManager;
-
-import com.android.keyguard.KeyguardViewController;
-import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.car.CarDeviceProvisionedControllerImpl;
-import com.android.systemui.car.keyguard.CarKeyguardViewController;
-import com.android.systemui.car.notification.NotificationShadeWindowControllerImpl;
-import com.android.systemui.car.statusbar.DozeServiceHost;
-import com.android.systemui.car.volume.CarVolumeDialogComponent;
-import com.android.systemui.dagger.GlobalRootComponent;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Background;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.demomode.DemoModeController;
-import com.android.systemui.dock.DockManager;
-import com.android.systemui.dock.DockManagerImpl;
-import com.android.systemui.doze.DozeHost;
-import com.android.systemui.plugins.qs.QSFactory;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.power.EnhancedEstimates;
-import com.android.systemui.power.EnhancedEstimatesImpl;
-import com.android.systemui.qs.dagger.QSModule;
-import com.android.systemui.qs.tileimpl.QSFactoryImpl;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsImplementation;
-import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
-import com.android.systemui.statusbar.NotificationShadeWindowController;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
-import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
-import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.phone.ShadeControllerImpl;
-import com.android.systemui.statusbar.policy.BatteryController;
-import com.android.systemui.statusbar.policy.BatteryControllerImpl;
-import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.volume.VolumeDialogComponent;
-
-import javax.inject.Named;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.Provides;
-
-@Module(
- includes = {
- QSModule.class
- })
-abstract class CarSystemUIModule {
-
- @SysUISingleton
- @Provides
- @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME)
- static boolean provideAllowNotificationLongPress() {
- return false;
- }
-
- @SysUISingleton
- @Provides
- static HeadsUpManagerPhone provideHeadsUpManagerPhone(
- Context context,
- StatusBarStateController statusBarStateController,
- KeyguardBypassController bypassController,
- GroupMembershipManager groupManager,
- ConfigurationController configurationController) {
- return new HeadsUpManagerPhone(context, statusBarStateController, bypassController,
- groupManager, configurationController);
- }
-
- @SysUISingleton
- @Provides
- @Named(LEAK_REPORT_EMAIL_NAME)
- static String provideLeakReportEmail() {
- return "buganizer-system+181579@google.com";
- }
-
- @Provides
- @SysUISingleton
- static Recents provideRecents(Context context, RecentsImplementation recentsImplementation,
- CommandQueue commandQueue) {
- return new Recents(context, recentsImplementation, commandQueue);
- }
-
- @Binds
- abstract HeadsUpManager bindHeadsUpManagerPhone(HeadsUpManagerPhone headsUpManagerPhone);
-
- @Binds
- abstract EnhancedEstimates bindEnhancedEstimates(EnhancedEstimatesImpl enhancedEstimates);
-
- @Binds
- abstract NotificationLockscreenUserManager bindNotificationLockscreenUserManager(
- NotificationLockscreenUserManagerImpl notificationLockscreenUserManager);
-
- @Provides
- @SysUISingleton
- static BatteryController provideBatteryController(Context context,
- EnhancedEstimates enhancedEstimates, PowerManager powerManager,
- BroadcastDispatcher broadcastDispatcher, DemoModeController demoModeController,
- @Main Handler mainHandler,
- @Background Handler bgHandler) {
- BatteryController bC = new BatteryControllerImpl(context, enhancedEstimates, powerManager,
- broadcastDispatcher, demoModeController, mainHandler, bgHandler);
- bC.init();
- return bC;
- }
-
- @Binds
- @SysUISingleton
- public abstract QSFactory bindQSFactory(QSFactoryImpl qsFactoryImpl);
-
- @Binds
- abstract DockManager bindDockManager(DockManagerImpl dockManager);
-
- @Binds
- abstract NotificationEntryManager.KeyguardEnvironment bindKeyguardEnvironment(
- KeyguardEnvironmentImpl keyguardEnvironment);
-
- @Binds
- abstract ShadeController provideShadeController(ShadeControllerImpl shadeController);
-
- @Binds
- abstract GlobalRootComponent bindGlobalRootComponent(
- CarGlobalRootComponent globalRootComponent);
-
- @Binds
- abstract VolumeDialogComponent bindVolumeDialogComponent(
- CarVolumeDialogComponent carVolumeDialogComponent);
-
- @Binds
- abstract KeyguardViewController bindKeyguardViewController(
- CarKeyguardViewController carKeyguardViewController);
-
- @Binds
- abstract NotificationShadeWindowController bindNotificationShadeController(
- NotificationShadeWindowControllerImpl notificationPanelViewController);
-
- @Binds
- abstract DeviceProvisionedController bindDeviceProvisionedController(
- CarDeviceProvisionedControllerImpl deviceProvisionedController);
-
- @Binds
- abstract CarDeviceProvisionedController bindCarDeviceProvisionedController(
- CarDeviceProvisionedControllerImpl deviceProvisionedController);
-
- @Binds
- abstract DozeHost bindDozeHost(DozeServiceHost dozeServiceHost);
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/CarDeviceProvisionedController.java b/packages/CarSystemUI/src/com/android/systemui/car/CarDeviceProvisionedController.java
deleted file mode 100644
index 44e43fe..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/CarDeviceProvisionedController.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2019 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.car;
-
-import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-
-/**
- * This interface defines controller that monitors the status of SUW progress for each user in
- * addition to the functionality defined by {@link DeviceProvisionedController}.
- */
-public interface CarDeviceProvisionedController extends DeviceProvisionedController {
- /**
- * Returns {@code true} when SUW is in progress for the given user.
- */
- boolean isUserSetupInProgress(int user);
-
- /**
- * Returns {@code true} when SUW is in progress for the current user.
- */
- default boolean isCurrentUserSetupInProgress() {
- return isUserSetupInProgress(getCurrentUser());
- }
-
- /**
- * Returns {@code true} when the user is setup and not currently in SUW.
- */
- default boolean isCurrentUserFullySetup() {
- return isCurrentUserSetup() && !isCurrentUserSetupInProgress();
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/CarDeviceProvisionedControllerImpl.java b/packages/CarSystemUI/src/com/android/systemui/car/CarDeviceProvisionedControllerImpl.java
deleted file mode 100644
index fef0324..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/CarDeviceProvisionedControllerImpl.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2019 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.car;
-
-import android.annotation.NonNull;
-import android.app.ActivityManager;
-import android.car.settings.CarSettings;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
-
-import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl;
-import com.android.systemui.util.settings.GlobalSettings;
-import com.android.systemui.util.settings.SecureSettings;
-
-import javax.inject.Inject;
-
-/**
- * A controller that monitors the status of SUW progress for each user in addition to the
- * functionality provided by {@link DeviceProvisionedControllerImpl}.
- */
-@SysUISingleton
-public class CarDeviceProvisionedControllerImpl extends DeviceProvisionedControllerImpl implements
- CarDeviceProvisionedController {
- private final Uri mUserSetupInProgressUri;
- private final ContentObserver mCarSettingsObserver;
- private final Handler mMainHandler;
- private final SecureSettings mSecureSettings;
-
- @Inject
- public CarDeviceProvisionedControllerImpl(@Main Handler mainHandler,
- BroadcastDispatcher broadcastDispatcher, GlobalSettings globalSetting,
- SecureSettings secureSettings) {
- super(mainHandler, broadcastDispatcher, globalSetting, secureSettings);
- mMainHandler = mainHandler;
- mSecureSettings = secureSettings;
- mUserSetupInProgressUri = mSecureSettings.getUriFor(
- CarSettings.Secure.KEY_SETUP_WIZARD_IN_PROGRESS);
- mCarSettingsObserver = new ContentObserver(mMainHandler) {
- @Override
- public void onChange(boolean selfChange, Uri uri, int flags) {
- if (mUserSetupInProgressUri.equals(uri)) {
- notifyUserSetupInProgressChanged();
- }
- }
- };
- }
-
- @Override
- public boolean isUserSetupInProgress(int user) {
- return mSecureSettings.getIntForUser(
- CarSettings.Secure.KEY_SETUP_WIZARD_IN_PROGRESS, /* def= */ 0, user) != 0;
- }
-
- @Override
- public boolean isCurrentUserSetupInProgress() {
- return isUserSetupInProgress(ActivityManager.getCurrentUser());
- }
-
- @Override
- public void addCallback(@NonNull DeviceProvisionedListener listener) {
- super.addCallback(listener);
- if (listener instanceof CarDeviceProvisionedListener) {
- ((CarDeviceProvisionedListener) listener).onUserSetupInProgressChanged();
- }
- }
-
- @Override
- protected void startListening(int user) {
- mSecureSettings.registerContentObserverForUser(
- mUserSetupInProgressUri, /* notifyForDescendants= */ true,
- mCarSettingsObserver, user);
- // The SUW Flag observer is registered before super.startListening() so that the observer is
- // in place before DeviceProvisionedController starts to track user switches which avoids
- // an edge case where our observer gets registered twice.
- super.startListening(user);
- }
-
- @Override
- protected void stopListening() {
- super.stopListening();
- mSecureSettings.unregisterContentObserver(mCarSettingsObserver);
- }
-
- @Override
- public void onUserSwitched(int newUserId) {
- super.onUserSwitched(newUserId);
- mSecureSettings.unregisterContentObserver(mCarSettingsObserver);
- mSecureSettings.registerContentObserverForUser(
- mUserSetupInProgressUri, /* notifyForDescendants= */ true,
- mCarSettingsObserver, newUserId);
- }
-
- private void notifyUserSetupInProgressChanged() {
- for (int i = mListeners.size() - 1; i >= 0; --i) {
- DeviceProvisionedListener listener = mListeners.get(i);
- if (listener instanceof CarDeviceProvisionedListener) {
- ((CarDeviceProvisionedListener) listener).onUserSetupInProgressChanged();
- }
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/CarDeviceProvisionedListener.java b/packages/CarSystemUI/src/com/android/systemui/car/CarDeviceProvisionedListener.java
deleted file mode 100644
index 0086322..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/CarDeviceProvisionedListener.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2019 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.car;
-
-import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
-
-/**
- * A listener that listens for changes in SUW progress for a user in addition to the
- * functionality defined by {@link DeviceProvisionedListener}.
- */
-public interface CarDeviceProvisionedListener extends DeviceProvisionedListener {
- @Override
- default void onUserSwitched() {
- onUserSetupChanged();
- onUserSetupInProgressChanged();
- }
- /**
- * A callback for when a change occurs in SUW progress for a user.
- */
- default void onUserSetupInProgressChanged() {
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/CarServiceProvider.java b/packages/CarSystemUI/src/com/android/systemui/car/CarServiceProvider.java
deleted file mode 100644
index 5778d66..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/CarServiceProvider.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2019 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.car;
-
-import android.car.Car;
-import android.content.Context;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.android.systemui.dagger.SysUISingleton;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.inject.Inject;
-
-/** Provides a common connection to the car service that can be shared. */
-@SysUISingleton
-public class CarServiceProvider {
-
- private final Context mContext;
- private final List<CarServiceOnConnectedListener> mListeners = new ArrayList<>();
- private Car mCar;
-
- @Inject
- public CarServiceProvider(Context context) {
- mContext = context;
- mCar = Car.createCar(mContext, /* handler= */ null, Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT,
- (car, ready) -> {
- mCar = car;
-
- synchronized (mListeners) {
- for (CarServiceOnConnectedListener listener : mListeners) {
- if (ready) {
- listener.onConnected(mCar);
- }
- }
- }
- });
- }
-
- @VisibleForTesting
- public CarServiceProvider(Context context, Car car) {
- mContext = context;
- mCar = car;
- }
-
- /**
- * Let's other components hook into the connection to the car service. If we're already
- * connected to the car service, the callback is immediately triggered.
- */
- public void addListener(CarServiceOnConnectedListener listener) {
- if (mCar.isConnected()) {
- listener.onConnected(mCar);
- }
- mListeners.add(listener);
- }
-
- /**
- * Listener which is triggered when Car Service is connected.
- */
- public interface CarServiceOnConnectedListener {
- /** This will be called when the car service has successfully been connected. */
- void onConnected(Car car);
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/CarSystemUiTest.java b/packages/CarSystemUI/src/com/android/systemui/car/CarSystemUiTest.java
deleted file mode 100644
index 5f593b0..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/CarSystemUiTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2020 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.car;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Annotates that a test class should be run as part of CarSystemUI presubmit
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-@Documented
-public @interface CarSystemUiTest {
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/bluetooth/CarBatteryController.java b/packages/CarSystemUI/src/com/android/systemui/car/bluetooth/CarBatteryController.java
deleted file mode 100644
index 9b5e2712..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/bluetooth/CarBatteryController.java
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.bluetooth;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHeadsetClient;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothProfile.ServiceListener;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Bundle;
-import android.util.Log;
-
-import com.android.systemui.statusbar.policy.BatteryController;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-
-/**
- * A {@link BatteryController} that is specific to the Auto use-case. For Auto, the battery icon
- * displays the battery status of a device that is connected via bluetooth and not the system's
- * battery.
- */
-public class CarBatteryController extends BroadcastReceiver implements BatteryController {
- private static final String TAG = "CarBatteryController";
-
- // According to the Bluetooth HFP 1.5 specification, battery levels are indicated by a
- // value from 1-5, where these values represent the following:
- // 0%% - 0, 1-25%% - 1, 26-50%% - 2, 51-75%% - 3, 76-99%% - 4, 100%% - 5
- // As a result, set the level as the average within that range.
- private static final int BATTERY_LEVEL_EMPTY = 0;
- private static final int BATTERY_LEVEL_1 = 12;
- private static final int BATTERY_LEVEL_2 = 28;
- private static final int BATTERY_LEVEL_3 = 63;
- private static final int BATTERY_LEVEL_4 = 87;
- private static final int BATTERY_LEVEL_FULL = 100;
-
- private static final int INVALID_BATTERY_LEVEL = -1;
-
- private final Context mContext;
-
- private final BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
- private final ArrayList<BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>();
- private BluetoothHeadsetClient mBluetoothHeadsetClient;
- private final ServiceListener mHfpServiceListener = new ServiceListener() {
- @Override
- public void onServiceConnected(int profile, BluetoothProfile proxy) {
- if (profile == BluetoothProfile.HEADSET_CLIENT) {
- mBluetoothHeadsetClient = (BluetoothHeadsetClient) proxy;
- }
- }
-
- @Override
- public void onServiceDisconnected(int profile) {
- if (profile == BluetoothProfile.HEADSET_CLIENT) {
- mBluetoothHeadsetClient = null;
- }
- }
- };
- private int mLevel;
- private BatteryViewHandler mBatteryViewHandler;
-
- public CarBatteryController(Context context) {
- mContext = context;
-
- if (mAdapter == null) {
- return;
- }
-
- mAdapter.getProfileProxy(context.getApplicationContext(), mHfpServiceListener,
- BluetoothProfile.HEADSET_CLIENT);
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("CarBatteryController state:");
- pw.print(" mLevel=");
- pw.println(mLevel);
- }
-
- @Override
- public void setPowerSaveMode(boolean powerSave) {
- // No-op. No power save mode for the car.
- }
-
- @Override
- public void addCallback(BatteryController.BatteryStateChangeCallback cb) {
- mChangeCallbacks.add(cb);
-
- // There is no way to know if the phone is plugged in or charging via bluetooth, so pass
- // false for these values.
- cb.onBatteryLevelChanged(mLevel, false /* pluggedIn */, false /* charging */);
- cb.onPowerSaveChanged(false /* isPowerSave */);
- }
-
- @Override
- public void removeCallback(BatteryController.BatteryStateChangeCallback cb) {
- mChangeCallbacks.remove(cb);
- }
-
- /** Sets {@link BatteryViewHandler}. */
- public void addBatteryViewHandler(BatteryViewHandler batteryViewHandler) {
- mBatteryViewHandler = batteryViewHandler;
- }
-
- /** Starts listening for bluetooth broadcast messages. */
- public void startListening() {
- IntentFilter filter = new IntentFilter();
- filter.addAction(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED);
- filter.addAction(BluetoothHeadsetClient.ACTION_AG_EVENT);
- mContext.registerReceiver(this, filter);
- }
-
- /** Stops listening for bluetooth broadcast messages. */
- public void stopListening() {
- mContext.unregisterReceiver(this);
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
-
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "onReceive(). action: " + action);
- }
-
- if (BluetoothHeadsetClient.ACTION_AG_EVENT.equals(action)) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Received ACTION_AG_EVENT");
- }
-
- int batteryLevel = intent.getIntExtra(BluetoothHeadsetClient.EXTRA_BATTERY_LEVEL,
- INVALID_BATTERY_LEVEL);
-
- updateBatteryLevel(batteryLevel);
-
- if (batteryLevel != INVALID_BATTERY_LEVEL && mBatteryViewHandler != null) {
- mBatteryViewHandler.showBatteryView();
- }
- } else if (BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
-
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- int oldState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1);
- Log.d(TAG, "ACTION_CONNECTION_STATE_CHANGED event: "
- + oldState + " -> " + newState);
-
- }
- BluetoothDevice device =
- (BluetoothDevice) intent.getExtra(BluetoothDevice.EXTRA_DEVICE);
- updateBatteryIcon(device, newState);
- }
- }
-
- /**
- * Converts the battery level to a percentage that can be displayed on-screen and notifies
- * any {@link BatteryStateChangeCallback}s of this.
- */
- private void updateBatteryLevel(int batteryLevel) {
- if (batteryLevel == INVALID_BATTERY_LEVEL) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Battery level invalid. Ignoring.");
- }
- return;
- }
-
- // The battery level is a value between 0-5. Let the default battery level be 0.
- switch (batteryLevel) {
- case 5:
- mLevel = BATTERY_LEVEL_FULL;
- break;
- case 4:
- mLevel = BATTERY_LEVEL_4;
- break;
- case 3:
- mLevel = BATTERY_LEVEL_3;
- break;
- case 2:
- mLevel = BATTERY_LEVEL_2;
- break;
- case 1:
- mLevel = BATTERY_LEVEL_1;
- break;
- case 0:
- default:
- mLevel = BATTERY_LEVEL_EMPTY;
- }
-
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Battery level: " + batteryLevel + "; setting mLevel as: " + mLevel);
- }
-
- notifyBatteryLevelChanged();
- }
-
- /**
- * Updates the display of the battery icon depending on the given connection state from the
- * given {@link BluetoothDevice}.
- */
- private void updateBatteryIcon(BluetoothDevice device, int newState) {
- if (newState == BluetoothProfile.STATE_CONNECTED) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Device connected");
- }
-
- if (mBatteryViewHandler != null) {
- mBatteryViewHandler.showBatteryView();
- }
-
- if (mBluetoothHeadsetClient == null || device == null) {
- return;
- }
-
- // Check if battery information is available and immediately update.
- Bundle featuresBundle = mBluetoothHeadsetClient.getCurrentAgEvents(device);
- if (featuresBundle == null) {
- return;
- }
-
- int batteryLevel = featuresBundle.getInt(BluetoothHeadsetClient.EXTRA_BATTERY_LEVEL,
- INVALID_BATTERY_LEVEL);
- updateBatteryLevel(batteryLevel);
- } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Device disconnected");
- }
-
- if (mBatteryViewHandler != null) {
- mBatteryViewHandler.hideBatteryView();
- }
- }
- }
-
- @Override
- public void dispatchDemoCommand(String command, Bundle args) {
- // TODO: Car demo mode.
- }
-
- @Override
- public boolean isPluggedIn() {
- return true;
- }
-
- @Override
- public boolean isPowerSave() {
- // Power save is not valid for the car, so always return false.
- return false;
- }
-
- @Override
- public boolean isAodPowerSave() {
- return false;
- }
-
- private void notifyBatteryLevelChanged() {
- for (int i = 0, size = mChangeCallbacks.size(); i < size; i++) {
- mChangeCallbacks.get(i)
- .onBatteryLevelChanged(mLevel, false /* pluggedIn */, false /* charging */);
- }
- }
-
- /**
- * An interface indicating the container of a View that will display what the information
- * in the {@link CarBatteryController}.
- */
- public interface BatteryViewHandler {
- /** Hides the battery view. */
- void hideBatteryView();
-
- /** Shows the battery view. */
- void showBatteryView();
- }
-
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/bluetooth/ConnectedDeviceSignalController.java b/packages/CarSystemUI/src/com/android/systemui/car/bluetooth/ConnectedDeviceSignalController.java
deleted file mode 100644
index 4642868..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/bluetooth/ConnectedDeviceSignalController.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.bluetooth;
-
-import static com.android.systemui.statusbar.phone.StatusBar.DEBUG;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHeadsetClient;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothProfile.ServiceListener;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Bundle;
-import android.telephony.SignalStrength;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.View;
-import android.widget.ImageView;
-
-import com.android.settingslib.graph.SignalDrawable;
-import com.android.systemui.Dependency;
-import com.android.systemui.R;
-import com.android.systemui.statusbar.ScalingDrawableWrapper;
-import com.android.systemui.statusbar.policy.BluetoothController;
-
-/**
- * Controller that monitors signal strength for a device that is connected via bluetooth.
- */
-public class ConnectedDeviceSignalController extends BroadcastReceiver implements
- BluetoothController.Callback {
- private static final String TAG = "DeviceSignalCtlr";
-
- /**
- * The value that indicates if a network is unavailable. This value is according ot the
- * Bluetooth HFP 1.5 spec, which indicates this value is one of two: 0 or 1. These stand
- * for network unavailable and available respectively.
- */
- private static final int NETWORK_UNAVAILABLE = 0;
- private static final int NETWORK_UNAVAILABLE_ICON_ID = R.drawable.stat_sys_signal_null;
-
- /**
- * All possible signal strength icons. According to the Bluetooth HFP 1.5 specification,
- * signal strength is indicated by a value from 1-5, where these values represent the following:
- *
- * <p>0%% - 0, 1-25%% - 1, 26-50%% - 2, 51-75%% - 3, 76-99%% - 4, 100%% - 5
- *
- * <p>As a result, these are treated as an index into this array for the corresponding icon.
- * Note that the icon is the same for 0 and 1.
- */
- private static final int[] SIGNAL_STRENGTH_ICONS = {
- 0,
- 0,
- 1,
- 2,
- 3,
- 4,
- };
-
- private static final int INVALID_SIGNAL = -1;
-
- private final BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
- private final Context mContext;
- private final BluetoothController mController;
-
- private final View mSignalsView;
- private final ImageView mNetworkSignalView;
-
- private final float mIconScaleFactor;
- private final SignalDrawable mSignalDrawable;
-
- private BluetoothHeadsetClient mBluetoothHeadsetClient;
- private final ServiceListener mHfpServiceListener = new ServiceListener() {
- @Override
- public void onServiceConnected(int profile, BluetoothProfile proxy) {
- if (profile == BluetoothProfile.HEADSET_CLIENT) {
- mBluetoothHeadsetClient = (BluetoothHeadsetClient) proxy;
- }
- }
-
- @Override
- public void onServiceDisconnected(int profile) {
- if (profile == BluetoothProfile.HEADSET_CLIENT) {
- mBluetoothHeadsetClient = null;
- }
- }
- };
-
- public ConnectedDeviceSignalController(Context context, View signalsView) {
- mContext = context;
- mController = Dependency.get(BluetoothController.class);
-
- mSignalsView = signalsView;
- mNetworkSignalView = (ImageView)
- mSignalsView.findViewById(R.id.connected_device_network_signal);
-
- TypedValue typedValue = new TypedValue();
- context.getResources().getValue(R.dimen.status_bar_icon_scale_factor, typedValue, true);
- mIconScaleFactor = typedValue.getFloat();
- mSignalDrawable = new SignalDrawable(mNetworkSignalView.getContext());
- mNetworkSignalView.setImageDrawable(
- new ScalingDrawableWrapper(mSignalDrawable, mIconScaleFactor));
-
- if (mAdapter == null) {
- return;
- }
-
- mAdapter.getProfileProxy(context.getApplicationContext(), mHfpServiceListener,
- BluetoothProfile.HEADSET_CLIENT);
- }
-
- /** Starts listening for bluetooth broadcast messages. */
- public void startListening() {
- IntentFilter filter = new IntentFilter();
- filter.addAction(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED);
- filter.addAction(BluetoothHeadsetClient.ACTION_AG_EVENT);
- mContext.registerReceiver(this, filter);
-
- mController.addCallback(this);
- }
-
- /** Stops listening for bluetooth broadcast messages. */
- public void stopListening() {
- mContext.unregisterReceiver(this);
- mController.removeCallback(this);
- }
-
- @Override
- public void onBluetoothDevicesChanged() {
- // Nothing to do here because this Controller is not displaying a list of possible
- // bluetooth devices.
- }
-
- @Override
- public void onBluetoothStateChange(boolean enabled) {
- if (DEBUG) {
- Log.d(TAG, "onBluetoothStateChange(). enabled: " + enabled);
- }
-
- // Only need to handle the case if bluetooth has been disabled, in which case the
- // signal indicators are hidden. If bluetooth has been enabled, then this class should
- // receive updates to the connection state via onReceive().
- if (!enabled) {
- mNetworkSignalView.setVisibility(View.GONE);
- mSignalsView.setVisibility(View.GONE);
- }
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
-
- if (DEBUG) {
- Log.d(TAG, "onReceive(). action: " + action);
- }
-
- if (BluetoothHeadsetClient.ACTION_AG_EVENT.equals(action)) {
- if (DEBUG) {
- Log.d(TAG, "Received ACTION_AG_EVENT");
- }
-
- processActionAgEvent(intent);
- } else if (BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
-
- if (DEBUG) {
- int oldState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1);
- Log.d(TAG, "ACTION_CONNECTION_STATE_CHANGED event: "
- + oldState + " -> " + newState);
- }
- BluetoothDevice device =
- (BluetoothDevice) intent.getExtra(BluetoothDevice.EXTRA_DEVICE);
- updateViewVisibility(device, newState);
- }
- }
-
- /**
- * Processes an {@link Intent} that had an action of
- * {@link BluetoothHeadsetClient#ACTION_AG_EVENT}.
- */
- private void processActionAgEvent(Intent intent) {
- int networkStatus = intent.getIntExtra(BluetoothHeadsetClient.EXTRA_NETWORK_STATUS,
- INVALID_SIGNAL);
- if (networkStatus != INVALID_SIGNAL) {
- if (DEBUG) {
- Log.d(TAG, "EXTRA_NETWORK_STATUS: " + " " + networkStatus);
- }
-
- if (networkStatus == NETWORK_UNAVAILABLE) {
- setNetworkSignalIcon(NETWORK_UNAVAILABLE_ICON_ID);
- }
- }
-
- int signalStrength = intent.getIntExtra(
- BluetoothHeadsetClient.EXTRA_NETWORK_SIGNAL_STRENGTH, INVALID_SIGNAL);
- if (signalStrength != INVALID_SIGNAL) {
- if (DEBUG) {
- Log.d(TAG, "EXTRA_NETWORK_SIGNAL_STRENGTH: " + signalStrength);
- }
-
- setNetworkSignalIcon(SIGNAL_STRENGTH_ICONS[signalStrength]);
- }
-
- int roamingStatus = intent.getIntExtra(BluetoothHeadsetClient.EXTRA_NETWORK_ROAMING,
- INVALID_SIGNAL);
- if (roamingStatus != INVALID_SIGNAL) {
- if (DEBUG) {
- Log.d(TAG, "EXTRA_NETWORK_ROAMING: " + roamingStatus);
- }
- }
- }
-
- private void setNetworkSignalIcon(int level) {
- // Setting the icon on a child view of mSignalView, so toggle this container visible.
- mSignalsView.setVisibility(View.VISIBLE);
-
- mSignalDrawable.setLevel(SignalDrawable.getState(level,
- SignalStrength.NUM_SIGNAL_STRENGTH_BINS, false));
- mNetworkSignalView.setVisibility(View.VISIBLE);
- }
-
- private void updateViewVisibility(BluetoothDevice device, int newState) {
- if (newState == BluetoothProfile.STATE_CONNECTED) {
- if (DEBUG) {
- Log.d(TAG, "Device connected");
- }
-
- if (mBluetoothHeadsetClient == null || device == null) {
- return;
- }
-
- // Check if battery information is available and immediately update.
- Bundle featuresBundle = mBluetoothHeadsetClient.getCurrentAgEvents(device);
- if (featuresBundle == null) {
- return;
- }
-
- int signalStrength = featuresBundle.getInt(
- BluetoothHeadsetClient.EXTRA_NETWORK_SIGNAL_STRENGTH, INVALID_SIGNAL);
- if (signalStrength != INVALID_SIGNAL) {
- if (DEBUG) {
- Log.d(TAG, "EXTRA_NETWORK_SIGNAL_STRENGTH: " + signalStrength);
- }
-
- setNetworkSignalIcon(SIGNAL_STRENGTH_ICONS[signalStrength]);
- }
- } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
- if (DEBUG) {
- Log.d(TAG, "Device disconnected");
- }
-
- mNetworkSignalView.setVisibility(View.GONE);
- mSignalsView.setVisibility(View.GONE);
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/hvac/AdjustableTemperatureView.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/AdjustableTemperatureView.java
deleted file mode 100644
index af2a1d3..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/hvac/AdjustableTemperatureView.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.hvac;
-
-import static com.android.systemui.car.hvac.HvacController.convertToCelsius;
-import static com.android.systemui.car.hvac.HvacController.convertToFahrenheit;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.android.systemui.R;
-
-/**
- * Displays temperature with a button to decrease and a button to increase on either side.
- * Properties configured in the XML:
- * hvacAreaId - Example: VehicleSeat.SEAT_ROW_1_LEFT (1)
- */
-public class AdjustableTemperatureView extends LinearLayout implements TemperatureView {
-
- private final int mAreaId;
- private TextView mTempTextView;
- private float mMinTempC;
- private float mMaxTempC;
- private String mTempFormat;
- private String mNullTempText;
- private String mMinTempText;
- private String mMaxTempText;
- private boolean mDisplayInFahrenheit = false;
-
- private HvacController mHvacController;
- private float mCurrentTempC;
-
- public AdjustableTemperatureView(Context context, AttributeSet attrs) {
- super(context, attrs);
- TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TemperatureView);
- mAreaId = typedArray.getInt(R.styleable.TemperatureView_hvacAreaId, -1);
- }
-
- @Override
- public void onFinishInflate() {
- super.onFinishInflate();
- LayoutInflater.from(getContext()).inflate(R.layout.adjustable_temperature_view,
- /* root= */ this);
- mTempFormat = getResources().getString(R.string.hvac_temperature_format);
- mMinTempC = getResources().getFloat(R.dimen.hvac_min_value_celsius);
- mMaxTempC = getResources().getFloat(R.dimen.hvac_max_value_celsius);
- mNullTempText = getResources().getString(R.string.hvac_null_temp_text);
- mMinTempText = getResources().getString(R.string.hvac_min_text);
- mMaxTempText = getResources().getString(R.string.hvac_max_text);
- initializeButtons();
- }
-
- @Override
- public void setHvacController(HvacController controller) {
- mHvacController = controller;
- }
-
- @Override
- public void setTemp(float tempC) {
- if (mTempTextView == null) {
- mTempTextView = findViewById(R.id.hvac_temperature_text);
- }
- if (Float.isNaN(tempC)) {
- mTempTextView.setText(mNullTempText);
- return;
- }
- if (tempC <= mMinTempC) {
- mTempTextView.setText(mMinTempText);
- mCurrentTempC = mMinTempC;
- return;
- }
- if (tempC >= mMaxTempC) {
- mTempTextView.setText(mMaxTempText);
- mCurrentTempC = mMaxTempC;
- return;
- }
- mTempTextView.setText(String.format(mTempFormat,
- mDisplayInFahrenheit ? convertToFahrenheit(tempC) : tempC));
- mCurrentTempC = tempC;
- }
-
- @Override
- public void setDisplayInFahrenheit(boolean displayFahrenheit) {
- mDisplayInFahrenheit = displayFahrenheit;
- setTemp(mCurrentTempC);
- }
-
- @Override
- public int getAreaId() {
- return mAreaId;
- }
-
- private void initializeButtons() {
- findViewById(R.id.hvac_decrease_button).setOnClickListener(v -> {
- float newTemp = mDisplayInFahrenheit ? convertToCelsius(
- convertToFahrenheit(mCurrentTempC) - 1) : (mCurrentTempC - 1);
- setTemperature(newTemp, mAreaId);
- });
-
- findViewById(R.id.hvac_increase_button).setOnClickListener(v -> {
- float newTemp = mDisplayInFahrenheit ? convertToCelsius(
- convertToFahrenheit(mCurrentTempC) + 1) : (mCurrentTempC + 1);
- setTemperature(newTemp, mAreaId);
- });
- }
-
- private void setTemperature(float tempC, int zone) {
- if (tempC < mMaxTempC && tempC > mMinTempC && mHvacController != null) {
- mHvacController.setTemperature(tempC, zone);
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/hvac/AnimatedTemperatureView.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/AnimatedTemperatureView.java
deleted file mode 100644
index b98b680..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/hvac/AnimatedTemperatureView.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.hvac;
-
-import static com.android.systemui.car.hvac.HvacController.convertToFahrenheit;
-
-import android.animation.ObjectAnimator;
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Color;
-import android.graphics.Rect;
-import android.graphics.drawable.ColorDrawable;
-import android.util.AttributeSet;
-import android.util.Property;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.TextSwitcher;
-import android.widget.TextView;
-
-import com.android.systemui.R;
-
-/**
- * Simple text display of HVAC properties, It is designed to show mTemperature and is configured in
- * the XML.
- * XML properties:
- * hvacAreaId - Example: VehicleAreaSeat.SEAT_ROW_1_LEFT (1)
- * hvacOrientaion = Example: left
- */
-public class AnimatedTemperatureView extends FrameLayout implements TemperatureView {
-
- private static final float TEMPERATURE_EQUIVALENT_DELTA = .01f;
- private static final Property<ColorDrawable, Integer> COLOR_PROPERTY =
- new Property<ColorDrawable, Integer>(Integer.class, "color") {
-
- @Override
- public Integer get(ColorDrawable object) {
- return object.getColor();
- }
-
- @Override
- public void set(ColorDrawable object, Integer value) {
- object.setColor(value);
- }
- };
-
- static boolean isHorizontal(int gravity) {
- return Gravity.isHorizontal(gravity)
- && (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) != Gravity.CENTER_HORIZONTAL;
- }
-
- @SuppressLint("RtlHardcoded")
- static boolean isLeft(int gravity, int layoutDirection) {
- return Gravity
- .getAbsoluteGravity(gravity & Gravity.HORIZONTAL_GRAVITY_MASK, layoutDirection)
- == Gravity.LEFT;
- }
-
- static boolean isVertical(int gravity) {
- return Gravity.isVertical(gravity)
- && (gravity & Gravity.VERTICAL_GRAVITY_MASK) != Gravity.CENTER_VERTICAL;
- }
-
- static boolean isTop(int gravity) {
- return (gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.TOP;
- }
-
- private final int mAreaId;
- private final int mPivotOffset;
- private final int mGravity;
- private final int mTextAppearanceRes;
- private final int mMinEms;
- private final Rect mPaddingRect;
- private final float mMinValue;
- private final float mMaxValue;
-
- private final ColorDrawable mBackgroundColor;
-
- private final TemperatureColorStore mColorStore = new TemperatureColorStore();
- private final TemperatureBackgroundAnimator mBackgroundAnimator;
- private final TemperatureTextAnimator mTextAnimator;
- boolean mDisplayInFahrenheit = false;
-
- private HvacController mHvacController;
-
- public AnimatedTemperatureView(Context context, AttributeSet attrs) {
- super(context, attrs);
- TypedArray typedArray = context.obtainStyledAttributes(attrs,
- R.styleable.AnimatedTemperatureView);
- mAreaId = typedArray.getInt(R.styleable.AnimatedTemperatureView_hvacAreaId, -1);
- mPivotOffset =
- typedArray.getDimensionPixelOffset(
- R.styleable.AnimatedTemperatureView_hvacPivotOffset, 0);
- mGravity = typedArray.getInt(R.styleable.AnimatedTemperatureView_android_gravity,
- Gravity.START);
- mTextAppearanceRes =
- typedArray.getResourceId(R.styleable.AnimatedTemperatureView_android_textAppearance,
- 0);
- mMinEms = typedArray.getInteger(R.styleable.AnimatedTemperatureView_android_minEms, 0);
- mMinValue = getResources().getFloat(R.dimen.hvac_min_value_celsius);
- mMaxValue = getResources().getFloat(R.dimen.hvac_max_value_celsius);
-
- mPaddingRect =
- new Rect(getPaddingLeft(), getPaddingTop(), getPaddingRight(), getPaddingBottom());
- setPadding(0, 0, 0, 0);
-
- setClipChildren(false);
- setClipToPadding(false);
-
- // init Views
- TextSwitcher textSwitcher = new TextSwitcher(context);
- textSwitcher.setFactory(this::generateTextView);
- ImageView background = new ImageView(context);
- mBackgroundColor = new ColorDrawable(Color.TRANSPARENT);
- background.setImageDrawable(mBackgroundColor);
- background.setVisibility(View.GONE);
-
- mBackgroundAnimator = new TemperatureBackgroundAnimator(this, background);
-
- mTextAnimator = new TemperatureTextAnimator(this, textSwitcher,
- getResources().getString(R.string.hvac_temperature_format), mPivotOffset,
- getResources().getString(R.string.hvac_min_text),
- getResources().getString(R.string.hvac_max_text));
-
- addView(background, ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT);
- addView(textSwitcher, ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT);
-
- typedArray.recycle();
- }
-
-
- private TextView generateTextView() {
- TextView textView = new TextView(getContext());
- textView.setTextAppearance(mTextAppearanceRes);
- textView.setAllCaps(true);
- textView.setMinEms(mMinEms);
- textView.setGravity(mGravity);
- textView.setPadding(mPaddingRect.left, mPaddingRect.top, mPaddingRect.right,
- mPaddingRect.bottom);
- textView.getViewTreeObserver()
- .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
- @Override
- public boolean onPreDraw() {
- if (isHorizontal(mGravity)) {
- if (isLeft(mGravity, getLayoutDirection())) {
- textView.setPivotX(-mPivotOffset);
- } else {
- textView.setPivotX(textView.getWidth() + mPivotOffset);
- }
- }
- textView.getViewTreeObserver().removeOnPreDrawListener(this);
- return true;
- }
- });
- textView.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT));
-
- return textView;
- }
-
- @Override
- public void setHvacController(HvacController controller) {
- mHvacController = controller;
- }
-
- /**
- * Formats the float for display
- *
- * @param temp - The current temp or NaN
- */
- @Override
- public void setTemp(float temp) {
- if (mDisplayInFahrenheit) {
- temp = convertToFahrenheit(temp);
- }
- mTextAnimator.setTemp(temp);
- if (Float.isNaN(temp)) {
- mBackgroundAnimator.hideCircle();
- return;
- }
- int color;
- if (isMinValue(temp)) {
- color = mColorStore.getMinColor();
- } else if (isMaxValue(temp)) {
- color = mColorStore.getMaxColor();
- } else {
- color = mColorStore.getColorForTemperature(temp);
- }
- if (mBackgroundAnimator.isOpen()) {
- ObjectAnimator colorAnimator =
- ObjectAnimator.ofInt(mBackgroundColor, COLOR_PROPERTY, color);
- colorAnimator.setEvaluator((fraction, startValue, endValue) -> mColorStore
- .lerpColor(fraction, (int) startValue, (int) endValue));
- colorAnimator.start();
- } else {
- mBackgroundColor.setColor(color);
- }
-
- mBackgroundAnimator.animateOpen();
- }
-
- @Override
- public void setDisplayInFahrenheit(boolean displayInFahrenheit) {
- mDisplayInFahrenheit = displayInFahrenheit;
- }
-
- boolean isMinValue(float temp) {
- return !Float.isNaN(mMinValue) && isApproxEqual(temp, mMinValue);
- }
-
- boolean isMaxValue(float temp) {
- return !Float.isNaN(mMaxValue) && isApproxEqual(temp, mMaxValue);
- }
-
- private boolean isApproxEqual(float left, float right) {
- return Math.abs(left - right) <= TEMPERATURE_EQUIVALENT_DELTA;
- }
-
- int getGravity() {
- return mGravity;
- }
-
- int getPivotOffset() {
- return mPivotOffset;
- }
-
- Rect getPaddingRect() {
- return mPaddingRect;
- }
-
- /**
- * @return hvac AreaId - Example: VehicleAreaSeat.SEAT_ROW_1_LEFT (1)
- */
- @Override
- public int getAreaId() {
- return mAreaId;
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- mBackgroundAnimator.stopAnimations();
- }
-}
-
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/hvac/HvacController.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/HvacController.java
deleted file mode 100644
index 10a361c..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/hvac/HvacController.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.hvac;
-
-import static android.car.VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;
-import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS;
-import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_SET;
-
-import android.car.Car;
-import android.car.VehicleUnit;
-import android.car.hardware.CarPropertyValue;
-import android.car.hardware.property.CarPropertyManager;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.systemui.car.CarServiceProvider;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.UiBackground;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Executor;
-
-import javax.inject.Inject;
-
-/**
- * Manages the connection to the Car service and delegates value changes to the registered
- * {@link TemperatureView}s
- */
-@SysUISingleton
-public class HvacController {
- public static final String TAG = "HvacController";
- private static final boolean DEBUG = true;
-
- private final Executor mBackgroundExecutor;
- private final CarServiceProvider mCarServiceProvider;
- private final Set<TemperatureView> mRegisteredViews = new HashSet<>();
-
- private CarPropertyManager mCarPropertyManager;
- private HashMap<Integer, List<TemperatureView>> mTempComponents = new HashMap<>();
-
- private final CarPropertyManager.CarPropertyEventCallback mHvacTemperatureSetCallback =
- new CarPropertyManager.CarPropertyEventCallback() {
- @Override
- public void onChangeEvent(CarPropertyValue value) {
- try {
- int areaId = value.getAreaId();
- List<TemperatureView> temperatureViews = mTempComponents.get(areaId);
- if (temperatureViews != null && !temperatureViews.isEmpty()) {
- float newTemp = (float) value.getValue();
- if (DEBUG) {
- Log.d(TAG, "onChangeEvent: " + areaId + ":" + value);
- }
- for (TemperatureView view : temperatureViews) {
- view.setTemp(newTemp);
- }
- }
- } catch (Exception e) {
- Log.e(TAG, "Failed handling hvac change event", e);
- }
- }
-
- @Override
- public void onErrorEvent(int propId, int zone) {
- Log.d(TAG, "HVAC error event, propertyId: " + propId + " zone: " + zone);
- }
- };
-
- private final CarPropertyManager.CarPropertyEventCallback mTemperatureUnitChangeCallback =
- new CarPropertyManager.CarPropertyEventCallback() {
- @Override
- public void onChangeEvent(CarPropertyValue value) {
- if (!mRegisteredViews.isEmpty()) {
- for (TemperatureView view : mRegisteredViews) {
- view.setDisplayInFahrenheit(
- value.getValue().equals(VehicleUnit.FAHRENHEIT));
- }
- }
- }
-
- @Override
- public void onErrorEvent(int propId, int zone) {
- Log.d(TAG, "HVAC error event, propertyId: " + propId + " zone: " + zone);
- }
- };
-
- private final CarServiceProvider.CarServiceOnConnectedListener mCarServiceLifecycleListener =
- car -> {
- try {
- mCarPropertyManager = (CarPropertyManager) car.getCarManager(
- Car.PROPERTY_SERVICE);
- mCarPropertyManager.registerCallback(mHvacTemperatureSetCallback,
- HVAC_TEMPERATURE_SET, CarPropertyManager.SENSOR_RATE_ONCHANGE);
- mCarPropertyManager.registerCallback(mTemperatureUnitChangeCallback,
- HVAC_TEMPERATURE_DISPLAY_UNITS,
- CarPropertyManager.SENSOR_RATE_ONCHANGE);
- initComponents();
- } catch (Exception e) {
- Log.e(TAG, "Failed to correctly connect to HVAC", e);
- }
- };
-
- @Inject
- public HvacController(CarServiceProvider carServiceProvider,
- @UiBackground Executor backgroundExecutor) {
- mCarServiceProvider = carServiceProvider;
- mBackgroundExecutor = backgroundExecutor;
- }
-
- /**
- * Create connection to the Car service.
- */
- public void connectToCarService() {
- mCarServiceProvider.addListener(mCarServiceLifecycleListener);
- }
-
- /**
- * Add component to list and initialize it if the connection is up.
- */
- private void addHvacTextView(TemperatureView temperatureView) {
- if (mRegisteredViews.contains(temperatureView)) {
- return;
- }
-
- int areaId = temperatureView.getAreaId();
- if (!mTempComponents.containsKey(areaId)) {
- mTempComponents.put(areaId, new ArrayList<>());
- }
- mTempComponents.get(areaId).add(temperatureView);
- initComponent(temperatureView);
-
- mRegisteredViews.add(temperatureView);
- }
-
- private void initComponents() {
- for (Map.Entry<Integer, List<TemperatureView>> next : mTempComponents.entrySet()) {
- List<TemperatureView> temperatureViews = next.getValue();
- for (TemperatureView view : temperatureViews) {
- initComponent(view);
- }
- }
- }
-
- private void initComponent(TemperatureView view) {
- int zone = view.getAreaId();
- if (DEBUG) {
- Log.d(TAG, "initComponent: " + zone);
- }
-
- try {
- if (mCarPropertyManager != null && mCarPropertyManager.isPropertyAvailable(
- HVAC_TEMPERATURE_DISPLAY_UNITS, VEHICLE_AREA_TYPE_GLOBAL)) {
- if (mCarPropertyManager.getIntProperty(HVAC_TEMPERATURE_DISPLAY_UNITS,
- VEHICLE_AREA_TYPE_GLOBAL) == VehicleUnit.FAHRENHEIT) {
- view.setDisplayInFahrenheit(true);
- }
- }
- if (mCarPropertyManager == null || !mCarPropertyManager.isPropertyAvailable(
- HVAC_TEMPERATURE_SET, zone)) {
- view.setTemp(Float.NaN);
- return;
- }
- view.setTemp(
- mCarPropertyManager.getFloatProperty(HVAC_TEMPERATURE_SET, zone));
- view.setHvacController(this);
- } catch (Exception e) {
- view.setTemp(Float.NaN);
- Log.e(TAG, "Failed to get value from hvac service", e);
- }
- }
-
- /**
- * Removes all registered components. This is useful if you need to rebuild the UI since
- * components self register.
- */
- public void removeAllComponents() {
- mTempComponents.clear();
- mRegisteredViews.clear();
- }
-
- /**
- * Iterate through a view, looking for {@link TemperatureView} instances and add them to the
- * controller if found.
- */
- public void addTemperatureViewToController(View v) {
- if (v instanceof TemperatureView) {
- addHvacTextView((TemperatureView) v);
- } else if (v instanceof ViewGroup) {
- ViewGroup viewGroup = (ViewGroup) v;
- for (int i = 0; i < viewGroup.getChildCount(); i++) {
- addTemperatureViewToController(viewGroup.getChildAt(i));
- }
- }
- }
-
- /**
- * Set the temperature in Celsius of the specified zone
- */
- public void setTemperature(float tempC, int zone) {
- if (mCarPropertyManager != null) {
- // Internally, all temperatures are represented in floating point Celsius
- mBackgroundExecutor.execute(
- () -> mCarPropertyManager.setFloatProperty(HVAC_TEMPERATURE_SET, zone, tempC));
- }
- }
-
- /**
- * Convert the given temperature in Celsius into Fahrenheit
- *
- * @param tempC - The temperature in Celsius
- * @return Temperature in Fahrenheit.
- */
- public static float convertToFahrenheit(float tempC) {
- return (tempC * 9f / 5f) + 32;
- }
-
- /**
- * Convert the given temperature in Fahrenheit to Celsius
- *
- * @param tempF - The temperature in Fahrenheit.
- * @return Temperature in Celsius.
- */
- public static float convertToCelsius(float tempF) {
- return (tempF - 32) * 5f / 9f;
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureBackgroundAnimator.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureBackgroundAnimator.java
deleted file mode 100644
index a4c4573..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureBackgroundAnimator.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.hvac;
-
-import static com.android.systemui.car.hvac.AnimatedTemperatureView.isHorizontal;
-import static com.android.systemui.car.hvac.AnimatedTemperatureView.isLeft;
-import static com.android.systemui.car.hvac.AnimatedTemperatureView.isTop;
-import static com.android.systemui.car.hvac.AnimatedTemperatureView.isVertical;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.annotation.IntDef;
-import android.graphics.Rect;
-import android.view.View;
-import android.view.ViewAnimationUtils;
-import android.view.animation.AnticipateInterpolator;
-import android.widget.ImageView;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Controls circular reveal animation of temperature background
- */
-class TemperatureBackgroundAnimator {
-
- private static final AnticipateInterpolator ANTICIPATE_INTERPOLATOR =
- new AnticipateInterpolator();
- private static final float MAX_OPACITY = .6f;
-
- private final View mAnimatedView;
-
- private int mPivotX;
- private int mPivotY;
- private int mGoneRadius;
- private int mOvershootRadius;
- private int mRestingRadius;
- private int mBumpRadius;
-
- @CircleState
- private int mCircleState;
-
- private Animator mCircularReveal;
- private boolean mAnimationsReady;
-
- @IntDef({CircleState.GONE, CircleState.ENTERING, CircleState.OVERSHOT, CircleState.RESTING,
- CircleState.RESTED, CircleState.BUMPING, CircleState.BUMPED, CircleState.EXITING})
- private @interface CircleState {
- int GONE = 0;
- int ENTERING = 1;
- int OVERSHOT = 2;
- int RESTING = 3;
- int RESTED = 4;
- int BUMPING = 5;
- int BUMPED = 6;
- int EXITING = 7;
- }
-
- TemperatureBackgroundAnimator(
- AnimatedTemperatureView parent,
- ImageView animatedView) {
- mAnimatedView = animatedView;
- mAnimatedView.setAlpha(0);
-
- parent.addOnLayoutChangeListener(
- (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
- setupAnimations(parent.getGravity(), parent.getPivotOffset(),
- parent.getPaddingRect(), parent.getWidth(), parent.getHeight()));
- }
-
- private void setupAnimations(int gravity, int pivotOffset, Rect paddingRect,
- int width, int height) {
- int padding;
- if (isHorizontal(gravity)) {
- mGoneRadius = pivotOffset;
- if (isLeft(gravity, mAnimatedView.getLayoutDirection())) {
- mPivotX = -pivotOffset;
- padding = paddingRect.right;
- } else {
- mPivotX = width + pivotOffset;
- padding = paddingRect.left;
- }
- mPivotY = height / 2;
- mOvershootRadius = pivotOffset + width;
- } else if (isVertical(gravity)) {
- mGoneRadius = pivotOffset;
- if (isTop(gravity)) {
- mPivotY = -pivotOffset;
- padding = paddingRect.bottom;
- } else {
- mPivotY = height + pivotOffset;
- padding = paddingRect.top;
- }
- mPivotX = width / 2;
- mOvershootRadius = pivotOffset + height;
- } else {
- mPivotX = width / 2;
- mPivotY = height / 2;
- mGoneRadius = 0;
- if (width > height) {
- mOvershootRadius = height;
- padding = Math.max(paddingRect.top, paddingRect.bottom);
- } else {
- mOvershootRadius = width;
- padding = Math.max(paddingRect.left, paddingRect.right);
- }
- }
- mRestingRadius = mOvershootRadius - padding;
- mBumpRadius = mOvershootRadius - padding / 3;
- mAnimationsReady = true;
- }
-
- boolean isOpen() {
- return mCircleState != CircleState.GONE;
- }
-
- void animateOpen() {
- if (!mAnimationsReady
- || !mAnimatedView.isAttachedToWindow()
- || mCircleState == CircleState.ENTERING) {
- return;
- }
-
- AnimatorSet set = new AnimatorSet();
- List<Animator> animators = new ArrayList<>();
- switch (mCircleState) {
- case CircleState.ENTERING:
- throw new AssertionError("Should not be able to reach this statement");
- case CircleState.GONE: {
- Animator startCircle = createEnterAnimator();
- markState(startCircle, CircleState.ENTERING);
- animators.add(startCircle);
- Animator holdOvershoot = ViewAnimationUtils
- .createCircularReveal(mAnimatedView, mPivotX, mPivotY, mOvershootRadius,
- mOvershootRadius);
- holdOvershoot.setDuration(50);
- markState(holdOvershoot, CircleState.OVERSHOT);
- animators.add(holdOvershoot);
- Animator rest = ViewAnimationUtils
- .createCircularReveal(mAnimatedView, mPivotX, mPivotY, mOvershootRadius,
- mRestingRadius);
- markState(rest, CircleState.RESTING);
- animators.add(rest);
- Animator holdRest = ViewAnimationUtils
- .createCircularReveal(mAnimatedView, mPivotX, mPivotY, mRestingRadius,
- mRestingRadius);
- markState(holdRest, CircleState.RESTED);
- holdRest.setDuration(1000);
- animators.add(holdRest);
- Animator exit = createExitAnimator(mRestingRadius);
- markState(exit, CircleState.EXITING);
- animators.add(exit);
- }
- break;
- case CircleState.RESTED:
- case CircleState.RESTING:
- case CircleState.EXITING:
- case CircleState.OVERSHOT:
- int startRadius =
- mCircleState == CircleState.OVERSHOT ? mOvershootRadius : mRestingRadius;
- Animator bump = ViewAnimationUtils
- .createCircularReveal(mAnimatedView, mPivotX, mPivotY, startRadius,
- mBumpRadius);
- bump.setDuration(50);
- markState(bump, CircleState.BUMPING);
- animators.add(bump);
- // fallthrough intentional
- case CircleState.BUMPED:
- case CircleState.BUMPING:
- Animator holdBump = ViewAnimationUtils
- .createCircularReveal(mAnimatedView, mPivotX, mPivotY, mBumpRadius,
- mBumpRadius);
- holdBump.setDuration(100);
- markState(holdBump, CircleState.BUMPED);
- animators.add(holdBump);
- Animator rest = ViewAnimationUtils
- .createCircularReveal(mAnimatedView, mPivotX, mPivotY, mBumpRadius,
- mRestingRadius);
- markState(rest, CircleState.RESTING);
- animators.add(rest);
- Animator holdRest = ViewAnimationUtils
- .createCircularReveal(mAnimatedView, mPivotX, mPivotY, mRestingRadius,
- mRestingRadius);
- holdRest.setDuration(1000);
- markState(holdRest, CircleState.RESTED);
- animators.add(holdRest);
- Animator exit = createExitAnimator(mRestingRadius);
- markState(exit, CircleState.EXITING);
- animators.add(exit);
- break;
- }
- set.playSequentially(animators);
- set.addListener(new AnimatorListenerAdapter() {
- private boolean mCanceled = false;
-
- @Override
- public void onAnimationStart(Animator animation) {
- if (mCircularReveal != null) {
- mCircularReveal.cancel();
- }
- mCircularReveal = animation;
- mAnimatedView.setVisibility(View.VISIBLE);
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- mCanceled = true;
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (mCanceled) {
- return;
- }
- mCircularReveal = null;
- mCircleState = CircleState.GONE;
- mAnimatedView.setVisibility(View.GONE);
- }
- });
-
- set.start();
- }
-
- private Animator createEnterAnimator() {
- AnimatorSet animatorSet = new AnimatorSet();
- Animator circularReveal = ViewAnimationUtils
- .createCircularReveal(mAnimatedView, mPivotX, mPivotY, mGoneRadius,
- mOvershootRadius);
- Animator fade = ObjectAnimator.ofFloat(mAnimatedView, View.ALPHA, MAX_OPACITY);
- animatorSet.playTogether(circularReveal, fade);
- return animatorSet;
- }
-
- private Animator createExitAnimator(int startRadius) {
- AnimatorSet animatorSet = new AnimatorSet();
- Animator circularHide = ViewAnimationUtils
- .createCircularReveal(mAnimatedView, mPivotX, mPivotY, startRadius,
- (mGoneRadius + startRadius) / 2);
- circularHide.setInterpolator(ANTICIPATE_INTERPOLATOR);
- Animator fade = ObjectAnimator.ofFloat(mAnimatedView, View.ALPHA, 0);
- fade.setStartDelay(50);
- animatorSet.playTogether(circularHide, fade);
- return animatorSet;
- }
-
- void hideCircle() {
- if (!mAnimationsReady || mCircleState == CircleState.GONE
- || mCircleState == CircleState.EXITING) {
- return;
- }
-
- int startRadius;
- switch (mCircleState) {
- // Unreachable, but here to exhaust switch cases
- //noinspection ConstantConditions
- case CircleState.EXITING:
- //noinspection ConstantConditions
- case CircleState.GONE:
- throw new AssertionError("Should not be able to reach this statement");
- case CircleState.BUMPED:
- case CircleState.BUMPING:
- startRadius = mBumpRadius;
- break;
- case CircleState.OVERSHOT:
- startRadius = mOvershootRadius;
- break;
- case CircleState.ENTERING:
- case CircleState.RESTED:
- case CircleState.RESTING:
- startRadius = mRestingRadius;
- break;
- default:
- throw new IllegalStateException("Unknown CircleState: " + mCircleState);
- }
-
- Animator hideAnimation = createExitAnimator(startRadius);
- if (startRadius == mRestingRadius) {
- hideAnimation.setInterpolator(ANTICIPATE_INTERPOLATOR);
- }
- hideAnimation.addListener(new AnimatorListenerAdapter() {
- private boolean mCanceled = false;
-
- @Override
- public void onAnimationStart(Animator animation) {
- mCircleState = CircleState.EXITING;
- if (mCircularReveal != null) {
- mCircularReveal.cancel();
- }
- mCircularReveal = animation;
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- mCanceled = true;
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (mCanceled) {
- return;
- }
- mCircularReveal = null;
- mCircleState = CircleState.GONE;
- mAnimatedView.setVisibility(View.GONE);
- }
- });
- hideAnimation.start();
- }
-
- void stopAnimations() {
- if (mCircularReveal != null) {
- mCircularReveal.end();
- }
- }
-
- private void markState(Animator animator, @CircleState int startState) {
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- mCircleState = startState;
- }
- });
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureColorStore.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureColorStore.java
deleted file mode 100644
index 9a7b0b9..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureColorStore.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.hvac;
-
-import android.graphics.Color;
-
-/**
- * Contains the logic for mapping colors to temperatures
- */
-class TemperatureColorStore {
-
- private static class TemperatureColorValue {
- final float mTemperature;
- final int mColor;
-
- private TemperatureColorValue(float temperature, int color) {
- this.mTemperature = temperature;
- this.mColor = color;
- }
-
- float getTemperature() {
- return mTemperature;
- }
-
- int getColor() {
- return mColor;
- }
- }
-
- private static TemperatureColorValue tempToColor(float temperature, int color) {
- return new TemperatureColorValue(temperature, color);
- }
-
- private static final int COLOR_COLDEST = 0xFF406DFF;
- private static final int COLOR_COLD = 0xFF4094FF;
- private static final int COLOR_NEUTRAL = 0xFFF4F4F4;
- private static final int COLOR_WARM = 0xFFFF550F;
- private static final int COLOR_WARMEST = 0xFFFF0000;
- // must be sorted by temperature
- private static final TemperatureColorValue[] sTemperatureColorValues =
- {
- // Celsius
- tempToColor(19, COLOR_COLDEST),
- tempToColor(21, COLOR_COLD),
- tempToColor(23, COLOR_NEUTRAL),
- tempToColor(25, COLOR_WARM),
- tempToColor(27, COLOR_WARMEST),
-
- // Switch over
- tempToColor(45, COLOR_WARMEST),
- tempToColor(45.00001f, COLOR_COLDEST),
-
- // Farenheight
- tempToColor(66, COLOR_COLDEST),
- tempToColor(70, COLOR_COLD),
- tempToColor(74, COLOR_NEUTRAL),
- tempToColor(76, COLOR_WARM),
- tempToColor(80, COLOR_WARMEST)
- };
-
- private static final int COLOR_UNSET = Color.BLACK;
-
- private final float[] mTempHsv1 = new float[3];
- private final float[] mTempHsv2 = new float[3];
- private final float[] mTempHsv3 = new float[3];
-
- int getMinColor() {
- return COLOR_COLDEST;
- }
-
- int getMaxColor() {
- return COLOR_WARMEST;
- }
-
- int getColorForTemperature(float temperature) {
- if (Float.isNaN(temperature)) {
- return COLOR_UNSET;
- }
- TemperatureColorValue bottomValue = sTemperatureColorValues[0];
- if (temperature <= bottomValue.getTemperature()) {
- return bottomValue.getColor();
- }
- TemperatureColorValue topValue =
- sTemperatureColorValues[sTemperatureColorValues.length - 1];
- if (temperature >= topValue.getTemperature()) {
- return topValue.getColor();
- }
-
- int index = binarySearch(temperature);
- if (index >= 0) {
- return sTemperatureColorValues[index].getColor();
- }
-
- index = -index - 1; // move to the insertion point
-
- TemperatureColorValue startValue = sTemperatureColorValues[index - 1];
- TemperatureColorValue endValue = sTemperatureColorValues[index];
- float fraction = (temperature - startValue.getTemperature()) / (endValue.getTemperature()
- - startValue.getTemperature());
- return lerpColor(fraction, startValue.getColor(), endValue.getColor());
- }
-
- int lerpColor(float fraction, int startColor, int endColor) {
- float[] startHsv = mTempHsv1;
- Color.colorToHSV(startColor, startHsv);
- float[] endHsv = mTempHsv2;
- Color.colorToHSV(endColor, endHsv);
-
- // If a target color is white/gray, it should use the same hue as the other target
- if (startHsv[1] == 0) {
- startHsv[0] = endHsv[0];
- }
- if (endHsv[1] == 0) {
- endHsv[0] = startHsv[0];
- }
-
- float[] outColor = mTempHsv3;
- outColor[0] = hueLerp(fraction, startHsv[0], endHsv[0]);
- outColor[1] = lerp(fraction, startHsv[1], endHsv[1]);
- outColor[2] = lerp(fraction, startHsv[2], endHsv[2]);
-
- return Color.HSVToColor(outColor);
- }
-
- private float hueLerp(float fraction, float start, float end) {
- // If in flat part of curve, no interpolation necessary
- if (start == end) {
- return start;
- }
-
- // If the hues are more than 180 degrees apart, go the other way around the color wheel
- // by moving the smaller value above 360
- if (Math.abs(start - end) > 180f) {
- if (start < end) {
- start += 360f;
- } else {
- end += 360f;
- }
- }
- // Lerp and ensure the final output is within [0, 360)
- return lerp(fraction, start, end) % 360f;
-
- }
-
- private float lerp(float fraction, float start, float end) {
- // If in flat part of curve, no interpolation necessary
- if (start == end) {
- return start;
- }
-
- // If outside bounds, use boundary value
- if (fraction >= 1) {
- return end;
- }
- if (fraction <= 0) {
- return start;
- }
-
- return (end - start) * fraction + start;
- }
-
- private int binarySearch(float temperature) {
- int low = 0;
- int high = sTemperatureColorValues.length;
-
- while (low <= high) {
- int mid = (low + high) >>> 1;
- float midVal = sTemperatureColorValues[mid].getTemperature();
-
- if (midVal < temperature) {
- low = mid + 1; // Neither val is NaN, thisVal is smaller
- } else if (midVal > temperature) {
- high = mid - 1; // Neither val is NaN, thisVal is larger
- } else {
- int midBits = Float.floatToIntBits(midVal);
- int keyBits = Float.floatToIntBits(temperature);
- if (midBits == keyBits) { // Values are equal
- return mid; // Key found
- } else if (midBits < keyBits) { // (-0.0, 0.0) or (!NaN, NaN)
- low = mid + 1;
- } else { /* (0.0, -0.0) or (NaN, !NaN)*/
- high = mid - 1;
- }
- }
- }
- return -(low + 1); // key not found.
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextAnimator.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextAnimator.java
deleted file mode 100644
index 74d9704..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextAnimator.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.hvac;
-
-import static com.android.systemui.car.hvac.AnimatedTemperatureView.isHorizontal;
-import static com.android.systemui.car.hvac.AnimatedTemperatureView.isLeft;
-
-import android.annotation.NonNull;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.view.animation.AnimationSet;
-import android.view.animation.DecelerateInterpolator;
-import android.view.animation.RotateAnimation;
-import android.view.animation.TranslateAnimation;
-import android.widget.TextSwitcher;
-
-/**
- * Controls animating TemperatureView's text
- */
-class TemperatureTextAnimator {
-
- private static final DecelerateInterpolator DECELERATE_INTERPOLATOR =
- new DecelerateInterpolator();
- private static final AccelerateDecelerateInterpolator ACCELERATE_DECELERATE_INTERPOLATOR =
- new AccelerateDecelerateInterpolator();
-
- private static final int ROTATION_DEGREES = 15;
- private static final int DURATION_MILLIS = 200;
-
- private AnimatedTemperatureView mParent;
- private final TextSwitcher mTextSwitcher;
- private final String mTempFormat;
- private final int mPivotOffset;
- private final CharSequence mMinText;
- private final CharSequence mMaxText;
-
- private Animation mTextInAnimationUp;
- private Animation mTextOutAnimationUp;
- private Animation mTextInAnimationDown;
- private Animation mTextOutAnimationDown;
- private Animation mTextFadeInAnimation;
- private Animation mTextFadeOutAnimation;
-
- private float mLastTemp = Float.NaN;
-
- TemperatureTextAnimator(AnimatedTemperatureView parent, TextSwitcher textSwitcher,
- String tempFormat, int pivotOffset,
- CharSequence minText, CharSequence maxText) {
- mParent = parent;
- mTextSwitcher = textSwitcher;
- mTempFormat = tempFormat;
- mPivotOffset = pivotOffset;
- mMinText = minText;
- mMaxText = maxText;
-
- mParent.addOnLayoutChangeListener(
- (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
- setupAnimations(mParent.getGravity()));
- }
-
- void setTemp(float temp) {
- if (Float.isNaN(temp)) {
- mTextSwitcher.setInAnimation(mTextFadeInAnimation);
- mTextSwitcher.setOutAnimation(mTextFadeOutAnimation);
- mTextSwitcher.setText("--");
- mLastTemp = temp;
- return;
- }
- boolean isMinValue = mParent.isMinValue(temp);
- boolean isMaxValue = mParent.isMaxValue(temp);
- if (Float.isNaN(mLastTemp)) {
- mTextSwitcher.setInAnimation(mTextFadeInAnimation);
- mTextSwitcher.setOutAnimation(mTextFadeOutAnimation);
- } else if (!isMinValue && (isMaxValue || temp > mLastTemp)) {
- mTextSwitcher.setInAnimation(mTextInAnimationUp);
- mTextSwitcher.setOutAnimation(mTextOutAnimationUp);
- } else {
- mTextSwitcher.setInAnimation(mTextInAnimationDown);
- mTextSwitcher.setOutAnimation(mTextOutAnimationDown);
- }
- CharSequence text;
- if (isMinValue) {
- text = mMinText;
- } else if (isMaxValue) {
- text = mMaxText;
- } else {
- text = String.format(mTempFormat, temp);
- }
- mTextSwitcher.setText(text);
- mLastTemp = temp;
- }
-
- private void setupAnimations(int gravity) {
- mTextFadeInAnimation = createFadeAnimation(true);
- mTextFadeOutAnimation = createFadeAnimation(false);
- if (!isHorizontal(gravity)) {
- mTextInAnimationUp = createTranslateFadeAnimation(true, true);
- mTextOutAnimationUp = createTranslateFadeAnimation(false, true);
- mTextInAnimationDown = createTranslateFadeAnimation(true, false);
- mTextOutAnimationDown = createTranslateFadeAnimation(false, false);
- } else {
- boolean isLeft = isLeft(gravity, mTextSwitcher.getLayoutDirection());
- mTextInAnimationUp = createRotateFadeAnimation(true, isLeft, true);
- mTextOutAnimationUp = createRotateFadeAnimation(false, isLeft, true);
- mTextInAnimationDown = createRotateFadeAnimation(true, isLeft, false);
- mTextOutAnimationDown = createRotateFadeAnimation(false, isLeft, false);
- }
- }
-
- @NonNull
- private Animation createFadeAnimation(boolean in) {
- AnimationSet set = new AnimationSet(true);
- AlphaAnimation alphaAnimation = new AlphaAnimation(in ? 0 : 1, in ? 1 : 0);
- alphaAnimation.setDuration(DURATION_MILLIS);
- set.addAnimation(new RotateAnimation(0, 0)); // Undo any previous rotation
- set.addAnimation(alphaAnimation);
- return set;
- }
-
- @NonNull
- private Animation createTranslateFadeAnimation(boolean in, boolean up) {
- AnimationSet set = new AnimationSet(true);
- set.setInterpolator(ACCELERATE_DECELERATE_INTERPOLATOR);
- set.setDuration(DURATION_MILLIS);
- int fromYDelta = in ? (up ? 1 : -1) : 0;
- int toYDelta = in ? 0 : (up ? -1 : 1);
- set.addAnimation(
- new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0,
- Animation.RELATIVE_TO_SELF, fromYDelta, Animation.RELATIVE_TO_SELF,
- toYDelta));
- set.addAnimation(new AlphaAnimation(in ? 0 : 1, in ? 1 : 0));
- return set;
- }
-
- @NonNull
- private Animation createRotateFadeAnimation(boolean in, boolean isLeft, boolean up) {
- AnimationSet set = new AnimationSet(true);
- set.setInterpolator(DECELERATE_INTERPOLATOR);
- set.setDuration(DURATION_MILLIS);
-
- float degrees = isLeft == up ? -ROTATION_DEGREES : ROTATION_DEGREES;
- int pivotX = isLeft ? -mPivotOffset : mParent.getWidth() + mPivotOffset;
- set.addAnimation(
- new RotateAnimation(in ? -degrees : 0f, in ? 0f : degrees, Animation.ABSOLUTE,
- pivotX, Animation.ABSOLUTE, 0f));
- set.addAnimation(new AlphaAnimation(in ? 0 : 1, in ? 1 : 0));
- return set;
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextView.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextView.java
deleted file mode 100644
index 90df15c..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextView.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.hvac;
-
-import static com.android.systemui.car.hvac.HvacController.convertToFahrenheit;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.widget.TextView;
-
-import com.android.systemui.R;
-
-/**
- * Simple text display of HVAC properties, It is designed to show temperature and is configured in
- * the XML.
- * XML properties:
- * hvacAreaId - Example: VehicleAreaSeat.SEAT_ROW_1_LEFT (1)
- */
-public class TemperatureTextView extends TextView implements TemperatureView {
-
- private final int mAreaId;
- private final String mTempFormat;
- private HvacController mHvacController;
- private boolean mDisplayFahrenheit = false;
-
- public TemperatureTextView(Context context, AttributeSet attrs) {
- super(context, attrs);
- TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TemperatureView);
- mAreaId = typedArray.getInt(R.styleable.TemperatureView_hvacAreaId, -1);
- mTempFormat = getResources().getString(R.string.hvac_temperature_format);
- }
-
- @Override
- public void setHvacController(HvacController controller) {
- mHvacController = controller;
- }
-
- /**
- * Formats the float for display
- *
- * @param temp - The current temp or NaN
- */
- @Override
- public void setTemp(float temp) {
- if (Float.isNaN(temp)) {
- setText("--");
- return;
- }
- if (mDisplayFahrenheit) {
- temp = convertToFahrenheit(temp);
- }
- setText(String.format(mTempFormat, temp));
- }
-
- @Override
- public void setDisplayInFahrenheit(boolean displayFahrenheit) {
- mDisplayFahrenheit = displayFahrenheit;
- }
-
- /**
- * @return hvac AreaId - Example: VehicleAreaSeat.SEAT_ROW_1_LEFT (1)
- */
- @Override
- public int getAreaId() {
- return mAreaId;
- }
-}
-
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureView.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureView.java
deleted file mode 100644
index 6edf254..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureView.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.hvac;
-
-/**
- * Interface for Views that display temperature HVAC properties.
- */
-public interface TemperatureView {
-
- /**
- * Sets the {@link HvacController} to handle changes to HVAC properties. The View is only
- * responsible for the UI to display temperature. It should not contain logic that makes direct
- * changes to HVAC properties and instead use this {@link HvacController}.
- */
- void setHvacController(HvacController controller);
-
- /**
- * Formats the float for display
- *
- * @param temp - The current temp in Celsius or NaN
- */
- void setTemp(float temp);
-
- /**
- * Render the displayed temperature in Fahrenheit
- *
- * @param displayFahrenheit - True if temperature should be displayed in Fahrenheit
- */
- void setDisplayInFahrenheit(boolean displayFahrenheit);
-
- /**
- * @return hvac AreaId - Example: VehicleAreaSeat.SEAT_ROW_1_LEFT (1)
- */
- int getAreaId();
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java
deleted file mode 100644
index c190ae54..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.keyguard;
-
-import android.car.Car;
-import android.car.user.CarUserManager;
-import android.os.Bundle;
-import android.os.Handler;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewRootImpl;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardViewController;
-import com.android.keyguard.ViewMediatorCallback;
-import com.android.systemui.R;
-import com.android.systemui.car.CarServiceProvider;
-import com.android.systemui.car.navigationbar.CarNavigationBarController;
-import com.android.systemui.car.window.OverlayViewController;
-import com.android.systemui.car.window.OverlayViewGlobalStateController;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.statusbar.phone.BiometricUnlockController;
-import com.android.systemui.statusbar.phone.KeyguardBouncer;
-import com.android.systemui.statusbar.phone.KeyguardBouncer.Factory;
-import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.phone.NotificationPanelViewController;
-import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-
-import javax.inject.Inject;
-
-import dagger.Lazy;
-
-/**
- * Automotive implementation of the {@link KeyguardViewController}. It controls the Keyguard View
- * that is mounted to the SystemUIOverlayWindow.
- */
-@SysUISingleton
-public class CarKeyguardViewController extends OverlayViewController implements
- KeyguardViewController {
- private static final String TAG = "CarKeyguardViewController";
- private static final boolean DEBUG = true;
-
- private final Handler mHandler;
- private final CarServiceProvider mCarServiceProvider;
- private final KeyguardStateController mKeyguardStateController;
- private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
- private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
- private final ViewMediatorCallback mViewMediatorCallback;
- private final CarNavigationBarController mCarNavigationBarController;
- private final Factory mKeyguardBouncerFactory;
- // Needed to instantiate mBouncer.
- private final KeyguardBouncer.BouncerExpansionCallback
- mExpansionCallback = new KeyguardBouncer.BouncerExpansionCallback() {
- @Override
- public void onFullyShown() {
- }
-
- @Override
- public void onStartingToHide() {
- }
-
- @Override
- public void onStartingToShow() {
- }
-
- @Override
- public void onFullyHidden() {
- }
- };
- private final CarUserManager.UserLifecycleListener mUserLifecycleListener = (e) -> {
- if (e.getEventType() == CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING) {
- revealKeyguardIfBouncerPrepared();
- }
- };
-
- private KeyguardBouncer mBouncer;
- private OnKeyguardCancelClickedListener mKeyguardCancelClickedListener;
- private boolean mShowing;
- private boolean mIsOccluded;
-
- @Inject
- public CarKeyguardViewController(
- @Main Handler mainHandler,
- CarServiceProvider carServiceProvider,
- OverlayViewGlobalStateController overlayViewGlobalStateController,
- KeyguardStateController keyguardStateController,
- KeyguardUpdateMonitor keyguardUpdateMonitor,
- Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
- ViewMediatorCallback viewMediatorCallback,
- CarNavigationBarController carNavigationBarController,
- KeyguardBouncer.Factory keyguardBouncerFactory) {
-
- super(R.id.keyguard_stub, overlayViewGlobalStateController);
-
- mHandler = mainHandler;
- mCarServiceProvider = carServiceProvider;
- mKeyguardStateController = keyguardStateController;
- mKeyguardUpdateMonitor = keyguardUpdateMonitor;
- mBiometricUnlockControllerLazy = biometricUnlockControllerLazy;
- mViewMediatorCallback = viewMediatorCallback;
- mCarNavigationBarController = carNavigationBarController;
- mKeyguardBouncerFactory = keyguardBouncerFactory;
-
- registerUserSwitchedListener();
- }
-
- @Override
- protected boolean shouldShowNavigationBarInsets() {
- return true;
- }
-
- @Override
- public void onFinishInflate() {
- mBouncer = mKeyguardBouncerFactory
- .create(getLayout().findViewById(R.id.keyguard_container), mExpansionCallback);
- mBiometricUnlockControllerLazy.get().setKeyguardViewController(this);
- }
-
- @Override
- public void notifyKeyguardAuthenticated(boolean strongAuth) {
- if (mBouncer != null) {
- mBouncer.notifyKeyguardAuthenticated(strongAuth);
- }
- }
-
- @Override
- public void showBouncer(boolean scrimmed) {
- if (mShowing && !mBouncer.isShowing()) {
- mBouncer.show(/* resetSecuritySelection= */ false);
- }
- }
-
- @Override
- public void show(Bundle options) {
- if (mShowing) return;
-
- mShowing = true;
- mKeyguardStateController.notifyKeyguardState(mShowing, /* occluded= */ false);
- mCarNavigationBarController.showAllKeyguardButtons(/* isSetUp= */ true);
- start();
- reset(/* hideBouncerWhenShowing= */ false);
- notifyKeyguardUpdateMonitor();
- }
-
- @Override
- public void hide(long startTime, long fadeoutDuration) {
- if (!mShowing) return;
-
- mViewMediatorCallback.readyForKeyguardDone();
- mShowing = false;
- mKeyguardStateController.notifyKeyguardState(mShowing, /* occluded= */ false);
- mBouncer.hide(/* destroyView= */ true);
- mCarNavigationBarController.hideAllKeyguardButtons(/* isSetUp= */ true);
- stop();
- mKeyguardStateController.notifyKeyguardDoneFading();
- mHandler.post(mViewMediatorCallback::keyguardGone);
- notifyKeyguardUpdateMonitor();
- }
-
- @Override
- public void reset(boolean hideBouncerWhenShowing) {
- if (mShowing) {
- if (mBouncer != null) {
- if (!mBouncer.isSecure()) {
- dismissAndCollapse();
- }
- mBouncer.show(/* resetSecuritySelection= */ true);
- }
- mKeyguardUpdateMonitor.sendKeyguardReset();
- notifyKeyguardUpdateMonitor();
- } else {
- // This is necessary in order to address an inconsistency between the keyguard service
- // and the keyguard views.
- // TODO: Investigate the source of the inconsistency.
- show(/* options= */ null);
- }
- }
-
- @Override
- public void onFinishedGoingToSleep() {
- if (mBouncer != null) {
- mBouncer.onScreenTurnedOff();
- }
- }
-
- @Override
- public void setOccluded(boolean occluded, boolean animate) {
- mIsOccluded = occluded;
- getOverlayViewGlobalStateController().setOccluded(occluded);
- if (!occluded) {
- reset(/* hideBouncerWhenShowing= */ false);
- }
- }
-
- @Override
- public void onCancelClicked() {
- if (mBouncer == null) return;
-
- getOverlayViewGlobalStateController().setWindowNeedsInput(/* needsInput= */ false);
-
- mBouncer.hide(/* destroyView= */ true);
- mKeyguardCancelClickedListener.onCancelClicked();
- }
-
- @Override
- public boolean isShowing() {
- return mShowing;
- }
-
- @Override
- public void dismissAndCollapse() {
- // If dismissing and collapsing Keyguard is requested (e.g. by a Keyguard-dismissing
- // Activity) while Keyguard is occluded, unocclude Keyguard so the user can authenticate to
- // dismiss Keyguard.
- if (mIsOccluded) {
- setOccluded(/* occluded= */ false, /* animate= */ false);
- }
- if (!mBouncer.isSecure()) {
- hide(/* startTime= */ 0, /* fadeoutDuration= */ 0);
- }
- }
-
- @Override
- public void startPreHideAnimation(Runnable finishRunnable) {
- if (mBouncer == null) return;
-
- mBouncer.startPreHideAnimation(finishRunnable);
- }
-
- @Override
- public void setNeedsInput(boolean needsInput) {
- getOverlayViewGlobalStateController().setWindowNeedsInput(needsInput);
- }
-
- /**
- * Add listener for keyguard cancel clicked.
- */
- public void registerOnKeyguardCancelClickedListener(
- OnKeyguardCancelClickedListener keyguardCancelClickedListener) {
- mKeyguardCancelClickedListener = keyguardCancelClickedListener;
- }
-
- /**
- * Remove listener for keyguard cancel clicked.
- */
- public void unregisterOnKeyguardCancelClickedListener(
- OnKeyguardCancelClickedListener keyguardCancelClickedListener) {
- mKeyguardCancelClickedListener = null;
- }
-
- @Override
- public ViewRootImpl getViewRootImpl() {
- return ((View) getLayout().getParent()).getViewRootImpl();
- }
-
- @Override
- public boolean isBouncerShowing() {
- return mBouncer != null && mBouncer.isShowing();
- }
-
- @Override
- public boolean bouncerIsOrWillBeShowing() {
- return mBouncer != null && (mBouncer.isShowing() || mBouncer.inTransit());
- }
-
- @Override
- public void keyguardGoingAway() {
- // no-op
- }
-
- @Override
- public void setKeyguardGoingAwayState(boolean isKeyguardGoingAway) {
- // no-op
- }
-
- @Override
- public void onStartedGoingToSleep() {
- // no-op
- }
-
- @Override
- public void onStartedWakingUp() {
- // no-op
- }
-
- @Override
- public void onScreenTurningOn() {
- // no-op
- }
-
- @Override
- public void onScreenTurnedOn() {
- // no-op
- }
-
- @Override
- public boolean shouldDisableWindowAnimationsForUnlock() {
- return false;
- }
-
- @Override
- public boolean isGoingToNotificationShade() {
- return false;
- }
-
- @Override
- public boolean isUnlockWithWallpaper() {
- return false;
- }
-
- @Override
- public boolean shouldSubtleWindowAnimationsForUnlock() {
- return false;
- }
-
- @Override
- public void registerStatusBar(StatusBar statusBar, ViewGroup container,
- NotificationPanelViewController notificationPanelViewController,
- BiometricUnlockController biometricUnlockController,
- ViewGroup lockIconContainer,
- View notificationContainer, KeyguardBypassController bypassController) {
- // no-op
- }
-
- /**
- * Hides Keyguard so that the transitioning Bouncer can be hidden until it is prepared. To be
- * called by {@link com.android.systemui.car.userswitcher.FullscreenUserSwitcherViewMediator}
- * when a new user is selected.
- */
- public void hideKeyguardToPrepareBouncer() {
- getLayout().setVisibility(View.INVISIBLE);
- }
-
- @VisibleForTesting
- void setKeyguardBouncer(KeyguardBouncer keyguardBouncer) {
- mBouncer = keyguardBouncer;
- }
-
- private void revealKeyguardIfBouncerPrepared() {
- int reattemptDelayMillis = 50;
- Runnable revealKeyguard = () -> {
- if (mBouncer == null) {
- if (DEBUG) {
- Log.d(TAG, "revealKeyguardIfBouncerPrepared: revealKeyguard request is ignored "
- + "since the Bouncer has not been initialized yet.");
- }
- return;
- }
- if (!mBouncer.inTransit() || !mBouncer.isSecure()) {
- getLayout().setVisibility(View.VISIBLE);
- } else {
- if (DEBUG) {
- Log.d(TAG, "revealKeyguardIfBouncerPrepared: Bouncer is not prepared "
- + "yet so reattempting after " + reattemptDelayMillis + "ms.");
- }
- mHandler.postDelayed(this::revealKeyguardIfBouncerPrepared, reattemptDelayMillis);
- }
- };
- mHandler.post(revealKeyguard);
- }
-
- private void notifyKeyguardUpdateMonitor() {
- mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(mShowing);
- if (mBouncer != null) {
- mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(isBouncerShowing());
- }
- }
-
- private void registerUserSwitchedListener() {
- mCarServiceProvider.addListener(car -> {
- CarUserManager userManager = (CarUserManager) car.getCarManager(Car.CAR_USER_SERVICE);
- userManager.addListener(Runnable::run, mUserLifecycleListener);
- });
- }
-
- /**
- * Defines a callback for keyguard cancel button clicked listeners.
- */
- public interface OnKeyguardCancelClickedListener {
- /**
- * Called when keyguard cancel button is clicked.
- */
- void onCancelClicked();
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewMediator.java
deleted file mode 100644
index 155b73e..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewMediator.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.keyguard;
-
-import com.android.systemui.car.userswitcher.FullScreenUserSwitcherViewController;
-import com.android.systemui.car.window.OverlayViewMediator;
-import com.android.systemui.dagger.SysUISingleton;
-
-import javax.inject.Inject;
-
-/**
- * Manages events originating from the Keyguard service that cause Keyguard or other OverlayWindow
- * Components to appear or disappear.
- */
-@SysUISingleton
-public class CarKeyguardViewMediator implements OverlayViewMediator {
-
- private final CarKeyguardViewController mCarKeyguardViewController;
- private final FullScreenUserSwitcherViewController mFullScreenUserSwitcherViewController;
-
- @Inject
- public CarKeyguardViewMediator(
- CarKeyguardViewController carKeyguardViewController,
- FullScreenUserSwitcherViewController fullScreenUserSwitcherViewController
- ) {
- mCarKeyguardViewController = carKeyguardViewController;
- mFullScreenUserSwitcherViewController = fullScreenUserSwitcherViewController;
- }
-
- @Override
- public void registerListeners() {
- mCarKeyguardViewController.registerOnKeyguardCancelClickedListener(
- mFullScreenUserSwitcherViewController::start);
- }
-
- @Override
- public void setupOverlayContentViewControllers() {
- // no-op
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/AssitantButton.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/AssitantButton.java
deleted file mode 100644
index ede4696..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/AssitantButton.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.navigationbar;
-
-import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_ASSIST_GESTURE;
-
-import android.app.role.RoleManager;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.util.Log;
-
-import com.android.internal.app.AssistUtils;
-import com.android.internal.app.IVoiceInteractionSessionShowCallback;
-
-/**
- * AssitantButton is a ui component that will trigger the Voice Interaction Service.
- */
-public class AssitantButton extends CarNavigationButton {
- private static final String TAG = "AssistantButton";
- private final AssistUtils mAssistUtils;
- private IVoiceInteractionSessionShowCallback mShowCallback =
- new IVoiceInteractionSessionShowCallback.Stub() {
- @Override
- public void onFailed() {
- Log.w(TAG, "Failed to show VoiceInteractionSession");
- }
-
- @Override
- public void onShown() {
- Log.d(TAG, "IVoiceInteractionSessionShowCallback onShown()");
- }
- };
-
- public AssitantButton(Context context, AttributeSet attrs) {
- super(context, attrs);
- mAssistUtils = new AssistUtils(context);
- setOnClickListener(v -> showAssistant());
- }
-
- private void showAssistant() {
- final Bundle args = new Bundle();
- mAssistUtils.showSessionForActiveService(args,
- SHOW_SOURCE_ASSIST_GESTURE, mShowCallback, /*activityToken=*/ null);
- }
-
- @Override
- protected void setUpIntents(TypedArray typedArray) {
- // left blank because for the assistant button Intent will not be passed from the layout.
- }
-
- @Override
- protected String getRoleName() {
- return RoleManager.ROLE_ASSISTANT;
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonRoleHolderController.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonRoleHolderController.java
deleted file mode 100644
index f8cd20f..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonRoleHolderController.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.navigationbar;
-
-import android.annotation.Nullable;
-import android.app.role.OnRoleHoldersChangedListener;
-import android.app.role.RoleManager;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
-import android.os.UserHandle;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.dagger.SysUISingleton;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-/**
- * Some CarNavigationButtons can be associated to a {@link RoleManager} role. When they are, it is
- * possible to have them display the icon of the default application (role holder) for the given
- * role.
- *
- * This class monitors the current role holders for each role type and updates the button icon for
- * this buttons with have this feature enabled.
- */
-@SysUISingleton
-public class ButtonRoleHolderController {
- private static final String TAG = "ButtonRoleHolderController";
-
- private final Context mContext;
- private final PackageManager mPackageManager;
- private final RoleManager mRoleManager;
- private final CarDeviceProvisionedController mDeviceController;
- private final Map<String, CarNavigationButton> mButtonMap = new HashMap<>();
- private final OnRoleHoldersChangedListener mListener = this::onRoleChanged;
- private boolean mRegistered;
-
- @Inject
- public ButtonRoleHolderController(Context context, PackageManager packageManager,
- RoleManager roleManager, CarDeviceProvisionedController deviceController) {
- mContext = context;
- mPackageManager = packageManager;
- mRoleManager = roleManager;
- mDeviceController = deviceController;
- }
-
- /**
- * Iterate through a view looking for CarNavigationButton and add it to this controller if it
- * opted to be associated with a {@link RoleManager} role type.
- *
- * @param v the View that may contain CarFacetButtons
- */
- void addAllButtonsWithRoleName(View v) {
- if (v instanceof CarNavigationButton) {
- CarNavigationButton button = (CarNavigationButton) v;
- String roleName = button.getRoleName();
- if (roleName != null && button.isDefaultAppIconForRoleEnabled()) {
- addButtonWithRoleName(button, roleName);
- }
- } else if (v instanceof ViewGroup) {
- ViewGroup viewGroup = (ViewGroup) v;
- for (int i = 0; i < viewGroup.getChildCount(); i++) {
- addAllButtonsWithRoleName(viewGroup.getChildAt(i));
- }
- }
- }
-
- private void addButtonWithRoleName(CarNavigationButton button, String roleName) {
- mButtonMap.put(roleName, button);
- updateIcon(roleName);
- if (!mRegistered) {
- mRoleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(),
- mListener, UserHandle.ALL);
- mRegistered = true;
- }
- }
-
- void removeAll() {
- mButtonMap.clear();
- if (mRegistered) {
- mRoleManager.removeOnRoleHoldersChangedListenerAsUser(mListener, UserHandle.ALL);
- mRegistered = false;
- }
- }
-
- @VisibleForTesting
- void onRoleChanged(String roleName, UserHandle user) {
- if (RoleManager.ROLE_ASSISTANT.equals(roleName)
- && user.getIdentifier() == mDeviceController.getCurrentUser()) {
- updateIcon(roleName);
- }
- }
-
- private void updateIcon(String roleName) {
- CarNavigationButton button = mButtonMap.get(roleName);
- if (button == null) {
- return;
- }
- List<String> holders = mRoleManager.getRoleHoldersAsUser(button.getRoleName(),
- UserHandle.of(mDeviceController.getCurrentUser()));
- if (holders == null || holders.isEmpty()) {
- button.setAppIcon(null);
- } else {
- button.setAppIcon(loadIcon(holders.get(0)));
- }
- }
-
- @Nullable
- private Drawable loadIcon(String packageName) {
- try {
- ApplicationInfo appInfo = mPackageManager.getApplicationInfo(packageName,
- PackageManager.MATCH_ANY_USER);
- return appInfo.loadIcon(mPackageManager);
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(ButtonRoleHolderController.TAG, "Package not found: " + packageName, e);
- return null;
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateController.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateController.java
deleted file mode 100644
index 2dc4756..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateController.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.navigationbar;
-
-import android.app.ActivityTaskManager.RootTaskInfo;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.view.Display;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.systemui.dagger.SysUISingleton;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.inject.Inject;
-
-/**
- * CarNavigationButtons can optionally have selection state that toggles certain visual indications
- * based on whether the active application on screen is associated with it. This is basically a
- * similar concept to a radio button group.
- *
- * This class controls the selection state of CarNavigationButtons that have opted in to have such
- * selection state-dependent visual indications.
- */
-@SysUISingleton
-public class ButtonSelectionStateController {
-
- private final Set<CarNavigationButton> mRegisteredViews = new HashSet<>();
-
- protected ButtonMap mButtonsByCategory = new ButtonMap();
- protected ButtonMap mButtonsByPackage = new ButtonMap();
- protected ButtonMap mButtonsByComponentName = new ButtonMap();
- protected HashSet<CarNavigationButton> mSelectedButtons;
- protected Context mContext;
-
- @Inject
- public ButtonSelectionStateController(Context context) {
- mContext = context;
- mSelectedButtons = new HashSet<>();
- }
-
- /**
- * Iterate through a view looking for CarNavigationButton and add it to the controller if it
- * opted in to be highlighted when the active application is associated with it.
- *
- * @param v the View that may contain CarFacetButtons
- */
- protected void addAllButtonsWithSelectionState(View v) {
- if (v instanceof CarNavigationButton) {
- if (((CarNavigationButton) v).hasSelectionState()) {
- addButtonWithSelectionState((CarNavigationButton) v);
- }
- } else if (v instanceof ViewGroup) {
- ViewGroup viewGroup = (ViewGroup) v;
- for (int i = 0; i < viewGroup.getChildCount(); i++) {
- addAllButtonsWithSelectionState(viewGroup.getChildAt(i));
- }
- }
- }
-
- /** Removes all buttons from the button maps. */
- protected void removeAll() {
- mButtonsByCategory.clear();
- mButtonsByPackage.clear();
- mButtonsByComponentName.clear();
- mSelectedButtons.clear();
- mRegisteredViews.clear();
- }
-
- /**
- * This will unselect the currently selected CarNavigationButton and determine which one should
- * be selected next. It does this by reading the properties on the CarNavigationButton and
- * seeing if they are a match with the supplied StackInfo list.
- * The order of selection detection is ComponentName, PackageName then Category
- * They will then be compared with the supplied StackInfo list.
- * The StackInfo is expected to be supplied in order of recency and StackInfo will only be used
- * for consideration if it has the same displayId as the CarNavigationButton.
- *
- * @param taskInfoList of the currently running application
- * @param validDisplay index of the valid display
- */
-
- protected void taskChanged(List<RootTaskInfo> taskInfoList, int validDisplay) {
- RootTaskInfo validTaskInfo = null;
- for (RootTaskInfo taskInfo : taskInfoList) {
- // Find the first stack info with a topActivity in the primary display.
- // TODO: We assume that CarFacetButton will launch an app only in the primary display.
- // We need to extend the functionality to handle the multiple display properly.
- if (taskInfo.topActivity != null && taskInfo.displayId == validDisplay) {
- validTaskInfo = taskInfo;
- break;
- }
- }
-
- if (validTaskInfo == null) {
- // No stack was found that was on the same display as the buttons thus return
- return;
- }
- int displayId = validTaskInfo.displayId;
-
- mSelectedButtons.forEach(carNavigationButton -> {
- if (carNavigationButton.getDisplayId() == displayId) {
- carNavigationButton.setSelected(false);
- }
- });
- mSelectedButtons.clear();
-
- HashSet<CarNavigationButton> selectedButtons = findSelectedButtons(validTaskInfo);
-
- if (selectedButtons != null) {
- selectedButtons.forEach(carNavigationButton -> {
- if (carNavigationButton.getDisplayId() == displayId) {
- carNavigationButton.setSelected(true);
- mSelectedButtons.add(carNavigationButton);
- }
- });
- }
- }
-
- /**
- * Defaults to Display.DEFAULT_DISPLAY when no parameter is provided for the validDisplay.
- *
- * @param taskInfoList
- */
- protected void taskChanged(List<RootTaskInfo> taskInfoList) {
- taskChanged(taskInfoList, Display.DEFAULT_DISPLAY);
- }
-
- /**
- * Add navigation button to this controller if it uses selection state.
- */
- private void addButtonWithSelectionState(CarNavigationButton carNavigationButton) {
- if (mRegisteredViews.contains(carNavigationButton)) {
- return;
- }
- String[] categories = carNavigationButton.getCategories();
- for (int i = 0; i < categories.length; i++) {
- mButtonsByCategory.add(categories[i], carNavigationButton);
- }
-
- String[] packages = carNavigationButton.getPackages();
- for (int i = 0; i < packages.length; i++) {
- mButtonsByPackage.add(packages[i], carNavigationButton);
- }
- String[] componentNames = carNavigationButton.getComponentName();
- for (int i = 0; i < componentNames.length; i++) {
- mButtonsByComponentName.add(componentNames[i], carNavigationButton);
- }
-
- mRegisteredViews.add(carNavigationButton);
- }
-
- private HashSet<CarNavigationButton> findSelectedButtons(RootTaskInfo validTaskInfo) {
- String packageName = validTaskInfo.topActivity.getPackageName();
-
- HashSet<CarNavigationButton> selectedButtons =
- findButtonsByComponentName(validTaskInfo.topActivity);
- if (selectedButtons == null) {
- selectedButtons = mButtonsByPackage.get(packageName);
- }
- if (selectedButtons == null) {
- String category = getPackageCategory(packageName);
- if (category != null) {
- selectedButtons = mButtonsByCategory.get(category);
- }
- }
-
- return selectedButtons;
- }
-
- private HashSet<CarNavigationButton> findButtonsByComponentName(
- ComponentName componentName) {
- HashSet<CarNavigationButton> buttons =
- mButtonsByComponentName.get(componentName.flattenToShortString());
- return (buttons != null) ? buttons :
- mButtonsByComponentName.get(componentName.flattenToString());
- }
-
- private String getPackageCategory(String packageName) {
- PackageManager pm = mContext.getPackageManager();
- Set<String> supportedCategories = mButtonsByCategory.keySet();
- for (String category : supportedCategories) {
- Intent intent = new Intent();
- intent.setPackage(packageName);
- intent.setAction(Intent.ACTION_MAIN);
- intent.addCategory(category);
- List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);
- if (list.size() > 0) {
- // Cache this package name into ButtonsByPackage map, so we won't have to query
- // all categories next time this package name shows up.
- mButtonsByPackage.put(packageName, mButtonsByCategory.get(category));
- return category;
- }
- }
- return null;
- }
-
- // simple multi-map
- private static class ButtonMap extends HashMap<String, HashSet<CarNavigationButton>> {
-
- public boolean add(String key, CarNavigationButton value) {
- if (containsKey(key)) {
- return get(key).add(value);
- }
- HashSet<CarNavigationButton> set = new HashSet<>();
- set.add(value);
- put(key, set);
- return true;
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateListener.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateListener.java
deleted file mode 100644
index f74bd4f..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateListener.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.navigationbar;
-
-import android.app.ActivityTaskManager;
-import android.util.Log;
-
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.shared.system.TaskStackChangeListener;
-
-import javax.inject.Inject;
-
-/**
- * An implementation of TaskStackChangeListener, that listens for changes in the system
- * task stack and notifies the navigation bar.
- */
-@SysUISingleton
-class ButtonSelectionStateListener extends TaskStackChangeListener {
- private static final String TAG = ButtonSelectionStateListener.class.getSimpleName();
-
- private final ButtonSelectionStateController mButtonSelectionStateController;
-
- @Inject
- ButtonSelectionStateListener(ButtonSelectionStateController carNavigationButtonController) {
- mButtonSelectionStateController = carNavigationButtonController;
- }
-
- @Override
- public void onTaskStackChanged() {
- try {
- mButtonSelectionStateController.taskChanged(
- ActivityTaskManager.getService().getAllRootTaskInfos());
- } catch (Exception e) {
- Log.e(TAG, "Getting RootTaskInfo from activity task manager failed", e);
- }
- }
-
- @Override
- public void onTaskDisplayChanged(int taskId, int newDisplayId) {
- try {
- mButtonSelectionStateController.taskChanged(
- ActivityTaskManager.getService().getAllRootTaskInfos());
- } catch (Exception e) {
- Log.e(TAG, "Getting RootTaskInfo from activity task manager failed", e);
- }
-
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
deleted file mode 100644
index c7db3f6..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
+++ /dev/null
@@ -1,590 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.navigationbar;
-
-import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.ITYPE_STATUS_BAR;
-import static android.view.InsetsState.containsType;
-import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
-
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.inputmethodservice.InputMethodService;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.view.Display;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowInsetsController;
-import android.view.WindowManager;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.statusbar.RegisterStatusBarResult;
-import com.android.internal.view.AppearanceRegion;
-import com.android.systemui.SystemUI;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.car.CarDeviceProvisionedListener;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dagger.qualifiers.UiBackground;
-import com.android.systemui.plugins.DarkIconDispatcher;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.statusbar.AutoHideUiElement;
-import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.phone.AutoHideController;
-import com.android.systemui.statusbar.phone.BarTransitions;
-import com.android.systemui.statusbar.phone.LightBarController;
-import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy;
-import com.android.systemui.statusbar.phone.StatusBarIconController;
-import com.android.systemui.statusbar.phone.StatusBarSignalPolicy;
-import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.concurrent.Executor;
-
-import javax.inject.Inject;
-
-import dagger.Lazy;
-
-/** Navigation bars customized for the automotive use case. */
-public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks {
- private final Resources mResources;
- private final CarNavigationBarController mCarNavigationBarController;
- private final SysuiDarkIconDispatcher mStatusBarIconController;
- private final WindowManager mWindowManager;
- private final CarDeviceProvisionedController mCarDeviceProvisionedController;
- private final CommandQueue mCommandQueue;
- private final AutoHideController mAutoHideController;
- private final ButtonSelectionStateListener mButtonSelectionStateListener;
- private final Handler mMainHandler;
- private final Executor mUiBgExecutor;
- private final IStatusBarService mBarService;
- private final Lazy<KeyguardStateController> mKeyguardStateControllerLazy;
- private final Lazy<PhoneStatusBarPolicy> mIconPolicyLazy;
- private final Lazy<StatusBarIconController> mIconControllerLazy;
-
- private final int mDisplayId;
- private final SystemBarConfigs mSystemBarConfigs;
-
- private StatusBarSignalPolicy mSignalPolicy;
- private ActivityManagerWrapper mActivityManagerWrapper;
-
- // If the nav bar should be hidden when the soft keyboard is visible.
- private boolean mHideTopBarForKeyboard;
- private boolean mHideLeftBarForKeyboard;
- private boolean mHideRightBarForKeyboard;
- private boolean mHideBottomBarForKeyboard;
-
- private boolean mBottomNavBarVisible;
-
- // Nav bar views.
- private ViewGroup mTopNavigationBarWindow;
- private ViewGroup mBottomNavigationBarWindow;
- private ViewGroup mLeftNavigationBarWindow;
- private ViewGroup mRightNavigationBarWindow;
- private CarNavigationBarView mTopNavigationBarView;
- private CarNavigationBarView mBottomNavigationBarView;
- private CarNavigationBarView mLeftNavigationBarView;
- private CarNavigationBarView mRightNavigationBarView;
-
- // To be attached to the navigation bars such that they can close the notification panel if
- // it's open.
- private boolean mDeviceIsSetUpForUser = true;
- private boolean mIsUserSetupInProgress = false;
-
- private AppearanceRegion[] mAppearanceRegions = new AppearanceRegion[0];
- @BarTransitions.TransitionMode
- private int mStatusBarMode;
- @BarTransitions.TransitionMode
- private int mNavigationBarMode;
- private boolean mStatusBarTransientShown;
- private boolean mNavBarTransientShown;
-
- @Inject
- public CarNavigationBar(Context context,
- @Main Resources resources,
- CarNavigationBarController carNavigationBarController,
- // TODO(b/156052638): Should not need to inject LightBarController
- LightBarController lightBarController,
- DarkIconDispatcher darkIconDispatcher,
- WindowManager windowManager,
- CarDeviceProvisionedController deviceProvisionedController,
- CommandQueue commandQueue,
- AutoHideController autoHideController,
- ButtonSelectionStateListener buttonSelectionStateListener,
- @Main Handler mainHandler,
- @UiBackground Executor uiBgExecutor,
- IStatusBarService barService,
- Lazy<KeyguardStateController> keyguardStateControllerLazy,
- Lazy<PhoneStatusBarPolicy> iconPolicyLazy,
- Lazy<StatusBarIconController> iconControllerLazy,
- SystemBarConfigs systemBarConfigs
- ) {
- super(context);
- mResources = resources;
- mCarNavigationBarController = carNavigationBarController;
- mStatusBarIconController = (SysuiDarkIconDispatcher) darkIconDispatcher;
- mWindowManager = windowManager;
- mCarDeviceProvisionedController = deviceProvisionedController;
- mCommandQueue = commandQueue;
- mAutoHideController = autoHideController;
- mButtonSelectionStateListener = buttonSelectionStateListener;
- mMainHandler = mainHandler;
- mUiBgExecutor = uiBgExecutor;
- mBarService = barService;
- mKeyguardStateControllerLazy = keyguardStateControllerLazy;
- mIconPolicyLazy = iconPolicyLazy;
- mIconControllerLazy = iconControllerLazy;
- mSystemBarConfigs = systemBarConfigs;
-
- mDisplayId = context.getDisplayId();
- }
-
- @Override
- public void start() {
- // Set initial state.
- mHideTopBarForKeyboard = mSystemBarConfigs.getHideForKeyboardBySide(SystemBarConfigs.TOP);
- mHideBottomBarForKeyboard = mSystemBarConfigs.getHideForKeyboardBySide(
- SystemBarConfigs.BOTTOM);
- mHideLeftBarForKeyboard = mSystemBarConfigs.getHideForKeyboardBySide(SystemBarConfigs.LEFT);
- mHideRightBarForKeyboard = mSystemBarConfigs.getHideForKeyboardBySide(
- SystemBarConfigs.RIGHT);
-
- mBottomNavBarVisible = false;
-
- // Connect into the status bar manager service
- mCommandQueue.addCallback(this);
-
- RegisterStatusBarResult result = null;
- try {
- result = mBarService.registerStatusBar(mCommandQueue);
- } catch (RemoteException ex) {
- ex.rethrowFromSystemServer();
- }
-
- onSystemBarAppearanceChanged(mDisplayId, result.mAppearance, result.mAppearanceRegions,
- result.mNavbarColorManagedByIme);
-
- // StatusBarManagerService has a back up of IME token and it's restored here.
- setImeWindowStatus(mDisplayId, result.mImeToken, result.mImeWindowVis,
- result.mImeBackDisposition, result.mShowImeSwitcher);
-
- // Set up the initial icon state
- int numIcons = result.mIcons.size();
- for (int i = 0; i < numIcons; i++) {
- mCommandQueue.setIcon(result.mIcons.keyAt(i), result.mIcons.valueAt(i));
- }
-
- mAutoHideController.setStatusBar(new AutoHideUiElement() {
- @Override
- public void synchronizeState() {
- // No op.
- }
-
- @Override
- public boolean isVisible() {
- return mStatusBarTransientShown;
- }
-
- @Override
- public void hide() {
- clearTransient();
- }
- });
-
- mAutoHideController.setNavigationBar(new AutoHideUiElement() {
- @Override
- public void synchronizeState() {
- // No op.
- }
-
- @Override
- public boolean isVisible() {
- return mNavBarTransientShown;
- }
-
- @Override
- public void hide() {
- clearTransient();
- }
- });
-
- mDeviceIsSetUpForUser = mCarDeviceProvisionedController.isCurrentUserSetup();
- mIsUserSetupInProgress = mCarDeviceProvisionedController.isCurrentUserSetupInProgress();
- mCarDeviceProvisionedController.addCallback(
- new CarDeviceProvisionedListener() {
- @Override
- public void onUserSetupInProgressChanged() {
- mMainHandler.post(() -> restartNavBarsIfNecessary());
- }
-
- @Override
- public void onUserSetupChanged() {
- mMainHandler.post(() -> restartNavBarsIfNecessary());
- }
-
- @Override
- public void onUserSwitched() {
- mMainHandler.post(() -> restartNavBarsIfNecessary());
- }
- });
-
- createNavigationBar(result);
-
- mActivityManagerWrapper = ActivityManagerWrapper.getInstance();
- mActivityManagerWrapper.registerTaskStackListener(mButtonSelectionStateListener);
-
- mUiBgExecutor.execute(mCarNavigationBarController::connectToHvac);
-
- // Lastly, call to the icon policy to install/update all the icons.
- // Must be called on the main thread due to the use of observeForever() in
- // mIconPolicy.init().
- mMainHandler.post(() -> {
- mIconPolicyLazy.get().init();
- mSignalPolicy = new StatusBarSignalPolicy(mContext, mIconControllerLazy.get());
- });
- }
-
- private void restartNavBarsIfNecessary() {
- boolean currentUserSetup = mCarDeviceProvisionedController.isCurrentUserSetup();
- boolean currentUserSetupInProgress = mCarDeviceProvisionedController
- .isCurrentUserSetupInProgress();
- if (mIsUserSetupInProgress != currentUserSetupInProgress
- || mDeviceIsSetUpForUser != currentUserSetup) {
- mDeviceIsSetUpForUser = currentUserSetup;
- mIsUserSetupInProgress = currentUserSetupInProgress;
- restartNavBars();
- }
- }
-
- /**
- * Remove all content from navbars and rebuild them. Used to allow for different nav bars
- * before and after the device is provisioned. . Also for change of density and font size.
- */
- private void restartNavBars() {
- // remove and reattach all components such that we don't keep a reference to unused ui
- // elements
- mCarNavigationBarController.removeAll();
-
- if (mTopNavigationBarWindow != null) {
- mTopNavigationBarWindow.removeAllViews();
- mTopNavigationBarView = null;
- }
-
- if (mBottomNavigationBarWindow != null) {
- mBottomNavigationBarWindow.removeAllViews();
- mBottomNavigationBarView = null;
- }
-
- if (mLeftNavigationBarWindow != null) {
- mLeftNavigationBarWindow.removeAllViews();
- mLeftNavigationBarView = null;
- }
-
- if (mRightNavigationBarWindow != null) {
- mRightNavigationBarWindow.removeAllViews();
- mRightNavigationBarView = null;
- }
-
- buildNavBarContent();
- // If the UI was rebuilt (day/night change or user change) while the keyguard was up we need
- // to correctly respect that state.
- if (mKeyguardStateControllerLazy.get().isShowing()) {
- mCarNavigationBarController.showAllKeyguardButtons(isDeviceSetupForUser());
- } else {
- mCarNavigationBarController.hideAllKeyguardButtons(isDeviceSetupForUser());
- }
-
- // Upon restarting the Navigation Bar, CarFacetButtonController should immediately apply the
- // selection state that reflects the current task stack.
- mButtonSelectionStateListener.onTaskStackChanged();
- }
-
- private boolean isDeviceSetupForUser() {
- return mDeviceIsSetUpForUser && !mIsUserSetupInProgress;
- }
-
- private void createNavigationBar(RegisterStatusBarResult result) {
- buildNavBarWindows();
- buildNavBarContent();
- attachNavBarWindows();
-
- // Try setting up the initial state of the nav bar if applicable.
- if (result != null) {
- setImeWindowStatus(Display.DEFAULT_DISPLAY, result.mImeToken,
- result.mImeWindowVis, result.mImeBackDisposition,
- result.mShowImeSwitcher);
- }
- }
-
- private void buildNavBarWindows() {
- mTopNavigationBarWindow = mCarNavigationBarController.getTopWindow();
- mBottomNavigationBarWindow = mCarNavigationBarController.getBottomWindow();
- mLeftNavigationBarWindow = mCarNavigationBarController.getLeftWindow();
- mRightNavigationBarWindow = mCarNavigationBarController.getRightWindow();
- }
-
- private void buildNavBarContent() {
- mTopNavigationBarView = mCarNavigationBarController.getTopBar(isDeviceSetupForUser());
- if (mTopNavigationBarView != null) {
- mSystemBarConfigs.insetSystemBar(SystemBarConfigs.TOP, mTopNavigationBarView);
- mSystemBarConfigs.setInsetUpdater(SystemBarConfigs.TOP, mTopNavigationBarView);
- mTopNavigationBarWindow.addView(mTopNavigationBarView);
- }
-
- mBottomNavigationBarView = mCarNavigationBarController.getBottomBar(isDeviceSetupForUser());
- if (mBottomNavigationBarView != null) {
- mSystemBarConfigs.insetSystemBar(SystemBarConfigs.BOTTOM, mBottomNavigationBarView);
- mSystemBarConfigs.setInsetUpdater(SystemBarConfigs.BOTTOM, mBottomNavigationBarView);
- mBottomNavigationBarWindow.addView(mBottomNavigationBarView);
- }
-
- mLeftNavigationBarView = mCarNavigationBarController.getLeftBar(isDeviceSetupForUser());
- if (mLeftNavigationBarView != null) {
- mSystemBarConfigs.insetSystemBar(SystemBarConfigs.LEFT, mLeftNavigationBarView);
- mSystemBarConfigs.setInsetUpdater(SystemBarConfigs.LEFT, mLeftNavigationBarView);
- mLeftNavigationBarWindow.addView(mLeftNavigationBarView);
- }
-
- mRightNavigationBarView = mCarNavigationBarController.getRightBar(isDeviceSetupForUser());
- if (mRightNavigationBarView != null) {
- mSystemBarConfigs.insetSystemBar(SystemBarConfigs.RIGHT, mRightNavigationBarView);
- mSystemBarConfigs.setInsetUpdater(SystemBarConfigs.RIGHT, mRightNavigationBarView);
- mRightNavigationBarWindow.addView(mRightNavigationBarView);
- }
- }
-
- private void attachNavBarWindows() {
- mSystemBarConfigs.getSystemBarSidesByZOrder().forEach(this::attachNavBarBySide);
- }
-
- private void attachNavBarBySide(int side) {
- switch (side) {
- case SystemBarConfigs.TOP:
- if (mTopNavigationBarWindow != null) {
- mWindowManager.addView(mTopNavigationBarWindow,
- mSystemBarConfigs.getLayoutParamsBySide(SystemBarConfigs.TOP));
- }
- break;
- case SystemBarConfigs.BOTTOM:
- if (mBottomNavigationBarWindow != null && !mBottomNavBarVisible) {
- mBottomNavBarVisible = true;
-
- mWindowManager.addView(mBottomNavigationBarWindow,
- mSystemBarConfigs.getLayoutParamsBySide(SystemBarConfigs.BOTTOM));
- }
- break;
- case SystemBarConfigs.LEFT:
- if (mLeftNavigationBarWindow != null) {
- mWindowManager.addView(mLeftNavigationBarWindow,
- mSystemBarConfigs.getLayoutParamsBySide(SystemBarConfigs.LEFT));
- }
- break;
- case SystemBarConfigs.RIGHT:
- if (mRightNavigationBarWindow != null) {
- mWindowManager.addView(mRightNavigationBarWindow,
- mSystemBarConfigs.getLayoutParamsBySide(SystemBarConfigs.RIGHT));
- }
- break;
- default:
- return;
- }
- }
-
- /**
- * We register for soft keyboard visibility events such that we can hide the navigation bar
- * giving more screen space to the IME. Note: this is optional and controlled by
- * {@code com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard}.
- */
- @Override
- public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
- boolean showImeSwitcher) {
- if (mContext.getDisplayId() != displayId) {
- return;
- }
-
- boolean isKeyboardVisible = (vis & InputMethodService.IME_VISIBLE) != 0;
-
- if (mHideTopBarForKeyboard) {
- mCarNavigationBarController.setTopWindowVisibility(
- isKeyboardVisible ? View.GONE : View.VISIBLE);
- }
-
- if (mHideBottomBarForKeyboard) {
- mCarNavigationBarController.setBottomWindowVisibility(
- isKeyboardVisible ? View.GONE : View.VISIBLE);
- }
-
- if (mHideLeftBarForKeyboard) {
- mCarNavigationBarController.setLeftWindowVisibility(
- isKeyboardVisible ? View.GONE : View.VISIBLE);
- }
- if (mHideRightBarForKeyboard) {
- mCarNavigationBarController.setRightWindowVisibility(
- isKeyboardVisible ? View.GONE : View.VISIBLE);
- }
- }
-
- @Override
- public void onSystemBarAppearanceChanged(
- int displayId,
- @WindowInsetsController.Appearance int appearance,
- AppearanceRegion[] appearanceRegions,
- boolean navbarColorManagedByIme) {
- if (displayId != mDisplayId) {
- return;
- }
- boolean barModeChanged = updateStatusBarMode(
- mStatusBarTransientShown ? MODE_SEMI_TRANSPARENT : MODE_TRANSPARENT);
- int numStacks = appearanceRegions.length;
- boolean stackAppearancesChanged = mAppearanceRegions.length != numStacks;
- for (int i = 0; i < numStacks && !stackAppearancesChanged; i++) {
- stackAppearancesChanged |= !appearanceRegions[i].equals(mAppearanceRegions[i]);
- }
- if (stackAppearancesChanged || barModeChanged) {
- mAppearanceRegions = appearanceRegions;
- updateStatusBarAppearance();
- }
- }
-
- private void updateStatusBarAppearance() {
- int numStacks = mAppearanceRegions.length;
- int numLightStacks = 0;
-
- // We can only have maximum one light stack.
- int indexLightStack = -1;
-
- for (int i = 0; i < numStacks; i++) {
- if (isLight(mAppearanceRegions[i].getAppearance())) {
- numLightStacks++;
- indexLightStack = i;
- }
- }
-
- // If all stacks are light, all icons become dark.
- if (numLightStacks == numStacks) {
- mStatusBarIconController.setIconsDarkArea(null);
- mStatusBarIconController.getTransitionsController().setIconsDark(
- /* dark= */ true, /* animate= */ false);
- } else if (numLightStacks == 0) {
- // If no one is light, all icons become white.
- mStatusBarIconController.getTransitionsController().setIconsDark(
- /* dark= */ false, /* animate= */ false);
- } else {
- // Not the same for every stack, update icons in area only.
- mStatusBarIconController.setIconsDarkArea(
- mAppearanceRegions[indexLightStack].getBounds());
- mStatusBarIconController.getTransitionsController().setIconsDark(
- /* dark= */ true, /* animate= */ false);
- }
- }
-
- private static boolean isLight(int appearance) {
- return (appearance & APPEARANCE_LIGHT_STATUS_BARS) != 0;
- }
-
- @Override
- public void showTransient(int displayId, int[] types) {
- if (displayId != mDisplayId) {
- return;
- }
- if (containsType(types, ITYPE_STATUS_BAR)) {
- if (!mStatusBarTransientShown) {
- mStatusBarTransientShown = true;
- handleTransientChanged();
- }
- }
- if (containsType(types, ITYPE_NAVIGATION_BAR)) {
- if (!mNavBarTransientShown) {
- mNavBarTransientShown = true;
- handleTransientChanged();
- }
- }
- }
-
- @Override
- public void abortTransient(int displayId, int[] types) {
- if (displayId != mDisplayId) {
- return;
- }
- if (!containsType(types, ITYPE_STATUS_BAR) && !containsType(types, ITYPE_NAVIGATION_BAR)) {
- return;
- }
- clearTransient();
- }
-
- private void clearTransient() {
- if (mStatusBarTransientShown) {
- mStatusBarTransientShown = false;
- handleTransientChanged();
- }
- if (mNavBarTransientShown) {
- mNavBarTransientShown = false;
- handleTransientChanged();
- }
- }
-
- @VisibleForTesting
- boolean isStatusBarTransientShown() {
- return mStatusBarTransientShown;
- }
-
- @VisibleForTesting
- boolean isNavBarTransientShown() {
- return mNavBarTransientShown;
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.print(" mTaskStackListener=");
- pw.println(mButtonSelectionStateListener);
- pw.print(" mBottomNavigationBarView=");
- pw.println(mBottomNavigationBarView);
- }
-
- private void handleTransientChanged() {
- updateStatusBarMode(mStatusBarTransientShown ? MODE_SEMI_TRANSPARENT : MODE_TRANSPARENT);
- updateNavBarMode(mNavBarTransientShown ? MODE_SEMI_TRANSPARENT : MODE_TRANSPARENT);
- }
-
- // Returns true if the status bar mode has changed.
- private boolean updateStatusBarMode(int barMode) {
- if (mStatusBarMode != barMode) {
- mStatusBarMode = barMode;
- mAutoHideController.touchAutoHide();
- return true;
- }
- return false;
- }
-
- // Returns true if the nav bar mode has changed.
- private boolean updateNavBarMode(int barMode) {
- if (mNavigationBarMode != barMode) {
- mNavigationBarMode = barMode;
- mAutoHideController.touchAutoHide();
- return true;
- }
- return false;
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java
deleted file mode 100644
index 4fb5220..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.navigationbar;
-
-import android.content.Context;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.Nullable;
-
-import com.android.systemui.car.hvac.HvacController;
-import com.android.systemui.car.statusbar.UserNameViewController;
-import com.android.systemui.dagger.SysUISingleton;
-
-import javax.inject.Inject;
-
-import dagger.Lazy;
-
-/** A single class which controls the navigation bar views. */
-@SysUISingleton
-public class CarNavigationBarController {
-
- private final Context mContext;
- private final NavigationBarViewFactory mNavigationBarViewFactory;
- private final ButtonSelectionStateController mButtonSelectionStateController;
- private final ButtonRoleHolderController mButtonRoleHolderController;
- private final Lazy<HvacController> mHvacControllerLazy;
- private final Lazy<UserNameViewController> mUserNameViewControllerLazy;
-
- private boolean mShowTop;
- private boolean mShowBottom;
- private boolean mShowLeft;
- private boolean mShowRight;
-
- private View.OnTouchListener mTopBarTouchListener;
- private View.OnTouchListener mBottomBarTouchListener;
- private View.OnTouchListener mLeftBarTouchListener;
- private View.OnTouchListener mRightBarTouchListener;
- private NotificationsShadeController mNotificationsShadeController;
-
- private CarNavigationBarView mTopView;
- private CarNavigationBarView mBottomView;
- private CarNavigationBarView mLeftView;
- private CarNavigationBarView mRightView;
-
- @Inject
- public CarNavigationBarController(Context context,
- NavigationBarViewFactory navigationBarViewFactory,
- ButtonSelectionStateController buttonSelectionStateController,
- Lazy<HvacController> hvacControllerLazy,
- Lazy<UserNameViewController> userNameViewControllerLazy,
- ButtonRoleHolderController buttonRoleHolderController,
- SystemBarConfigs systemBarConfigs) {
- mContext = context;
- mNavigationBarViewFactory = navigationBarViewFactory;
- mButtonSelectionStateController = buttonSelectionStateController;
- mHvacControllerLazy = hvacControllerLazy;
- mUserNameViewControllerLazy = userNameViewControllerLazy;
- mButtonRoleHolderController = buttonRoleHolderController;
-
- // Read configuration.
- mShowTop = systemBarConfigs.getEnabledStatusBySide(SystemBarConfigs.TOP);
- mShowBottom = systemBarConfigs.getEnabledStatusBySide(SystemBarConfigs.BOTTOM);
- mShowLeft = systemBarConfigs.getEnabledStatusBySide(SystemBarConfigs.LEFT);
- mShowRight = systemBarConfigs.getEnabledStatusBySide(SystemBarConfigs.RIGHT);
- }
-
- /**
- * Hides all system bars.
- */
- public void hideBars() {
- setTopWindowVisibility(View.GONE);
- setBottomWindowVisibility(View.GONE);
- setLeftWindowVisibility(View.GONE);
- setRightWindowVisibility(View.GONE);
- }
-
- /**
- * Shows all system bars.
- */
- public void showBars() {
- setTopWindowVisibility(View.VISIBLE);
- setBottomWindowVisibility(View.VISIBLE);
- setLeftWindowVisibility(View.VISIBLE);
- setRightWindowVisibility(View.VISIBLE);
- }
-
- /** Connect to hvac service. */
- public void connectToHvac() {
- mHvacControllerLazy.get().connectToCarService();
- }
-
- /** Clean up */
- public void removeAll() {
- mHvacControllerLazy.get().removeAllComponents();
- mButtonSelectionStateController.removeAll();
- mButtonRoleHolderController.removeAll();
- mUserNameViewControllerLazy.get().removeAll();
- }
-
- /** Gets the top window if configured to do so. */
- @Nullable
- public ViewGroup getTopWindow() {
- return mShowTop ? mNavigationBarViewFactory.getTopWindow() : null;
- }
-
- /** Gets the bottom window if configured to do so. */
- @Nullable
- public ViewGroup getBottomWindow() {
- return mShowBottom ? mNavigationBarViewFactory.getBottomWindow() : null;
- }
-
- /** Gets the left window if configured to do so. */
- @Nullable
- public ViewGroup getLeftWindow() {
- return mShowLeft ? mNavigationBarViewFactory.getLeftWindow() : null;
- }
-
- /** Gets the right window if configured to do so. */
- @Nullable
- public ViewGroup getRightWindow() {
- return mShowRight ? mNavigationBarViewFactory.getRightWindow() : null;
- }
-
- /** Toggles the top nav bar visibility. */
- public boolean setTopWindowVisibility(@View.Visibility int visibility) {
- return setWindowVisibility(getTopWindow(), visibility);
- }
-
- /** Toggles the bottom nav bar visibility. */
- public boolean setBottomWindowVisibility(@View.Visibility int visibility) {
- return setWindowVisibility(getBottomWindow(), visibility);
- }
-
- /** Toggles the left nav bar visibility. */
- public boolean setLeftWindowVisibility(@View.Visibility int visibility) {
- return setWindowVisibility(getLeftWindow(), visibility);
- }
-
- /** Toggles the right nav bar visibility. */
- public boolean setRightWindowVisibility(@View.Visibility int visibility) {
- return setWindowVisibility(getRightWindow(), visibility);
- }
-
- private boolean setWindowVisibility(ViewGroup window, @View.Visibility int visibility) {
- if (window == null) {
- return false;
- }
-
- if (window.getVisibility() == visibility) {
- return false;
- }
-
- window.setVisibility(visibility);
- return true;
- }
-
- /** Gets the top navigation bar with the appropriate listeners set. */
- @Nullable
- public CarNavigationBarView getTopBar(boolean isSetUp) {
- if (!mShowTop) {
- return null;
- }
-
- mTopView = mNavigationBarViewFactory.getTopBar(isSetUp);
- setupBar(mTopView, mTopBarTouchListener, mNotificationsShadeController);
- return mTopView;
- }
-
- /** Gets the bottom navigation bar with the appropriate listeners set. */
- @Nullable
- public CarNavigationBarView getBottomBar(boolean isSetUp) {
- if (!mShowBottom) {
- return null;
- }
-
- mBottomView = mNavigationBarViewFactory.getBottomBar(isSetUp);
- setupBar(mBottomView, mBottomBarTouchListener, mNotificationsShadeController);
- return mBottomView;
- }
-
- /** Gets the left navigation bar with the appropriate listeners set. */
- @Nullable
- public CarNavigationBarView getLeftBar(boolean isSetUp) {
- if (!mShowLeft) {
- return null;
- }
-
- mLeftView = mNavigationBarViewFactory.getLeftBar(isSetUp);
- setupBar(mLeftView, mLeftBarTouchListener, mNotificationsShadeController);
- return mLeftView;
- }
-
- /** Gets the right navigation bar with the appropriate listeners set. */
- @Nullable
- public CarNavigationBarView getRightBar(boolean isSetUp) {
- if (!mShowRight) {
- return null;
- }
-
- mRightView = mNavigationBarViewFactory.getRightBar(isSetUp);
- setupBar(mRightView, mRightBarTouchListener, mNotificationsShadeController);
- return mRightView;
- }
-
- private void setupBar(CarNavigationBarView view, View.OnTouchListener statusBarTouchListener,
- NotificationsShadeController notifShadeController) {
- view.setStatusBarWindowTouchListener(statusBarTouchListener);
- view.setNotificationsPanelController(notifShadeController);
- mButtonSelectionStateController.addAllButtonsWithSelectionState(view);
- mButtonRoleHolderController.addAllButtonsWithRoleName(view);
- mHvacControllerLazy.get().addTemperatureViewToController(view);
- mUserNameViewControllerLazy.get().addUserNameView(view);
- }
-
- /** Sets a touch listener for the top navigation bar. */
- public void registerTopBarTouchListener(View.OnTouchListener listener) {
- mTopBarTouchListener = listener;
- if (mTopView != null) {
- mTopView.setStatusBarWindowTouchListener(mTopBarTouchListener);
- }
- }
-
- /** Sets a touch listener for the bottom navigation bar. */
- public void registerBottomBarTouchListener(View.OnTouchListener listener) {
- mBottomBarTouchListener = listener;
- if (mBottomView != null) {
- mBottomView.setStatusBarWindowTouchListener(mBottomBarTouchListener);
- }
- }
-
- /** Sets a touch listener for the left navigation bar. */
- public void registerLeftBarTouchListener(View.OnTouchListener listener) {
- mLeftBarTouchListener = listener;
- if (mLeftView != null) {
- mLeftView.setStatusBarWindowTouchListener(mLeftBarTouchListener);
- }
- }
-
- /** Sets a touch listener for the right navigation bar. */
- public void registerRightBarTouchListener(View.OnTouchListener listener) {
- mRightBarTouchListener = listener;
- if (mRightView != null) {
- mRightView.setStatusBarWindowTouchListener(mRightBarTouchListener);
- }
- }
-
- /** Sets a notification controller which toggles the notification panel. */
- public void registerNotificationController(
- NotificationsShadeController notificationsShadeController) {
- mNotificationsShadeController = notificationsShadeController;
- if (mTopView != null) {
- mTopView.setNotificationsPanelController(mNotificationsShadeController);
- }
- if (mBottomView != null) {
- mBottomView.setNotificationsPanelController(mNotificationsShadeController);
- }
- if (mLeftView != null) {
- mLeftView.setNotificationsPanelController(mNotificationsShadeController);
- }
- if (mRightView != null) {
- mRightView.setNotificationsPanelController(mNotificationsShadeController);
- }
- }
-
- /**
- * Shows all of the keyguard specific buttons on the valid instances of
- * {@link CarNavigationBarView}.
- */
- public void showAllKeyguardButtons(boolean isSetUp) {
- checkAllBars(isSetUp);
- if (mTopView != null) {
- mTopView.showKeyguardButtons();
- }
- if (mBottomView != null) {
- mBottomView.showKeyguardButtons();
- }
- if (mLeftView != null) {
- mLeftView.showKeyguardButtons();
- }
- if (mRightView != null) {
- mRightView.showKeyguardButtons();
- }
- }
-
- /**
- * Hides all of the keyguard specific buttons on the valid instances of
- * {@link CarNavigationBarView}.
- */
- public void hideAllKeyguardButtons(boolean isSetUp) {
- checkAllBars(isSetUp);
- if (mTopView != null) {
- mTopView.hideKeyguardButtons();
- }
- if (mBottomView != null) {
- mBottomView.hideKeyguardButtons();
- }
- if (mLeftView != null) {
- mLeftView.hideKeyguardButtons();
- }
- if (mRightView != null) {
- mRightView.hideKeyguardButtons();
- }
- }
-
- /** Toggles whether the notifications icon has an unseen indicator or not. */
- public void toggleAllNotificationsUnseenIndicator(boolean isSetUp, boolean hasUnseen) {
- checkAllBars(isSetUp);
- if (mTopView != null) {
- mTopView.toggleNotificationUnseenIndicator(hasUnseen);
- }
- if (mBottomView != null) {
- mBottomView.toggleNotificationUnseenIndicator(hasUnseen);
- }
- if (mLeftView != null) {
- mLeftView.toggleNotificationUnseenIndicator(hasUnseen);
- }
- if (mRightView != null) {
- mRightView.toggleNotificationUnseenIndicator(hasUnseen);
- }
- }
-
- /** Interface for controlling the notifications shade. */
- public interface NotificationsShadeController {
- /** Toggles the visibility of the notifications shade. */
- void togglePanel();
-
- /** Returns {@code true} if the panel is open. */
- boolean isNotificationPanelOpen();
- }
-
- private void checkAllBars(boolean isSetUp) {
- mTopView = getTopBar(isSetUp);
- mBottomView = getBottomBar(isSetUp);
- mLeftView = getLeftBar(isSetUp);
- mRightView = getRightBar(isSetUp);
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java
deleted file mode 100644
index ab401bb..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.navigationbar;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import com.android.systemui.Dependency;
-import com.android.systemui.R;
-import com.android.systemui.car.navigationbar.CarNavigationBarController.NotificationsShadeController;
-import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.phone.StatusBarIconController;
-
-/**
- * A custom navigation bar for the automotive use case.
- * <p>
- * The navigation bar in the automotive use case is more like a list of shortcuts, rendered
- * in a linear layout.
- */
-public class CarNavigationBarView extends LinearLayout {
- private final boolean mConsumeTouchWhenPanelOpen;
-
- private View mNavButtons;
- private CarNavigationButton mNotificationsButton;
- private NotificationsShadeController mNotificationsShadeController;
- private View mLockScreenButtons;
- // used to wire in open/close gestures for notifications
- private OnTouchListener mStatusBarWindowTouchListener;
-
- public CarNavigationBarView(Context context, AttributeSet attrs) {
- super(context, attrs);
- mConsumeTouchWhenPanelOpen = getResources().getBoolean(
- R.bool.config_consumeNavigationBarTouchWhenNotificationPanelOpen);
- }
-
- @Override
- public void onFinishInflate() {
- mNavButtons = findViewById(R.id.nav_buttons);
- mLockScreenButtons = findViewById(R.id.lock_screen_nav_buttons);
-
- mNotificationsButton = findViewById(R.id.notifications);
- if (mNotificationsButton != null) {
- mNotificationsButton.setOnClickListener(this::onNotificationsClick);
- }
- View mStatusIcons = findViewById(R.id.statusIcons);
- if (mStatusIcons != null) {
- // Attach the controllers for Status icons such as wifi and bluetooth if the standard
- // container is in the view.
- StatusBarIconController.DarkIconManager mDarkIconManager =
- new StatusBarIconController.DarkIconManager(
- mStatusIcons.findViewById(R.id.statusIcons),
- Dependency.get(CommandQueue.class));
- mDarkIconManager.setShouldLog(true);
- Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager);
- }
- // Needs to be clickable so that it will receive ACTION_MOVE events.
- setClickable(true);
- // Needs to not be focusable so rotary won't highlight the entire nav bar.
- setFocusable(false);
- }
-
- // Used to forward touch events even if the touch was initiated from a child component
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (mStatusBarWindowTouchListener != null) {
- boolean shouldConsumeEvent = mNotificationsShadeController == null ? false
- : mNotificationsShadeController.isNotificationPanelOpen();
-
- // Forward touch events to the status bar window so it can drag
- // windows if required (Notification shade)
- mStatusBarWindowTouchListener.onTouch(this, ev);
-
- if (mConsumeTouchWhenPanelOpen && shouldConsumeEvent) {
- return true;
- }
- }
- return super.onInterceptTouchEvent(ev);
- }
-
- /** Sets the notifications panel controller. */
- public void setNotificationsPanelController(NotificationsShadeController controller) {
- mNotificationsShadeController = controller;
- }
-
- /** Gets the notifications panel controller. */
- public NotificationsShadeController getNotificationsPanelController() {
- return mNotificationsShadeController;
- }
-
- /**
- * Sets a touch listener that will be called from onInterceptTouchEvent and onTouchEvent
- *
- * @param statusBarWindowTouchListener The listener to call from touch and intercept touch
- */
- public void setStatusBarWindowTouchListener(OnTouchListener statusBarWindowTouchListener) {
- mStatusBarWindowTouchListener = statusBarWindowTouchListener;
- }
-
- /** Gets the touch listener that will be called from onInterceptTouchEvent and onTouchEvent. */
- public OnTouchListener getStatusBarWindowTouchListener() {
- return mStatusBarWindowTouchListener;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (mStatusBarWindowTouchListener != null) {
- mStatusBarWindowTouchListener.onTouch(this, event);
- }
- return super.onTouchEvent(event);
- }
-
- protected void onNotificationsClick(View v) {
- if (mNotificationsShadeController != null) {
- mNotificationsShadeController.togglePanel();
- }
- }
-
- /**
- * If there are buttons declared in the layout they will be shown and the normal
- * Nav buttons will be hidden.
- */
- public void showKeyguardButtons() {
- if (mLockScreenButtons == null) {
- return;
- }
- mLockScreenButtons.setVisibility(View.VISIBLE);
- mNavButtons.setVisibility(View.GONE);
- }
-
- /**
- * If there are buttons declared in the layout they will be hidden and the normal
- * Nav buttons will be shown.
- */
- public void hideKeyguardButtons() {
- if (mLockScreenButtons == null) return;
-
- mNavButtons.setVisibility(View.VISIBLE);
- mLockScreenButtons.setVisibility(View.GONE);
- }
-
- /**
- * Toggles the notification unseen indicator on/off.
- *
- * @param hasUnseen true if the unseen notification count is great than 0.
- */
- public void toggleNotificationUnseenIndicator(Boolean hasUnseen) {
- if (mNotificationsButton == null) return;
-
- mNotificationsButton.setUnseen(hasUnseen);
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationButton.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationButton.java
deleted file mode 100644
index d2b931b..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationButton.java
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.navigationbar;
-
-import android.app.ActivityOptions;
-import android.app.role.RoleManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-import android.os.UserHandle;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Display;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
-import com.android.systemui.statusbar.AlphaOptimizedImageView;
-
-import java.net.URISyntaxException;
-
-/**
- * CarNavigationButton is an image button that allows for a bit more configuration at the
- * xml file level. This allows for more control via overlays instead of having to update
- * code.
- */
-public class CarNavigationButton extends LinearLayout {
-
- protected static final float DEFAULT_SELECTED_ALPHA = 1f;
- protected static final float DEFAULT_UNSELECTED_ALPHA = 0.75f;
-
- private static final String TAG = "CarNavigationButton";
- private static final String BUTTON_FILTER_DELIMITER = ";";
- private static final String EXTRA_BUTTON_CATEGORIES = "categories";
- private static final String EXTRA_BUTTON_PACKAGES = "packages";
-
- private Context mContext;
- private AlphaOptimizedImageView mIcon;
- private AlphaOptimizedImageView mMoreIcon;
- private ImageView mUnseenIcon;
- private String mIntent;
- private String mLongIntent;
- private boolean mBroadcastIntent;
- private boolean mHasUnseen = false;
- private boolean mSelected = false;
- private float mSelectedAlpha;
- private float mUnselectedAlpha;
- private int mSelectedIconResourceId;
- private int mIconResourceId;
- private Drawable mAppIcon;
- private boolean mIsDefaultAppIconForRoleEnabled;
- private String[] mComponentNames;
- /** App categories that are to be used with this widget */
- private String[] mButtonCategories;
- /** App packages that are allowed to be used with this widget */
- private String[] mButtonPackages;
- /** Whether to display more icon beneath the primary icon when the button is selected */
- private boolean mShowMoreWhenSelected = false;
- /** Whether to highlight the button if the active application is associated with it */
- private boolean mHighlightWhenSelected = false;
-
- public CarNavigationButton(Context context, AttributeSet attrs) {
- super(context, attrs);
- mContext = context;
- View.inflate(mContext, R.layout.car_navigation_button, /* root= */ this);
- // CarNavigationButton attrs
- TypedArray typedArray = context.obtainStyledAttributes(attrs,
- R.styleable.CarNavigationButton);
-
- setUpIntents(typedArray);
- setUpIcons(typedArray);
- typedArray.recycle();
- }
-
- /**
- * @param selected true if should indicate if this is a selected state, false otherwise
- */
- public void setSelected(boolean selected) {
- super.setSelected(selected);
- mSelected = selected;
-
- if (mHighlightWhenSelected) {
- setAlpha(mSelected ? mSelectedAlpha : mUnselectedAlpha);
- }
-
- if (mShowMoreWhenSelected && mMoreIcon != null) {
- mMoreIcon.setVisibility(selected ? VISIBLE : GONE);
- }
- updateImage();
- }
-
- /**
- * @param hasUnseen true if should indicate if this is a Unseen state, false otherwise.
- */
- public void setUnseen(boolean hasUnseen) {
- mHasUnseen = hasUnseen;
- updateImage();
- }
-
- /**
- * Sets the current icon of the default application associated with this button.
- */
- public void setAppIcon(Drawable appIcon) {
- mAppIcon = appIcon;
- updateImage();
- }
-
- /** Gets the icon of the app currently associated to the role of this button. */
- @VisibleForTesting
- protected Drawable getAppIcon() {
- return mAppIcon;
- }
-
- /** Gets whether the icon is in an unseen state. */
- public boolean getUnseen() {
- return mHasUnseen;
- }
-
- /**
- * @return The app categories the component represents
- */
- public String[] getCategories() {
- if (mButtonCategories == null) {
- return new String[0];
- }
- return mButtonCategories;
- }
-
- /**
- * @return The valid packages that should be considered.
- */
- public String[] getPackages() {
- if (mButtonPackages == null) {
- return new String[0];
- }
- return mButtonPackages;
- }
-
- /**
- * @return The list of component names.
- */
- public String[] getComponentName() {
- if (mComponentNames == null) {
- return new String[0];
- }
- return mComponentNames;
- }
-
- /**
- * Subclasses should override this method to return the {@link RoleManager} role associated
- * with this button.
- */
- protected String getRoleName() {
- return null;
- }
-
- /**
- * @return true if this button should show the icon of the default application for the
- * role returned by {@link #getRoleName()}.
- */
- protected boolean isDefaultAppIconForRoleEnabled() {
- return mIsDefaultAppIconForRoleEnabled;
- }
-
- /**
- * @return The id of the display the button is on or Display.INVALID_DISPLAY if it's not yet on
- * a display.
- */
- protected int getDisplayId() {
- Display display = getDisplay();
- if (display == null) {
- return Display.INVALID_DISPLAY;
- }
- return display.getDisplayId();
- }
-
- protected boolean hasSelectionState() {
- return mHighlightWhenSelected || mShowMoreWhenSelected;
- }
-
- /**
- * Sets up intents for click, long touch, and broadcast.
- */
- protected void setUpIntents(TypedArray typedArray) {
- mIntent = typedArray.getString(R.styleable.CarNavigationButton_intent);
- mLongIntent = typedArray.getString(R.styleable.CarNavigationButton_longIntent);
- mBroadcastIntent = typedArray.getBoolean(R.styleable.CarNavigationButton_broadcast, false);
-
- String categoryString = typedArray.getString(R.styleable.CarNavigationButton_categories);
- String packageString = typedArray.getString(R.styleable.CarNavigationButton_packages);
- String componentNameString =
- typedArray.getString(R.styleable.CarNavigationButton_componentNames);
-
- try {
- if (mIntent != null) {
- final Intent intent = Intent.parseUri(mIntent, Intent.URI_INTENT_SCHEME);
- setOnClickListener(getButtonClickListener(intent));
- if (packageString != null) {
- mButtonPackages = packageString.split(BUTTON_FILTER_DELIMITER);
- intent.putExtra(EXTRA_BUTTON_PACKAGES, mButtonPackages);
- }
- if (categoryString != null) {
- mButtonCategories = categoryString.split(BUTTON_FILTER_DELIMITER);
- intent.putExtra(EXTRA_BUTTON_CATEGORIES, mButtonCategories);
- }
- if (componentNameString != null) {
- mComponentNames = componentNameString.split(BUTTON_FILTER_DELIMITER);
- }
- }
- } catch (URISyntaxException e) {
- throw new RuntimeException("Failed to attach intent", e);
- }
-
- try {
- if (mLongIntent != null && (Build.IS_ENG || Build.IS_USERDEBUG)) {
- final Intent intent = Intent.parseUri(mLongIntent, Intent.URI_INTENT_SCHEME);
- setOnLongClickListener(getButtonLongClickListener(intent));
- }
- } catch (URISyntaxException e) {
- throw new RuntimeException("Failed to attach long press intent", e);
- }
- }
-
- /** Defines the behavior of a button click. */
- protected OnClickListener getButtonClickListener(Intent toSend) {
- return v -> {
- mContext.sendBroadcastAsUser(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS),
- UserHandle.CURRENT);
- try {
- if (mBroadcastIntent) {
- mContext.sendBroadcastAsUser(toSend, UserHandle.CURRENT);
- return;
- }
- ActivityOptions options = ActivityOptions.makeBasic();
- options.setLaunchDisplayId(mContext.getDisplayId());
- mContext.startActivityAsUser(toSend, options.toBundle(),
- UserHandle.CURRENT);
- } catch (Exception e) {
- Log.e(TAG, "Failed to launch intent", e);
- }
- };
- }
-
- /** Defines the behavior of a long click. */
- protected OnLongClickListener getButtonLongClickListener(Intent toSend) {
- return v -> {
- mContext.sendBroadcastAsUser(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS),
- UserHandle.CURRENT);
- try {
- ActivityOptions options = ActivityOptions.makeBasic();
- options.setLaunchDisplayId(mContext.getDisplayId());
- mContext.startActivityAsUser(toSend, options.toBundle(),
- UserHandle.CURRENT);
- } catch (Exception e) {
- Log.e(TAG, "Failed to launch intent", e);
- }
- // consume event either way
- return true;
- };
- }
-
- /**
- * Initializes view-related aspects of the button.
- */
- private void setUpIcons(TypedArray typedArray) {
- mSelectedAlpha = typedArray.getFloat(
- R.styleable.CarNavigationButton_selectedAlpha, DEFAULT_SELECTED_ALPHA);
- mUnselectedAlpha = typedArray.getFloat(
- R.styleable.CarNavigationButton_unselectedAlpha, DEFAULT_UNSELECTED_ALPHA);
- mHighlightWhenSelected = typedArray.getBoolean(
- R.styleable.CarNavigationButton_highlightWhenSelected,
- mHighlightWhenSelected);
- mShowMoreWhenSelected = typedArray.getBoolean(
- R.styleable.CarNavigationButton_showMoreWhenSelected,
- mShowMoreWhenSelected);
-
- mIconResourceId = typedArray.getResourceId(
- R.styleable.CarNavigationButton_icon, 0);
- mSelectedIconResourceId = typedArray.getResourceId(
- R.styleable.CarNavigationButton_selectedIcon, mIconResourceId);
- mIsDefaultAppIconForRoleEnabled = typedArray.getBoolean(
- R.styleable.CarNavigationButton_useDefaultAppIconForRole, false);
- mIcon = findViewById(R.id.car_nav_button_icon_image);
- // Always apply un-selected alpha regardless of if the button toggles alpha based on
- // selection state.
- setAlpha(mHighlightWhenSelected ? mUnselectedAlpha : mSelectedAlpha);
- mMoreIcon = findViewById(R.id.car_nav_button_more_icon);
- mUnseenIcon = findViewById(R.id.car_nav_button_unseen_icon);
- updateImage();
- }
-
- private void updateImage() {
- if (mIsDefaultAppIconForRoleEnabled && mAppIcon != null) {
- mIcon.setImageDrawable(mAppIcon);
- } else {
- mIcon.setImageResource(mSelected ? mSelectedIconResourceId : mIconResourceId);
- }
- mUnseenIcon.setVisibility(mHasUnseen ? VISIBLE : GONE);
- }
-
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/NavigationBarViewFactory.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/NavigationBarViewFactory.java
deleted file mode 100644
index a473bb7..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/NavigationBarViewFactory.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.navigationbar;
-
-import android.content.Context;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.LayoutRes;
-
-import com.android.car.ui.FocusParkingView;
-import com.android.systemui.R;
-import com.android.systemui.dagger.SysUISingleton;
-
-import javax.inject.Inject;
-
-/** A factory that creates and caches views for navigation bars. */
-@SysUISingleton
-public class NavigationBarViewFactory {
-
- private static final String TAG = NavigationBarViewFactory.class.getSimpleName();
- private static final ArrayMap<Type, Integer> sLayoutMap = setupLayoutMapping();
-
- private static ArrayMap<Type, Integer> setupLayoutMapping() {
- ArrayMap<Type, Integer> map = new ArrayMap<>();
- map.put(Type.TOP, R.layout.car_top_navigation_bar);
- map.put(Type.TOP_UNPROVISIONED, R.layout.car_top_navigation_bar_unprovisioned);
- map.put(Type.BOTTOM, R.layout.car_navigation_bar);
- map.put(Type.BOTTOM_UNPROVISIONED, R.layout.car_navigation_bar_unprovisioned);
- map.put(Type.LEFT, R.layout.car_left_navigation_bar);
- map.put(Type.LEFT_UNPROVISIONED, R.layout.car_left_navigation_bar_unprovisioned);
- map.put(Type.RIGHT, R.layout.car_right_navigation_bar);
- map.put(Type.RIGHT_UNPROVISIONED, R.layout.car_right_navigation_bar_unprovisioned);
- return map;
- }
-
- private final Context mContext;
- private final ArrayMap<Type, CarNavigationBarView> mCachedViewMap = new ArrayMap<>(
- Type.values().length);
- private final ArrayMap<Type, ViewGroup> mCachedContainerMap = new ArrayMap<>();
-
- /** Type of navigation bar to be created. */
- private enum Type {
- TOP,
- TOP_UNPROVISIONED,
- BOTTOM,
- BOTTOM_UNPROVISIONED,
- LEFT,
- LEFT_UNPROVISIONED,
- RIGHT,
- RIGHT_UNPROVISIONED
- }
-
- @Inject
- public NavigationBarViewFactory(Context context) {
- mContext = context;
- }
-
- /** Gets the top window. */
- public ViewGroup getTopWindow() {
- return getWindowCached(Type.TOP);
- }
-
- /** Gets the bottom window. */
- public ViewGroup getBottomWindow() {
- return getWindowCached(Type.BOTTOM);
- }
-
- /** Gets the left window. */
- public ViewGroup getLeftWindow() {
- return getWindowCached(Type.LEFT);
- }
-
- /** Gets the right window. */
- public ViewGroup getRightWindow() {
- return getWindowCached(Type.RIGHT);
- }
-
- /** Gets the top bar. */
- public CarNavigationBarView getTopBar(boolean isSetUp) {
- return getBar(isSetUp, Type.TOP, Type.TOP_UNPROVISIONED);
- }
-
- /** Gets the bottom bar. */
- public CarNavigationBarView getBottomBar(boolean isSetUp) {
- return getBar(isSetUp, Type.BOTTOM, Type.BOTTOM_UNPROVISIONED);
- }
-
- /** Gets the left bar. */
- public CarNavigationBarView getLeftBar(boolean isSetUp) {
- return getBar(isSetUp, Type.LEFT, Type.LEFT_UNPROVISIONED);
- }
-
- /** Gets the right bar. */
- public CarNavigationBarView getRightBar(boolean isSetUp) {
- return getBar(isSetUp, Type.RIGHT, Type.RIGHT_UNPROVISIONED);
- }
-
- private ViewGroup getWindowCached(Type type) {
- if (mCachedContainerMap.containsKey(type)) {
- return mCachedContainerMap.get(type);
- }
-
- ViewGroup window = (ViewGroup) View.inflate(mContext,
- R.layout.navigation_bar_window, /* root= */ null);
- mCachedContainerMap.put(type, window);
- return mCachedContainerMap.get(type);
- }
-
- private CarNavigationBarView getBar(boolean isSetUp, Type provisioned, Type unprovisioned) {
- CarNavigationBarView view;
- if (isSetUp) {
- view = getBarCached(provisioned, sLayoutMap.get(provisioned));
- } else {
- view = getBarCached(unprovisioned, sLayoutMap.get(unprovisioned));
- }
-
- if (view == null) {
- String name = isSetUp ? provisioned.name() : unprovisioned.name();
- Log.e(TAG, "CarStatusBar failed inflate for " + name);
- throw new RuntimeException(
- "Unable to build " + name + " nav bar due to missing layout");
- }
- return view;
- }
-
- private CarNavigationBarView getBarCached(Type type, @LayoutRes int barLayout) {
- if (mCachedViewMap.containsKey(type)) {
- return mCachedViewMap.get(type);
- }
-
- CarNavigationBarView view = (CarNavigationBarView) View.inflate(mContext, barLayout,
- /* root= */ null);
-
- // Include a FocusParkingView at the beginning. The rotary controller "parks" the focus here
- // when the user navigates to another window. This is also used to prevent wrap-around.
- view.addView(new FocusParkingView(mContext), 0);
-
- mCachedViewMap.put(type, view);
- return mCachedViewMap.get(type);
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java
deleted file mode 100644
index 92cf600..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.navigationbar;
-
-import android.annotation.IntDef;
-import android.content.res.Resources;
-import android.graphics.PixelFormat;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.InsetsState;
-import android.view.ViewGroup;
-import android.view.WindowInsets;
-import android.view.WindowManager;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
-import com.android.systemui.car.notification.BottomNotificationPanelViewMediator;
-import com.android.systemui.car.notification.TopNotificationPanelViewMediator;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Target;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.inject.Inject;
-
-/**
- * Reads configs for system bars for each side (TOP, BOTTOM, LEFT, and RIGHT) and returns the
- * corresponding {@link android.view.WindowManager.LayoutParams} per the configuration.
- */
-@SysUISingleton
-public class SystemBarConfigs {
-
- private static final String TAG = SystemBarConfigs.class.getSimpleName();
- // The z-order from which system bars will start to appear on top of HUN's.
- private static final int HUN_ZORDER = 10;
-
- @IntDef(value = {TOP, BOTTOM, LEFT, RIGHT})
- @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
- private @interface SystemBarSide {
- }
-
- public static final int TOP = 0;
- public static final int BOTTOM = 1;
- public static final int LEFT = 2;
- public static final int RIGHT = 3;
-
- /*
- NOTE: The elements' order in the map below must be preserved as-is since the correct
- corresponding values are obtained by the index.
- */
- private static final int[] BAR_TYPE_MAP = {
- InsetsState.ITYPE_STATUS_BAR,
- InsetsState.ITYPE_NAVIGATION_BAR,
- InsetsState.ITYPE_CLIMATE_BAR,
- InsetsState.ITYPE_EXTRA_NAVIGATION_BAR
- };
-
- private static final Map<@SystemBarSide Integer, Integer> BAR_GRAVITY_MAP = new ArrayMap<>();
- private static final Map<@SystemBarSide Integer, String> BAR_TITLE_MAP = new ArrayMap<>();
- private static final Map<@SystemBarSide Integer, Integer> BAR_GESTURE_MAP = new ArrayMap<>();
-
- private final Resources mResources;
- private final Map<@SystemBarSide Integer, SystemBarConfig> mSystemBarConfigMap =
- new ArrayMap<>();
- private final List<@SystemBarSide Integer> mSystemBarSidesByZOrder = new ArrayList<>();
-
- private boolean mTopNavBarEnabled;
- private boolean mBottomNavBarEnabled;
- private boolean mLeftNavBarEnabled;
- private boolean mRightNavBarEnabled;
-
- @Inject
- public SystemBarConfigs(@Main Resources resources) {
- mResources = resources;
-
- populateMaps();
- readConfigs();
-
- checkEnabledBarsHaveUniqueBarTypes();
- checkAllOverlappingBarsHaveDifferentZOrders();
- checkSystemBarEnabledForNotificationPanel();
- checkHideBottomBarForKeyboardConfigSync();
-
- setInsetPaddingsForOverlappingCorners();
- sortSystemBarSidesByZOrder();
- }
-
- protected WindowManager.LayoutParams getLayoutParamsBySide(@SystemBarSide int side) {
- return mSystemBarConfigMap.get(side) != null
- ? mSystemBarConfigMap.get(side).getLayoutParams() : null;
- }
-
- protected boolean getEnabledStatusBySide(@SystemBarSide int side) {
- switch (side) {
- case TOP:
- return mTopNavBarEnabled;
- case BOTTOM:
- return mBottomNavBarEnabled;
- case LEFT:
- return mLeftNavBarEnabled;
- case RIGHT:
- return mRightNavBarEnabled;
- default:
- return false;
- }
- }
-
- protected boolean getHideForKeyboardBySide(@SystemBarSide int side) {
- return mSystemBarConfigMap.get(side) != null
- && mSystemBarConfigMap.get(side).getHideForKeyboard();
- }
-
- protected void insetSystemBar(@SystemBarSide int side, CarNavigationBarView view) {
- if (mSystemBarConfigMap.get(side) == null) return;
-
- int[] paddings = mSystemBarConfigMap.get(side).getPaddings();
- view.setPadding(paddings[2], paddings[0], paddings[3], paddings[1]);
- }
-
- protected void setInsetUpdater(@SystemBarSide int side, CarNavigationBarView view) {
- view.setOnApplyWindowInsetsListener((v, insets) -> {
- updateInsetPaddings(side, getSystemBarsVisibility(insets));
- insetSystemBar(side, view);
- return insets;
- });
- }
-
- protected List<Integer> getSystemBarSidesByZOrder() {
- return mSystemBarSidesByZOrder;
- }
-
- @VisibleForTesting
- void updateInsetPaddings(@SystemBarSide int side,
- Map<@SystemBarSide Integer, Boolean> barVisibilities) {
- SystemBarConfig currentConfig = mSystemBarConfigMap.get(side);
-
- if (currentConfig == null) return;
-
- if (isHorizontalBar(side)) {
- if (mLeftNavBarEnabled && currentConfig.getZOrder() < mSystemBarConfigMap.get(
- LEFT).getZOrder()) {
- currentConfig.setPaddingBySide(LEFT,
- barVisibilities.get(LEFT) ? mSystemBarConfigMap.get(LEFT).getGirth() : 0);
- }
- if (mRightNavBarEnabled && currentConfig.getZOrder() < mSystemBarConfigMap.get(
- RIGHT).getZOrder()) {
- currentConfig.setPaddingBySide(RIGHT,
- barVisibilities.get(RIGHT) ? mSystemBarConfigMap.get(RIGHT).getGirth() : 0);
- }
- }
- if (isVerticalBar(side)) {
- if (mTopNavBarEnabled && currentConfig.getZOrder() < mSystemBarConfigMap.get(
- TOP).getZOrder()) {
- currentConfig.setPaddingBySide(TOP,
- barVisibilities.get(TOP) ? mSystemBarConfigMap.get(TOP).getGirth() : 0);
- }
- if (mBottomNavBarEnabled && currentConfig.getZOrder() < mSystemBarConfigMap.get(
- BOTTOM).getZOrder()) {
- currentConfig.setPaddingBySide(BOTTOM,
- barVisibilities.get(BOTTOM) ? mSystemBarConfigMap.get(BOTTOM).getGirth()
- : 0);
- }
- }
- }
-
- @VisibleForTesting
- static int getHunZOrder() {
- return HUN_ZORDER;
- }
-
- private static void populateMaps() {
- BAR_GRAVITY_MAP.put(TOP, Gravity.TOP);
- BAR_GRAVITY_MAP.put(BOTTOM, Gravity.BOTTOM);
- BAR_GRAVITY_MAP.put(LEFT, Gravity.LEFT);
- BAR_GRAVITY_MAP.put(RIGHT, Gravity.RIGHT);
-
- BAR_TITLE_MAP.put(TOP, "TopCarSystemBar");
- BAR_TITLE_MAP.put(BOTTOM, "BottomCarSystemBar");
- BAR_TITLE_MAP.put(LEFT, "LeftCarSystemBar");
- BAR_TITLE_MAP.put(RIGHT, "RightCarSystemBar");
-
- BAR_GESTURE_MAP.put(TOP, InsetsState.ITYPE_TOP_MANDATORY_GESTURES);
- BAR_GESTURE_MAP.put(BOTTOM, InsetsState.ITYPE_BOTTOM_MANDATORY_GESTURES);
- BAR_GESTURE_MAP.put(LEFT, InsetsState.ITYPE_LEFT_MANDATORY_GESTURES);
- BAR_GESTURE_MAP.put(RIGHT, InsetsState.ITYPE_RIGHT_MANDATORY_GESTURES);
- }
-
- private void readConfigs() {
- mTopNavBarEnabled = mResources.getBoolean(R.bool.config_enableTopNavigationBar);
- mBottomNavBarEnabled = mResources.getBoolean(R.bool.config_enableBottomNavigationBar);
- mLeftNavBarEnabled = mResources.getBoolean(R.bool.config_enableLeftNavigationBar);
- mRightNavBarEnabled = mResources.getBoolean(R.bool.config_enableRightNavigationBar);
-
- if (mTopNavBarEnabled) {
- SystemBarConfig topBarConfig =
- new SystemBarConfigBuilder()
- .setSide(TOP)
- .setGirth(mResources.getDimensionPixelSize(
- R.dimen.car_top_navigation_bar_height))
- .setBarType(mResources.getInteger(R.integer.config_topSystemBarType))
- .setZOrder(mResources.getInteger(R.integer.config_topSystemBarZOrder))
- .setHideForKeyboard(mResources.getBoolean(
- R.bool.config_hideTopSystemBarForKeyboard))
- .build();
- mSystemBarConfigMap.put(TOP, topBarConfig);
- }
-
- if (mBottomNavBarEnabled) {
- SystemBarConfig bottomBarConfig =
- new SystemBarConfigBuilder()
- .setSide(BOTTOM)
- .setGirth(mResources.getDimensionPixelSize(
- R.dimen.car_bottom_navigation_bar_height))
- .setBarType(mResources.getInteger(R.integer.config_bottomSystemBarType))
- .setZOrder(
- mResources.getInteger(R.integer.config_bottomSystemBarZOrder))
- .setHideForKeyboard(mResources.getBoolean(
- R.bool.config_hideBottomSystemBarForKeyboard))
- .build();
- mSystemBarConfigMap.put(BOTTOM, bottomBarConfig);
- }
-
- if (mLeftNavBarEnabled) {
- SystemBarConfig leftBarConfig =
- new SystemBarConfigBuilder()
- .setSide(LEFT)
- .setGirth(mResources.getDimensionPixelSize(
- R.dimen.car_left_navigation_bar_width))
- .setBarType(mResources.getInteger(R.integer.config_leftSystemBarType))
- .setZOrder(mResources.getInteger(R.integer.config_leftSystemBarZOrder))
- .setHideForKeyboard(mResources.getBoolean(
- R.bool.config_hideLeftSystemBarForKeyboard))
- .build();
- mSystemBarConfigMap.put(LEFT, leftBarConfig);
- }
-
- if (mRightNavBarEnabled) {
- SystemBarConfig rightBarConfig =
- new SystemBarConfigBuilder()
- .setSide(RIGHT)
- .setGirth(mResources.getDimensionPixelSize(
- R.dimen.car_right_navigation_bar_width))
- .setBarType(mResources.getInteger(R.integer.config_rightSystemBarType))
- .setZOrder(mResources.getInteger(R.integer.config_rightSystemBarZOrder))
- .setHideForKeyboard(mResources.getBoolean(
- R.bool.config_hideRightSystemBarForKeyboard))
- .build();
- mSystemBarConfigMap.put(RIGHT, rightBarConfig);
- }
- }
-
- private void checkEnabledBarsHaveUniqueBarTypes() throws RuntimeException {
- Set<Integer> barTypesUsed = new ArraySet<>();
- int enabledNavBarCount = mSystemBarConfigMap.size();
-
- for (SystemBarConfig systemBarConfig : mSystemBarConfigMap.values()) {
- barTypesUsed.add(systemBarConfig.getBarType());
- }
-
- // The number of bar types used cannot be fewer than that of enabled system bars.
- if (barTypesUsed.size() < enabledNavBarCount) {
- throw new RuntimeException("Each enabled system bar must have a unique bar type. Check "
- + "the configuration in config.xml");
- }
- }
-
- private void checkAllOverlappingBarsHaveDifferentZOrders() {
- checkOverlappingBarsHaveDifferentZOrders(TOP, LEFT);
- checkOverlappingBarsHaveDifferentZOrders(TOP, RIGHT);
- checkOverlappingBarsHaveDifferentZOrders(BOTTOM, LEFT);
- checkOverlappingBarsHaveDifferentZOrders(BOTTOM, RIGHT);
- }
-
- private void checkSystemBarEnabledForNotificationPanel() throws RuntimeException {
- String notificationPanelMediatorName =
- mResources.getString(R.string.config_notificationPanelViewMediator);
- if (notificationPanelMediatorName == null) {
- return;
- }
-
- Class<?> notificationPanelMediatorUsed = null;
- try {
- notificationPanelMediatorUsed = Class.forName(notificationPanelMediatorName);
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
-
- if (!mTopNavBarEnabled && TopNotificationPanelViewMediator.class.isAssignableFrom(
- notificationPanelMediatorUsed)) {
- throw new RuntimeException(
- "Top System Bar must be enabled to use " + notificationPanelMediatorName);
- }
-
- if (!mBottomNavBarEnabled && BottomNotificationPanelViewMediator.class.isAssignableFrom(
- notificationPanelMediatorUsed)) {
- throw new RuntimeException("Bottom System Bar must be enabled to use "
- + notificationPanelMediatorName);
- }
- }
-
- private void checkHideBottomBarForKeyboardConfigSync() throws RuntimeException {
- if (mBottomNavBarEnabled) {
- boolean actual = mResources.getBoolean(R.bool.config_hideBottomSystemBarForKeyboard);
- boolean expected = mResources.getBoolean(
- com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard);
-
- if (actual != expected) {
- throw new RuntimeException("config_hideBottomSystemBarForKeyboard must not be "
- + "overlaid directly and should always refer to"
- + "config_automotiveHideNavBarForKeyboard. However, their values "
- + "currently do not sync. Set config_hideBottomSystemBarForKeyguard to "
- + "@*android:bool/config_automotiveHideNavBarForKeyboard. To change its "
- + "value, overlay config_automotiveHideNavBarForKeyboard in "
- + "framework/base/core/res/res.");
- }
- }
- }
-
- private void setInsetPaddingsForOverlappingCorners() {
- Map<@SystemBarSide Integer, Boolean> systemBarVisibilityOnInit =
- getSystemBarsVisibilityOnInit();
- updateInsetPaddings(TOP, systemBarVisibilityOnInit);
- updateInsetPaddings(BOTTOM, systemBarVisibilityOnInit);
- updateInsetPaddings(LEFT, systemBarVisibilityOnInit);
- updateInsetPaddings(RIGHT, systemBarVisibilityOnInit);
- }
-
- private void sortSystemBarSidesByZOrder() {
- List<SystemBarConfig> systemBarsByZOrder = new ArrayList<>(mSystemBarConfigMap.values());
-
- systemBarsByZOrder.sort(new Comparator<SystemBarConfig>() {
- @Override
- public int compare(SystemBarConfig o1, SystemBarConfig o2) {
- return o1.getZOrder() - o2.getZOrder();
- }
- });
-
- systemBarsByZOrder.forEach(systemBarConfig -> {
- mSystemBarSidesByZOrder.add(systemBarConfig.getSide());
- });
- }
-
- @InsetsState.InternalInsetsType
- private int getSystemBarTypeBySide(@SystemBarSide int side) {
- return mSystemBarConfigMap.get(side) != null
- ? mSystemBarConfigMap.get(side).getBarType() : null;
- }
-
- // On init, system bars are visible as long as they are enabled.
- private Map<@SystemBarSide Integer, Boolean> getSystemBarsVisibilityOnInit() {
- ArrayMap<@SystemBarSide Integer, Boolean> visibilityMap = new ArrayMap<>();
- visibilityMap.put(TOP, mTopNavBarEnabled);
- visibilityMap.put(BOTTOM, mBottomNavBarEnabled);
- visibilityMap.put(LEFT, mLeftNavBarEnabled);
- visibilityMap.put(RIGHT, mRightNavBarEnabled);
- return visibilityMap;
- }
-
- private Map<@SystemBarSide Integer, Boolean> getSystemBarsVisibility(WindowInsets insets) {
- ArrayMap<@SystemBarSide Integer, Boolean> visibilityMap = new ArrayMap<>();
- if (mTopNavBarEnabled) {
- visibilityMap.put(TOP, getSystemBarInsetVisibleBySide(TOP, insets));
- }
- if (mBottomNavBarEnabled) {
- visibilityMap.put(BOTTOM, getSystemBarInsetVisibleBySide(BOTTOM, insets));
- }
- if (mLeftNavBarEnabled) {
- visibilityMap.put(LEFT, getSystemBarInsetVisibleBySide(LEFT, insets));
- }
- if (mRightNavBarEnabled) {
- visibilityMap.put(RIGHT, getSystemBarInsetVisibleBySide(RIGHT, insets));
- }
- return visibilityMap;
- }
-
- private boolean getSystemBarInsetVisibleBySide(@SystemBarSide int side, WindowInsets insets) {
- if (mSystemBarConfigMap.get(side) == null) return false;
-
- int internalInsetType = BAR_TYPE_MAP[getSystemBarTypeBySide(side)];
- int publicInsetType = InsetsState.toPublicType(internalInsetType);
-
- return insets.isVisible(publicInsetType);
- }
-
- private void checkOverlappingBarsHaveDifferentZOrders(@SystemBarSide int horizontalSide,
- @SystemBarSide int verticalSide) {
-
- if (isVerticalBar(horizontalSide) || isHorizontalBar(verticalSide)) {
- Log.w(TAG, "configureBarPaddings: Returning immediately since the horizontal and "
- + "vertical sides were not provided correctly.");
- return;
- }
-
- SystemBarConfig horizontalBarConfig = mSystemBarConfigMap.get(horizontalSide);
- SystemBarConfig verticalBarConfig = mSystemBarConfigMap.get(verticalSide);
-
- if (verticalBarConfig != null && horizontalBarConfig != null) {
- int horizontalBarZOrder = horizontalBarConfig.getZOrder();
- int verticalBarZOrder = verticalBarConfig.getZOrder();
-
- if (horizontalBarZOrder == verticalBarZOrder) {
- throw new RuntimeException(
- BAR_TITLE_MAP.get(horizontalSide) + " " + BAR_TITLE_MAP.get(verticalSide)
- + " have the same Z-Order, and so their placing order cannot be "
- + "determined. Determine which bar should be placed on top of the "
- + "other bar and change the Z-order in config.xml accordingly."
- );
- }
- }
- }
-
- private static boolean isHorizontalBar(@SystemBarSide int side) {
- return side == TOP || side == BOTTOM;
- }
-
- private static boolean isVerticalBar(@SystemBarSide int side) {
- return side == LEFT || side == RIGHT;
- }
-
- private static final class SystemBarConfig {
- private final int mSide;
- private final int mBarType;
- private final int mGirth;
- private final int mZOrder;
- private final boolean mHideForKeyboard;
-
- private int[] mPaddings = new int[]{0, 0, 0, 0};
-
- private SystemBarConfig(@SystemBarSide int side, int barType, int girth, int zOrder,
- boolean hideForKeyboard) {
- mSide = side;
- mBarType = barType;
- mGirth = girth;
- mZOrder = zOrder;
- mHideForKeyboard = hideForKeyboard;
- }
-
- private int getSide() {
- return mSide;
- }
-
- private int getBarType() {
- return mBarType;
- }
-
- private int getGirth() {
- return mGirth;
- }
-
- private int getZOrder() {
- return mZOrder;
- }
-
- private boolean getHideForKeyboard() {
- return mHideForKeyboard;
- }
-
- private int[] getPaddings() {
- return mPaddings;
- }
-
- private WindowManager.LayoutParams getLayoutParams() {
- WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
- isHorizontalBar(mSide) ? ViewGroup.LayoutParams.MATCH_PARENT : mGirth,
- isHorizontalBar(mSide) ? mGirth : ViewGroup.LayoutParams.MATCH_PARENT,
- mapZOrderToBarType(mZOrder),
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
- | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
- PixelFormat.TRANSLUCENT);
- lp.setTitle(BAR_TITLE_MAP.get(mSide));
- lp.providesInsetsTypes = new int[]{BAR_TYPE_MAP[mBarType], BAR_GESTURE_MAP.get(mSide)};
- lp.setFitInsetsTypes(0);
- lp.windowAnimations = 0;
- lp.gravity = BAR_GRAVITY_MAP.get(mSide);
- return lp;
- }
-
- private int mapZOrderToBarType(int zOrder) {
- return zOrder >= HUN_ZORDER ? WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL
- : WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
- }
-
- private void setPaddingBySide(@SystemBarSide int side, int padding) {
- mPaddings[side] = padding;
- }
- }
-
- private static final class SystemBarConfigBuilder {
- private int mSide;
- private int mBarType;
- private int mGirth;
- private int mZOrder;
- private boolean mHideForKeyboard;
-
- private SystemBarConfigBuilder setSide(@SystemBarSide int side) {
- mSide = side;
- return this;
- }
-
- private SystemBarConfigBuilder setBarType(int type) {
- mBarType = type;
- return this;
- }
-
- private SystemBarConfigBuilder setGirth(int girth) {
- mGirth = girth;
- return this;
- }
-
- private SystemBarConfigBuilder setZOrder(int zOrder) {
- mZOrder = zOrder;
- return this;
- }
-
- private SystemBarConfigBuilder setHideForKeyboard(boolean hide) {
- mHideForKeyboard = hide;
- return this;
- }
-
- private SystemBarConfig build() {
- return new SystemBarConfig(mSide, mBarType, mGirth, mZOrder, mHideForKeyboard);
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/BottomNotificationPanelViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/BottomNotificationPanelViewMediator.java
deleted file mode 100644
index 8468bef..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/notification/BottomNotificationPanelViewMediator.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.notification;
-
-import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.car.navigationbar.CarNavigationBarController;
-import com.android.systemui.car.window.OverlayPanelViewController;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.statusbar.policy.ConfigurationController;
-
-import javax.inject.Inject;
-
-/**
- * Implementation of NotificationPanelViewMediator that sets the notification panel to be opened
- * from the top navigation bar.
- */
-@SysUISingleton
-public class BottomNotificationPanelViewMediator extends NotificationPanelViewMediator {
-
- @Inject
- public BottomNotificationPanelViewMediator(
- CarNavigationBarController carNavigationBarController,
- NotificationPanelViewController notificationPanelViewController,
-
- PowerManagerHelper powerManagerHelper,
- BroadcastDispatcher broadcastDispatcher,
-
- CarDeviceProvisionedController carDeviceProvisionedController,
- ConfigurationController configurationController
- ) {
- super(carNavigationBarController,
- notificationPanelViewController,
- powerManagerHelper,
- broadcastDispatcher,
- carDeviceProvisionedController,
- configurationController);
- notificationPanelViewController.setOverlayDirection(
- OverlayPanelViewController.OVERLAY_FROM_BOTTOM_BAR);
- }
-
- @Override
- public void registerListeners() {
- super.registerListeners();
- getCarNavigationBarController().registerBottomBarTouchListener(
- getNotificationPanelViewController().getDragOpenTouchListener());
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainer.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainer.java
deleted file mode 100644
index 3b22a30..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainer.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.notification;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.PixelFormat;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-
-import com.android.car.notification.R;
-import com.android.car.notification.headsup.CarHeadsUpNotificationContainer;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.car.window.OverlayViewGlobalStateController;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-
-import javax.inject.Inject;
-
-/**
- * A controller for SysUI's HUN display.
- */
-@SysUISingleton
-public class CarHeadsUpNotificationSystemContainer implements CarHeadsUpNotificationContainer {
- private final CarDeviceProvisionedController mCarDeviceProvisionedController;
- private final OverlayViewGlobalStateController mOverlayViewGlobalStateController;
-
- private final ViewGroup mWindow;
- private final ViewGroup mHeadsUpContentFrame;
-
- @Inject
- CarHeadsUpNotificationSystemContainer(Context context,
- @Main Resources resources,
- CarDeviceProvisionedController deviceProvisionedController,
- WindowManager windowManager,
- OverlayViewGlobalStateController overlayViewGlobalStateController) {
- mCarDeviceProvisionedController = deviceProvisionedController;
- mOverlayViewGlobalStateController = overlayViewGlobalStateController;
-
- boolean showOnBottom = resources.getBoolean(R.bool.config_showHeadsUpNotificationOnBottom);
-
- // Use TYPE_STATUS_BAR_SUB_PANEL window type since we need to find a window that is above
- // status bar but below navigation bar.
- WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- WindowManager.LayoutParams.WRAP_CONTENT,
- WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL,
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
- PixelFormat.TRANSLUCENT);
-
- lp.gravity = showOnBottom ? Gravity.BOTTOM : Gravity.TOP;
- lp.setTitle("HeadsUpNotification");
-
- int layoutId = showOnBottom
- ? R.layout.headsup_container_bottom
- : R.layout.headsup_container;
- mWindow = (ViewGroup) LayoutInflater.from(context).inflate(layoutId, null, false);
- windowManager.addView(mWindow, lp);
- mWindow.setVisibility(View.INVISIBLE);
- mHeadsUpContentFrame = mWindow.findViewById(R.id.headsup_content);
- }
-
- private void animateShow() {
- if (mCarDeviceProvisionedController.isCurrentUserFullySetup()
- && mOverlayViewGlobalStateController.shouldShowHUN()) {
- mWindow.setVisibility(View.VISIBLE);
- }
- }
-
- private void animateHide() {
- mWindow.setVisibility(View.INVISIBLE);
- }
-
- @Override
- public void displayNotification(View notificationView) {
- mHeadsUpContentFrame.addView(notificationView);
- animateShow();
- }
-
- @Override
- public void removeNotification(View notificationView) {
- mHeadsUpContentFrame.removeView(notificationView);
- if (mHeadsUpContentFrame.getChildCount() == 0) {
- animateHide();
- }
- }
-
- @Override
- public boolean isVisible() {
- return mWindow.getVisibility() == View.VISIBLE;
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/CarNotificationModule.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/CarNotificationModule.java
deleted file mode 100644
index 8a3bcfc..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/notification/CarNotificationModule.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.notification;
-
-import android.content.Context;
-
-import com.android.car.notification.CarHeadsUpNotificationManager;
-import com.android.car.notification.CarNotificationListener;
-import com.android.car.notification.CarUxRestrictionManagerWrapper;
-import com.android.car.notification.NotificationClickHandlerFactory;
-import com.android.car.notification.NotificationDataManager;
-import com.android.car.notification.headsup.CarHeadsUpNotificationContainer;
-import com.android.internal.statusbar.IStatusBarService;
-import com.android.systemui.dagger.SysUISingleton;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.Provides;
-
-/**
- * Module for Car SysUI Notifications
- */
-@Module
-public abstract class CarNotificationModule {
- @Provides
- @SysUISingleton
- static NotificationClickHandlerFactory provideNotificationClickHandlerFactory(
- IStatusBarService barService) {
- return new NotificationClickHandlerFactory(barService);
- }
-
- @Provides
- @SysUISingleton
- static NotificationDataManager provideNotificationDataManager() {
- return new NotificationDataManager();
- }
-
- @Provides
- @SysUISingleton
- static CarUxRestrictionManagerWrapper provideCarUxRestrictionManagerWrapper() {
- return new CarUxRestrictionManagerWrapper();
- }
-
- @Provides
- @SysUISingleton
- static CarNotificationListener provideCarNotificationListener(Context context,
- CarUxRestrictionManagerWrapper carUxRestrictionManagerWrapper,
- CarHeadsUpNotificationManager carHeadsUpNotificationManager,
- NotificationDataManager notificationDataManager) {
- CarNotificationListener listener = new CarNotificationListener();
- listener.registerAsSystemService(context, carUxRestrictionManagerWrapper,
- carHeadsUpNotificationManager, notificationDataManager);
- return listener;
- }
-
- @Provides
- @SysUISingleton
- static CarHeadsUpNotificationManager provideCarHeadsUpNotificationManager(Context context,
- NotificationClickHandlerFactory notificationClickHandlerFactory,
- NotificationDataManager notificationDataManager,
- CarHeadsUpNotificationContainer headsUpNotificationDisplay) {
- return new CarHeadsUpNotificationManager(context, notificationClickHandlerFactory,
- notificationDataManager, headsUpNotificationDisplay);
- }
-
- @Binds
- abstract CarHeadsUpNotificationContainer bindsCarHeadsUpNotificationContainer(
- CarHeadsUpNotificationSystemContainer carHeadsUpNotificationSystemContainer);
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java
deleted file mode 100644
index 599e69c..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.notification;
-
-import android.app.ActivityManager;
-import android.car.Car;
-import android.car.drivingstate.CarUxRestrictionsManager;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.inputmethodservice.InputMethodService;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowInsets;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.notification.CarNotificationListener;
-import com.android.car.notification.CarNotificationView;
-import com.android.car.notification.CarUxRestrictionManagerWrapper;
-import com.android.car.notification.NotificationClickHandlerFactory;
-import com.android.car.notification.NotificationDataManager;
-import com.android.car.notification.NotificationViewController;
-import com.android.car.notification.PreprocessingManager;
-import com.android.internal.statusbar.IStatusBarService;
-import com.android.systemui.R;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.car.CarServiceProvider;
-import com.android.systemui.car.window.OverlayPanelViewController;
-import com.android.systemui.car.window.OverlayViewController;
-import com.android.systemui.car.window.OverlayViewGlobalStateController;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dagger.qualifiers.UiBackground;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.StatusBarState;
-import com.android.wm.shell.animation.FlingAnimationUtils;
-
-import java.util.concurrent.Executor;
-
-import javax.inject.Inject;
-
-/** View controller for the notification panel. */
-@SysUISingleton
-public class NotificationPanelViewController extends OverlayPanelViewController
- implements CommandQueue.Callbacks {
-
- private static final boolean DEBUG = true;
- private static final String TAG = "NotificationPanelViewController";
-
- private final Context mContext;
- private final Resources mResources;
- private final CarServiceProvider mCarServiceProvider;
- private final IStatusBarService mBarService;
- private final CommandQueue mCommandQueue;
- private final Executor mUiBgExecutor;
- private final NotificationDataManager mNotificationDataManager;
- private final CarUxRestrictionManagerWrapper mCarUxRestrictionManagerWrapper;
- private final CarNotificationListener mCarNotificationListener;
- private final NotificationClickHandlerFactory mNotificationClickHandlerFactory;
- private final StatusBarStateController mStatusBarStateController;
- private final boolean mEnableHeadsUpNotificationWhenNotificationShadeOpen;
- private final NotificationVisibilityLogger mNotificationVisibilityLogger;
-
- private final boolean mFitTopSystemBarInset;
- private final boolean mFitBottomSystemBarInset;
- private final boolean mFitLeftSystemBarInset;
- private final boolean mFitRightSystemBarInset;
-
- private float mInitialBackgroundAlpha;
- private float mBackgroundAlphaDiff;
-
- private CarNotificationView mNotificationView;
- private View mHandleBar;
- private RecyclerView mNotificationList;
- private NotificationViewController mNotificationViewController;
-
- private boolean mNotificationListAtEnd;
- private float mFirstTouchDownOnGlassPane;
- private boolean mNotificationListAtEndAtTimeOfTouch;
- private boolean mIsSwipingVerticallyToClose;
- private boolean mIsNotificationCardSwiping;
- private boolean mImeVisible = false;
-
- private OnUnseenCountUpdateListener mUnseenCountUpdateListener;
-
- @Inject
- public NotificationPanelViewController(
- Context context,
- @Main Resources resources,
- OverlayViewGlobalStateController overlayViewGlobalStateController,
- FlingAnimationUtils.Builder flingAnimationUtilsBuilder,
- @UiBackground Executor uiBgExecutor,
-
- /* Other things */
- CarServiceProvider carServiceProvider,
- CarDeviceProvisionedController carDeviceProvisionedController,
-
- /* Things needed for notifications */
- IStatusBarService barService,
- CommandQueue commandQueue,
- NotificationDataManager notificationDataManager,
- CarUxRestrictionManagerWrapper carUxRestrictionManagerWrapper,
- CarNotificationListener carNotificationListener,
- NotificationClickHandlerFactory notificationClickHandlerFactory,
- NotificationVisibilityLogger notificationVisibilityLogger,
-
- /* Things that need to be replaced */
- StatusBarStateController statusBarStateController
- ) {
- super(context, resources, R.id.notification_panel_stub, overlayViewGlobalStateController,
- flingAnimationUtilsBuilder, carDeviceProvisionedController);
- mContext = context;
- mResources = resources;
- mCarServiceProvider = carServiceProvider;
- mBarService = barService;
- mCommandQueue = commandQueue;
- mUiBgExecutor = uiBgExecutor;
- mNotificationDataManager = notificationDataManager;
- mCarUxRestrictionManagerWrapper = carUxRestrictionManagerWrapper;
- mCarNotificationListener = carNotificationListener;
- mNotificationClickHandlerFactory = notificationClickHandlerFactory;
- mStatusBarStateController = statusBarStateController;
- mNotificationVisibilityLogger = notificationVisibilityLogger;
-
- mCommandQueue.addCallback(this);
-
- // Notification background setup.
- mInitialBackgroundAlpha = (float) mResources.getInteger(
- R.integer.config_initialNotificationBackgroundAlpha) / 100;
- if (mInitialBackgroundAlpha < 0 || mInitialBackgroundAlpha > 100) {
- throw new RuntimeException(
- "Unable to setup notification bar due to incorrect initial background alpha"
- + " percentage");
- }
- float finalBackgroundAlpha = Math.max(
- mInitialBackgroundAlpha,
- (float) mResources.getInteger(
- R.integer.config_finalNotificationBackgroundAlpha) / 100);
- if (finalBackgroundAlpha < 0 || finalBackgroundAlpha > 100) {
- throw new RuntimeException(
- "Unable to setup notification bar due to incorrect final background alpha"
- + " percentage");
- }
- mBackgroundAlphaDiff = finalBackgroundAlpha - mInitialBackgroundAlpha;
-
- mEnableHeadsUpNotificationWhenNotificationShadeOpen = mResources.getBoolean(
- com.android.car.notification.R.bool
- .config_enableHeadsUpNotificationWhenNotificationShadeOpen);
-
- mFitTopSystemBarInset = mResources.getBoolean(
- R.bool.config_notif_panel_inset_by_top_systembar);
- mFitBottomSystemBarInset = mResources.getBoolean(
- R.bool.config_notif_panel_inset_by_bottom_systembar);
- mFitLeftSystemBarInset = mResources.getBoolean(
- R.bool.config_notif_panel_inset_by_left_systembar);
- mFitRightSystemBarInset = mResources.getBoolean(
- R.bool.config_notif_panel_inset_by_right_systembar);
- }
-
- // CommandQueue.Callbacks
-
- @Override
- public void animateExpandNotificationsPanel() {
- if (!isPanelExpanded()) {
- toggle();
- }
- }
-
- @Override
- public void animateCollapsePanels(int flags, boolean force) {
- if (isPanelExpanded()) {
- toggle();
- }
- }
-
- @Override
- public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
- boolean showImeSwitcher) {
- if (mContext.getDisplayId() != displayId) {
- return;
- }
- mImeVisible = (vis & InputMethodService.IME_VISIBLE) != 0;
- }
-
- // OverlayViewController
-
- @Override
- protected void onFinishInflate() {
- reinflate();
- }
-
- @Override
- protected void hideInternal() {
- super.hideInternal();
- mNotificationVisibilityLogger.stop();
- }
-
- @Override
- protected boolean shouldShowNavigationBarInsets() {
- return true;
- }
-
- @Override
- protected boolean shouldShowStatusBarInsets() {
- return true;
- }
-
- @Override
- protected int getInsetSidesToFit() {
- int insetSidesToFit = OverlayViewController.NO_INSET_SIDE;
-
- if (mFitTopSystemBarInset) {
- insetSidesToFit = insetSidesToFit | WindowInsets.Side.TOP;
- }
-
- if (mFitBottomSystemBarInset) {
- insetSidesToFit = insetSidesToFit | WindowInsets.Side.BOTTOM;
- }
-
- if (mFitLeftSystemBarInset) {
- insetSidesToFit = insetSidesToFit | WindowInsets.Side.LEFT;
- }
-
- if (mFitRightSystemBarInset) {
- insetSidesToFit = insetSidesToFit | WindowInsets.Side.RIGHT;
- }
-
- return insetSidesToFit;
- }
-
- @Override
- protected boolean shouldShowHUN() {
- return mEnableHeadsUpNotificationWhenNotificationShadeOpen;
- }
-
- @Override
- protected boolean shouldUseStableInsets() {
- // When IME is visible, then the inset from the nav bar should not be applied.
- return !mImeVisible;
- }
-
- /** Reinflates the view. */
- public void reinflate() {
- ViewGroup container = (ViewGroup) getLayout();
- container.removeView(mNotificationView);
-
- mNotificationView = (CarNotificationView) LayoutInflater.from(mContext).inflate(
- R.layout.notification_center_activity, container,
- /* attachToRoot= */ false);
-
- container.addView(mNotificationView);
- onNotificationViewInflated();
- }
-
- private void onNotificationViewInflated() {
- // Find views.
- mNotificationView = getLayout().findViewById(R.id.notification_view);
- setupHandleBar();
- setupNotificationPanel();
-
- mNotificationClickHandlerFactory.registerClickListener((launchResult, alertEntry) -> {
- if (launchResult == ActivityManager.START_TASK_TO_FRONT
- || launchResult == ActivityManager.START_SUCCESS) {
- animateCollapsePanel();
- }
- });
-
- mNotificationDataManager.setOnUnseenCountUpdateListener(() -> {
- if (mUnseenCountUpdateListener != null) {
- mUnseenCountUpdateListener.onUnseenCountUpdate(
- mNotificationDataManager.getUnseenNotificationCount());
- }
- mCarNotificationListener.setNotificationsShown(
- mNotificationDataManager.getSeenNotifications());
- // This logs both when the notification panel is expanded and when the notification
- // panel is scrolled.
- mNotificationVisibilityLogger.log(isPanelExpanded());
- });
-
- mNotificationClickHandlerFactory.setNotificationDataManager(mNotificationDataManager);
- mNotificationView.setClickHandlerFactory(mNotificationClickHandlerFactory);
- mNotificationView.setNotificationDataManager(mNotificationDataManager);
-
- mCarServiceProvider.addListener(car -> {
- CarUxRestrictionsManager carUxRestrictionsManager =
- (CarUxRestrictionsManager)
- car.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);
- mCarUxRestrictionManagerWrapper.setCarUxRestrictionsManager(
- carUxRestrictionsManager);
-
- mNotificationViewController = new NotificationViewController(
- mNotificationView,
- PreprocessingManager.getInstance(mContext),
- mCarNotificationListener,
- mCarUxRestrictionManagerWrapper,
- mNotificationDataManager);
- mNotificationViewController.enable();
- });
- }
-
- private void setupHandleBar() {
- mHandleBar = mNotificationView.findViewById(R.id.handle_bar);
- GestureDetector handleBarCloseNotificationGestureDetector = new GestureDetector(mContext,
- new HandleBarCloseGestureListener());
- mHandleBar.setOnTouchListener((v, event) -> {
- handleBarCloseNotificationGestureDetector.onTouchEvent(event);
- maybeCompleteAnimation(event);
- return true;
- });
- }
-
- private void setupNotificationPanel() {
- View glassPane = mNotificationView.findViewById(R.id.glass_pane);
- mNotificationList = mNotificationView.findViewById(R.id.notifications);
- GestureDetector closeGestureDetector = new GestureDetector(mContext,
- new CloseGestureListener() {
- @Override
- protected void close() {
- if (isPanelExpanded()) {
- animateCollapsePanel();
- }
- }
- });
-
- // The glass pane is used to view touch events before passed to the notification list.
- // This allows us to initialize gesture listeners and detect when to close the notifications
- glassPane.setOnTouchListener((v, event) -> {
- if (isClosingAction(event)) {
- mNotificationListAtEndAtTimeOfTouch = false;
- }
- if (isOpeningAction(event)) {
- mFirstTouchDownOnGlassPane = event.getRawX();
- mNotificationListAtEndAtTimeOfTouch = mNotificationListAtEnd;
- // Reset the tracker when there is a touch down on the glass pane.
- setIsTracking(false);
- // Pass the down event to gesture detector so that it knows where the touch event
- // started.
- closeGestureDetector.onTouchEvent(event);
- }
- return false;
- });
-
- mNotificationList.addOnScrollListener(new RecyclerView.OnScrollListener() {
- @Override
- public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
- super.onScrolled(recyclerView, dx, dy);
- // Check if we can scroll vertically in the animation direction.
- if (!mNotificationList.canScrollVertically(mAnimateDirection)) {
- mNotificationListAtEnd = true;
- return;
- }
- mNotificationListAtEnd = false;
- mIsSwipingVerticallyToClose = false;
- mNotificationListAtEndAtTimeOfTouch = false;
- }
- });
-
- mNotificationList.setOnTouchListener((v, event) -> {
- mIsNotificationCardSwiping = Math.abs(mFirstTouchDownOnGlassPane - event.getRawX())
- > SWIPE_MAX_OFF_PATH;
- if (mNotificationListAtEndAtTimeOfTouch && mNotificationListAtEnd) {
- // We need to save the state here as if notification card is swiping we will
- // change the mNotificationListAtEndAtTimeOfTouch. This is to protect
- // closing the notification shade while the notification card is being swiped.
- mIsSwipingVerticallyToClose = true;
- }
-
- // If the card is swiping we should not allow the notification shade to close.
- // Hence setting mNotificationListAtEndAtTimeOfTouch to false will stop that
- // for us. We are also checking for isTracking() because while swiping the
- // notification shade to close if the user goes a bit horizontal while swiping
- // upwards then also this should close.
- if (mIsNotificationCardSwiping && !isTracking()) {
- mNotificationListAtEndAtTimeOfTouch = false;
- }
-
- boolean handled = closeGestureDetector.onTouchEvent(event);
- boolean isTracking = isTracking();
- Rect rect = getLayout().getClipBounds();
- float clippedHeight = 0;
- if (rect != null) {
- clippedHeight = rect.bottom;
- }
- if (!handled && isClosingAction(event) && mIsSwipingVerticallyToClose) {
- if (getSettleClosePercentage() < getPercentageFromEndingEdge() && isTracking) {
- animatePanel(DEFAULT_FLING_VELOCITY, false);
- } else if (clippedHeight != getLayout().getHeight() && isTracking) {
- // this can be caused when user is at the end of the list and trying to
- // fling to top of the list by scrolling down.
- animatePanel(DEFAULT_FLING_VELOCITY, true);
- }
- }
-
- // Updating the mNotificationListAtEndAtTimeOfTouch state has to be done after
- // the event has been passed to the closeGestureDetector above, such that the
- // closeGestureDetector sees the up event before the state has changed.
- if (isClosingAction(event)) {
- mNotificationListAtEndAtTimeOfTouch = false;
- }
- return handled || isTracking;
- });
- }
-
- /** Called when the car power state is changed to ON. */
- public void onCarPowerStateOn() {
- if (mNotificationClickHandlerFactory != null) {
- mNotificationClickHandlerFactory.clearAllNotifications();
- }
- mNotificationDataManager.clearAll();
- }
-
- // OverlayPanelViewController
-
- @Override
- protected boolean shouldAnimateCollapsePanel() {
- return true;
- }
-
- @Override
- protected void onAnimateCollapsePanel() {
- // No op.
- }
-
- @Override
- protected boolean shouldAnimateExpandPanel() {
- return mCommandQueue.panelsEnabled();
- }
-
- @Override
- protected void onAnimateExpandPanel() {
- mNotificationList.scrollToPosition(0);
- }
-
- @Override
- protected void onCollapseAnimationEnd() {
- mNotificationViewController.onVisibilityChanged(false);
- }
-
- @Override
- protected void onExpandAnimationEnd() {
- mNotificationViewController.onVisibilityChanged(true);
- mNotificationView.setVisibleNotificationsAsSeen();
- }
-
- @Override
- protected void onPanelVisible(boolean visible) {
- super.onPanelVisible(visible);
- mUiBgExecutor.execute(() -> {
- try {
- if (visible) {
- // When notification panel is open even just a bit, we want to clear
- // notification effects.
- boolean clearNotificationEffects =
- mStatusBarStateController.getState() != StatusBarState.KEYGUARD;
- mBarService.onPanelRevealed(clearNotificationEffects,
- mNotificationDataManager.getVisibleNotifications().size());
- } else {
- mBarService.onPanelHidden();
- }
- } catch (RemoteException ex) {
- // Won't fail unless the world has ended.
- Log.e(TAG, String.format(
- "Unable to notify StatusBarService of panel visibility: %s", visible));
- }
- });
-
- }
-
- @Override
- protected void onPanelExpanded(boolean expand) {
- super.onPanelExpanded(expand);
-
- if (expand && mStatusBarStateController.getState() != StatusBarState.KEYGUARD) {
- if (DEBUG) {
- Log.v(TAG, "clearing notification effects from setExpandedHeight");
- }
- clearNotificationEffects();
- }
- if (!expand) {
- mNotificationVisibilityLogger.log(isPanelExpanded());
- }
- }
-
- /**
- * Clear Buzz/Beep/Blink.
- */
- private void clearNotificationEffects() {
- try {
- mBarService.clearNotificationEffects();
- } catch (RemoteException e) {
- // Won't fail unless the world has ended.
- }
- }
-
- @Override
- protected void onOpenScrollStart() {
- mNotificationList.scrollToPosition(0);
- }
-
- @Override
- protected void onScroll(int y) {
- if (mHandleBar != null) {
- ViewGroup.MarginLayoutParams lp =
- (ViewGroup.MarginLayoutParams) mHandleBar.getLayoutParams();
- // Adjust handlebar to new pointer position, and a little more depending on the
- // animate direction so the bar can be seen fully.
- if (mAnimateDirection > 0) {
- mHandleBar.setTranslationY(y - mHandleBar.getHeight() - lp.bottomMargin);
- } else {
- mHandleBar.setTranslationY(y + mHandleBar.getHeight() + lp.topMargin);
- }
- }
-
- if (mNotificationView.getHeight() > 0) {
- Drawable background = mNotificationView.getBackground().mutate();
- background.setAlpha((int) (getBackgroundAlpha(y) * 255));
- mNotificationView.setBackground(background);
- }
- }
-
- @Override
- protected boolean shouldAllowClosingScroll() {
- // Unless the notification list is at the end, the panel shouldn't be allowed to
- // collapse on scroll.
- return mNotificationListAtEndAtTimeOfTouch;
- }
-
- /**
- * Calculates the alpha value for the background based on how much of the notification
- * shade is visible to the user. When the notification shade is completely open then
- * alpha value will be 1.
- */
- private float getBackgroundAlpha(int y) {
- float fractionCovered =
- ((float) (mAnimateDirection > 0 ? y : mNotificationView.getHeight() - y))
- / mNotificationView.getHeight();
- return mInitialBackgroundAlpha + fractionCovered * mBackgroundAlphaDiff;
- }
-
- /** Sets the unseen count listener. */
- public void setOnUnseenCountUpdateListener(OnUnseenCountUpdateListener listener) {
- mUnseenCountUpdateListener = listener;
- }
-
- /** Listener that is updated when the number of unseen notifications changes. */
- public interface OnUnseenCountUpdateListener {
- /**
- * This method is automatically called whenever there is an update to the number of unseen
- * notifications. This method can be extended by OEMs to customize the desired logic.
- */
- void onUnseenCountUpdate(int unseenNotificationCount);
- }
-
- /**
- * To be installed on the handle bar.
- */
- private class HandleBarCloseGestureListener extends
- GestureDetector.SimpleOnGestureListener {
-
- @Override
- public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
- float distanceY) {
- calculatePercentageFromEndingEdge(event2.getRawY());
- // To prevent the jump in the clip bounds while closing the notification panel using
- // the handle bar we should calculate the height using the diff of event1 and event2.
- // This will help the notification shade to clip smoothly as the event2 value changes
- // as event1 value will be fixed.
- float diff = mAnimateDirection * (event1.getRawY() - event2.getRawY());
- float y = mAnimateDirection > 0
- ? getLayout().getHeight() - diff
- : diff;
- // Ensure the position is within the overlay panel.
- y = Math.max(0, Math.min(y, getLayout().getHeight()));
- setViewClipBounds((int) y);
- return true;
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewMediator.java
deleted file mode 100644
index 17b6b74..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewMediator.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.notification;
-
-import android.car.hardware.power.CarPowerManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Configuration;
-import android.os.UserHandle;
-import android.util.Log;
-
-import androidx.annotation.CallSuper;
-
-import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.car.navigationbar.CarNavigationBarController;
-import com.android.systemui.car.window.OverlayViewMediator;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.statusbar.policy.ConfigurationController;
-
-import javax.inject.Inject;
-
-/**
- * The view mediator which attaches the view controller to other elements of the system ui. Disables
- * drag open behavior of the notification panel from any navigation bar.
- */
-@SysUISingleton
-public class NotificationPanelViewMediator implements OverlayViewMediator,
- ConfigurationController.ConfigurationListener {
-
- private static final boolean DEBUG = false;
- private static final String TAG = "NotificationPanelVM";
-
- private final CarNavigationBarController mCarNavigationBarController;
- private final NotificationPanelViewController mNotificationPanelViewController;
- private final PowerManagerHelper mPowerManagerHelper;
- private final BroadcastDispatcher mBroadcastDispatcher;
- private final CarDeviceProvisionedController mCarDeviceProvisionedController;
- private final ConfigurationController mConfigurationController;
-
- private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (DEBUG) Log.v(TAG, "onReceive: " + intent);
- String action = intent.getAction();
- if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
- if (mNotificationPanelViewController.isPanelExpanded()) {
- mNotificationPanelViewController.toggle();
- }
- }
- }
- };
-
- @Inject
- public NotificationPanelViewMediator(
- CarNavigationBarController carNavigationBarController,
- NotificationPanelViewController notificationPanelViewController,
-
- PowerManagerHelper powerManagerHelper,
- BroadcastDispatcher broadcastDispatcher,
-
- CarDeviceProvisionedController carDeviceProvisionedController,
- ConfigurationController configurationController
- ) {
- mCarNavigationBarController = carNavigationBarController;
- mNotificationPanelViewController = notificationPanelViewController;
- mPowerManagerHelper = powerManagerHelper;
- mBroadcastDispatcher = broadcastDispatcher;
- mCarDeviceProvisionedController = carDeviceProvisionedController;
- mConfigurationController = configurationController;
- }
-
- @Override
- @CallSuper
- public void registerListeners() {
- mCarNavigationBarController.registerTopBarTouchListener(
- mNotificationPanelViewController.getDragCloseTouchListener());
- mCarNavigationBarController.registerBottomBarTouchListener(
- mNotificationPanelViewController.getDragCloseTouchListener());
- mCarNavigationBarController.registerLeftBarTouchListener(
- mNotificationPanelViewController.getDragCloseTouchListener());
- mCarNavigationBarController.registerRightBarTouchListener(
- mNotificationPanelViewController.getDragCloseTouchListener());
-
- mCarNavigationBarController.registerNotificationController(
- new CarNavigationBarController.NotificationsShadeController() {
- @Override
- public void togglePanel() {
- mNotificationPanelViewController.toggle();
- }
-
- @Override
- public boolean isNotificationPanelOpen() {
- return mNotificationPanelViewController.isPanelExpanded();
- }
- });
-
- mBroadcastDispatcher.registerReceiver(mBroadcastReceiver,
- new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), null, UserHandle.ALL);
- }
-
- @Override
- public void setupOverlayContentViewControllers() {
- mNotificationPanelViewController.setOnUnseenCountUpdateListener(unseenNotificationCount -> {
- boolean hasUnseen = unseenNotificationCount > 0;
- mCarNavigationBarController.toggleAllNotificationsUnseenIndicator(
- mCarDeviceProvisionedController.isCurrentUserFullySetup(), hasUnseen);
- });
-
- mPowerManagerHelper.setCarPowerStateListener(state -> {
- if (state == CarPowerManager.CarPowerStateListener.ON) {
- mNotificationPanelViewController.onCarPowerStateOn();
- }
- });
- mPowerManagerHelper.connectToCarService();
-
- mConfigurationController.addCallback(this);
- }
-
- @Override
- public void onConfigChanged(Configuration newConfig) {
- // No op.
- }
-
- @Override
- public void onDensityOrFontScaleChanged() {
- registerListeners();
- }
-
- @Override
- public void onOverlayChanged() {
- // No op.
- }
-
- @Override
- public void onUiModeChanged() {
- // No op.
- }
-
- @Override
- public void onThemeChanged() {
- // No op.
- }
-
- @Override
- public void onLocaleListChanged() {
- mNotificationPanelViewController.reinflate();
- registerListeners();
- }
-
- protected final CarNavigationBarController getCarNavigationBarController() {
- return mCarNavigationBarController;
- }
-
- protected final NotificationPanelViewController getNotificationPanelViewController() {
- return mNotificationPanelViewController;
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationShadeWindowControllerImpl.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationShadeWindowControllerImpl.java
deleted file mode 100644
index 1a1da89..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationShadeWindowControllerImpl.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.notification;
-
-import com.android.systemui.car.window.OverlayViewGlobalStateController;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.statusbar.NotificationShadeWindowController;
-
-import javax.inject.Inject;
-
-/** The automotive version of the notification shade window controller. */
-@SysUISingleton
-public class NotificationShadeWindowControllerImpl implements
- NotificationShadeWindowController {
-
- private final OverlayViewGlobalStateController mController;
-
- @Inject
- public NotificationShadeWindowControllerImpl(OverlayViewGlobalStateController controller) {
- mController = controller;
- }
-
- @Override
- public void setForceDozeBrightness(boolean forceDozeBrightness) {
- // No-op since dozing is not supported in Automotive devices.
- }
-
- @Override
- public void setNotificationShadeFocusable(boolean focusable) {
- mController.setWindowFocusable(focusable);
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationVisibilityLogger.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationVisibilityLogger.java
deleted file mode 100644
index b263f72..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationVisibilityLogger.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.notification;
-
-import android.os.RemoteException;
-import android.util.ArraySet;
-import android.util.Log;
-
-import com.android.car.notification.AlertEntry;
-import com.android.car.notification.NotificationDataManager;
-import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.UiBackground;
-
-import java.util.Set;
-import java.util.concurrent.Executor;
-
-import javax.inject.Inject;
-
-/**
- * Handles notification logging, in particular, logging which notifications are visible and which
- * are not.
- */
-@SysUISingleton
-public class NotificationVisibilityLogger {
-
- private static final String TAG = "NotificationVisibilityLogger";
-
- private final ArraySet<NotificationVisibility> mCurrentlyVisible = new ArraySet<>();
- private final ArraySet<NotificationVisibility> mNewlyVisible = new ArraySet<>();
- private final ArraySet<NotificationVisibility> mPreviouslyVisible = new ArraySet<>();
- private final ArraySet<NotificationVisibility> mTmpCurrentlyVisible = new ArraySet<>();
-
- private final IStatusBarService mBarService;
- private final Executor mUiBgExecutor;
- private final NotificationDataManager mNotificationDataManager;
-
- private boolean mIsVisible;
-
- private final Runnable mVisibilityReporter = new Runnable() {
-
- @Override
- public void run() {
- if (mIsVisible) {
- int count = mNotificationDataManager.getVisibleNotifications().size();
- for (AlertEntry alertEntry : mNotificationDataManager.getVisibleNotifications()) {
- NotificationVisibility visObj = NotificationVisibility.obtain(
- alertEntry.getKey(),
- /* rank= */ -1,
- count,
- mIsVisible,
- NotificationVisibility.NotificationLocation.LOCATION_MAIN_AREA);
- mTmpCurrentlyVisible.add(visObj);
- if (!mCurrentlyVisible.contains(visObj)) {
- mNewlyVisible.add(visObj);
- }
- }
- }
- mPreviouslyVisible.addAll(mCurrentlyVisible);
- mPreviouslyVisible.removeAll(mTmpCurrentlyVisible);
- onNotificationVisibilityChanged(mNewlyVisible, mPreviouslyVisible);
-
- recycleAllVisibilityObjects(mCurrentlyVisible);
- mCurrentlyVisible.addAll(mTmpCurrentlyVisible);
-
- recycleAllVisibilityObjects(mPreviouslyVisible);
- recycleAllVisibilityObjects(mNewlyVisible);
- recycleAllVisibilityObjects(mTmpCurrentlyVisible);
- }
- };
-
- @Inject
- public NotificationVisibilityLogger(
- @UiBackground Executor uiBgExecutor,
- IStatusBarService barService,
- NotificationDataManager notificationDataManager) {
- mUiBgExecutor = uiBgExecutor;
- mBarService = barService;
- mNotificationDataManager = notificationDataManager;
- }
-
- /** Triggers a visibility report update to be sent to StatusBarService. */
- public void log(boolean isVisible) {
- mIsVisible = isVisible;
- mUiBgExecutor.execute(mVisibilityReporter);
- }
-
- /** Stops logging, clearing all visibility objects. */
- public void stop() {
- recycleAllVisibilityObjects(mCurrentlyVisible);
- }
-
- /**
- * Notify StatusBarService of change in notifications' visibility.
- */
- private void onNotificationVisibilityChanged(
- Set<NotificationVisibility> newlyVisible, Set<NotificationVisibility> noLongerVisible) {
- if (newlyVisible.isEmpty() && noLongerVisible.isEmpty()) {
- return;
- }
-
- try {
- mBarService.onNotificationVisibilityChanged(
- cloneVisibilitiesAsArr(newlyVisible), cloneVisibilitiesAsArr(noLongerVisible));
- } catch (RemoteException e) {
- // Won't fail unless the world has ended.
- Log.e(TAG, "Failed to notify StatusBarService of notification visibility change");
- }
- }
-
- /**
- * Clears array and recycles NotificationVisibility objects for reuse.
- */
- private static void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) {
- for (int i = 0; i < array.size(); i++) {
- array.valueAt(i).recycle();
- }
- array.clear();
- }
-
- /**
- * Converts Set of NotificationVisibility objects to primitive array.
- */
- private static NotificationVisibility[] cloneVisibilitiesAsArr(Set<NotificationVisibility> c) {
- NotificationVisibility[] array = new NotificationVisibility[c.size()];
- int i = 0;
- for (NotificationVisibility nv : c) {
- if (nv != null) {
- array[i] = nv.clone();
- }
- i++;
- }
- return array;
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/PowerManagerHelper.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/PowerManagerHelper.java
deleted file mode 100644
index da43c54..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/notification/PowerManagerHelper.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.notification;
-
-import android.annotation.NonNull;
-import android.car.Car;
-import android.car.hardware.power.CarPowerManager;
-import android.car.hardware.power.CarPowerManager.CarPowerStateListener;
-import android.util.Log;
-
-import com.android.systemui.car.CarServiceProvider;
-import com.android.systemui.dagger.SysUISingleton;
-
-import javax.inject.Inject;
-
-/**
- * Helper class for connecting to the {@link CarPowerManager} and listening for power state changes.
- */
-@SysUISingleton
-public class PowerManagerHelper {
- public static final String TAG = "PowerManagerHelper";
-
- private final CarServiceProvider mCarServiceProvider;
-
- private CarPowerManager mCarPowerManager;
- private CarPowerStateListener mCarPowerStateListener;
-
- private final CarServiceProvider.CarServiceOnConnectedListener mCarServiceLifecycleListener;
-
- @Inject
- public PowerManagerHelper(CarServiceProvider carServiceProvider) {
- mCarServiceProvider = carServiceProvider;
- mCarServiceLifecycleListener = car -> {
- Log.d(TAG, "Car Service connected");
- mCarPowerManager = (CarPowerManager) car.getCarManager(Car.POWER_SERVICE);
- if (mCarPowerManager != null) {
- mCarPowerManager.setListener(mCarPowerStateListener);
- } else {
- Log.e(TAG, "CarPowerManager service not available");
- }
- };
- }
-
- /**
- * Sets a {@link CarPowerStateListener}. Should be set before {@link #connectToCarService()}.
- */
- public void setCarPowerStateListener(@NonNull CarPowerStateListener listener) {
- mCarPowerStateListener = listener;
- }
-
- /**
- * Connect to Car service.
- */
- public void connectToCarService() {
- mCarServiceProvider.addListener(mCarServiceLifecycleListener);
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/TopNotificationPanelViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/TopNotificationPanelViewMediator.java
deleted file mode 100644
index 9bc5b74c..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/notification/TopNotificationPanelViewMediator.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.notification;
-
-import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.car.navigationbar.CarNavigationBarController;
-import com.android.systemui.car.window.OverlayPanelViewController;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.statusbar.policy.ConfigurationController;
-
-import javax.inject.Inject;
-
-/**
- * Implementation of NotificationPanelViewMediator that sets the notification panel to be opened
- * from the top navigation bar.
- */
-@SysUISingleton
-public class TopNotificationPanelViewMediator extends NotificationPanelViewMediator {
-
- @Inject
- public TopNotificationPanelViewMediator(
- CarNavigationBarController carNavigationBarController,
- NotificationPanelViewController notificationPanelViewController,
-
- PowerManagerHelper powerManagerHelper,
- BroadcastDispatcher broadcastDispatcher,
-
- CarDeviceProvisionedController carDeviceProvisionedController,
- ConfigurationController configurationController
- ) {
- super(carNavigationBarController,
- notificationPanelViewController,
- powerManagerHelper,
- broadcastDispatcher,
- carDeviceProvisionedController,
- configurationController);
- notificationPanelViewController.setOverlayDirection(
- OverlayPanelViewController.OVERLAY_FROM_TOP_BAR);
- }
-
- @Override
- public void registerListeners() {
- super.registerListeners();
- getCarNavigationBarController().registerTopBarTouchListener(
- getNotificationPanelViewController().getDragOpenTouchListener());
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/rvc/RearViewCameraViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/rvc/RearViewCameraViewController.java
deleted file mode 100644
index d634633..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/rvc/RearViewCameraViewController.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.rvc;
-
-import android.app.ActivityView;
-import android.app.ActivityView.StateCallback;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.util.Slog;
-import android.view.ViewGroup;
-import android.widget.LinearLayout.LayoutParams;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
-import com.android.systemui.car.window.OverlayViewController;
-import com.android.systemui.car.window.OverlayViewGlobalStateController;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-
-import javax.inject.Inject;
-
-/** View controller for the rear view camera. */
-@SysUISingleton
-public class RearViewCameraViewController extends OverlayViewController {
- private static final String TAG = "RearViewCameraView";
- private static final boolean DBG = false;
-
- private final ComponentName mRearViewCameraActivity;
- private ViewGroup mRvcView;
- private final LayoutParams mRvcViewLayoutParams = new LayoutParams(
- LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, /* weight= */ 1.0f);
- @VisibleForTesting
- ActivityView mActivityView;
- @VisibleForTesting
- final StateCallback mActivityViewCallback = new StateCallback() {
- @Override
- public void onActivityViewReady(ActivityView view) {
- Intent intent = new Intent(Intent.ACTION_MAIN)
- .setComponent(mRearViewCameraActivity)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
- .addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
- // TODO(b/170899079): Migrate this to FixedActivityService.
- view.startActivity(intent);
- }
-
- @Override
- public void onActivityViewDestroyed(ActivityView view) {}
- };
-
- @Inject
- public RearViewCameraViewController(
- @Main Resources resources,
- OverlayViewGlobalStateController overlayViewGlobalStateController) {
- super(R.id.rear_view_camera_stub, overlayViewGlobalStateController);
- String rearViewCameraActivityName = resources.getString(
- R.string.config_rearViewCameraActivity);
- if (!rearViewCameraActivityName.isEmpty()) {
- mRearViewCameraActivity = ComponentName.unflattenFromString(rearViewCameraActivityName);
- if (DBG) Slog.d(TAG, "mRearViewCameraActivity=" + mRearViewCameraActivity);
- } else {
- mRearViewCameraActivity = null;
- Slog.e(TAG, "RearViewCameraViewController is disabled, since no Activity is defined");
- }
- }
-
- @Override
- protected void onFinishInflate() {
- mRvcView = (ViewGroup) getLayout().findViewById(R.id.rear_view_camera_container);
- getLayout().findViewById(R.id.close_button).setOnClickListener(v -> {
- stop();
- });
- }
-
- @Override
- protected void hideInternal() {
- super.hideInternal();
- if (DBG) Slog.d(TAG, "hideInternal: mActivityView=" + mActivityView);
- if (mActivityView == null) return;
- mRvcView.removeView(mActivityView);
- // Release ActivityView since the Activity on ActivityView (with showWhenLocked flag) keeps
- // running even if ActivityView is hidden.
- mActivityView.release();
- mActivityView = null;
- }
-
- @Override
- protected void showInternal() {
- super.showInternal();
- if (DBG) Slog.d(TAG, "showInternal: mActivityView=" + mActivityView);
- if (mActivityView != null) return;
- mActivityView = new ActivityView(mRvcView.getContext());
- mActivityView.setCallback(mActivityViewCallback);
- mActivityView.setLayoutParams(mRvcViewLayoutParams);
- mRvcView.addView(mActivityView, /* index= */ 0);
- }
-
- boolean isShown() {
- return mActivityView != null;
- }
-
- boolean isEnabled() {
- return mRearViewCameraActivity != null;
- }
-
- @Override
- protected boolean shouldShowHUN() {
- return false;
- }
-
- @Override
- protected boolean shouldShowWhenOccluded() {
- // Returns true to show it on top of Keylock.
- return true;
- }
-
- @Override
- protected boolean shouldShowNavigationBarInsets() {
- return true;
- }
-
- @Override
- protected boolean shouldShowStatusBarInsets() {
- return true;
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/rvc/RearViewCameraViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/rvc/RearViewCameraViewMediator.java
deleted file mode 100644
index c575c42..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/rvc/RearViewCameraViewMediator.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.rvc;
-
-import android.car.Car;
-import android.car.VehicleGear;
-import android.car.VehiclePropertyIds;
-import android.car.hardware.CarPropertyValue;
-import android.car.hardware.property.CarPropertyManager;
-import android.car.hardware.property.CarPropertyManager.CarPropertyEventCallback;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.UserHandle;
-import android.util.Slog;
-
-import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.car.CarServiceProvider;
-import com.android.systemui.car.window.OverlayViewMediator;
-import com.android.systemui.dagger.SysUISingleton;
-
-import javax.inject.Inject;
-
-/**
- * View mediator for the rear view camera (RVC), which monitors the gear changes and shows
- * the RVC when the gear position is R and otherwise it hides the RVC.
- */
-@SysUISingleton
-public class RearViewCameraViewMediator implements OverlayViewMediator {
- private static final String TAG = "RearViewCameraView";
- private static final boolean DBG = false;
-
- private final RearViewCameraViewController mRearViewCameraViewController;
- private final CarServiceProvider mCarServiceProvider;
- private final BroadcastDispatcher mBroadcastDispatcher;
-
- private CarPropertyManager mCarPropertyManager;
- // TODO(b/170792252): Replace the following with the callback from CarEvsManager if it's ready.
- private final CarPropertyEventCallback mPropertyEventCallback = new CarPropertyEventCallback() {
- @Override
- public void onChangeEvent(CarPropertyValue value) {
- if (DBG) Slog.d(TAG, "onChangeEvent value=" + value);
- if (value.getPropertyId() != VehiclePropertyIds.GEAR_SELECTION) {
- Slog.w(TAG, "Got the event for non-registered property: " + value.getPropertyId());
- return;
- }
- if ((Integer) value.getValue() == VehicleGear.GEAR_REVERSE) {
- mRearViewCameraViewController.start();
- } else {
- mRearViewCameraViewController.stop();
- }
- }
- @Override
- public void onErrorEvent(int propId, int zone) {
- Slog.e(TAG, "onErrorEvent propId=" + propId + ", zone=" + zone);
- }
- };
-
- private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (DBG) Slog.d(TAG, "onReceive: " + intent);
- if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())
- && mRearViewCameraViewController.isShown()) {
- mRearViewCameraViewController.stop();
- }
- }
- };
-
- @Inject
- public RearViewCameraViewMediator(
- RearViewCameraViewController rearViewCameraViewController,
- CarServiceProvider carServiceProvider,
- BroadcastDispatcher broadcastDispatcher) {
- if (DBG) Slog.d(TAG, "RearViewCameraViewMediator:init");
- mRearViewCameraViewController = rearViewCameraViewController;
- mCarServiceProvider = carServiceProvider;
- mBroadcastDispatcher = broadcastDispatcher;
- }
-
- @Override
- public void registerListeners() {
- if (DBG) Slog.d(TAG, "RearViewCameraViewMediator:registerListeners");
- if (!mRearViewCameraViewController.isEnabled()) {
- Slog.i(TAG, "RearViewCameraViewController isn't enabled");
- return;
- }
-
- mCarServiceProvider.addListener(car -> {
- mCarPropertyManager = (CarPropertyManager) car.getCarManager(Car.PROPERTY_SERVICE);
- if (mCarPropertyManager == null) {
- Slog.e(TAG, "Unable to get CarPropertyManager");
- return;
- }
- if (DBG) Slog.d(TAG, "Registering mPropertyEventCallback.");
- mCarPropertyManager.registerCallback(mPropertyEventCallback,
- VehiclePropertyIds.GEAR_SELECTION, CarPropertyManager.SENSOR_RATE_UI);
- });
- mBroadcastDispatcher.registerReceiver(mBroadcastReceiver,
- new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), /* executor= */ null,
- UserHandle.ALL);
- }
-
- @Override
- public void setupOverlayContentViewControllers() {}
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppController.java b/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppController.java
deleted file mode 100644
index b8d6964..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppController.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.sideloaded;
-
-import android.app.IActivityTaskManager;
-import android.content.Context;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.systemui.SystemUI;
-import com.android.systemui.dagger.SysUISingleton;
-
-import javax.inject.Inject;
-
-/**
- * Controller responsible for detecting unsafe apps.
- */
-@SysUISingleton
-public class SideLoadedAppController extends SystemUI {
- private static final String TAG = SideLoadedAppController.class.getSimpleName();
-
- private IActivityTaskManager mActivityTaskManager;
- private SideLoadedAppListener mSideLoadedAppListener;
- private SideLoadedAppDetector mSideLoadedAppDetector;
- private SideLoadedAppStateController mSideLoadedAppStateController;
-
- @Inject
- public SideLoadedAppController(Context context,
- IActivityTaskManager activityTaskManager,
- SideLoadedAppDetector sideLoadedAppDetector,
- SideLoadedAppListener sideLoadedAppListener,
- SideLoadedAppStateController sideLoadedAppStateController) {
- super(context);
-
- mSideLoadedAppDetector = sideLoadedAppDetector;
- mActivityTaskManager = activityTaskManager;
- mSideLoadedAppListener = sideLoadedAppListener;
- mSideLoadedAppStateController = sideLoadedAppStateController;
- }
-
- @Override
- public void start() {
- }
-
- @Override
- protected void onBootCompleted() {
- Log.i(TAG, "OnBootCompleted");
-
- try {
- mActivityTaskManager.registerTaskStackListener(mSideLoadedAppListener);
- } catch (RemoteException e) {
- Log.e(TAG, "Could not register car side loaded app listener.", e);
- }
-
- if (mSideLoadedAppDetector.hasUnsafeInstalledApps()) {
- mSideLoadedAppStateController.onUnsafeInstalledAppsDetected();
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppDetector.java b/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppDetector.java
deleted file mode 100644
index f96ee0f..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppDetector.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.sideloaded;
-
-import android.annotation.NonNull;
-import android.app.ActivityTaskManager.RootTaskInfo;
-import android.content.ComponentName;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.InstallSourceInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.os.UserHandle;
-import android.util.Log;
-
-import com.android.systemui.R;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-
-import java.util.Arrays;
-import java.util.List;
-
-import javax.inject.Inject;
-
-/**
- * A class that detects unsafe apps.
- * An app is considered safe if is a system app or installed through allowed sources.
- */
-@SysUISingleton
-public class SideLoadedAppDetector {
- private static final String TAG = SideLoadedAppDetector.class.getSimpleName();
-
- private final PackageManager mPackageManager;
- private final CarDeviceProvisionedController mCarDeviceProvisionedController;
- private final List<String> mAllowedAppInstallSources;
-
- @Inject
- public SideLoadedAppDetector(@Main Resources resources, PackageManager packageManager,
- CarDeviceProvisionedController deviceProvisionedController) {
- mAllowedAppInstallSources = Arrays.asList(
- resources.getStringArray(R.array.config_allowedAppInstallSources));
- mPackageManager = packageManager;
- mCarDeviceProvisionedController = deviceProvisionedController;
- }
-
- boolean hasUnsafeInstalledApps() {
- int userId = mCarDeviceProvisionedController.getCurrentUser();
-
- List<PackageInfo> packages = mPackageManager.getInstalledPackagesAsUser(
- PackageManager.MATCH_DIRECT_BOOT_AWARE
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- userId);
- for (PackageInfo info : packages) {
- if (info.applicationInfo == null) {
- Log.w(TAG, info.packageName + " does not have application info.");
- return true;
- }
-
- if (!isSafe(info.applicationInfo)) {
- return true;
- }
- }
- return false;
- }
-
- boolean isSafe(@NonNull RootTaskInfo taskInfo) {
- ComponentName componentName = taskInfo.topActivity;
- if (componentName == null) {
- Log.w(TAG, "Task info does not have top activity: " + taskInfo.taskId);
- return false;
- }
- return isSafe(componentName.getPackageName());
- }
-
- private boolean isSafe(@NonNull String packageName) {
- if (packageName == null) {
- return false;
- }
-
- ApplicationInfo applicationInfo;
- try {
- int userId = mCarDeviceProvisionedController.getCurrentUser();
- applicationInfo = mPackageManager.getApplicationInfoAsUser(packageName,
- PackageManager.MATCH_DIRECT_BOOT_AWARE
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- UserHandle.of(userId));
-
- if (applicationInfo == null) {
- Log.e(TAG, packageName + " did not have an application info!");
- return false;
- }
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, "Could not get application info for package:" + packageName, e);
- return false;
- }
-
- return isSafe(applicationInfo);
- }
-
- private boolean isSafe(@NonNull ApplicationInfo applicationInfo) {
- String packageName = applicationInfo.packageName;
-
- if (applicationInfo.isSystemApp() || applicationInfo.isUpdatedSystemApp()) {
- return true;
- }
-
- String initiatingPackageName;
- try {
- InstallSourceInfo sourceInfo = mPackageManager.getInstallSourceInfo(packageName);
- initiatingPackageName = sourceInfo.getInitiatingPackageName();
- if (initiatingPackageName == null) {
- Log.w(TAG, packageName + " does not have an installer name.");
- return false;
- }
-
- return mAllowedAppInstallSources.contains(initiatingPackageName);
- } catch (IllegalArgumentException | PackageManager.NameNotFoundException e) {
- return false;
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppListener.java b/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppListener.java
deleted file mode 100644
index db7718b..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppListener.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.sideloaded;
-
-import android.app.ActivityTaskManager.RootTaskInfo;
-import android.app.IActivityTaskManager;
-import android.app.TaskStackListener;
-import android.content.ComponentName;
-import android.hardware.display.DisplayManager;
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.Display;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-/**
- * A TaskStackListener to detect when an unsafe app is launched/foregrounded.
- */
-public class SideLoadedAppListener extends TaskStackListener {
- private static final String TAG = SideLoadedAppListener.class.getSimpleName();
-
- private IActivityTaskManager mActivityTaskManager;
- private DisplayManager mDisplayManager;
- private SideLoadedAppDetector mSideLoadedAppDetector;
- private SideLoadedAppStateController mSideLoadedAppStateController;
-
- @Inject
- SideLoadedAppListener(SideLoadedAppDetector sideLoadedAppDetector,
- IActivityTaskManager activityTaskManager,
- DisplayManager displayManager,
- SideLoadedAppStateController sideLoadedAppStateController) {
- mSideLoadedAppDetector = sideLoadedAppDetector;
- mActivityTaskManager = activityTaskManager;
- mDisplayManager = displayManager;
- mSideLoadedAppStateController = sideLoadedAppStateController;
- }
-
- @Override
- public void onTaskCreated(int taskId, ComponentName componentName) throws RemoteException {
- super.onTaskCreated(taskId, componentName);
-
- List<RootTaskInfo> taskInfoList = mActivityTaskManager.getAllRootTaskInfos();
- RootTaskInfo taskInfo = getStackInfo(taskInfoList, taskId);
- if (taskInfo == null) {
- Log.e(TAG, "Stack info was not available for taskId: " + taskId);
- return;
- }
-
- if (!mSideLoadedAppDetector.isSafe(taskInfo)) {
- Display display = mDisplayManager.getDisplay(taskInfo.displayId);
- mSideLoadedAppStateController.onUnsafeTaskCreatedOnDisplay(display);
- }
- }
-
- @Override
- public void onTaskStackChanged() throws RemoteException {
- super.onTaskStackChanged();
-
- Display[] displays = mDisplayManager.getDisplays();
- for (Display display : displays) {
- // Note that the taskInfoList is ordered by recency.
- List<RootTaskInfo> taskInfoList =
- mActivityTaskManager.getAllRootTaskInfosOnDisplay(display.getDisplayId());
-
- if (taskInfoList == null) {
- continue;
- }
- RootTaskInfo taskInfo = getTopVisibleStackInfo(taskInfoList);
- if (taskInfo == null) {
- continue;
- }
- if (mSideLoadedAppDetector.isSafe(taskInfo)) {
- mSideLoadedAppStateController.onSafeTaskDisplayedOnDisplay(display);
- } else {
- mSideLoadedAppStateController.onUnsafeTaskDisplayedOnDisplay(display);
- }
- }
- }
-
- /**
- * Returns stack info for a given taskId.
- */
- private RootTaskInfo getStackInfo(List<RootTaskInfo> taskInfoList, int taskId) {
- if (taskInfoList == null) {
- return null;
- }
- for (RootTaskInfo taskInfo : taskInfoList) {
- if (taskInfo.childTaskIds == null) {
- continue;
- }
- for (int taskTaskId : taskInfo.childTaskIds) {
- if (taskId == taskTaskId) {
- return taskInfo;
- }
- }
- }
- return null;
- }
-
- /**
- * Returns the first visible stackInfo.
- */
- private RootTaskInfo getTopVisibleStackInfo(List<RootTaskInfo> taskInfoList) {
- for (RootTaskInfo taskInfo : taskInfoList) {
- if (taskInfo.visible) {
- return taskInfo;
- }
- }
- return null;
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppStateController.java b/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppStateController.java
deleted file mode 100644
index 5b4faa1..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppStateController.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.sideloaded;
-
-import android.util.Log;
-import android.view.Display;
-
-import com.android.systemui.dagger.SysUISingleton;
-
-import javax.inject.Inject;
-
-/**
- * Manager responsible for displaying proper UI when an unsafe app is detected.
- */
-@SysUISingleton
-public class SideLoadedAppStateController {
- private static final String TAG = SideLoadedAppStateController.class.getSimpleName();
-
- @Inject
- SideLoadedAppStateController() {
- }
-
- void onUnsafeInstalledAppsDetected() {
- Log.d(TAG, "Unsafe installed apps detected.");
- }
-
- void onUnsafeTaskCreatedOnDisplay(Display display) {
- Log.d(TAG, "Unsafe task created on display " + display.getDisplayId() + ".");
- }
-
- void onSafeTaskDisplayedOnDisplay(Display display) {
- Log.d(TAG, "Safe task displayed on display " + display.getDisplayId() + ".");
- }
-
- void onUnsafeTaskDisplayedOnDisplay(Display display) {
- Log.d(TAG, "Unsafe task displayed on display " + display.getDisplayId() + ".");
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/statusbar/DozeServiceHost.java b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/DozeServiceHost.java
deleted file mode 100644
index 3fb3cd8..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/statusbar/DozeServiceHost.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.statusbar;
-
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.doze.DozeHost;
-
-import javax.inject.Inject;
-
-/** No-op implementation of {@link DozeHost} for use by car sysui, which does not support dozing. */
-@SysUISingleton
-public class DozeServiceHost implements DozeHost {
-
- @Inject
- public DozeServiceHost() {}
-
- @Override
- public void addCallback(Callback callback) {
- // No op.
- }
-
- @Override
- public void removeCallback(Callback callback) {
- // No op.
- }
-
- @Override
- public void startDozing() {
- // No op.
- }
-
- @Override
- public void pulseWhileDozing(PulseCallback callback, int reason) {
- // No op.
- }
-
- @Override
- public void stopDozing() {
- // No op.
- }
-
- @Override
- public void dozeTimeTick() {
- // No op.
- }
-
- @Override
- public boolean isPowerSaveActive() {
- return false;
- }
-
- @Override
- public boolean isPulsingBlocked() {
- return true;
- }
-
- @Override
- public boolean isProvisioned() {
- return false;
- }
-
- @Override
- public boolean isBlockingDoze() {
- return true;
- }
-
- @Override
- public void extendPulse(int reason) {
- // No op.
- }
-
- @Override
- public void setAnimateWakeup(boolean animateWakeup) {
- // No op.
- }
-
- @Override
- public void setAnimateScreenOff(boolean animateScreenOff) {
- // No op.
- }
-
- @Override
- public void onSlpiTap(float x, float y) {
- // No op.
- }
-
- @Override
- public void setDozeScreenBrightness(int value) {
- // No op.
- }
-
- @Override
- public void prepareForGentleSleep(Runnable onDisplayOffCallback) {
- // No op.
- }
-
- @Override
- public void cancelGentleSleep() {
- // No op.
- }
-
- @Override
- public void onIgnoreTouchWhilePulsing(boolean ignore) {
- // No op.
- }
-
- @Override
- public void stopPulsing() {
- // No op.
- }
-
- @Override
- public boolean isDozeSuppressed() {
- return true;
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/statusbar/UserNameViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/UserNameViewController.java
deleted file mode 100644
index 1b1a118..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/statusbar/UserNameViewController.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.statusbar;
-
-import android.car.Car;
-import android.car.user.CarUserManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.UserInfo;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.Log;
-import android.view.View;
-import android.widget.TextView;
-
-import com.android.systemui.R;
-import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.car.CarServiceProvider;
-import com.android.systemui.dagger.SysUISingleton;
-
-import javax.inject.Inject;
-
-/**
- * Controls a TextView with the current driver's username
- */
-@SysUISingleton
-public class UserNameViewController {
- private static final String TAG = "UserNameViewController";
-
- private Context mContext;
- private UserManager mUserManager;
- private CarUserManager mCarUserManager;
- private CarServiceProvider mCarServiceProvider;
- private CarDeviceProvisionedController mCarDeviceProvisionedController;
- private BroadcastDispatcher mBroadcastDispatcher;
- private TextView mUserNameView;
-
- private final BroadcastReceiver mUserUpdateReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- updateUser(mCarDeviceProvisionedController.getCurrentUser());
- }
- };
-
- private boolean mUserLifecycleListenerRegistered = false;
-
- private final CarUserManager.UserLifecycleListener mUserLifecycleListener =
- new CarUserManager.UserLifecycleListener() {
- @Override
- public void onEvent(CarUserManager.UserLifecycleEvent event) {
- if (event.getEventType()
- == CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING) {
- updateUser(event.getUserId());
- }
- }
- };
-
- @Inject
- public UserNameViewController(Context context, CarServiceProvider carServiceProvider,
- UserManager userManager, BroadcastDispatcher broadcastDispatcher,
- CarDeviceProvisionedController carDeviceProvisionedController) {
- mContext = context;
- mCarServiceProvider = carServiceProvider;
- mUserManager = userManager;
- mBroadcastDispatcher = broadcastDispatcher;
- mCarDeviceProvisionedController = carDeviceProvisionedController;
- }
-
- /**
- * Find the {@link TextView} for the driver's user name from a view and if found set it with the
- * current driver's user name.
- */
- public void addUserNameView(View v) {
- TextView userNameView = v.findViewById(R.id.user_name_text);
- if (userNameView != null) {
- if (mUserNameView == null) {
- registerForUserChangeEvents();
- }
- mUserNameView = userNameView;
- updateUser(mCarDeviceProvisionedController.getCurrentUser());
- }
- }
-
- /**
- * Clean up the controller and unregister receiver.
- */
- public void removeAll() {
- mUserNameView = null;
- if (mUserLifecycleListenerRegistered) {
- mBroadcastDispatcher.unregisterReceiver(mUserUpdateReceiver);
- if (mCarUserManager != null) {
- mCarUserManager.removeListener(mUserLifecycleListener);
- }
- mUserLifecycleListenerRegistered = false;
- }
- }
-
- private void registerForUserChangeEvents() {
- // Register for user switching
- mCarServiceProvider.addListener(car -> {
- mCarUserManager = (CarUserManager) car.getCarManager(Car.CAR_USER_SERVICE);
- if (mCarUserManager != null) {
- mCarUserManager.addListener(Runnable::run, mUserLifecycleListener);
- mUserLifecycleListenerRegistered = true;
- } else {
- Log.e(TAG, "CarUserManager could not be obtained.");
- }
- });
- // Also register for user info changing
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_USER_INFO_CHANGED);
- mBroadcastDispatcher.registerReceiver(mUserUpdateReceiver, filter, /* executor= */ null,
- UserHandle.ALL);
- }
-
- private void updateUser(int userId) {
- if (mUserNameView != null) {
- UserInfo currentUserInfo = mUserManager.getUserInfo(userId);
- mUserNameView.setText(currentUserInfo.name);
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/CarStatusBarHeader.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/CarStatusBarHeader.java
deleted file mode 100644
index 0a677bf..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/CarStatusBarHeader.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.userswitcher;
-
-import android.content.Context;
-import android.graphics.Color;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import androidx.annotation.IdRes;
-
-import com.android.settingslib.Utils;
-import com.android.systemui.R;
-import com.android.systemui.plugins.DarkIconDispatcher;
-
-/**
- * A view that forms the header of the notification panel. This view will ensure that any
- * status icons that are displayed are tinted accordingly to the current theme.
- */
-public class CarStatusBarHeader extends LinearLayout {
- public CarStatusBarHeader(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
-
- // Set the light/dark theming on the header status UI to match the current theme.
- int colorForeground = Utils.getColorAttrDefaultColor(getContext(),
- android.R.attr.colorForeground);
- float intensity = colorForeground == Color.WHITE ? 0f : 1f;
- Rect tintArea = new Rect(0, 0, 0, 0);
-
- applyDarkness(R.id.clock, tintArea, intensity, colorForeground);
- }
-
- private void applyDarkness(@IdRes int id, Rect tintArea, float intensity, int color) {
- View v = findViewById(id);
- if (v instanceof DarkIconDispatcher.DarkReceiver) {
- ((DarkIconDispatcher.DarkReceiver) v).onDarkChanged(tintArea, intensity, color);
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullScreenUserSwitcherViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullScreenUserSwitcherViewController.java
deleted file mode 100644
index 3a7fac9..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullScreenUserSwitcherViewController.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.userswitcher;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.car.Car;
-import android.car.user.CarUserManager;
-import android.content.Context;
-import android.content.res.Resources;
-import android.view.View;
-
-import androidx.recyclerview.widget.GridLayoutManager;
-
-import com.android.systemui.R;
-import com.android.systemui.car.CarServiceProvider;
-import com.android.systemui.car.window.OverlayViewController;
-import com.android.systemui.car.window.OverlayViewGlobalStateController;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-
-import javax.inject.Inject;
-
-/**
- * Controller for {@link R.layout#car_fullscreen_user_switcher}.
- */
-@SysUISingleton
-public class FullScreenUserSwitcherViewController extends OverlayViewController {
- private final Context mContext;
- private final Resources mResources;
- private final CarServiceProvider mCarServiceProvider;
- private final int mShortAnimationDuration;
- private CarUserManager mCarUserManager;
- private UserGridRecyclerView mUserGridView;
- private UserGridRecyclerView.UserSelectionListener mUserSelectionListener;
-
- @Inject
- public FullScreenUserSwitcherViewController(
- Context context,
- @Main Resources resources,
- CarServiceProvider carServiceProvider,
- OverlayViewGlobalStateController overlayViewGlobalStateController) {
- super(R.id.fullscreen_user_switcher_stub, overlayViewGlobalStateController);
- mContext = context;
- mResources = resources;
- mCarServiceProvider = carServiceProvider;
- mCarServiceProvider.addListener(car -> {
- mCarUserManager = (CarUserManager) car.getCarManager(Car.CAR_USER_SERVICE);
- registerCarUserManagerIfPossible();
- });
- mShortAnimationDuration = mResources.getInteger(android.R.integer.config_shortAnimTime);
- }
-
- @Override
- protected void onFinishInflate() {
- // Initialize user grid.
- mUserGridView = getLayout().findViewById(R.id.user_grid);
- GridLayoutManager layoutManager = new GridLayoutManager(mContext,
- mResources.getInteger(R.integer.user_fullscreen_switcher_num_col));
- mUserGridView.setLayoutManager(layoutManager);
- mUserGridView.buildAdapter();
- mUserGridView.setUserSelectionListener(mUserSelectionListener);
- registerCarUserManagerIfPossible();
- }
-
- @Override
- protected boolean shouldFocusWindow() {
- return false;
- }
-
- @Override
- protected void showInternal() {
- getLayout().setVisibility(View.VISIBLE);
- }
-
- @Override
- protected void hideInternal() {
- // Switching is about to happen, since it takes time, fade out the switcher gradually.
- fadeOut();
- }
-
- private void fadeOut() {
- mUserGridView.animate()
- .alpha(0.0f)
- .setDuration(mShortAnimationDuration)
- .setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- getLayout().setVisibility(View.GONE);
- mUserGridView.setAlpha(1.0f);
- }
- });
-
- }
-
- /**
- * Set {@link UserGridRecyclerView.UserSelectionListener}.
- */
- void setUserGridSelectionListener(
- UserGridRecyclerView.UserSelectionListener userGridSelectionListener) {
- mUserSelectionListener = userGridSelectionListener;
- }
-
- private void registerCarUserManagerIfPossible() {
- if (mUserGridView != null && mCarUserManager != null) {
- mUserGridView.setCarUserManager(mCarUserManager);
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullscreenUserSwitcherViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullscreenUserSwitcherViewMediator.java
deleted file mode 100644
index 165fe63..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullscreenUserSwitcherViewMediator.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.userswitcher;
-
-import com.android.systemui.car.keyguard.CarKeyguardViewController;
-import com.android.systemui.car.window.OverlayViewMediator;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.StatusBarState;
-
-import javax.inject.Inject;
-
-/**
- * Manages the fullscreen user switcher and it's interactions with the keyguard.
- */
-@SysUISingleton
-public class FullscreenUserSwitcherViewMediator implements OverlayViewMediator {
- private static final String TAG = FullscreenUserSwitcherViewMediator.class.getSimpleName();
-
- private final StatusBarStateController mStatusBarStateController;
- private final FullScreenUserSwitcherViewController mFullScreenUserSwitcherViewController;
- private final CarKeyguardViewController mCarKeyguardViewController;
- private final UserSwitchTransitionViewController mUserSwitchTransitionViewController;
-
- @Inject
- public FullscreenUserSwitcherViewMediator(
- StatusBarStateController statusBarStateController,
- CarKeyguardViewController carKeyguardViewController,
- UserSwitchTransitionViewController userSwitchTransitionViewController,
- FullScreenUserSwitcherViewController fullScreenUserSwitcherViewController) {
-
- mStatusBarStateController = statusBarStateController;
- mCarKeyguardViewController = carKeyguardViewController;
- mUserSwitchTransitionViewController = userSwitchTransitionViewController;
- mFullScreenUserSwitcherViewController = fullScreenUserSwitcherViewController;
- }
-
- @Override
- public void registerListeners() {
- registerUserSwitcherHideListeners();
- }
-
- private void registerUserSwitcherHideListeners() {
- mStatusBarStateController.addCallback(new StatusBarStateController.StateListener() {
- @Override
- public void onStateChanged(int newState) {
- if (newState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
- return;
- }
- hide();
- }
- });
- }
-
- @Override
- public void setupOverlayContentViewControllers() {
- mFullScreenUserSwitcherViewController.setUserGridSelectionListener(this::onUserSelected);
- }
-
- /**
- * Every time user clicks on an item in the switcher, we hide the switcher.
- */
- private void onUserSelected(UserGridRecyclerView.UserRecord record) {
- if (record.mType != UserGridRecyclerView.UserRecord.FOREGROUND_USER) {
- mCarKeyguardViewController.hideKeyguardToPrepareBouncer();
- // If guest user, we cannot use record.mInfo.id and should listen to the User lifecycle
- // event instead.
- if (record.mType != UserGridRecyclerView.UserRecord.START_GUEST) {
- mUserSwitchTransitionViewController.handleShow(record.mInfo.id);
- }
- }
-
- hide();
- }
-
- private void hide() {
- mFullScreenUserSwitcherViewController.stop();
- }
-
- private void show() {
- mFullScreenUserSwitcherViewController.start();
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserGridRecyclerView.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserGridRecyclerView.java
deleted file mode 100644
index 6d63e31..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserGridRecyclerView.java
+++ /dev/null
@@ -1,657 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.userswitcher;
-
-import static android.content.DialogInterface.BUTTON_NEGATIVE;
-import static android.content.DialogInterface.BUTTON_POSITIVE;
-import static android.os.UserManager.DISALLOW_ADD_USER;
-import static android.os.UserManager.SWITCHABILITY_STATUS_OK;
-import static android.view.WindowInsets.Type.statusBars;
-
-import android.annotation.IntDef;
-import android.annotation.Nullable;
-import android.annotation.UserIdInt;
-import android.app.ActivityManager;
-import android.app.AlertDialog;
-import android.app.AlertDialog.Builder;
-import android.app.Dialog;
-import android.car.user.CarUserManager;
-import android.car.user.UserCreationResult;
-import android.car.user.UserSwitchResult;
-import android.car.userlib.UserHelper;
-import android.car.util.concurrent.AsyncFuture;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.UserInfo;
-import android.content.res.Resources;
-import android.graphics.Rect;
-import android.os.AsyncTask;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.sysprop.CarProperties;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.core.graphics.drawable.RoundedBitmapDrawable;
-import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
-import androidx.recyclerview.widget.GridLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.internal.util.UserIcons;
-import com.android.systemui.R;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-/**
- * Displays a GridLayout with icons for the users in the system to allow switching between users.
- * One of the uses of this is for the lock screen in auto.
- */
-public class UserGridRecyclerView extends RecyclerView {
- private static final String TAG = UserGridRecyclerView.class.getSimpleName();
- private static final int TIMEOUT_MS = CarProperties.user_hal_timeout().orElse(5_000) + 500;
-
- private UserSelectionListener mUserSelectionListener;
- private UserAdapter mAdapter;
- private CarUserManager mCarUserManager;
- private UserManager mUserManager;
- private Context mContext;
- private UserIconProvider mUserIconProvider;
-
- private final BroadcastReceiver mUserUpdateReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- onUsersUpdate();
- }
- };
-
- public UserGridRecyclerView(Context context, AttributeSet attrs) {
- super(context, attrs);
- mContext = context;
- mUserManager = UserManager.get(mContext);
- mUserIconProvider = new UserIconProvider();
-
- addItemDecoration(new ItemSpacingDecoration(mContext.getResources().getDimensionPixelSize(
- R.dimen.car_user_switcher_vertical_spacing_between_users)));
- }
-
- /**
- * Register listener for any update to the users
- */
- @Override
- public void onFinishInflate() {
- super.onFinishInflate();
- registerForUserEvents();
- }
-
- /**
- * Unregisters listener checking for any change to the users
- */
- @Override
- public void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- unregisterForUserEvents();
- }
-
- /**
- * Initializes the adapter that populates the grid layout
- */
- public void buildAdapter() {
- List<UserRecord> userRecords = createUserRecords(getUsersForUserGrid());
- mAdapter = new UserAdapter(mContext, userRecords);
- super.setAdapter(mAdapter);
- }
-
- private List<UserInfo> getUsersForUserGrid() {
- return mUserManager.getAliveUsers()
- .stream()
- .filter(UserInfo::supportsSwitchToByUser)
- .collect(Collectors.toList());
- }
-
- private List<UserRecord> createUserRecords(List<UserInfo> userInfoList) {
- int fgUserId = ActivityManager.getCurrentUser();
- UserHandle fgUserHandle = UserHandle.of(fgUserId);
- List<UserRecord> userRecords = new ArrayList<>();
-
- // If the foreground user CANNOT switch to other users, only display the foreground user.
- if (mUserManager.getUserSwitchability(fgUserHandle) != SWITCHABILITY_STATUS_OK) {
- userRecords.add(createForegroundUserRecord());
- return userRecords;
- }
-
- for (UserInfo userInfo : userInfoList) {
- if (userInfo.isGuest()) {
- // Don't display guests in the switcher.
- continue;
- }
-
- boolean isForeground = fgUserId == userInfo.id;
- UserRecord record = new UserRecord(userInfo,
- isForeground ? UserRecord.FOREGROUND_USER : UserRecord.BACKGROUND_USER);
- userRecords.add(record);
- }
-
- // Add button for starting guest session.
- userRecords.add(createStartGuestUserRecord());
-
- // Add add user record if the foreground user can add users
- if (!mUserManager.hasUserRestriction(DISALLOW_ADD_USER, fgUserHandle)) {
- userRecords.add(createAddUserRecord());
- }
-
- return userRecords;
- }
-
- private UserRecord createForegroundUserRecord() {
- return new UserRecord(mUserManager.getUserInfo(ActivityManager.getCurrentUser()),
- UserRecord.FOREGROUND_USER);
- }
-
- /**
- * Create guest user record
- */
- private UserRecord createStartGuestUserRecord() {
- return new UserRecord(null /* userInfo */, UserRecord.START_GUEST);
- }
-
- /**
- * Create add user record
- */
- private UserRecord createAddUserRecord() {
- return new UserRecord(null /* userInfo */, UserRecord.ADD_USER);
- }
-
- public void setUserSelectionListener(UserSelectionListener userSelectionListener) {
- mUserSelectionListener = userSelectionListener;
- }
-
- /** Sets a {@link CarUserManager}. */
- public void setCarUserManager(CarUserManager carUserManager) {
- mCarUserManager = carUserManager;
- }
-
- private void onUsersUpdate() {
- mAdapter.clearUsers();
- mAdapter.updateUsers(createUserRecords(getUsersForUserGrid()));
- mAdapter.notifyDataSetChanged();
- }
-
- private void registerForUserEvents() {
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_USER_REMOVED);
- filter.addAction(Intent.ACTION_USER_ADDED);
- filter.addAction(Intent.ACTION_USER_INFO_CHANGED);
- filter.addAction(Intent.ACTION_USER_SWITCHED);
- mContext.registerReceiverAsUser(
- mUserUpdateReceiver,
- UserHandle.ALL, // Necessary because CarSystemUi lives in User 0
- filter,
- /* broadcastPermission= */ null,
- /* scheduler= */ null);
- }
-
- private void unregisterForUserEvents() {
- mContext.unregisterReceiver(mUserUpdateReceiver);
- }
-
- /**
- * Adapter to populate the grid layout with the available user profiles
- */
- public final class UserAdapter extends RecyclerView.Adapter<UserAdapter.UserAdapterViewHolder>
- implements Dialog.OnClickListener, Dialog.OnCancelListener {
-
- private final Context mContext;
- private List<UserRecord> mUsers;
- private final Resources mRes;
- private final String mGuestName;
- private final String mNewUserName;
- // View that holds the add user button. Used to enable/disable the view
- private View mAddUserView;
- // User record for the add user. Need to call notifyUserSelected only if the user
- // confirms adding a user
- private UserRecord mAddUserRecord;
-
- public UserAdapter(Context context, List<UserRecord> users) {
- mRes = context.getResources();
- mContext = context;
- updateUsers(users);
- mGuestName = mRes.getString(R.string.car_guest);
- mNewUserName = mRes.getString(R.string.car_new_user);
- }
-
- /**
- * Clears list of user records.
- */
- public void clearUsers() {
- mUsers.clear();
- }
-
- /**
- * Updates list of user records.
- */
- public void updateUsers(List<UserRecord> users) {
- mUsers = users;
- }
-
- @Override
- public UserAdapterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View view = LayoutInflater.from(mContext)
- .inflate(R.layout.car_fullscreen_user_pod, parent, false);
- view.setAlpha(1f);
- view.bringToFront();
- return new UserAdapterViewHolder(view);
- }
-
- @Override
- public void onBindViewHolder(UserAdapterViewHolder holder, int position) {
- UserRecord userRecord = mUsers.get(position);
- RoundedBitmapDrawable circleIcon = getCircularUserRecordIcon(userRecord);
- holder.mUserAvatarImageView.setImageDrawable(circleIcon);
- holder.mUserNameTextView.setText(getUserRecordName(userRecord));
-
- holder.mView.setOnClickListener(v -> {
- if (userRecord == null) {
- return;
- }
-
- switch (userRecord.mType) {
- case UserRecord.START_GUEST:
- notifyUserSelected(userRecord);
- UserInfo guest = createNewOrFindExistingGuest(mContext);
- if (guest != null) {
- if (!switchUser(guest.id)) {
- Log.e(TAG, "Failed to switch to guest user: " + guest.id);
- }
- }
- break;
- case UserRecord.ADD_USER:
- // If the user wants to add a user, show dialog to confirm adding a user
- // Disable button so it cannot be clicked multiple times
- mAddUserView = holder.mView;
- mAddUserView.setEnabled(false);
- mAddUserRecord = userRecord;
-
- handleAddUserClicked();
- break;
- default:
- // If the user doesn't want to be a guest or add a user, switch to the user
- // selected
- notifyUserSelected(userRecord);
- if (!switchUser(userRecord.mInfo.id)) {
- Log.e(TAG, "Failed to switch users: " + userRecord.mInfo.id);
- }
- }
- });
-
- }
-
- private void handleAddUserClicked() {
- if (!mUserManager.canAddMoreUsers()) {
- mAddUserView.setEnabled(true);
- showMaxUserLimitReachedDialog();
- } else {
- showConfirmAddUserDialog();
- }
- }
-
- /**
- * Get the maximum number of real (non-guest, non-managed profile) users that can be created
- * on the device. This is a dynamic value and it decreases with the increase of the number
- * of managed profiles on the device.
- *
- * <p> It excludes system user in headless system user model.
- *
- * @return Maximum number of real users that can be created.
- */
- private int getMaxSupportedRealUsers() {
- int maxSupportedUsers = UserManager.getMaxSupportedUsers();
- if (UserManager.isHeadlessSystemUserMode()) {
- maxSupportedUsers -= 1;
- }
-
- List<UserInfo> users = mUserManager.getAliveUsers();
-
- // Count all users that are managed profiles of another user.
- int managedProfilesCount = 0;
- for (UserInfo user : users) {
- if (user.isManagedProfile()) {
- managedProfilesCount++;
- }
- }
-
- return maxSupportedUsers - managedProfilesCount;
- }
-
- private void showMaxUserLimitReachedDialog() {
- AlertDialog maxUsersDialog = new Builder(mContext,
- com.android.internal.R.style.Theme_DeviceDefault_Dialog_Alert)
- .setTitle(R.string.user_limit_reached_title)
- .setMessage(getResources().getQuantityString(
- R.plurals.user_limit_reached_message,
- getMaxSupportedRealUsers(),
- getMaxSupportedRealUsers()))
- .setPositiveButton(android.R.string.ok, null)
- .create();
- // Sets window flags for the SysUI dialog
- applyCarSysUIDialogFlags(maxUsersDialog);
- maxUsersDialog.show();
- }
-
- private void showConfirmAddUserDialog() {
- String message = mRes.getString(R.string.user_add_user_message_setup)
- .concat(System.getProperty("line.separator"))
- .concat(System.getProperty("line.separator"))
- .concat(mRes.getString(R.string.user_add_user_message_update));
-
- AlertDialog addUserDialog = new Builder(mContext,
- com.android.internal.R.style.Theme_DeviceDefault_Dialog_Alert)
- .setTitle(R.string.user_add_user_title)
- .setMessage(message)
- .setNegativeButton(android.R.string.cancel, this)
- .setPositiveButton(android.R.string.ok, this)
- .setOnCancelListener(this)
- .create();
- // Sets window flags for the SysUI dialog
- applyCarSysUIDialogFlags(addUserDialog);
- addUserDialog.show();
- }
-
- private void applyCarSysUIDialogFlags(AlertDialog dialog) {
- final Window window = dialog.getWindow();
- window.setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
- window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
- | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
- window.getAttributes().setFitInsetsTypes(
- window.getAttributes().getFitInsetsTypes() & ~statusBars());
- }
-
- private void notifyUserSelected(UserRecord userRecord) {
- // Notify the listener which user was selected
- if (mUserSelectionListener != null) {
- mUserSelectionListener.onUserSelected(userRecord);
- }
- }
-
- private RoundedBitmapDrawable getCircularUserRecordIcon(UserRecord userRecord) {
- Resources resources = mContext.getResources();
- RoundedBitmapDrawable circleIcon;
- switch (userRecord.mType) {
- case UserRecord.START_GUEST:
- circleIcon = mUserIconProvider.getRoundedGuestDefaultIcon(resources);
- break;
- case UserRecord.ADD_USER:
- circleIcon = getCircularAddUserIcon();
- break;
- default:
- circleIcon = mUserIconProvider.getRoundedUserIcon(userRecord.mInfo, mContext);
- break;
- }
- return circleIcon;
- }
-
- private RoundedBitmapDrawable getCircularAddUserIcon() {
- RoundedBitmapDrawable circleIcon =
- RoundedBitmapDrawableFactory.create(mRes, UserIcons.convertToBitmap(
- mContext.getDrawable(R.drawable.car_add_circle_round)));
- circleIcon.setCircular(true);
- return circleIcon;
- }
-
- private String getUserRecordName(UserRecord userRecord) {
- String recordName;
- switch (userRecord.mType) {
- case UserRecord.START_GUEST:
- recordName = mContext.getString(R.string.start_guest_session);
- break;
- case UserRecord.ADD_USER:
- recordName = mContext.getString(R.string.car_add_user);
- break;
- default:
- recordName = userRecord.mInfo.name;
- break;
- }
- return recordName;
- }
-
- /**
- * Finds the existing Guest user, or creates one if it doesn't exist.
- * @param context App context
- * @return UserInfo representing the Guest user
- */
- @Nullable
- public UserInfo createNewOrFindExistingGuest(Context context) {
- AsyncFuture<UserCreationResult> future = mCarUserManager.createGuest(mGuestName);
- // CreateGuest will return null if a guest already exists.
- UserInfo newGuest = getUserInfo(future);
- if (newGuest != null) {
- new UserIconProvider().assignDefaultIcon(
- mUserManager, context.getResources(), newGuest);
- return newGuest;
- }
-
- return mUserManager.findCurrentGuestUser();
- }
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- if (which == BUTTON_POSITIVE) {
- new AddNewUserTask().execute(mNewUserName);
- } else if (which == BUTTON_NEGATIVE) {
- // Enable the add button only if cancel
- if (mAddUserView != null) {
- mAddUserView.setEnabled(true);
- }
- }
- }
-
- @Override
- public void onCancel(DialogInterface dialog) {
- // Enable the add button again if user cancels dialog by clicking outside the dialog
- if (mAddUserView != null) {
- mAddUserView.setEnabled(true);
- }
- }
-
- @Nullable
- private UserInfo getUserInfo(AsyncFuture<UserCreationResult> future) {
- UserCreationResult userCreationResult;
- try {
- userCreationResult = future.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
- } catch (Exception e) {
- Log.w(TAG, "Could not create user.", e);
- return null;
- }
-
- if (userCreationResult == null) {
- Log.w(TAG, "Timed out while creating user: " + TIMEOUT_MS + "ms");
- return null;
- }
- if (!userCreationResult.isSuccess() || userCreationResult.getUser() == null) {
- Log.w(TAG, "Could not create user: " + userCreationResult);
- return null;
- }
-
- return userCreationResult.getUser();
- }
-
- private boolean switchUser(@UserIdInt int userId) {
- AsyncFuture<UserSwitchResult> userSwitchResultFuture =
- mCarUserManager.switchUser(userId);
- UserSwitchResult userSwitchResult;
- try {
- userSwitchResult = userSwitchResultFuture.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
- } catch (Exception e) {
- Log.w(TAG, "Could not switch user.", e);
- return false;
- }
-
- if (userSwitchResult == null) {
- Log.w(TAG, "Timed out while switching user: " + TIMEOUT_MS + "ms");
- return false;
- }
- if (!userSwitchResult.isSuccess()) {
- Log.w(TAG, "Could not switch user: " + userSwitchResult);
- return false;
- }
-
- return true;
- }
-
- // TODO(b/161539497): Replace AsyncTask with standard {@link java.util.concurrent} code.
- private class AddNewUserTask extends AsyncTask<String, Void, UserInfo> {
-
- @Override
- protected UserInfo doInBackground(String... userNames) {
- AsyncFuture<UserCreationResult> future = mCarUserManager.createUser(userNames[0],
- /* flags= */ 0);
- try {
- UserInfo user = getUserInfo(future);
- if (user != null) {
- UserHelper.setDefaultNonAdminRestrictions(mContext, user,
- /* enable= */ true);
- UserHelper.assignDefaultIcon(mContext, user);
- mAddUserRecord = new UserRecord(user, UserRecord.ADD_USER);
- return user;
- } else {
- Log.e(TAG, "Failed to create user in the background");
- return user;
- }
- } catch (Exception e) {
- if (e instanceof InterruptedException) {
- Thread.currentThread().interrupt();
- }
- Log.e(TAG, "Error creating new user: ", e);
- }
- return null;
- }
-
- @Override
- protected void onPreExecute() {
- }
-
- @Override
- protected void onPostExecute(UserInfo user) {
- if (user != null) {
- notifyUserSelected(mAddUserRecord);
- mAddUserView.setEnabled(true);
- if (!switchUser(user.id)) {
- Log.e(TAG, "Failed to switch to new user: " + user.id);
- }
- }
- if (mAddUserView != null) {
- mAddUserView.setEnabled(true);
- }
- }
- }
-
- @Override
- public int getItemCount() {
- return mUsers.size();
- }
-
- /**
- * An extension of {@link RecyclerView.ViewHolder} that also houses the user name and the
- * user avatar.
- */
- public class UserAdapterViewHolder extends RecyclerView.ViewHolder {
-
- public ImageView mUserAvatarImageView;
- public TextView mUserNameTextView;
- public View mView;
-
- public UserAdapterViewHolder(View view) {
- super(view);
- mView = view;
- mUserAvatarImageView = (ImageView) view.findViewById(R.id.user_avatar);
- mUserNameTextView = (TextView) view.findViewById(R.id.user_name);
- }
- }
- }
-
- /**
- * Object wrapper class for the userInfo. Use it to distinguish if a profile is a
- * guest profile, add user profile, or the foreground user.
- */
- public static final class UserRecord {
- public final UserInfo mInfo;
- public final @UserRecordType int mType;
-
- public static final int START_GUEST = 0;
- public static final int ADD_USER = 1;
- public static final int FOREGROUND_USER = 2;
- public static final int BACKGROUND_USER = 3;
-
- @IntDef({START_GUEST, ADD_USER, FOREGROUND_USER, BACKGROUND_USER})
- @Retention(RetentionPolicy.SOURCE)
- public @interface UserRecordType{}
-
- public UserRecord(@Nullable UserInfo userInfo, @UserRecordType int recordType) {
- mInfo = userInfo;
- mType = recordType;
- }
- }
-
- /**
- * Listener used to notify when a user has been selected
- */
- interface UserSelectionListener {
-
- void onUserSelected(UserRecord record);
- }
-
- /**
- * A {@link RecyclerView.ItemDecoration} that will add spacing between each item in the
- * RecyclerView that it is added to.
- */
- private static class ItemSpacingDecoration extends RecyclerView.ItemDecoration {
- private int mItemSpacing;
-
- private ItemSpacingDecoration(int itemSpacing) {
- mItemSpacing = itemSpacing;
- }
-
- @Override
- public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
- RecyclerView.State state) {
- super.getItemOffsets(outRect, view, parent, state);
- int position = parent.getChildAdapterPosition(view);
-
- // Skip offset for last item except for GridLayoutManager.
- if (position == state.getItemCount() - 1
- && !(parent.getLayoutManager() instanceof GridLayoutManager)) {
- return;
- }
-
- outRect.bottom = mItemSpacing;
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserIconProvider.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserIconProvider.java
deleted file mode 100644
index dc5953e..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserIconProvider.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.userswitcher;
-
-import android.annotation.UserIdInt;
-import android.content.Context;
-import android.content.pm.UserInfo;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.UserHandle;
-import android.os.UserManager;
-
-import androidx.core.graphics.drawable.RoundedBitmapDrawable;
-import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
-
-import com.android.internal.util.UserIcons;
-import com.android.systemui.R;
-
-/**
- * Simple class for providing icons for users.
- */
-public class UserIconProvider {
- /**
- * Gets a scaled rounded icon for the given user. If a user does not have an icon saved, this
- * method will default to a generic icon and update UserManager to use that icon.
- *
- * @param userInfo User for which the icon is requested.
- * @param context Context to use for resources
- * @return {@link RoundedBitmapDrawable} representing the icon for the user.
- */
- public RoundedBitmapDrawable getRoundedUserIcon(UserInfo userInfo, Context context) {
- UserManager userManager = UserManager.get(context);
- Resources res = context.getResources();
- Bitmap icon = userManager.getUserIcon(userInfo.id);
-
- if (icon == null) {
- icon = assignDefaultIcon(userManager, res, userInfo);
- }
-
- return createScaledRoundIcon(res, icon);
- }
-
- /** Returns a scaled, rounded, default icon for the Guest user */
- public RoundedBitmapDrawable getRoundedGuestDefaultIcon(Resources resources) {
- return createScaledRoundIcon(resources, getGuestUserDefaultIcon(resources));
- }
-
- private RoundedBitmapDrawable createScaledRoundIcon(Resources resources, Bitmap icon) {
- BitmapDrawable scaledIcon = scaleUserIcon(resources, icon);
- RoundedBitmapDrawable circleIcon =
- RoundedBitmapDrawableFactory.create(resources, scaledIcon.getBitmap());
- circleIcon.setCircular(true);
- return circleIcon;
- }
-
- /**
- * Returns a {@link Drawable} for the given {@code icon} scaled to the appropriate size.
- */
- private static BitmapDrawable scaleUserIcon(Resources res, Bitmap icon) {
- int desiredSize = res.getDimensionPixelSize(R.dimen.car_primary_icon_size);
- Bitmap scaledIcon =
- Bitmap.createScaledBitmap(icon, desiredSize, desiredSize, /*filter=*/ true);
- return new BitmapDrawable(res, scaledIcon);
- }
-
- /**
- * Assigns a default icon to a user according to the user's id. Handles Guest icon and non-guest
- * user icons.
- *
- * @param userManager {@link UserManager} to set user icon
- * @param resources {@link Resources} to grab icons from
- * @param userInfo User whose avatar is set to default icon.
- * @return Bitmap of the user icon.
- */
- public Bitmap assignDefaultIcon(
- UserManager userManager, Resources resources, UserInfo userInfo) {
- Bitmap bitmap = userInfo.isGuest()
- ? getGuestUserDefaultIcon(resources)
- : getUserDefaultIcon(resources, userInfo.id);
- userManager.setUserIcon(userInfo.id, bitmap);
- return bitmap;
- }
-
- /**
- * Gets a bitmap representing the user's default avatar.
- *
- * @param resources The resources to pull from
- * @param id The id of the user to get the icon for. Pass {@link UserHandle#USER_NULL} for
- * Guest user.
- * @return Default user icon
- */
- private Bitmap getUserDefaultIcon(Resources resources, @UserIdInt int id) {
- return UserIcons.convertToBitmap(
- UserIcons.getDefaultUserIcon(resources, id, /* light= */ false));
- }
-
- private Bitmap getGuestUserDefaultIcon(Resources resources) {
- return getUserDefaultIcon(resources, UserHandle.USER_NULL);
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewController.java
deleted file mode 100644
index 6178cbd..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewController.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.userswitcher;
-
-import static android.car.settings.CarSettings.Global.ENABLE_USER_SWITCH_DEVELOPER_MESSAGE;
-
-import android.annotation.UserIdInt;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.util.Log;
-import android.view.IWindowManager;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.settingslib.drawable.CircleFramedDrawable;
-import com.android.systemui.R;
-import com.android.systemui.car.window.OverlayViewController;
-import com.android.systemui.car.window.OverlayViewGlobalStateController;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-
-import javax.inject.Inject;
-
-/**
- * Handles showing and hiding UserSwitchTransitionView that is mounted to SystemUiOverlayWindow.
- */
-@SysUISingleton
-public class UserSwitchTransitionViewController extends OverlayViewController {
- private static final String TAG = "UserSwitchTransition";
- private static final String ENABLE_DEVELOPER_MESSAGE_TRUE = "true";
- private static final boolean DEBUG = false;
-
- private final Context mContext;
- private final Handler mHandler;
- private final Resources mResources;
- private final UserManager mUserManager;
- private final IWindowManager mWindowManagerService;
- private final int mWindowShownTimeoutMs;
- private final Runnable mWindowShownTimeoutCallback = () -> {
- if (DEBUG) {
- Log.w(TAG, "Window was not hidden within " + getWindowShownTimeoutMs() + " ms, so it"
- + "was hidden by mWindowShownTimeoutCallback.");
- }
-
- handleHide();
- };
-
- @GuardedBy("this")
- private boolean mShowing;
- private int mPreviousUserId = UserHandle.USER_NULL;
-
- @Inject
- public UserSwitchTransitionViewController(
- Context context,
- @Main Handler handler,
- @Main Resources resources,
- UserManager userManager,
- IWindowManager windowManagerService,
- OverlayViewGlobalStateController overlayViewGlobalStateController) {
-
- super(R.id.user_switching_dialog_stub, overlayViewGlobalStateController);
-
- mContext = context;
- mHandler = handler;
- mResources = resources;
- mUserManager = userManager;
- mWindowManagerService = windowManagerService;
- mWindowShownTimeoutMs = mResources.getInteger(
- R.integer.config_userSwitchTransitionViewShownTimeoutMs);
- }
-
- @Override
- protected int getInsetTypesToFit() {
- return 0;
- }
-
- /**
- * Makes the user switch transition view appear and draws the content inside of it if a user
- * that is different from the previous user is provided and if the dialog is not already
- * showing.
- */
- void handleShow(@UserIdInt int newUserId) {
- if (mPreviousUserId == newUserId || mShowing) return;
- mShowing = true;
- mHandler.post(() -> {
- try {
- mWindowManagerService.setSwitchingUser(true);
- mWindowManagerService.lockNow(null);
- } catch (RemoteException e) {
- Log.e(TAG, "unable to notify window manager service regarding user switch");
- }
-
- start();
- populateDialog(mPreviousUserId, newUserId);
- // next time a new user is selected, this current new user will be the previous user.
- mPreviousUserId = newUserId;
- // In case the window is still showing after WINDOW_SHOWN_TIMEOUT_MS, then hide the
- // window and log a warning message.
- mHandler.postDelayed(mWindowShownTimeoutCallback, mWindowShownTimeoutMs);
- });
- }
-
- void handleHide() {
- if (!mShowing) return;
- mShowing = false;
- mHandler.post(this::stop);
- mHandler.removeCallbacks(mWindowShownTimeoutCallback);
- }
-
- @VisibleForTesting
- int getWindowShownTimeoutMs() {
- return mWindowShownTimeoutMs;
- }
-
- private void populateDialog(@UserIdInt int previousUserId, @UserIdInt int newUserId) {
- drawUserIcon(newUserId);
- populateLoadingText(previousUserId, newUserId);
- }
-
- private void drawUserIcon(int newUserId) {
- Bitmap bitmap = mUserManager.getUserIcon(newUserId);
- if (bitmap != null) {
- CircleFramedDrawable drawable = CircleFramedDrawable.getInstance(mContext, bitmap);
- ((ImageView) getLayout().findViewById(R.id.user_loading_avatar))
- .setImageDrawable(drawable);
- }
- }
-
- private void populateLoadingText(@UserIdInt int previousUserId, @UserIdInt int newUserId) {
- TextView msgView = getLayout().findViewById(R.id.user_loading);
-
- boolean showInfo = ENABLE_DEVELOPER_MESSAGE_TRUE.equals(
- Settings.Global.getString(mContext.getContentResolver(),
- ENABLE_USER_SWITCH_DEVELOPER_MESSAGE));
-
- if (showInfo && mPreviousUserId != UserHandle.USER_NULL) {
- msgView.setText(
- mResources.getString(R.string.car_loading_profile_developer_message,
- previousUserId, newUserId));
- } else {
- msgView.setText(mResources.getString(R.string.car_loading_profile));
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediator.java
deleted file mode 100644
index 7db2823..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediator.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.userswitcher;
-
-import android.car.Car;
-import android.car.user.CarUserManager;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.car.CarServiceProvider;
-import com.android.systemui.car.window.OverlayViewMediator;
-
-import javax.inject.Inject;
-
-/**
- * Registers listeners that subscribe to events that show or hide CarUserSwitchingDialog that is
- * mounted to SystemUiOverlayWindow.
- */
-public class UserSwitchTransitionViewMediator implements OverlayViewMediator,
- CarUserManager.UserSwitchUiCallback {
- private static final String TAG = "UserSwitchTransitionViewMediator";
-
- private final CarServiceProvider mCarServiceProvider;
- private final CarDeviceProvisionedController mCarDeviceProvisionedController;
- private final UserSwitchTransitionViewController mUserSwitchTransitionViewController;
-
- @Inject
- public UserSwitchTransitionViewMediator(
- CarServiceProvider carServiceProvider,
- CarDeviceProvisionedController carDeviceProvisionedController,
- UserSwitchTransitionViewController userSwitchTransitionViewController) {
- mCarServiceProvider = carServiceProvider;
- mCarDeviceProvisionedController = carDeviceProvisionedController;
- mUserSwitchTransitionViewController = userSwitchTransitionViewController;
- }
-
- @Override
- public void registerListeners() {
- mCarServiceProvider.addListener(car -> {
- CarUserManager carUserManager =
- (CarUserManager) car.getCarManager(Car.CAR_USER_SERVICE);
-
- if (carUserManager != null) {
- carUserManager.setUserSwitchUiCallback(this);
- carUserManager.addListener(Runnable::run, this::handleUserLifecycleEvent);
- } else {
- Log.e(TAG, "registerListeners: CarUserManager could not be obtained.");
- }
- });
- }
-
- @Override
- public void setupOverlayContentViewControllers() {
- // no-op.
- }
-
- @Override
- public void showUserSwitchDialog(int userId) {
- mUserSwitchTransitionViewController.handleShow(userId);
- }
-
- @VisibleForTesting
- void handleUserLifecycleEvent(CarUserManager.UserLifecycleEvent event) {
- if (event.getEventType() == CarUserManager.USER_LIFECYCLE_EVENT_TYPE_STARTING
- && mCarDeviceProvisionedController.getCurrentUser() == event.getUserId()) {
- mUserSwitchTransitionViewController.handleShow(event.getUserId());
- }
-
- if (event.getEventType() == CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING) {
- mUserSwitchTransitionViewController.handleHide();
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifier.java b/packages/CarSystemUI/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifier.java
deleted file mode 100644
index c054d20..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifier.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.voicerecognition;
-
-import android.bluetooth.BluetoothHeadsetClient;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.util.Log;
-import android.widget.Toast;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
-import com.android.systemui.SysUIToast;
-import com.android.systemui.SystemUI;
-import com.android.systemui.dagger.qualifiers.Main;
-
-import javax.inject.Inject;
-
-/**
- * Controller responsible for showing toast message when voice recognition over bluetooth device
- * getting activated.
- */
-public class ConnectedDeviceVoiceRecognitionNotifier extends SystemUI {
-
- private static final String TAG = "CarVoiceRecognition";
- @VisibleForTesting
- static final int INVALID_VALUE = -1;
- @VisibleForTesting
- static final int VOICE_RECOGNITION_STARTED = 1;
-
- private Handler mHandler;
-
- private final BroadcastReceiver mVoiceRecognitionReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Voice recognition received an intent!");
- }
- if (intent == null
- || intent.getAction() == null
- || !BluetoothHeadsetClient.ACTION_AG_EVENT.equals(intent.getAction())
- || !intent.hasExtra(BluetoothHeadsetClient.EXTRA_VOICE_RECOGNITION)) {
- return;
- }
-
- int voiceRecognitionState = intent.getIntExtra(
- BluetoothHeadsetClient.EXTRA_VOICE_RECOGNITION, INVALID_VALUE);
-
- if (voiceRecognitionState == VOICE_RECOGNITION_STARTED) {
- showToastMessage();
- }
- }
- };
-
- private void showToastMessage() {
- mHandler.post(() -> SysUIToast.makeText(mContext, R.string.voice_recognition_toast,
- Toast.LENGTH_LONG).show());
- }
-
- @Inject
- public ConnectedDeviceVoiceRecognitionNotifier(Context context, @Main Handler handler) {
- super(context);
- mHandler = handler;
- }
-
- @Override
- public void start() {
- }
-
- @Override
- protected void onBootCompleted() {
- IntentFilter filter = new IntentFilter();
- filter.addAction(BluetoothHeadsetClient.ACTION_AG_EVENT);
- mContext.registerReceiverAsUser(mVoiceRecognitionReceiver, UserHandle.ALL, filter,
- /* broadcastPermission= */ null, /* scheduler= */ null);
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogComponent.java b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogComponent.java
deleted file mode 100644
index 4cdbfa3..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogComponent.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.volume;
-
-import android.content.Context;
-
-import com.android.systemui.car.CarServiceProvider;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.demomode.DemoModeController;
-import com.android.systemui.keyguard.KeyguardViewMediator;
-import com.android.systemui.plugins.VolumeDialog;
-import com.android.systemui.volume.VolumeDialogComponent;
-import com.android.systemui.volume.VolumeDialogControllerImpl;
-
-import javax.inject.Inject;
-
-/**
- * Allows for adding car specific dialog when the volume dialog is created.
- */
-@SysUISingleton
-public class CarVolumeDialogComponent extends VolumeDialogComponent {
-
- private CarVolumeDialogImpl mCarVolumeDialog;
-
- @Inject
- public CarVolumeDialogComponent(Context context, KeyguardViewMediator keyguardViewMediator,
- VolumeDialogControllerImpl volumeDialogController,
- DemoModeController demoModeController,
- CarServiceProvider carServiceProvider) {
- super(context, keyguardViewMediator, volumeDialogController, demoModeController);
- mCarVolumeDialog.setCarServiceProvider(carServiceProvider);
- }
-
- /** This method is called while calling the super constructor. */
- @Override
- protected VolumeDialog createDefault() {
- mCarVolumeDialog = new CarVolumeDialogImpl(mContext);
- return mCarVolumeDialog;
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogImpl.java b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogImpl.java
deleted file mode 100644
index 1281884..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogImpl.java
+++ /dev/null
@@ -1,658 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.volume;
-
-import android.animation.Animator;
-import android.animation.AnimatorInflater;
-import android.animation.AnimatorSet;
-import android.annotation.DrawableRes;
-import android.annotation.Nullable;
-import android.app.Dialog;
-import android.app.KeyguardManager;
-import android.car.Car;
-import android.car.media.CarAudioManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.graphics.Color;
-import android.graphics.PixelFormat;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.media.AudioManager;
-import android.os.Debug;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.UserHandle;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.SparseArray;
-import android.util.Xml;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.SeekBar;
-import android.widget.SeekBar.OnSeekBarChangeListener;
-
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.systemui.R;
-import com.android.systemui.car.CarServiceProvider;
-import com.android.systemui.plugins.VolumeDialog;
-import com.android.systemui.volume.Events;
-import com.android.systemui.volume.SystemUIInterpolators;
-import com.android.systemui.volume.VolumeDialogImpl;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Car version of the volume dialog.
- *
- * Methods ending in "H" must be called on the (ui) handler.
- */
-public class CarVolumeDialogImpl implements VolumeDialog {
-
- private static final String TAG = "CarVolumeDialog";
- private static final boolean DEBUG = false;
-
- private static final String XML_TAG_VOLUME_ITEMS = "carVolumeItems";
- private static final String XML_TAG_VOLUME_ITEM = "item";
- private static final int LISTVIEW_ANIMATION_DURATION_IN_MILLIS = 250;
- private static final int DISMISS_DELAY_IN_MILLIS = 50;
- private static final int ARROW_FADE_IN_START_DELAY_IN_MILLIS = 100;
-
- private final Context mContext;
- private final H mHandler = new H();
- // All the volume items.
- private final SparseArray<VolumeItem> mVolumeItems = new SparseArray<>();
- // Available volume items in car audio manager.
- private final List<VolumeItem> mAvailableVolumeItems = new ArrayList<>();
- // Volume items in the RecyclerView.
- private final List<CarVolumeItem> mCarVolumeLineItems = new ArrayList<>();
- private final KeyguardManager mKeyguard;
- private final int mNormalTimeout;
- private final int mHoveringTimeout;
- private final int mExpNormalTimeout;
- private final int mExpHoveringTimeout;
-
- private Window mWindow;
- private CustomDialog mDialog;
- private RecyclerView mListView;
- private CarVolumeItemAdapter mVolumeItemsAdapter;
- private CarAudioManager mCarAudioManager;
- private boolean mHovering;
- private int mCurrentlyDisplayingGroupId;
- private int mPreviouslyDisplayingGroupId;
- private boolean mShowing;
- private boolean mDismissing;
- private boolean mExpanded;
- private View mExpandIcon;
-
- private final CarAudioManager.CarVolumeCallback mVolumeChangeCallback =
- new CarAudioManager.CarVolumeCallback() {
- @Override
- public void onGroupVolumeChanged(int zoneId, int groupId, int flags) {
- // TODO: Include zoneId into consideration.
- // For instance
- // - single display + single-zone, ignore zoneId
- // - multi-display + single-zone, zoneId is fixed, may show volume bar on all
- // displays
- // - single-display + multi-zone, may show volume bar on primary display only
- // - multi-display + multi-zone, may show volume bar on display specified by
- // zoneId
- VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
- int value = getSeekbarValue(mCarAudioManager, groupId);
- // find if the group id for which the volume changed is currently being
- // displayed.
- boolean isShowing = mCarVolumeLineItems.stream().anyMatch(
- item -> item.getGroupId() == groupId);
- // Do not update the progress if it is the same as before. When car audio
- // manager sets
- // its group volume caused by the seekbar progress changed, it also triggers
- // this
- // callback. Updating the seekbar at the same time could block the continuous
- // seeking.
- if (value != volumeItem.mProgress && isShowing) {
- volumeItem.mCarVolumeItem.setProgress(value);
- volumeItem.mProgress = value;
- }
- if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
- mPreviouslyDisplayingGroupId = mCurrentlyDisplayingGroupId;
- mCurrentlyDisplayingGroupId = groupId;
- mHandler.obtainMessage(H.SHOW,
- Events.SHOW_REASON_VOLUME_CHANGED).sendToTarget();
- }
- }
-
- @Override
- public void onMasterMuteChanged(int zoneId, int flags) {
- // ignored
- }
- };
-
- private final CarServiceProvider.CarServiceOnConnectedListener mCarServiceOnConnectedListener =
- car -> {
- mExpanded = false;
- mCarAudioManager = (CarAudioManager) car.getCarManager(Car.AUDIO_SERVICE);
- int volumeGroupCount = mCarAudioManager.getVolumeGroupCount();
- // Populates volume slider items from volume groups to UI.
- for (int groupId = 0; groupId < volumeGroupCount; groupId++) {
- VolumeItem volumeItem = getVolumeItemForUsages(
- mCarAudioManager.getUsagesForVolumeGroupId(groupId));
- mAvailableVolumeItems.add(volumeItem);
- // The first one is the default item.
- if (groupId == 0) {
- clearAllAndSetupDefaultCarVolumeLineItem(0);
- }
- }
-
- // If list is already initiated, update its content.
- if (mVolumeItemsAdapter != null) {
- mVolumeItemsAdapter.notifyDataSetChanged();
- }
- mCarAudioManager.registerCarVolumeCallback(mVolumeChangeCallback);
- };
-
- private final BroadcastReceiver mHomeButtonPressedBroadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
- return;
- }
-
- dismissH(Events.DISMISS_REASON_VOLUME_CONTROLLER);
- }
- };
-
- public CarVolumeDialogImpl(Context context) {
- mContext = context;
- mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
- mNormalTimeout = mContext.getResources().getInteger(
- R.integer.car_volume_dialog_display_normal_timeout);
- mHoveringTimeout = mContext.getResources().getInteger(
- R.integer.car_volume_dialog_display_hovering_timeout);
- mExpNormalTimeout = mContext.getResources().getInteger(
- R.integer.car_volume_dialog_display_expanded_normal_timeout);
- mExpHoveringTimeout = mContext.getResources().getInteger(
- R.integer.car_volume_dialog_display_expanded_hovering_timeout);
- }
-
- /** Sets a {@link CarServiceProvider} which connects to the audio service. */
- public void setCarServiceProvider(CarServiceProvider carServiceProvider) {
- carServiceProvider.addListener(mCarServiceOnConnectedListener);
- }
-
- private static int getSeekbarValue(CarAudioManager carAudioManager, int volumeGroupId) {
- return carAudioManager.getGroupVolume(volumeGroupId);
- }
-
- private static int getMaxSeekbarValue(CarAudioManager carAudioManager, int volumeGroupId) {
- return carAudioManager.getGroupMaxVolume(volumeGroupId);
- }
-
- /**
- * Build the volume window and connect to the CarService which registers with car audio
- * manager.
- */
- @Override
- public void init(int windowType, Callback callback) {
- initDialog();
-
- mContext.registerReceiverAsUser(mHomeButtonPressedBroadcastReceiver, UserHandle.CURRENT,
- new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), /* broadcastPermission= */
- null, /* scheduler= */ null);
- }
-
- @Override
- public void destroy() {
- mHandler.removeCallbacksAndMessages(/* token= */ null);
-
- mContext.unregisterReceiver(mHomeButtonPressedBroadcastReceiver);
-
- cleanupAudioManager();
- }
-
- /**
- * Reveals volume dialog.
- */
- public void show(int reason) {
- mHandler.obtainMessage(H.SHOW, reason).sendToTarget();
- }
-
- /**
- * Hides volume dialog.
- */
- public void dismiss(int reason) {
- mHandler.obtainMessage(H.DISMISS, reason).sendToTarget();
- }
-
- private void initDialog() {
- loadAudioUsageItems();
- mCarVolumeLineItems.clear();
- mDialog = new CustomDialog(mContext);
-
- mHovering = false;
- mShowing = false;
- mDismissing = false;
- mExpanded = false;
- mWindow = mDialog.getWindow();
- mWindow.requestFeature(Window.FEATURE_NO_TITLE);
- mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
- mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND
- | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
- mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
- | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
- | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
- | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
- mWindow.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
- mWindow.setWindowAnimations(com.android.internal.R.style.Animation_Toast);
- final WindowManager.LayoutParams lp = mWindow.getAttributes();
- lp.format = PixelFormat.TRANSLUCENT;
- lp.setTitle(VolumeDialogImpl.class.getSimpleName());
- lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
- lp.windowAnimations = -1;
- mWindow.setAttributes(lp);
-
- mDialog.setContentView(R.layout.car_volume_dialog);
- mWindow.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
-
- mDialog.setCanceledOnTouchOutside(true);
- mDialog.setOnShowListener(dialog -> {
- mListView.setTranslationY(-mListView.getHeight());
- mListView.setAlpha(0);
- mListView.animate()
- .alpha(1)
- .translationY(0)
- .setDuration(LISTVIEW_ANIMATION_DURATION_IN_MILLIS)
- .setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator())
- .start();
- });
- mListView = mWindow.findViewById(R.id.volume_list);
- mListView.setOnHoverListener((v, event) -> {
- int action = event.getActionMasked();
- mHovering = (action == MotionEvent.ACTION_HOVER_ENTER)
- || (action == MotionEvent.ACTION_HOVER_MOVE);
- rescheduleTimeoutH();
- return true;
- });
-
- mVolumeItemsAdapter = new CarVolumeItemAdapter(mContext, mCarVolumeLineItems);
- mListView.setAdapter(mVolumeItemsAdapter);
- mListView.setLayoutManager(new LinearLayoutManager(mContext));
- }
-
-
- private void showH(int reason) {
- if (DEBUG) {
- Log.d(TAG, "showH r=" + Events.DISMISS_REASONS[reason]);
- }
-
- mHandler.removeMessages(H.SHOW);
- mHandler.removeMessages(H.DISMISS);
-
- rescheduleTimeoutH();
-
- // Refresh the data set before showing.
- mVolumeItemsAdapter.notifyDataSetChanged();
-
- if (mShowing) {
- if (mPreviouslyDisplayingGroupId == mCurrentlyDisplayingGroupId || mExpanded) {
- return;
- }
-
- clearAllAndSetupDefaultCarVolumeLineItem(mCurrentlyDisplayingGroupId);
- return;
- }
-
- mShowing = true;
- clearAllAndSetupDefaultCarVolumeLineItem(mCurrentlyDisplayingGroupId);
- mDialog.show();
- Events.writeEvent(Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
- }
-
- private void clearAllAndSetupDefaultCarVolumeLineItem(int groupId) {
- mCarVolumeLineItems.clear();
- VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
- volumeItem.mDefaultItem = true;
- addCarVolumeListItem(volumeItem, /* volumeGroupId = */ groupId,
- R.drawable.car_ic_keyboard_arrow_down, new ExpandIconListener());
- }
-
- protected void rescheduleTimeoutH() {
- mHandler.removeMessages(H.DISMISS);
- final int timeout = computeTimeoutH();
- mHandler.sendMessageDelayed(mHandler
- .obtainMessage(H.DISMISS, Events.DISMISS_REASON_TIMEOUT), timeout);
-
- if (DEBUG) {
- Log.d(TAG, "rescheduleTimeout " + timeout + " " + Debug.getCaller());
- }
- }
-
- private int computeTimeoutH() {
- if (mExpanded) {
- return mHovering ? mExpHoveringTimeout : mExpNormalTimeout;
- } else {
- return mHovering ? mHoveringTimeout : mNormalTimeout;
- }
- }
-
- private void dismissH(int reason) {
- if (DEBUG) {
- Log.d(TAG, "dismissH r=" + Events.DISMISS_REASONS[reason]);
- }
-
- mHandler.removeMessages(H.DISMISS);
- mHandler.removeMessages(H.SHOW);
- if (!mShowing || mDismissing) {
- return;
- }
-
- mDismissing = true;
- mListView.animate()
- .alpha(0)
- .translationY(-mListView.getHeight())
- .setDuration(LISTVIEW_ANIMATION_DURATION_IN_MILLIS)
- .setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator())
- .withEndAction(() -> mHandler.postDelayed(() -> {
- if (DEBUG) {
- Log.d(TAG, "mDialog.dismiss()");
- }
- mDialog.dismiss();
- mShowing = false;
- mDismissing = false;
- // if mExpandIcon is null that means user never clicked on the expanded arrow
- // which implies that the dialog is still not expanded. In that case we do
- // not want to reset the state
- if (mExpandIcon != null && mExpanded) {
- toggleDialogExpansion(/* isClicked = */ false);
- }
- }, DISMISS_DELAY_IN_MILLIS))
- .start();
-
- Events.writeEvent(Events.EVENT_DISMISS_DIALOG, reason);
- }
-
- private void loadAudioUsageItems() {
- try (XmlResourceParser parser = mContext.getResources().getXml(R.xml.car_volume_items)) {
- AttributeSet attrs = Xml.asAttributeSet(parser);
- int type;
- // Traverse to the first start tag
- while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT
- && type != XmlResourceParser.START_TAG) {
- // Do Nothing (moving parser to start element)
- }
-
- if (!XML_TAG_VOLUME_ITEMS.equals(parser.getName())) {
- throw new RuntimeException("Meta-data does not start with carVolumeItems tag");
- }
- int outerDepth = parser.getDepth();
- int rank = 0;
- while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT
- && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) {
- if (type == XmlResourceParser.END_TAG) {
- continue;
- }
- if (XML_TAG_VOLUME_ITEM.equals(parser.getName())) {
- TypedArray item = mContext.getResources().obtainAttributes(
- attrs, R.styleable.carVolumeItems_item);
- int usage = item.getInt(R.styleable.carVolumeItems_item_usage,
- /* defValue= */ -1);
- if (usage >= 0) {
- VolumeItem volumeItem = new VolumeItem();
- volumeItem.mRank = rank;
- volumeItem.mIcon = item.getResourceId(
- R.styleable.carVolumeItems_item_icon, /* defValue= */ 0);
- mVolumeItems.put(usage, volumeItem);
- rank++;
- }
- item.recycle();
- }
- }
- } catch (XmlPullParserException | IOException e) {
- Log.e(TAG, "Error parsing volume groups configuration", e);
- }
- }
-
- private VolumeItem getVolumeItemForUsages(int[] usages) {
- int rank = Integer.MAX_VALUE;
- VolumeItem result = null;
- for (int usage : usages) {
- VolumeItem volumeItem = mVolumeItems.get(usage);
- if (volumeItem.mRank < rank) {
- rank = volumeItem.mRank;
- result = volumeItem;
- }
- }
- return result;
- }
-
- private CarVolumeItem createCarVolumeListItem(VolumeItem volumeItem, int volumeGroupId,
- Drawable supplementalIcon, int seekbarProgressValue,
- @Nullable View.OnClickListener supplementalIconOnClickListener) {
- CarVolumeItem carVolumeItem = new CarVolumeItem();
- carVolumeItem.setMax(getMaxSeekbarValue(mCarAudioManager, volumeGroupId));
- carVolumeItem.setProgress(seekbarProgressValue);
- carVolumeItem.setOnSeekBarChangeListener(
- new CarVolumeDialogImpl.VolumeSeekBarChangeListener(volumeGroupId,
- mCarAudioManager));
- carVolumeItem.setGroupId(volumeGroupId);
-
- int color = mContext.getColor(R.color.car_volume_dialog_tint);
- Drawable primaryIcon = mContext.getDrawable(volumeItem.mIcon);
- primaryIcon.mutate().setTint(color);
- carVolumeItem.setPrimaryIcon(primaryIcon);
- if (supplementalIcon != null) {
- supplementalIcon.mutate().setTint(color);
- carVolumeItem.setSupplementalIcon(supplementalIcon,
- /* showSupplementalIconDivider= */ true);
- carVolumeItem.setSupplementalIconListener(supplementalIconOnClickListener);
- } else {
- carVolumeItem.setSupplementalIcon(/* drawable= */ null,
- /* showSupplementalIconDivider= */ false);
- }
-
- volumeItem.mCarVolumeItem = carVolumeItem;
- volumeItem.mProgress = seekbarProgressValue;
-
- return carVolumeItem;
- }
-
- private CarVolumeItem addCarVolumeListItem(VolumeItem volumeItem, int volumeGroupId,
- int supplementalIconId,
- @Nullable View.OnClickListener supplementalIconOnClickListener) {
- int seekbarProgressValue = getSeekbarValue(mCarAudioManager, volumeGroupId);
- Drawable supplementalIcon = supplementalIconId == 0 ? null : mContext.getDrawable(
- supplementalIconId);
- CarVolumeItem carVolumeItem = createCarVolumeListItem(volumeItem, volumeGroupId,
- supplementalIcon, seekbarProgressValue, supplementalIconOnClickListener);
- mCarVolumeLineItems.add(carVolumeItem);
- return carVolumeItem;
- }
-
- private void cleanupAudioManager() {
- mCarAudioManager.unregisterCarVolumeCallback(mVolumeChangeCallback);
- mCarVolumeLineItems.clear();
- mCarAudioManager = null;
- }
-
- /**
- * Wrapper class which contains information of each volume group.
- */
- private static class VolumeItem {
- private int mRank;
- private boolean mDefaultItem = false;
- @DrawableRes
- private int mIcon;
- private CarVolumeItem mCarVolumeItem;
- private int mProgress;
- }
-
- private final class H extends Handler {
-
- private static final int SHOW = 1;
- private static final int DISMISS = 2;
-
- private H() {
- super(Looper.getMainLooper());
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case SHOW:
- showH(msg.arg1);
- break;
- case DISMISS:
- dismissH(msg.arg1);
- break;
- default:
- }
- }
- }
-
- private final class CustomDialog extends Dialog implements DialogInterface {
-
- private CustomDialog(Context context) {
- super(context, com.android.systemui.R.style.qs_theme);
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- rescheduleTimeoutH();
- return super.dispatchTouchEvent(ev);
- }
-
- @Override
- protected void onStart() {
- super.setCanceledOnTouchOutside(true);
- super.onStart();
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (isShowing()) {
- if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
- mHandler.obtainMessage(
- H.DISMISS, Events.DISMISS_REASON_TOUCH_OUTSIDE).sendToTarget();
- return true;
- }
- }
- return false;
- }
- }
-
- private final class ExpandIconListener implements View.OnClickListener {
- @Override
- public void onClick(final View v) {
- mExpandIcon = v;
- toggleDialogExpansion(true);
- rescheduleTimeoutH();
- }
- }
-
- private void toggleDialogExpansion(boolean isClicked) {
- mExpanded = !mExpanded;
- Animator inAnimator;
- if (mExpanded) {
- for (int groupId = 0; groupId < mAvailableVolumeItems.size(); ++groupId) {
- if (groupId != mCurrentlyDisplayingGroupId) {
- VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
- addCarVolumeListItem(volumeItem, groupId, /* supplementalIconId= */ 0,
- /* supplementalIconOnClickListener= */ null);
- }
- }
- inAnimator = AnimatorInflater.loadAnimator(
- mContext, R.anim.car_arrow_fade_in_rotate_up);
-
- } else {
- clearAllAndSetupDefaultCarVolumeLineItem(mCurrentlyDisplayingGroupId);
- inAnimator = AnimatorInflater.loadAnimator(
- mContext, R.anim.car_arrow_fade_in_rotate_down);
- }
-
- Animator outAnimator = AnimatorInflater.loadAnimator(
- mContext, R.anim.car_arrow_fade_out);
- inAnimator.setStartDelay(ARROW_FADE_IN_START_DELAY_IN_MILLIS);
- AnimatorSet animators = new AnimatorSet();
- animators.playTogether(outAnimator, inAnimator);
- if (!isClicked) {
- // Do not animate when the state is called to reset the dialogs view and not clicked
- // by user.
- animators.setDuration(0);
- }
- animators.setTarget(mExpandIcon);
- animators.start();
- mVolumeItemsAdapter.notifyDataSetChanged();
- }
-
- private final class VolumeSeekBarChangeListener implements OnSeekBarChangeListener {
-
- private final int mVolumeGroupId;
- private final CarAudioManager mCarAudioManager;
-
- private VolumeSeekBarChangeListener(int volumeGroupId, CarAudioManager carAudioManager) {
- mVolumeGroupId = volumeGroupId;
- mCarAudioManager = carAudioManager;
- }
-
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- if (!fromUser) {
- // For instance, if this event is originated from AudioService,
- // we can ignore it as it has already been handled and doesn't need to be
- // sent back down again.
- return;
- }
- if (mCarAudioManager == null) {
- Log.w(TAG, "Ignoring volume change event because the car isn't connected");
- return;
- }
- mAvailableVolumeItems.get(mVolumeGroupId).mProgress = progress;
- mAvailableVolumeItems.get(
- mVolumeGroupId).mCarVolumeItem.setProgress(progress);
- mCarAudioManager.setGroupVolume(mVolumeGroupId, progress, 0);
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeItem.java b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeItem.java
deleted file mode 100644
index 1e7e534..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeItem.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.volume;
-
-import android.graphics.drawable.Drawable;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.SeekBar;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.systemui.R;
-
-/** Holds all related data to represent a volume group. */
-public class CarVolumeItem {
-
- private Drawable mPrimaryIcon;
- private Drawable mSupplementalIcon;
- private View.OnClickListener mSupplementalIconOnClickListener;
- private boolean mShowSupplementalIconDivider;
- private int mGroupId;
-
- private int mMax;
- private int mProgress;
- private SeekBar.OnSeekBarChangeListener mOnSeekBarChangeListener;
-
- /**
- * Called when {@link CarVolumeItem} is bound to its ViewHolder.
- */
- void bind(CarVolumeItemViewHolder viewHolder) {
- viewHolder.bind(/* carVolumeItem= */ this);
- }
-
- /** Sets progress of seekbar. */
- public void setProgress(int progress) {
- mProgress = progress;
- }
-
- /** Sets max value of seekbar. */
- public void setMax(int max) {
- mMax = max;
- }
-
- /** Sets {@link SeekBar.OnSeekBarChangeListener}. */
- public void setOnSeekBarChangeListener(SeekBar.OnSeekBarChangeListener listener) {
- mOnSeekBarChangeListener = listener;
- }
-
- /** Sets the primary icon. */
- public void setPrimaryIcon(Drawable drawable) {
- mPrimaryIcon = drawable;
- }
-
- /** Sets the supplemental icon and the visibility of the supplemental icon divider. */
- public void setSupplementalIcon(Drawable drawable, boolean showSupplementalIconDivider) {
- mSupplementalIcon = drawable;
- mShowSupplementalIconDivider = showSupplementalIconDivider;
- }
-
- /**
- * Gets the group id associated.
- */
- public int getGroupId() {
- return mGroupId;
- }
-
- /**
- * Sets the group id associated.
- */
- public void setGroupId(int groupId) {
- this.mGroupId = groupId;
- }
-
- /** Sets {@code OnClickListener} for the supplemental icon. */
- public void setSupplementalIconListener(View.OnClickListener listener) {
- mSupplementalIconOnClickListener = listener;
- }
-
- /** Defines the view holder which shows the information held by {@link CarVolumeItem}. */
- public static class CarVolumeItemViewHolder extends RecyclerView.ViewHolder {
-
- private SeekBar mSeekBar;
- private ImageView mPrimaryIcon;
- private View mSupplementalIconDivider;
- private ImageView mSupplementalIcon;
-
- public CarVolumeItemViewHolder(@NonNull View itemView) {
- super(itemView);
-
- mSeekBar = itemView.findViewById(R.id.seek_bar);
- mPrimaryIcon = itemView.findViewById(R.id.primary_icon);
- mSupplementalIcon = itemView.findViewById(R.id.supplemental_icon);
- mSupplementalIconDivider = itemView.findViewById(R.id.supplemental_icon_divider);
- }
-
- /**
- * Binds {@link CarVolumeItem} to the {@link CarVolumeItemViewHolder}.
- */
- void bind(CarVolumeItem carVolumeItem) {
- // Progress bar
- mSeekBar.setMax(carVolumeItem.mMax);
- mSeekBar.setProgress(carVolumeItem.mProgress);
- mSeekBar.setOnSeekBarChangeListener(carVolumeItem.mOnSeekBarChangeListener);
-
- // Primary icon
- mPrimaryIcon.setVisibility(View.VISIBLE);
- mPrimaryIcon.setImageDrawable(carVolumeItem.mPrimaryIcon);
-
- // Supplemental icon
- mSupplementalIcon.setVisibility(View.VISIBLE);
- mSupplementalIconDivider.setVisibility(
- carVolumeItem.mShowSupplementalIconDivider ? View.VISIBLE : View.INVISIBLE);
- mSupplementalIcon.setImageDrawable(carVolumeItem.mSupplementalIcon);
- mSupplementalIcon.setOnClickListener(
- carVolumeItem.mSupplementalIconOnClickListener);
- mSupplementalIcon.setClickable(
- carVolumeItem.mSupplementalIconOnClickListener != null);
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeItemAdapter.java b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeItemAdapter.java
deleted file mode 100644
index 7f336b5..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeItemAdapter.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.volume;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.systemui.R;
-
-import java.util.List;
-
-/** The {@link RecyclerView.Adapter} to show the volume items in the sysUI volume dialog. */
-public class CarVolumeItemAdapter extends
- RecyclerView.Adapter<CarVolumeItem.CarVolumeItemViewHolder> {
-
- private final Context mContext;
- private final List<CarVolumeItem> mItems;
-
- public CarVolumeItemAdapter(Context context, List<CarVolumeItem> items) {
- mContext = context;
- mItems = items;
- }
-
- @Override
- public CarVolumeItem.CarVolumeItemViewHolder onCreateViewHolder(ViewGroup parent,
- int viewType) {
- LayoutInflater inflater = LayoutInflater.from(mContext);
- View view = inflater.inflate(R.layout.car_volume_item, parent, false);
- return new CarVolumeItem.CarVolumeItemViewHolder(view);
- }
-
- @Override
- public void onBindViewHolder(CarVolumeItem.CarVolumeItemViewHolder holder, int position) {
- mItems.get(position).bind(holder);
- }
-
- @Override
- public int getItemCount() {
- return mItems.size();
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/volume/VolumeUI.java b/packages/CarSystemUI/src/com/android/systemui/car/volume/VolumeUI.java
deleted file mode 100644
index b0321ab..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/volume/VolumeUI.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.volume;
-
-import android.car.Car;
-import android.car.media.CarAudioManager;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.os.Handler;
-import android.util.Log;
-
-import com.android.systemui.R;
-import com.android.systemui.SystemUI;
-import com.android.systemui.car.CarServiceProvider;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.volume.VolumeDialogComponent;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-import javax.inject.Inject;
-
-import dagger.Lazy;
-
-/** The entry point for controlling the volume ui in cars. */
-@SysUISingleton
-public class VolumeUI extends SystemUI {
-
- private static final String TAG = "VolumeUI";
- private final Resources mResources;
- private final Handler mMainHandler;
- private final CarServiceProvider mCarServiceProvider;
- private final Lazy<VolumeDialogComponent> mVolumeDialogComponentLazy;
-
- private final CarAudioManager.CarVolumeCallback mVolumeChangeCallback =
- new CarAudioManager.CarVolumeCallback() {
- @Override
- public void onGroupVolumeChanged(int zoneId, int groupId, int flags) {
- initVolumeDialogComponent();
- }
-
- @Override
- public void onMasterMuteChanged(int zoneId, int flags) {
- initVolumeDialogComponent();
- }
-
- private void initVolumeDialogComponent() {
- if (mVolumeDialogComponent == null) {
- mMainHandler.post(() -> {
- mVolumeDialogComponent = mVolumeDialogComponentLazy.get();
- mVolumeDialogComponent.register();
- });
- mCarAudioManager.unregisterCarVolumeCallback(mVolumeChangeCallback);
- }
- }
- };
-
- private boolean mEnabled;
- private CarAudioManager mCarAudioManager;
- private VolumeDialogComponent mVolumeDialogComponent;
-
- @Inject
- public VolumeUI(
- Context context,
- @Main Resources resources,
- @Main Handler mainHandler,
- CarServiceProvider carServiceProvider,
- Lazy<VolumeDialogComponent> volumeDialogComponentLazy
- ) {
- super(context);
- mResources = resources;
- mMainHandler = mainHandler;
- mCarServiceProvider = carServiceProvider;
- mVolumeDialogComponentLazy = volumeDialogComponentLazy;
- }
-
- @Override
- public void start() {
- boolean enableVolumeUi = mResources.getBoolean(R.bool.enable_volume_ui);
- mEnabled = enableVolumeUi;
- if (!mEnabled) return;
-
- mCarServiceProvider.addListener(car -> {
- if (mCarAudioManager != null) {
- return;
- }
-
- mCarAudioManager = (CarAudioManager) car.getCarManager(Car.AUDIO_SERVICE);
- Log.d(TAG, "Registering mVolumeChangeCallback.");
- // This volume call back is never unregistered because CarStatusBar is
- // never destroyed.
- mCarAudioManager.registerCarVolumeCallback(mVolumeChangeCallback);
- });
- }
-
- @Override
- protected void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- if (!mEnabled) return;
- if (mVolumeDialogComponent != null) {
- mVolumeDialogComponent.onConfigurationChanged(newConfig);
- }
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.print("mEnabled="); pw.println(mEnabled);
- if (!mEnabled) return;
- if (mVolumeDialogComponent != null) {
- mVolumeDialogComponent.dump(fd, pw, args);
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java
deleted file mode 100644
index 44cb5cf..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java
+++ /dev/null
@@ -1,685 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.window;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.annotation.IntDef;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Rect;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewTreeObserver;
-
-import androidx.annotation.CallSuper;
-
-import com.android.systemui.R;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.wm.shell.animation.FlingAnimationUtils;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * The {@link OverlayPanelViewController} provides additional dragging animation capabilities to
- * {@link OverlayViewController}.
- */
-public abstract class OverlayPanelViewController extends OverlayViewController {
-
- /** @hide */
- @IntDef(flag = true, prefix = { "OVERLAY_" }, value = {
- OVERLAY_FROM_TOP_BAR,
- OVERLAY_FROM_BOTTOM_BAR
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface OverlayDirection {}
-
- /**
- * Indicates that the overlay panel should be opened from the top bar and expanded by dragging
- * towards the bottom bar.
- */
- public static final int OVERLAY_FROM_TOP_BAR = 0;
-
- /**
- * Indicates that the overlay panel should be opened from the bottom bar and expanded by
- * dragging towards the top bar.
- */
- public static final int OVERLAY_FROM_BOTTOM_BAR = 1;
-
- private static final boolean DEBUG = false;
- private static final String TAG = "OverlayPanelViewController";
-
- // used to calculate how fast to open or close the window
- protected static final float DEFAULT_FLING_VELOCITY = 0;
- // max time a fling animation takes
- protected static final float FLING_ANIMATION_MAX_TIME = 0.5f;
- // acceleration rate for the fling animation
- protected static final float FLING_SPEED_UP_FACTOR = 0.6f;
-
- protected static final int SWIPE_DOWN_MIN_DISTANCE = 25;
- protected static final int SWIPE_MAX_OFF_PATH = 75;
- protected static final int SWIPE_THRESHOLD_VELOCITY = 200;
- private static final int POSITIVE_DIRECTION = 1;
- private static final int NEGATIVE_DIRECTION = -1;
-
- private final FlingAnimationUtils mFlingAnimationUtils;
- private final CarDeviceProvisionedController mCarDeviceProvisionedController;
- private final View.OnTouchListener mDragOpenTouchListener;
- private final View.OnTouchListener mDragCloseTouchListener;
-
- protected int mAnimateDirection = POSITIVE_DIRECTION;
-
- private final int mSettleClosePercentage;
- private int mPercentageFromEndingEdge;
-
- private boolean mPanelVisible;
- private boolean mPanelExpanded;
-
- private float mOpeningVelocity = DEFAULT_FLING_VELOCITY;
- private float mClosingVelocity = DEFAULT_FLING_VELOCITY;
-
- private boolean mIsAnimating;
- private boolean mIsTracking;
-
- public OverlayPanelViewController(
- Context context,
- @Main Resources resources,
- int stubId,
- OverlayViewGlobalStateController overlayViewGlobalStateController,
- FlingAnimationUtils.Builder flingAnimationUtilsBuilder,
- CarDeviceProvisionedController carDeviceProvisionedController
- ) {
- super(stubId, overlayViewGlobalStateController);
-
- mFlingAnimationUtils = flingAnimationUtilsBuilder
- .setMaxLengthSeconds(FLING_ANIMATION_MAX_TIME)
- .setSpeedUpFactor(FLING_SPEED_UP_FACTOR)
- .build();
- mCarDeviceProvisionedController = carDeviceProvisionedController;
-
- mSettleClosePercentage = resources.getInteger(
- R.integer.notification_settle_close_percentage);
-
- // Attached to a navigation bar to open the overlay panel
- GestureDetector openGestureDetector = new GestureDetector(context,
- new OpenGestureListener() {
- @Override
- protected void open() {
- animateExpandPanel();
- }
- });
-
- // Attached to the other navigation bars to close the overlay panel
- GestureDetector closeGestureDetector = new GestureDetector(context,
- new SystemBarCloseGestureListener() {
- @Override
- protected void close() {
- if (isPanelExpanded()) {
- animateCollapsePanel();
- }
- }
- });
-
- mDragOpenTouchListener = (v, event) -> {
- if (!mCarDeviceProvisionedController.isCurrentUserFullySetup()) {
- return true;
- }
- if (!isInflated()) {
- getOverlayViewGlobalStateController().inflateView(this);
- }
-
- boolean consumed = openGestureDetector.onTouchEvent(event);
- if (consumed) {
- return true;
- }
- maybeCompleteAnimation(event);
- return true;
- };
-
- mDragCloseTouchListener = (v, event) -> {
- if (!isInflated()) {
- return true;
- }
- boolean consumed = closeGestureDetector.onTouchEvent(event);
- if (consumed) {
- return true;
- }
- maybeCompleteAnimation(event);
- return true;
- };
- }
-
- /** Sets the overlay panel animation direction along the x or y axis. */
- public void setOverlayDirection(@OverlayDirection int direction) {
- if (direction == OVERLAY_FROM_TOP_BAR) {
- mAnimateDirection = POSITIVE_DIRECTION;
- } else if (direction == OVERLAY_FROM_BOTTOM_BAR) {
- mAnimateDirection = NEGATIVE_DIRECTION;
- } else {
- throw new IllegalArgumentException("Direction not supported");
- }
- }
-
- /** Toggles the visibility of the panel. */
- public void toggle() {
- if (!isInflated()) {
- getOverlayViewGlobalStateController().inflateView(this);
- }
- if (isPanelExpanded()) {
- animateCollapsePanel();
- } else {
- animateExpandPanel();
- }
- }
-
- /** Checks if a {@link MotionEvent} is an action to open the panel.
- * @param e {@link MotionEvent} to check.
- * @return true only if opening action.
- */
- protected boolean isOpeningAction(MotionEvent e) {
- if (mAnimateDirection == POSITIVE_DIRECTION) {
- return e.getActionMasked() == MotionEvent.ACTION_DOWN;
- }
-
- if (mAnimateDirection == NEGATIVE_DIRECTION) {
- return e.getActionMasked() == MotionEvent.ACTION_UP;
- }
-
- return false;
- }
-
- /** Checks if a {@link MotionEvent} is an action to close the panel.
- * @param e {@link MotionEvent} to check.
- * @return true only if closing action.
- */
- protected boolean isClosingAction(MotionEvent e) {
- if (mAnimateDirection == POSITIVE_DIRECTION) {
- return e.getActionMasked() == MotionEvent.ACTION_UP;
- }
-
- if (mAnimateDirection == NEGATIVE_DIRECTION) {
- return e.getActionMasked() == MotionEvent.ACTION_DOWN;
- }
-
- return false;
- }
-
- /* ***************************************************************************************** *
- * Panel Animation
- * ***************************************************************************************** */
-
- /** Animates the closing of the panel. */
- protected void animateCollapsePanel() {
- if (!shouldAnimateCollapsePanel()) {
- return;
- }
-
- if (!isPanelExpanded() || !isPanelVisible()) {
- return;
- }
-
- onAnimateCollapsePanel();
- animatePanel(mClosingVelocity, /* isClosing= */ true);
- }
-
- /** Determines whether {@link #animateCollapsePanel()} should collapse the panel. */
- protected abstract boolean shouldAnimateCollapsePanel();
-
- /** Called when the panel is beginning to collapse. */
- protected abstract void onAnimateCollapsePanel();
-
- /** Animates the expansion of the panel. */
- protected void animateExpandPanel() {
- if (!shouldAnimateExpandPanel()) {
- return;
- }
-
- if (!mCarDeviceProvisionedController.isCurrentUserFullySetup()) {
- return;
- }
-
- onAnimateExpandPanel();
- setPanelVisible(true);
- animatePanel(mOpeningVelocity, /* isClosing= */ false);
-
- setPanelExpanded(true);
- }
-
- /** Determines whether {@link #animateExpandPanel()}} should expand the panel. */
- protected abstract boolean shouldAnimateExpandPanel();
-
- /** Called when the panel is beginning to expand. */
- protected abstract void onAnimateExpandPanel();
-
- /**
- * Depending on certain conditions, determines whether to fully expand or collapse the panel.
- */
- protected void maybeCompleteAnimation(MotionEvent event) {
- if (isClosingAction(event) && isPanelVisible()) {
- if (mSettleClosePercentage < mPercentageFromEndingEdge) {
- animatePanel(DEFAULT_FLING_VELOCITY, false);
- } else {
- animatePanel(DEFAULT_FLING_VELOCITY, true);
- }
- }
- }
-
- /**
- * Animates the panel from one position to other. This is used to either open or
- * close the panel completely with a velocity. If the animation is to close the
- * panel this method also makes the view invisible after animation ends.
- */
- protected void animatePanel(float velocity, boolean isClosing) {
- float to = getEndPosition(isClosing);
-
- Rect rect = getLayout().getClipBounds();
- if (rect != null) {
- float from = getCurrentStartPosition(rect);
- if (from != to) {
- animate(from, to, velocity, isClosing);
- }
-
- // If we swipe down the notification panel all the way to the bottom of the screen
- // (i.e. from == to), then we have finished animating the panel.
- return;
- }
-
- // We will only be here if the shade is being opened programmatically or via button when
- // height of the layout was not calculated.
- ViewTreeObserver panelTreeObserver = getLayout().getViewTreeObserver();
- panelTreeObserver.addOnGlobalLayoutListener(
- new ViewTreeObserver.OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- ViewTreeObserver obs = getLayout().getViewTreeObserver();
- obs.removeOnGlobalLayoutListener(this);
- animate(
- getDefaultStartPosition(),
- getEndPosition(/* isClosing= */ false),
- velocity,
- isClosing
- );
- }
- });
- }
-
- /* Returns the start position if the user has not started swiping. */
- private int getDefaultStartPosition() {
- return mAnimateDirection > 0 ? 0 : getLayout().getHeight();
- }
-
- /** Returns the start position if we are in the middle of swiping. */
- private int getCurrentStartPosition(Rect clipBounds) {
- return mAnimateDirection > 0 ? clipBounds.bottom : clipBounds.top;
- }
-
- private int getEndPosition(boolean isClosing) {
- return (mAnimateDirection > 0 && !isClosing) || (mAnimateDirection == -1 && isClosing)
- ? getLayout().getHeight()
- : 0;
- }
-
- private void animate(float from, float to, float velocity, boolean isClosing) {
- if (mIsAnimating) {
- return;
- }
- mIsAnimating = true;
- mIsTracking = true;
- ValueAnimator animator = ValueAnimator.ofFloat(from, to);
- animator.addUpdateListener(
- animation -> {
- float animatedValue = (Float) animation.getAnimatedValue();
- setViewClipBounds((int) animatedValue);
- });
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- mIsAnimating = false;
- mIsTracking = false;
- mOpeningVelocity = DEFAULT_FLING_VELOCITY;
- mClosingVelocity = DEFAULT_FLING_VELOCITY;
- if (isClosing) {
- setPanelVisible(false);
- getLayout().setClipBounds(null);
- onCollapseAnimationEnd();
- setPanelExpanded(false);
- } else {
- onExpandAnimationEnd();
- setPanelExpanded(true);
- }
- }
- });
- getFlingAnimationUtils().apply(animator, from, to, Math.abs(velocity));
- animator.start();
- }
-
- /**
- * Called in {@link Animator.AnimatorListener#onAnimationEnd(Animator)} when the panel is
- * closing.
- */
- protected abstract void onCollapseAnimationEnd();
-
- /**
- * Called in {@link Animator.AnimatorListener#onAnimationEnd(Animator)} when the panel is
- * opening.
- */
- protected abstract void onExpandAnimationEnd();
-
- /* ***************************************************************************************** *
- * Panel Visibility
- * ***************************************************************************************** */
-
- /** Set the panel view to be visible. */
- protected final void setPanelVisible(boolean visible) {
- mPanelVisible = visible;
- onPanelVisible(visible);
- }
-
- /** Returns {@code true} if panel is visible. */
- public final boolean isPanelVisible() {
- return mPanelVisible;
- }
-
- /** Business logic run when panel visibility is set. */
- @CallSuper
- protected void onPanelVisible(boolean visible) {
- if (DEBUG) {
- Log.e(TAG, "onPanelVisible: " + visible);
- }
-
- if (visible && !getOverlayViewGlobalStateController().isWindowVisible()) {
- getOverlayViewGlobalStateController().showView(/* panelViewController= */ this);
- }
- if (!visible && getOverlayViewGlobalStateController().isWindowVisible()) {
- getOverlayViewGlobalStateController().hideView(/* panelViewController= */ this);
- }
- getLayout().setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
- }
-
- /* ***************************************************************************************** *
- * Panel Expansion
- * ***************************************************************************************** */
-
- /**
- * Set the panel state to expanded. This will expand or collapse the overlay window if
- * necessary.
- */
- protected final void setPanelExpanded(boolean expand) {
- mPanelExpanded = expand;
- onPanelExpanded(expand);
- }
-
- /** Returns {@code true} if panel is expanded. */
- public final boolean isPanelExpanded() {
- return mPanelExpanded;
- }
-
- @CallSuper
- protected void onPanelExpanded(boolean expand) {
- if (DEBUG) {
- Log.e(TAG, "onPanelExpanded: " + expand);
- }
- }
-
- /* ***************************************************************************************** *
- * Misc
- * ***************************************************************************************** */
-
- /**
- * Given the position of the pointer dragging the panel, return the percentage of its closeness
- * to the ending edge.
- */
- protected void calculatePercentageFromEndingEdge(float y) {
- if (getLayout().getHeight() > 0) {
- float height = getVisiblePanelHeight(y);
- mPercentageFromEndingEdge = (int) Math.abs(height / getLayout().getHeight() * 100);
- }
- }
-
- private float getVisiblePanelHeight(float y) {
- return mAnimateDirection > 0 ? y : getLayout().getHeight() - y;
- }
-
- /** Sets the boundaries of the overlay panel that can be seen based on pointer position. */
- protected void setViewClipBounds(int y) {
- // Bound the pointer position to be within the overlay panel.
- y = Math.max(0, Math.min(y, getLayout().getHeight()));
- Rect clipBounds = new Rect();
- int top, bottom;
- if (mAnimateDirection > 0) {
- top = 0;
- bottom = y;
- } else {
- top = y;
- bottom = getLayout().getHeight();
- }
- clipBounds.set(0, top, getLayout().getWidth(), bottom);
- getLayout().setClipBounds(clipBounds);
- onScroll(y);
- }
-
- /**
- * Called while scrolling, this passes the position of the clip boundary that is currently
- * changing.
- */
- protected abstract void onScroll(int y);
-
- /* ***************************************************************************************** *
- * Getters
- * ***************************************************************************************** */
-
- /** Returns the open touch listener. */
- public final View.OnTouchListener getDragOpenTouchListener() {
- return mDragOpenTouchListener;
- }
-
- /** Returns the close touch listener. */
- public final View.OnTouchListener getDragCloseTouchListener() {
- return mDragCloseTouchListener;
- }
-
- /** Gets the fling animation utils used for animating this panel. */
- protected final FlingAnimationUtils getFlingAnimationUtils() {
- return mFlingAnimationUtils;
- }
-
- /** Returns {@code true} if the panel is currently tracking. */
- protected final boolean isTracking() {
- return mIsTracking;
- }
-
- /** Sets whether the panel is currently tracking or not. */
- protected final void setIsTracking(boolean isTracking) {
- mIsTracking = isTracking;
- }
-
- /** Returns {@code true} if the panel is currently animating. */
- protected final boolean isAnimating() {
- return mIsAnimating;
- }
-
- /** Returns the percentage of the panel that is open from the bottom. */
- protected final int getPercentageFromEndingEdge() {
- return mPercentageFromEndingEdge;
- }
-
- /** Returns the percentage at which we've determined whether to open or close the panel. */
- protected final int getSettleClosePercentage() {
- return mSettleClosePercentage;
- }
-
- /* ***************************************************************************************** *
- * Gesture Listeners
- * ***************************************************************************************** */
-
- /** Called when the user is beginning to scroll down the panel. */
- protected abstract void onOpenScrollStart();
-
- /**
- * Only responsible for open hooks. Since once the panel opens it covers all elements
- * there is no need to merge with close.
- */
- protected abstract class OpenGestureListener extends
- GestureDetector.SimpleOnGestureListener {
-
- @Override
- public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
- float distanceY) {
-
- if (!isPanelVisible()) {
- onOpenScrollStart();
- }
- setPanelVisible(true);
-
- // clips the view for the panel when the user scrolls to open.
- setViewClipBounds((int) event2.getRawY());
-
- // Initially the scroll starts with height being zero. This checks protects from divide
- // by zero error.
- calculatePercentageFromEndingEdge(event2.getRawY());
-
- mIsTracking = true;
- return true;
- }
-
-
- @Override
- public boolean onFling(MotionEvent event1, MotionEvent event2,
- float velocityX, float velocityY) {
- if (mAnimateDirection * velocityY > SWIPE_THRESHOLD_VELOCITY) {
- mOpeningVelocity = velocityY;
- open();
- return true;
- }
- animatePanel(DEFAULT_FLING_VELOCITY, true);
-
- return false;
- }
-
- protected abstract void open();
- }
-
- /** Determines whether the scroll event should allow closing of the panel. */
- protected abstract boolean shouldAllowClosingScroll();
-
- protected abstract class CloseGestureListener extends
- GestureDetector.SimpleOnGestureListener {
-
- @Override
- public boolean onSingleTapUp(MotionEvent motionEvent) {
- if (isPanelExpanded()) {
- animatePanel(DEFAULT_FLING_VELOCITY, true);
- }
- return true;
- }
-
- @Override
- public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
- float distanceY) {
- if (!shouldAllowClosingScroll()) {
- return false;
- }
- float y = getYPositionOfPanelEndingEdge(event1, event2);
- if (getLayout().getHeight() > 0) {
- mPercentageFromEndingEdge = (int) Math.abs(
- y / getLayout().getHeight() * 100);
- boolean isInClosingDirection = mAnimateDirection * distanceY > 0;
-
- // This check is to figure out if onScroll was called while swiping the card at
- // bottom of the panel. At that time we should not allow panel to
- // close. We are also checking for the upwards swipe gesture here because it is
- // possible if a user is closing the panel and while swiping starts
- // to open again but does not fling. At that time we should allow the
- // panel to close fully or else it would stuck in between.
- if (Math.abs(getLayout().getHeight() - y)
- > SWIPE_DOWN_MIN_DISTANCE && isInClosingDirection) {
- setViewClipBounds((int) y);
- mIsTracking = true;
- } else if (!isInClosingDirection) {
- setViewClipBounds((int) y);
- }
- }
- // if we return true the items in RV won't be scrollable.
- return false;
- }
-
- /**
- * To prevent the jump in the clip bounds while closing the panel we should calculate the y
- * position using the diff of event1 and event2. This will help the panel clip smoothly as
- * the event2 value changes while event1 value will be fixed.
- * @param event1 MotionEvent that contains the position of where the event2 started.
- * @param event2 MotionEvent that contains the position of where the user has scrolled to
- * on the screen.
- */
- private float getYPositionOfPanelEndingEdge(MotionEvent event1, MotionEvent event2) {
- float diff = mAnimateDirection * (event1.getRawY() - event2.getRawY());
- float y = mAnimateDirection > 0 ? getLayout().getHeight() - diff : diff;
- y = Math.max(0, Math.min(y, getLayout().getHeight()));
- return y;
- }
-
- @Override
- public boolean onFling(MotionEvent event1, MotionEvent event2,
- float velocityX, float velocityY) {
- // should not fling if the touch does not start when view is at the end of the list.
- if (!shouldAllowClosingScroll()) {
- return false;
- }
- if (Math.abs(event1.getX() - event2.getX()) > SWIPE_MAX_OFF_PATH
- || Math.abs(velocityY) < SWIPE_THRESHOLD_VELOCITY) {
- // swipe was not vertical or was not fast enough
- return false;
- }
- boolean isInClosingDirection = mAnimateDirection * velocityY < 0;
- if (isInClosingDirection) {
- close();
- return true;
- } else {
- // we should close the shade
- animatePanel(velocityY, false);
- }
- return false;
- }
-
- protected abstract void close();
- }
-
- protected abstract class SystemBarCloseGestureListener extends CloseGestureListener {
- @Override
- public boolean onSingleTapUp(MotionEvent e) {
- mClosingVelocity = DEFAULT_FLING_VELOCITY;
- if (isPanelExpanded()) {
- close();
- }
- return super.onSingleTapUp(e);
- }
-
- @Override
- public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
- float distanceY) {
- calculatePercentageFromEndingEdge(event2.getRawY());
- setViewClipBounds((int) event2.getRawY());
- return true;
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewController.java
deleted file mode 100644
index b989c42..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewController.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.window;
-
-import static android.view.WindowInsets.Type.statusBars;
-
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewStub;
-import android.view.WindowInsets;
-
-/**
- * Owns a {@link View} that is present in SystemUIOverlayWindow.
- */
-public class OverlayViewController {
- protected static final int INVALID_INSET_SIDE = -1;
- protected static final int NO_INSET_SIDE = 0;
-
- private final int mStubId;
- private final OverlayViewGlobalStateController mOverlayViewGlobalStateController;
-
- private View mLayout;
-
- public OverlayViewController(int stubId,
- OverlayViewGlobalStateController overlayViewGlobalStateController) {
- mLayout = null;
- mStubId = stubId;
- mOverlayViewGlobalStateController = overlayViewGlobalStateController;
- }
-
- /**
- * Shows content of {@link OverlayViewController}.
- *
- * Should be used to show view externally and in particular by {@link OverlayViewMediator}.
- */
- public final void start() {
- mOverlayViewGlobalStateController.showView(/* viewController= */ this, this::show);
- }
-
- /**
- * Hides content of {@link OverlayViewController}.
- *
- * Should be used to hide view externally and in particular by {@link OverlayViewMediator}.
- */
- public final void stop() {
- mOverlayViewGlobalStateController.hideView(/* viewController= */ this, this::hide);
- }
-
- /**
- * Inflate layout owned by controller.
- */
- public final void inflate(ViewGroup baseLayout) {
- ViewStub viewStub = baseLayout.findViewById(mStubId);
- mLayout = viewStub.inflate();
- onFinishInflate();
- }
-
- /**
- * Called once inflate finishes.
- */
- protected void onFinishInflate() {
- // no-op
- }
-
- /**
- * Returns {@code true} if layout owned by controller has been inflated.
- */
- public final boolean isInflated() {
- return mLayout != null;
- }
-
- private void show() {
- if (mLayout == null) {
- // layout must be inflated before show() is called.
- return;
- }
- showInternal();
- }
-
- /**
- * Subclasses should override this method to implement reveal animations and implement logic
- * specific to when the layout owned by the controller is shown.
- *
- * Should only be overridden by Superclass but not called by any {@link OverlayViewMediator}.
- */
- protected void showInternal() {
- mLayout.setVisibility(View.VISIBLE);
- }
-
- private void hide() {
- if (mLayout == null) {
- // layout must be inflated before hide() is called.
- return;
- }
- hideInternal();
- }
-
- /**
- * Subclasses should override this method to implement conceal animations and implement logic
- * specific to when the layout owned by the controller is hidden.
- *
- * Should only be overridden by Superclass but not called by any {@link OverlayViewMediator}.
- */
- protected void hideInternal() {
- mLayout.setVisibility(View.GONE);
- }
-
- /**
- * Provides access to layout owned by controller.
- */
- protected final View getLayout() {
- return mLayout;
- }
-
- /** Returns the {@link OverlayViewGlobalStateController}. */
- protected final OverlayViewGlobalStateController getOverlayViewGlobalStateController() {
- return mOverlayViewGlobalStateController;
- }
-
- /**
- * Returns {@code true} if heads up notifications should be displayed over this view.
- */
- protected boolean shouldShowHUN() {
- return true;
- }
-
- /**
- * Returns {@code true} if navigation bar insets should be displayed over this view. Has no
- * effect if {@link #shouldFocusWindow} returns {@code false}.
- */
- protected boolean shouldShowNavigationBarInsets() {
- return false;
- }
-
- /**
- * Returns {@code true} if status bar insets should be displayed over this view. Has no
- * effect if {@link #shouldFocusWindow} returns {@code false}.
- */
- protected boolean shouldShowStatusBarInsets() {
- return false;
- }
-
- /**
- * Returns {@code true} if this view should be hidden during the occluded state.
- */
- protected boolean shouldShowWhenOccluded() {
- return false;
- }
-
- /**
- * Returns {@code true} if the window should be focued when this view is visible. Note that
- * returning {@code false} here means that {@link #shouldShowStatusBarInsets} and
- * {@link #shouldShowNavigationBarInsets} will have no effect.
- */
- protected boolean shouldFocusWindow() {
- return true;
- }
-
- /**
- * Returns {@code true} if the window should use stable insets. Using stable insets means that
- * even when system bars are temporarily not visible, inset from the system bars will still be
- * applied.
- *
- * NOTE: When system bars are hidden in transient mode, insets from them will not be applied
- * even when the system bars become visible. Setting the return value to {@true} here can
- * prevent the OverlayView from overlapping with the system bars when that happens.
- */
- protected boolean shouldUseStableInsets() {
- return false;
- }
-
- /**
- * Returns the insets types to fit to the sysui overlay window when this
- * {@link OverlayViewController} is in the foreground.
- */
- @WindowInsets.Type.InsetsType
- protected int getInsetTypesToFit() {
- return statusBars();
- }
-
- /**
- * Optionally returns the sides of enabled system bar insets to fit to the sysui overlay window
- * when this {@link OverlayViewController} is in the foreground.
- *
- * For example, if the bottom and left system bars are enabled and this method returns
- * WindowInsets.Side.LEFT, then the inset from the bottom system bar will be ignored.
- *
- * NOTE: By default, this method returns {@link #INVALID_INSET_SIDE}, so insets to fit are
- * defined by {@link #getInsetTypesToFit()}, and not by this method, unless it is overridden
- * by subclasses.
- *
- * NOTE: {@link #NO_INSET_SIDE} signifies no insets from any system bars will be honored. Each
- * {@link OverlayViewController} can first take this value and add sides of the system bar
- * insets to honor to it.
- *
- * NOTE: If getInsetSidesToFit is overridden to return {@link WindowInsets.Side}, it always
- * takes precedence over {@link #getInsetTypesToFit()}. That is, the return value of {@link
- * #getInsetTypesToFit()} will be ignored.
- */
- @WindowInsets.Side.InsetsSide
- protected int getInsetSidesToFit() {
- return INVALID_INSET_SIDE;
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewGlobalStateController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewGlobalStateController.java
deleted file mode 100644
index 10f436b..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewGlobalStateController.java
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.window;
-
-import static android.view.WindowInsets.Type.navigationBars;
-import static android.view.WindowInsets.Type.statusBars;
-
-import android.annotation.Nullable;
-import android.util.Log;
-import android.view.WindowInsets;
-import android.view.WindowInsets.Side.InsetsSide;
-import android.view.WindowInsets.Type.InsetsType;
-import android.view.WindowInsetsController;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.android.systemui.dagger.SysUISingleton;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import javax.inject.Inject;
-
-/**
- * This controller is responsible for the following:
- * <p><ul>
- * <li>Holds the global state for SystemUIOverlayWindow.
- * <li>Allows {@link SystemUIOverlayWindowManager} to register {@link OverlayViewMediator}(s).
- * <li>Enables {@link OverlayViewController)(s) to reveal/conceal themselves while respecting the
- * global state of SystemUIOverlayWindow.
- * </ul>
- */
-@SysUISingleton
-public class OverlayViewGlobalStateController {
- private static final boolean DEBUG = false;
- private static final String TAG = OverlayViewGlobalStateController.class.getSimpleName();
- private static final int UNKNOWN_Z_ORDER = -1;
- private final SystemUIOverlayWindowController mSystemUIOverlayWindowController;
- private final WindowInsetsController mWindowInsetsController;
- @VisibleForTesting
- Map<OverlayViewController, Integer> mZOrderMap;
- @VisibleForTesting
- SortedMap<Integer, OverlayViewController> mZOrderVisibleSortedMap;
- @VisibleForTesting
- Set<OverlayViewController> mViewsHiddenForOcclusion;
- @VisibleForTesting
- OverlayViewController mHighestZOrder;
- private boolean mIsOccluded;
-
- @Inject
- public OverlayViewGlobalStateController(
- SystemUIOverlayWindowController systemUIOverlayWindowController) {
- mSystemUIOverlayWindowController = systemUIOverlayWindowController;
- mSystemUIOverlayWindowController.attach();
- mWindowInsetsController =
- mSystemUIOverlayWindowController.getBaseLayout().getWindowInsetsController();
- mZOrderMap = new HashMap<>();
- mZOrderVisibleSortedMap = new TreeMap<>();
- mViewsHiddenForOcclusion = new HashSet<>();
- }
-
- /**
- * Register {@link OverlayViewMediator} to use in SystemUIOverlayWindow.
- */
- public void registerMediator(OverlayViewMediator overlayViewMediator) {
- Log.d(TAG, "Registering content mediator: " + overlayViewMediator.getClass().getName());
-
- overlayViewMediator.registerListeners();
- overlayViewMediator.setupOverlayContentViewControllers();
- }
-
- /**
- * Show content in Overlay Window using {@link OverlayPanelViewController}.
- *
- * This calls {@link OverlayViewGlobalStateController#showView(OverlayViewController, Runnable)}
- * where the runnable is nullified since the actual showing of the panel is handled by the
- * controller itself.
- */
- public void showView(OverlayPanelViewController panelViewController) {
- showView(panelViewController, /* show= */ null);
- }
-
- /**
- * Show content in Overlay Window using {@link OverlayViewController}.
- */
- public void showView(OverlayViewController viewController, @Nullable Runnable show) {
- debugLog();
- if (mIsOccluded && !viewController.shouldShowWhenOccluded()) {
- mViewsHiddenForOcclusion.add(viewController);
- return;
- }
- if (mZOrderVisibleSortedMap.isEmpty()) {
- setWindowVisible(true);
- }
-
- if (!(viewController instanceof OverlayPanelViewController)) {
- inflateView(viewController);
- }
-
- if (show != null) {
- show.run();
- }
-
- updateInternalsWhenShowingView(viewController);
- refreshUseStableInsets();
- refreshInsetsToFit();
- refreshWindowFocus();
- refreshNavigationBarVisibility();
- refreshStatusBarVisibility();
-
- Log.d(TAG, "Content shown: " + viewController.getClass().getName());
- debugLog();
- }
-
- private void updateInternalsWhenShowingView(OverlayViewController viewController) {
- int zOrder;
- if (mZOrderMap.containsKey(viewController)) {
- zOrder = mZOrderMap.get(viewController);
- } else {
- zOrder = mSystemUIOverlayWindowController.getBaseLayout().indexOfChild(
- viewController.getLayout());
- mZOrderMap.put(viewController, zOrder);
- }
-
- mZOrderVisibleSortedMap.put(zOrder, viewController);
-
- refreshHighestZOrderWhenShowingView(viewController);
- }
-
- private void refreshHighestZOrderWhenShowingView(OverlayViewController viewController) {
- if (mZOrderMap.getOrDefault(mHighestZOrder, UNKNOWN_Z_ORDER) < mZOrderMap.get(
- viewController)) {
- mHighestZOrder = viewController;
- }
- }
-
- /**
- * Hide content in Overlay Window using {@link OverlayPanelViewController}.
- *
- * This calls {@link OverlayViewGlobalStateController#hideView(OverlayViewController, Runnable)}
- * where the runnable is nullified since the actual hiding of the panel is handled by the
- * controller itself.
- */
- public void hideView(OverlayPanelViewController panelViewController) {
- hideView(panelViewController, /* hide= */ null);
- }
-
- /**
- * Hide content in Overlay Window using {@link OverlayViewController}.
- */
- public void hideView(OverlayViewController viewController, @Nullable Runnable hide) {
- debugLog();
- if (mIsOccluded && mViewsHiddenForOcclusion.contains(viewController)) {
- mViewsHiddenForOcclusion.remove(viewController);
- return;
- }
- if (!viewController.isInflated()) {
- Log.d(TAG, "Content cannot be hidden since it isn't inflated: "
- + viewController.getClass().getName());
- return;
- }
- if (!mZOrderMap.containsKey(viewController)) {
- Log.d(TAG, "Content cannot be hidden since it has never been shown: "
- + viewController.getClass().getName());
- return;
- }
- if (!mZOrderVisibleSortedMap.containsKey(mZOrderMap.get(viewController))) {
- Log.d(TAG, "Content cannot be hidden since it isn't currently shown: "
- + viewController.getClass().getName());
- return;
- }
-
- if (hide != null) {
- hide.run();
- }
-
- mZOrderVisibleSortedMap.remove(mZOrderMap.get(viewController));
- refreshHighestZOrderWhenHidingView(viewController);
- refreshUseStableInsets();
- refreshInsetsToFit();
- refreshWindowFocus();
- refreshNavigationBarVisibility();
- refreshStatusBarVisibility();
-
- if (mZOrderVisibleSortedMap.isEmpty()) {
- setWindowVisible(false);
- }
-
- Log.d(TAG, "Content hidden: " + viewController.getClass().getName());
- debugLog();
- }
-
- private void refreshHighestZOrderWhenHidingView(OverlayViewController viewController) {
- if (mZOrderVisibleSortedMap.isEmpty()) {
- mHighestZOrder = null;
- return;
- }
- if (!mHighestZOrder.equals(viewController)) {
- return;
- }
-
- mHighestZOrder = mZOrderVisibleSortedMap.get(mZOrderVisibleSortedMap.lastKey());
- }
-
- private void refreshNavigationBarVisibility() {
- if (mZOrderVisibleSortedMap.isEmpty()) {
- mWindowInsetsController.show(navigationBars());
- return;
- }
-
- // Do not hide navigation bar insets if the window is not focusable.
- if (mHighestZOrder.shouldFocusWindow() && !mHighestZOrder.shouldShowNavigationBarInsets()) {
- mWindowInsetsController.hide(navigationBars());
- } else {
- mWindowInsetsController.show(navigationBars());
- }
- }
-
- private void refreshStatusBarVisibility() {
- if (mZOrderVisibleSortedMap.isEmpty()) {
- mWindowInsetsController.show(statusBars());
- return;
- }
-
- // Do not hide status bar insets if the window is not focusable.
- if (mHighestZOrder.shouldFocusWindow() && !mHighestZOrder.shouldShowStatusBarInsets()) {
- mWindowInsetsController.hide(statusBars());
- } else {
- mWindowInsetsController.show(statusBars());
- }
- }
-
- private void refreshWindowFocus() {
- setWindowFocusable(mHighestZOrder == null ? false : mHighestZOrder.shouldFocusWindow());
- }
-
- private void refreshUseStableInsets() {
- mSystemUIOverlayWindowController.setUsingStableInsets(
- mHighestZOrder == null ? false : mHighestZOrder.shouldUseStableInsets());
- }
-
- /**
- * Refreshes the insets to fit (or honor) either by {@link InsetsType} or {@link InsetsSide}.
- *
- * By default, the insets to fit are defined by the {@link InsetsType}. But if an
- * {@link OverlayViewController} overrides {@link OverlayViewController#getInsetSidesToFit()} to
- * return an {@link InsetsSide}, then that takes precedence over {@link InsetsType}.
- */
- private void refreshInsetsToFit() {
- if (mZOrderVisibleSortedMap.isEmpty()) {
- setFitInsetsTypes(statusBars());
- } else {
- if (mHighestZOrder.getInsetSidesToFit() != OverlayViewController.INVALID_INSET_SIDE) {
- // First fit all system bar insets as setFitInsetsSide defines which sides of system
- // bar insets to actually honor.
- setFitInsetsTypes(WindowInsets.Type.systemBars());
- setFitInsetsSides(mHighestZOrder.getInsetSidesToFit());
- } else {
- setFitInsetsTypes(mHighestZOrder.getInsetTypesToFit());
- }
- }
- }
-
- /** Returns {@code true} is the window is visible. */
- public boolean isWindowVisible() {
- return mSystemUIOverlayWindowController.isWindowVisible();
- }
-
- private void setWindowVisible(boolean visible) {
- mSystemUIOverlayWindowController.setWindowVisible(visible);
- }
-
- /** Sets the insets to fit based on the {@link InsetsType} */
- private void setFitInsetsTypes(@InsetsType int types) {
- mSystemUIOverlayWindowController.setFitInsetsTypes(types);
- }
-
- /** Sets the insets to fit based on the {@link InsetsSide} */
- private void setFitInsetsSides(@InsetsSide int sides) {
- mSystemUIOverlayWindowController.setFitInsetsSides(sides);
- }
-
- /**
- * Sets the {@link android.view.WindowManager.LayoutParams#FLAG_ALT_FOCUSABLE_IM} flag of the
- * sysui overlay window.
- */
- public void setWindowNeedsInput(boolean needsInput) {
- mSystemUIOverlayWindowController.setWindowNeedsInput(needsInput);
- }
-
- /** Returns {@code true} if the window is focusable. */
- public boolean isWindowFocusable() {
- return mSystemUIOverlayWindowController.isWindowFocusable();
- }
-
- /** Sets the focusable flag of the sysui overlawy window. */
- public void setWindowFocusable(boolean focusable) {
- mSystemUIOverlayWindowController.setWindowFocusable(focusable);
- }
-
- /** Inflates the view controlled by the given view controller. */
- public void inflateView(OverlayViewController viewController) {
- if (!viewController.isInflated()) {
- viewController.inflate(mSystemUIOverlayWindowController.getBaseLayout());
- }
- }
-
- /**
- * Return {@code true} if OverlayWindow is in a state where HUNs should be displayed above it.
- */
- public boolean shouldShowHUN() {
- return mZOrderVisibleSortedMap.isEmpty() || mHighestZOrder.shouldShowHUN();
- }
-
- /**
- * Set the OverlayViewWindow to be in occluded or unoccluded state. When OverlayViewWindow is
- * occluded, all views mounted to it that are not configured to be shown during occlusion will
- * be hidden.
- */
- public void setOccluded(boolean occluded) {
- if (occluded) {
- // Hide views before setting mIsOccluded to true so the regular hideView logic is used,
- // not the one used during occlusion.
- hideViewsForOcclusion();
- mIsOccluded = true;
- } else {
- mIsOccluded = false;
- // show views after setting mIsOccluded to false so the regular showView logic is used,
- // not the one used during occlusion.
- showViewsHiddenForOcclusion();
- }
- }
-
- private void hideViewsForOcclusion() {
- HashSet<OverlayViewController> viewsCurrentlyShowing = new HashSet<>(
- mZOrderVisibleSortedMap.values());
- viewsCurrentlyShowing.forEach(overlayController -> {
- if (!overlayController.shouldShowWhenOccluded()) {
- hideView(overlayController, overlayController::hideInternal);
- mViewsHiddenForOcclusion.add(overlayController);
- }
- });
- }
-
- private void showViewsHiddenForOcclusion() {
- mViewsHiddenForOcclusion.forEach(overlayViewController -> {
- showView(overlayViewController, overlayViewController::showInternal);
- });
- mViewsHiddenForOcclusion.clear();
- }
-
- private void debugLog() {
- if (!DEBUG) {
- return;
- }
-
- Log.d(TAG, "mHighestZOrder: " + mHighestZOrder);
- Log.d(TAG, "mZOrderVisibleSortedMap.size(): " + mZOrderVisibleSortedMap.size());
- Log.d(TAG, "mZOrderVisibleSortedMap: " + mZOrderVisibleSortedMap);
- Log.d(TAG, "mZOrderMap.size(): " + mZOrderMap.size());
- Log.d(TAG, "mZOrderMap: " + mZOrderMap);
- Log.d(TAG, "mIsOccluded: " + mIsOccluded);
- Log.d(TAG, "mViewsHiddenForOcclusion: " + mViewsHiddenForOcclusion);
- Log.d(TAG, "mViewsHiddenForOcclusion.size(): " + mViewsHiddenForOcclusion.size());
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewMediator.java
deleted file mode 100644
index 3e7b4a2..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewMediator.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.window;
-
-/**
- * Controls when to show and hide {@link OverlayViewController}(s).
- */
-public interface OverlayViewMediator {
-
- /**
- * Register listeners that could use ContentVisibilityAdjuster to show/hide content.
- *
- * Note that we do not unregister listeners because SystemUI components are expected to live
- * for the lifecycle of the device.
- */
- void registerListeners();
-
- /**
- * Allows for post-inflation callbacks and listeners to be set inside required {@link
- * OverlayViewController}(s).
- */
- void setupOverlayContentViewControllers();
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayWindowModule.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayWindowModule.java
deleted file mode 100644
index fcbb0b8..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayWindowModule.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.window;
-
-import com.android.systemui.car.keyguard.CarKeyguardViewMediator;
-import com.android.systemui.car.notification.BottomNotificationPanelViewMediator;
-import com.android.systemui.car.notification.NotificationPanelViewMediator;
-import com.android.systemui.car.notification.TopNotificationPanelViewMediator;
-import com.android.systemui.car.rvc.RearViewCameraViewMediator;
-import com.android.systemui.car.userswitcher.FullscreenUserSwitcherViewMediator;
-import com.android.systemui.car.userswitcher.UserSwitchTransitionViewMediator;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.multibindings.ClassKey;
-import dagger.multibindings.IntoMap;
-
-/**
- * Dagger injection module for {@link SystemUIOverlayWindowManager}
- */
-@Module
-public abstract class OverlayWindowModule {
-
- /** Injects NotificationPanelViewMediator. */
- @Binds
- @IntoMap
- @ClassKey(NotificationPanelViewMediator.class)
- public abstract OverlayViewMediator bindNotificationPanelViewMediator(
- NotificationPanelViewMediator notificationPanelViewMediator);
-
- /** Injects TopNotificationPanelViewMediator. */
- @Binds
- @IntoMap
- @ClassKey(TopNotificationPanelViewMediator.class)
- public abstract OverlayViewMediator bindTopNotificationPanelViewMediator(
- TopNotificationPanelViewMediator topNotificationPanelViewMediator);
-
- /** Injects BottomNotificationPanelViewMediator. */
- @Binds
- @IntoMap
- @ClassKey(BottomNotificationPanelViewMediator.class)
- public abstract OverlayViewMediator bindBottomNotificationPanelViewMediator(
- BottomNotificationPanelViewMediator bottomNotificationPanelViewMediator);
-
- /** Inject into CarKeyguardViewMediator. */
- @Binds
- @IntoMap
- @ClassKey(CarKeyguardViewMediator.class)
- public abstract OverlayViewMediator bindCarKeyguardViewMediator(
- CarKeyguardViewMediator carKeyguardViewMediator);
-
- /** Injects FullscreenUserSwitcherViewsMediator. */
- @Binds
- @IntoMap
- @ClassKey(FullscreenUserSwitcherViewMediator.class)
- public abstract OverlayViewMediator bindFullscreenUserSwitcherViewsMediator(
- FullscreenUserSwitcherViewMediator overlayViewsMediator);
-
- /** Injects CarUserSwitchingDialogMediator. */
- @Binds
- @IntoMap
- @ClassKey(UserSwitchTransitionViewMediator.class)
- public abstract OverlayViewMediator bindUserSwitchTransitionViewMediator(
- UserSwitchTransitionViewMediator userSwitchTransitionViewMediator);
-
- /** Injects RearViewCameraViewMediator. */
- @Binds
- @IntoMap
- @ClassKey(RearViewCameraViewMediator.class)
- public abstract OverlayViewMediator bindRearViewCameraViewMediator(
- RearViewCameraViewMediator overlayViewsMediator);
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowController.java
deleted file mode 100644
index 0e73f25..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowController.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.window;
-
-import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
-import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
-
-import android.content.Context;
-import android.graphics.PixelFormat;
-import android.os.Binder;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowInsets;
-import android.view.WindowManager;
-
-import com.android.systemui.R;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.statusbar.policy.ConfigurationController;
-
-import javax.inject.Inject;
-
-/**
- * Controls the expansion state of the primary window which will contain all of the fullscreen sysui
- * behavior. This window still has a collapsed state in order to watch for swipe events to expand
- * this window for the notification panel.
- */
-@SysUISingleton
-public class SystemUIOverlayWindowController implements
- ConfigurationController.ConfigurationListener {
-
- private final Context mContext;
- private final WindowManager mWindowManager;
-
- private ViewGroup mBaseLayout;
- private WindowManager.LayoutParams mLp;
- private WindowManager.LayoutParams mLpChanged;
- private boolean mIsAttached = false;
- private boolean mVisible = false;
- private boolean mFocusable = false;
- private boolean mUsingStableInsets = false;
-
- @Inject
- public SystemUIOverlayWindowController(
- Context context,
- WindowManager windowManager,
- ConfigurationController configurationController
- ) {
- mContext = context;
- mWindowManager = windowManager;
-
- mLpChanged = new WindowManager.LayoutParams();
- mBaseLayout = (ViewGroup) LayoutInflater.from(context)
- .inflate(R.layout.sysui_overlay_window, /* root= */ null, false);
-
- configurationController.addCallback(this);
- }
-
- /** Returns the base view of the primary window. */
- public ViewGroup getBaseLayout() {
- return mBaseLayout;
- }
-
- /** Returns {@code true} if the window is already attached. */
- public boolean isAttached() {
- return mIsAttached;
- }
-
- /** Attaches the window to the window manager. */
- public void attach() {
- if (mIsAttached) {
- return;
- }
- mIsAttached = true;
- // Now that the status bar window encompasses the sliding panel and its
- // translucent backdrop, the entire thing is made TRANSLUCENT and is
- // hardware-accelerated.
- mLp = new WindowManager.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT,
- WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE,
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
- | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
- | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
- | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
- PixelFormat.TRANSLUCENT);
- mLp.token = new Binder();
- mLp.gravity = Gravity.TOP;
- mLp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
- mLp.setTitle("SystemUIOverlayWindow");
- mLp.packageName = mContext.getPackageName();
- mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
- mLp.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
-
- mWindowManager.addView(mBaseLayout, mLp);
- mLpChanged.copyFrom(mLp);
- setWindowVisible(false);
- }
-
- /** Sets the types of insets to fit. Note: This should be rarely used. */
- public void setFitInsetsTypes(@WindowInsets.Type.InsetsType int types) {
- mLpChanged.setFitInsetsTypes(types);
- mLpChanged.setFitInsetsIgnoringVisibility(mUsingStableInsets);
- updateWindow();
- }
-
- /** Sets the sides of system bar insets to fit. Note: This should be rarely used. */
- public void setFitInsetsSides(@WindowInsets.Side.InsetsSide int sides) {
- mLpChanged.setFitInsetsSides(sides);
- mLpChanged.setFitInsetsIgnoringVisibility(mUsingStableInsets);
- updateWindow();
- }
-
- /** Sets the window to the visible state. */
- public void setWindowVisible(boolean visible) {
- mVisible = visible;
- if (visible) {
- mBaseLayout.setVisibility(View.VISIBLE);
- } else {
- mBaseLayout.setVisibility(View.INVISIBLE);
- }
- updateWindow();
- }
-
- /** Sets the window to be focusable. */
- public void setWindowFocusable(boolean focusable) {
- mFocusable = focusable;
- if (focusable) {
- mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
- } else {
- mLpChanged.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
- }
- updateWindow();
- }
-
- /** Sets the window to enable IME. */
- public void setWindowNeedsInput(boolean needsInput) {
- if (needsInput) {
- mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
- } else {
- mLpChanged.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
- }
- updateWindow();
- }
-
- /** Returns {@code true} if the window is visible */
- public boolean isWindowVisible() {
- return mVisible;
- }
-
- public boolean isWindowFocusable() {
- return mFocusable;
- }
-
- protected void setUsingStableInsets(boolean useStableInsets) {
- mUsingStableInsets = useStableInsets;
- }
-
- private void updateWindow() {
- if (mLp != null && mLp.copyFrom(mLpChanged) != 0) {
- if (isAttached()) {
- mLp.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
- mWindowManager.updateViewLayout(mBaseLayout, mLp);
- }
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowManager.java b/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowManager.java
deleted file mode 100644
index 6395ebf..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowManager.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.window;
-
-import android.content.Context;
-import android.util.Log;
-
-import com.android.systemui.R;
-import com.android.systemui.SystemUI;
-import com.android.systemui.dagger.SysUISingleton;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.inject.Provider;
-
-/**
- * Registers {@link OverlayViewMediator}(s) and synchronizes their calls to hide/show {@link
- * OverlayViewController}(s) to allow for the correct visibility of system bars.
- */
-@SysUISingleton
-public class SystemUIOverlayWindowManager extends SystemUI {
- private static final String TAG = "SystemUIOverlayWM";
- private final Map<Class<?>, Provider<OverlayViewMediator>>
- mContentMediatorCreators;
- private final OverlayViewGlobalStateController mOverlayViewGlobalStateController;
-
- @Inject
- public SystemUIOverlayWindowManager(
- Context context,
- Map<Class<?>, Provider<OverlayViewMediator>> contentMediatorCreators,
- OverlayViewGlobalStateController overlayViewGlobalStateController) {
- super(context);
- mContentMediatorCreators = contentMediatorCreators;
- mOverlayViewGlobalStateController = overlayViewGlobalStateController;
- }
-
- @Override
- public void start() {
- String[] names = mContext.getResources().getStringArray(
- R.array.config_carSystemUIOverlayViewsMediators);
- startServices(names);
- }
-
- private void startServices(String[] services) {
- for (String clsName : services) {
- long ti = System.currentTimeMillis();
- try {
- OverlayViewMediator obj = resolveContentMediator(clsName);
- if (obj == null) {
- Constructor constructor = Class.forName(clsName).getConstructor(Context.class);
- obj = (OverlayViewMediator) constructor.newInstance(this);
- }
- mOverlayViewGlobalStateController.registerMediator(obj);
- } catch (ClassNotFoundException
- | NoSuchMethodException
- | IllegalAccessException
- | InstantiationException
- | InvocationTargetException ex) {
- throw new RuntimeException(ex);
- }
-
- // Warn if initialization of component takes too long
- ti = System.currentTimeMillis() - ti;
- if (ti > 200) {
- Log.w(TAG, "Initialization of " + clsName + " took " + ti + " ms");
- }
- }
- }
-
- private OverlayViewMediator resolveContentMediator(String className) {
- return resolve(className, mContentMediatorCreators);
- }
-
- private <T> T resolve(String className, Map<Class<?>, Provider<T>> creators) {
- try {
- Class<?> clazz = Class.forName(className);
- Provider<T> provider = creators.get(clazz);
- return provider == null ? null : provider.get();
- } catch (ClassNotFoundException e) {
- return null;
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/wm/BarControlPolicy.java b/packages/CarSystemUI/src/com/android/systemui/wm/BarControlPolicy.java
deleted file mode 100644
index 0452b83..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/wm/BarControlPolicy.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright (C) 2020 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.wm;
-
-import android.car.settings.CarSettings;
-import android.content.Context;
-import android.database.ContentObserver;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.ArraySet;
-import android.util.Slog;
-import android.view.WindowInsets;
-
-import androidx.annotation.VisibleForTesting;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-/**
- * Util class to load PolicyControl and allow for querying if a package matches immersive filters.
- * Similar to {@link com.android.server.wm.PolicyControl}, but separate due to CarSystemUI needing
- * to set its own policies for system bar visibilities.
- *
- * This forces immersive mode behavior for one or both system bars (based on a package
- * list).
- *
- * Control by setting {@link Settings.Global#POLICY_CONTROL_AUTO} to one or more name-value pairs.
- * e.g.
- * to force immersive mode everywhere:
- * "immersive.full=*"
- * to force hide status bars for com.package1 but not com.package2:
- * "immersive.status=com.package1,-com.package2"
- *
- * Separate multiple name-value pairs with ':'
- * e.g. "immersive.status=com.package:immersive.navigation=*"
- */
-public class BarControlPolicy {
-
- private static final String TAG = "BarControlPolicy";
- private static final boolean DEBUG = false;
-
- private static final String NAME_IMMERSIVE_FULL = "immersive.full";
- private static final String NAME_IMMERSIVE_STATUS = "immersive.status";
- private static final String NAME_IMMERSIVE_NAVIGATION = "immersive.navigation";
-
- @VisibleForTesting
- static String sSettingValue;
- @VisibleForTesting
- static Filter sImmersiveStatusFilter;
- private static Filter sImmersiveNavigationFilter;
-
- /** Loads values from the POLICY_CONTROL setting to set filters. */
- static boolean reloadFromSetting(Context context) {
- if (DEBUG) Slog.d(TAG, "reloadFromSetting()");
- String value = null;
- try {
- value = Settings.Global.getStringForUser(context.getContentResolver(),
- CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE,
- UserHandle.USER_CURRENT);
- if (sSettingValue == value || sSettingValue != null && sSettingValue.equals(value)) {
- return false;
- }
- setFilters(value);
- sSettingValue = value;
- } catch (Throwable t) {
- Slog.w(TAG, "Error loading policy control, value=" + value, t);
- return false;
- }
- return true;
- }
-
- /** Used in testing to reset BarControlPolicy. */
- @VisibleForTesting
- static void reset() {
- sSettingValue = null;
- sImmersiveStatusFilter = null;
- sImmersiveNavigationFilter = null;
- }
-
- /**
- * Registers a content observer to listen to updates to the SYSTEM_BAR_VISIBILITY_OVERRIDE flag.
- */
- static void registerContentObserver(Context context, Handler handler, FilterListener listener) {
- context.getContentResolver().registerContentObserver(
- Settings.Global.getUriFor(CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE), false,
- new ContentObserver(handler) {
- @Override
- public void onChange(boolean selfChange) {
- if (reloadFromSetting(context)) {
- listener.onFilterUpdated();
- }
- }
- }, UserHandle.USER_ALL);
- }
-
- /**
- * Returns bar visibilities based on POLICY_CONTROL_AUTO filters and window policies.
- * @return int[], where the first value is the inset types that should be shown, and the second
- * is the inset types that should be hidden.
- */
- @WindowInsets.Type.InsetsType
- static int[] getBarVisibilities(String packageName) {
- int hideTypes = 0;
- int showTypes = 0;
- if (matchesStatusFilter(packageName)) {
- hideTypes |= WindowInsets.Type.statusBars();
- } else {
- showTypes |= WindowInsets.Type.statusBars();
- }
- if (matchesNavigationFilter(packageName)) {
- hideTypes |= WindowInsets.Type.navigationBars();
- } else {
- showTypes |= WindowInsets.Type.navigationBars();
- }
-
- return new int[] {showTypes, hideTypes};
- }
-
- private static boolean matchesStatusFilter(String packageName) {
- return sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(packageName);
- }
-
- private static boolean matchesNavigationFilter(String packageName) {
- return sImmersiveNavigationFilter != null
- && sImmersiveNavigationFilter.matches(packageName);
- }
-
- private static void setFilters(String value) {
- if (DEBUG) Slog.d(TAG, "setFilters: " + value);
- sImmersiveStatusFilter = null;
- sImmersiveNavigationFilter = null;
- if (value != null) {
- String[] nvps = value.split(":");
- for (String nvp : nvps) {
- int i = nvp.indexOf('=');
- if (i == -1) continue;
- String n = nvp.substring(0, i);
- String v = nvp.substring(i + 1);
- if (n.equals(NAME_IMMERSIVE_FULL)) {
- Filter f = Filter.parse(v);
- sImmersiveStatusFilter = sImmersiveNavigationFilter = f;
- } else if (n.equals(NAME_IMMERSIVE_STATUS)) {
- Filter f = Filter.parse(v);
- sImmersiveStatusFilter = f;
- } else if (n.equals(NAME_IMMERSIVE_NAVIGATION)) {
- Filter f = Filter.parse(v);
- sImmersiveNavigationFilter = f;
- }
- }
- }
- if (DEBUG) {
- Slog.d(TAG, "immersiveStatusFilter: " + sImmersiveStatusFilter);
- Slog.d(TAG, "immersiveNavigationFilter: " + sImmersiveNavigationFilter);
- }
- }
-
- private static class Filter {
- private static final String ALL = "*";
-
- private final ArraySet<String> mToInclude;
- private final ArraySet<String> mToExclude;
-
- private Filter(ArraySet<String> toInclude, ArraySet<String> toExclude) {
- mToInclude = toInclude;
- mToExclude = toExclude;
- }
-
- boolean matches(String packageName) {
- if (packageName == null) return false;
- if (toExclude(packageName)) return false;
- return toInclude(packageName);
- }
-
- private boolean toExclude(String packageName) {
- return mToExclude.contains(packageName) || mToExclude.contains(ALL);
- }
-
- private boolean toInclude(String packageName) {
- return mToInclude.contains(ALL) || mToInclude.contains(packageName);
- }
-
- void dump(PrintWriter pw) {
- pw.print("Filter[");
- dump("toInclude", mToInclude, pw); pw.print(',');
- dump("toExclude", mToExclude, pw); pw.print(']');
- }
-
- private void dump(String name, ArraySet<String> set, PrintWriter pw) {
- pw.print(name); pw.print("=(");
- int n = set.size();
- for (int i = 0; i < n; i++) {
- if (i > 0) pw.print(',');
- pw.print(set.valueAt(i));
- }
- pw.print(')');
- }
-
- @Override
- public String toString() {
- StringWriter sw = new StringWriter();
- dump(new PrintWriter(sw, true));
- return sw.toString();
- }
-
- // value = comma-delimited list of tokens, where token = (package name|*)
- // e.g. "com.package1", or "com.android.systemui, com.android.keyguard" or "*"
- static Filter parse(String value) {
- if (value == null) return null;
- ArraySet<String> toInclude = new ArraySet<String>();
- ArraySet<String> toExclude = new ArraySet<String>();
- for (String token : value.split(",")) {
- token = token.trim();
- if (token.startsWith("-") && token.length() > 1) {
- token = token.substring(1);
- toExclude.add(token);
- } else {
- toInclude.add(token);
- }
- }
- return new Filter(toInclude, toExclude);
- }
- }
-
- /**
- * Interface to listen for updates to the filter triggered by the content observer listening to
- * the SYSTEM_BAR_VISIBILITY_OVERRIDE flag.
- */
- interface FilterListener {
-
- /** Callback triggered when the content observer updates the filter. */
- void onFilterUpdated();
- }
-
- private BarControlPolicy() {}
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java b/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java
deleted file mode 100644
index f2ca495..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2020 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.wm;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.util.ArraySet;
-import android.util.Slog;
-import android.util.SparseArray;
-import android.view.IDisplayWindowInsetsController;
-import android.view.IWindowManager;
-import android.view.InsetsController;
-import android.view.InsetsSourceControl;
-import android.view.InsetsState;
-import android.view.WindowInsets;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.DisplayImeController;
-import com.android.wm.shell.common.TransactionPool;
-
-import java.util.Objects;
-
-/**
- * Controller that maps between displays and {@link IDisplayWindowInsetsController} in order to
- * give system bar control to SystemUI.
- * {@link R.bool#config_remoteInsetsControllerControlsSystemBars} determines whether this controller
- * takes control or not.
- */
-public class DisplaySystemBarsController extends DisplayImeController {
-
- private static final String TAG = "DisplaySystemBarsController";
-
- private final Context mContext;
- private final DisplayController mDisplayController;
- private final Handler mHandler;
- private SparseArray<PerDisplay> mPerDisplaySparseArray;
-
- public DisplaySystemBarsController(
- Context context,
- IWindowManager wmService,
- DisplayController displayController,
- @Main Handler mainHandler,
- TransactionPool transactionPool) {
- super(wmService, displayController, (r) -> mainHandler.post(r), transactionPool);
- mContext = context;
- mDisplayController = displayController;
- mHandler = mainHandler;
- }
-
- @Override
- public void onDisplayAdded(int displayId) {
- PerDisplay pd = new PerDisplay(displayId);
- try {
- mWmService.setDisplayWindowInsetsController(displayId, pd);
- } catch (RemoteException e) {
- Slog.w(TAG, "Unable to set insets controller on display " + displayId);
- }
- // Lazy loading policy control filters instead of during boot.
- if (mPerDisplaySparseArray == null) {
- mPerDisplaySparseArray = new SparseArray<>();
- BarControlPolicy.reloadFromSetting(mContext);
- BarControlPolicy.registerContentObserver(mContext, mHandler, () -> {
- int size = mPerDisplaySparseArray.size();
- for (int i = 0; i < size; i++) {
- mPerDisplaySparseArray.valueAt(i).modifyDisplayWindowInsets();
- }
- });
- }
- mPerDisplaySparseArray.put(displayId, pd);
- }
-
- @Override
- public void onDisplayRemoved(int displayId) {
- try {
- mWmService.setDisplayWindowInsetsController(displayId, null);
- } catch (RemoteException e) {
- Slog.w(TAG, "Unable to remove insets controller on display " + displayId);
- }
- mPerDisplaySparseArray.remove(displayId);
- }
-
- @VisibleForTesting
- class PerDisplay extends DisplayImeController.PerDisplay {
-
- int mDisplayId;
- InsetsController mInsetsController;
- InsetsState mInsetsState = new InsetsState();
- String mPackageName;
-
- PerDisplay(int displayId) {
- super(displayId, mDisplayController.getDisplayLayout(displayId).rotation());
- mDisplayId = displayId;
- mInsetsController = new InsetsController(
- new DisplaySystemBarsInsetsControllerHost(mHandler, this));
- }
-
- @Override
- public void insetsChanged(InsetsState insetsState) {
- super.insetsChanged(insetsState);
- if (mInsetsState.equals(insetsState)) {
- return;
- }
- mInsetsState.set(insetsState, true /* copySources */);
- mInsetsController.onStateChanged(insetsState);
- if (mPackageName != null) {
- modifyDisplayWindowInsets();
- }
- }
-
- @Override
- public void insetsControlChanged(InsetsState insetsState,
- InsetsSourceControl[] activeControls) {
- super.insetsControlChanged(insetsState, activeControls);
- mInsetsController.onControlsChanged(activeControls);
- }
-
- @Override
- public void hideInsets(@WindowInsets.Type.InsetsType int types, boolean fromIme) {
- if ((types & WindowInsets.Type.ime()) == 0) {
- mInsetsController.hide(types);
- } else {
- super.hideInsets(types, fromIme);
- }
-
- }
-
- @Override
- public void showInsets(@WindowInsets.Type.InsetsType int types, boolean fromIme) {
- if ((types & WindowInsets.Type.ime()) == 0) {
- mInsetsController.show(types);
- } else {
- super.showInsets(types, fromIme);
- }
-
- }
-
- @Override
- public void topFocusedWindowChanged(String packageName) {
- if (Objects.equals(mPackageName, packageName)) {
- return;
- }
- mPackageName = packageName;
- modifyDisplayWindowInsets();
- }
-
- private void modifyDisplayWindowInsets() {
- if (mPackageName == null) {
- return;
- }
- int[] barVisibilities = BarControlPolicy.getBarVisibilities(mPackageName);
- updateInsetsState(barVisibilities[0], /* visible= */ true);
- updateInsetsState(barVisibilities[1], /* visible= */ false);
- showInsets(barVisibilities[0], /* fromIme= */ false);
- hideInsets(barVisibilities[1], /* fromIme= */ false);
- try {
- mWmService.modifyDisplayWindowInsets(mDisplayId, mInsetsState);
- } catch (RemoteException e) {
- Slog.w(TAG, "Unable to update window manager service.");
- }
- }
-
- private void updateInsetsState(@WindowInsets.Type.InsetsType int types, boolean visible) {
- ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
- for (int i = internalTypes.size() - 1; i >= 0; i--) {
- mInsetsState.getSource(internalTypes.valueAt(i)).setVisible(visible);
- }
- }
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsInsetsControllerHost.java b/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsInsetsControllerHost.java
deleted file mode 100644
index 2f8da44..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsInsetsControllerHost.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2020 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.wm;
-
-import android.annotation.NonNull;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.IDisplayWindowInsetsController;
-import android.view.InsetsController;
-import android.view.InsetsState;
-import android.view.SurfaceControl;
-import android.view.SyncRtSurfaceTransactionApplier;
-import android.view.WindowInsets;
-import android.view.WindowInsetsAnimation;
-import android.view.WindowInsetsController;
-import android.view.inputmethod.InputMethodManager;
-
-import java.util.List;
-
-/**
- * Implements {@link InsetsController.Host} for usage by
- * {@link DisplaySystemBarsController.PerDisplay} instances in {@link DisplaySystemBarsController}.
- * @hide
- */
-public class DisplaySystemBarsInsetsControllerHost implements InsetsController.Host {
-
- private static final String TAG = DisplaySystemBarsInsetsControllerHost.class.getSimpleName();
-
- private final Handler mHandler;
- private final IDisplayWindowInsetsController mController;
- private final float[] mTmpFloat9 = new float[9];
-
- public DisplaySystemBarsInsetsControllerHost(
- Handler handler, IDisplayWindowInsetsController controller) {
- mHandler = handler;
- mController = controller;
- }
-
- @Override
- public Handler getHandler() {
- return mHandler;
- }
-
- @Override
- public void notifyInsetsChanged() {
- // no-op
- }
-
- @Override
- public void dispatchWindowInsetsAnimationPrepare(@NonNull WindowInsetsAnimation animation) {
- // no-op
- }
-
- @Override
- public WindowInsetsAnimation.Bounds dispatchWindowInsetsAnimationStart(
- @NonNull WindowInsetsAnimation animation,
- @NonNull WindowInsetsAnimation.Bounds bounds) {
- return null;
- }
-
- @Override
- public WindowInsets dispatchWindowInsetsAnimationProgress(@NonNull WindowInsets insets,
- @NonNull List<WindowInsetsAnimation> runningAnimations) {
- return null;
- }
-
- @Override
- public void dispatchWindowInsetsAnimationEnd(@NonNull WindowInsetsAnimation animation) {
- // no-op
- }
-
- @Override
- public void applySurfaceParams(final SyncRtSurfaceTransactionApplier.SurfaceParams... params) {
- for (int i = params.length - 1; i >= 0; i--) {
- SyncRtSurfaceTransactionApplier.applyParams(
- new SurfaceControl.Transaction(), params[i], mTmpFloat9);
- }
-
- }
-
- @Override
- public void updateCompatSysUiVisibility(
- @InsetsState.InternalInsetsType int type, boolean visible, boolean hasControl) {
- // no-op
- }
-
- @Override
- public void onInsetsModified(InsetsState insetsState) {
- try {
- mController.insetsChanged(insetsState);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to send insets to controller");
- }
- }
-
- @Override
- public boolean hasAnimationCallbacks() {
- return false;
- }
-
- @Override
- public void setSystemBarsAppearance(
- @WindowInsetsController.Appearance int appearance,
- @WindowInsetsController.Appearance int mask) {
- // no-op
- }
-
- @Override
- public @WindowInsetsController.Appearance int getSystemBarsAppearance() {
- return 0;
- }
-
- @Override
- public void setSystemBarsBehavior(@WindowInsetsController.Behavior int behavior) {
- // no-op
- }
-
- @Override
- public @WindowInsetsController.Behavior int getSystemBarsBehavior() {
- return 0;
- }
-
- @Override
- public void releaseSurfaceControlFromRt(SurfaceControl surfaceControl) {
- surfaceControl.release();
- }
-
- @Override
- public void addOnPreDrawRunnable(Runnable r) {
- mHandler.post(r);
- }
-
- @Override
- public void postInsetsAnimationCallback(Runnable r) {
- mHandler.post(r);
- }
-
- @Override
- public InputMethodManager getInputMethodManager() {
- return null;
- }
-
- @Override
- public String getRootViewTitle() {
- return null;
- }
-
- @Override
- public int dipToPx(int dips) {
- return 0;
- }
-
- @Override
- public IBinder getWindowToken() {
- return null;
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/wmshell/CarWMComponent.java b/packages/CarSystemUI/src/com/android/systemui/wmshell/CarWMComponent.java
deleted file mode 100644
index c6a7fd2..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/wmshell/CarWMComponent.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2020 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.wmshell;
-
-import com.android.systemui.dagger.WMComponent;
-import com.android.systemui.dagger.WMSingleton;
-
-import dagger.Subcomponent;
-
-
-/**
- * Dagger Subcomponent for WindowManager.
- */
-@WMSingleton
-@Subcomponent(modules = {CarWMShellModule.class})
-public interface CarWMComponent extends WMComponent {
-
- /**
- * Builder for a SysUIComponent.
- */
- @Subcomponent.Builder
- interface Builder extends WMComponent.Builder {
- CarWMComponent build();
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/wmshell/CarWMShellModule.java b/packages/CarSystemUI/src/com/android/systemui/wmshell/CarWMShellModule.java
deleted file mode 100644
index 27aabff..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/wmshell/CarWMShellModule.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2020 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.wmshell;
-
-import android.content.Context;
-import android.os.Handler;
-import android.view.IWindowManager;
-
-import com.android.systemui.dagger.WMSingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.wm.DisplaySystemBarsController;
-import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.DisplayImeController;
-import com.android.wm.shell.common.TransactionPool;
-import com.android.wm.shell.pip.Pip;
-
-import dagger.BindsOptionalOf;
-import dagger.Module;
-import dagger.Provides;
-
-/** Provides dependencies from {@link com.android.wm.shell} for CarSystemUI. */
-@Module(includes = WMShellBaseModule.class)
-public abstract class CarWMShellModule {
- @WMSingleton
- @Provides
- static DisplayImeController provideDisplayImeController(Context context,
- IWindowManager wmService, DisplayController displayController,
- @Main Handler mainHandler, TransactionPool transactionPool) {
- return new DisplaySystemBarsController(context, wmService, displayController,
- mainHandler, transactionPool);
- }
-
- @BindsOptionalOf
- abstract Pip optionalPip();
-}
diff --git a/packages/CarSystemUI/tests/Android.mk b/packages/CarSystemUI/tests/Android.mk
deleted file mode 100644
index 1366568..0000000
--- a/packages/CarSystemUI/tests/Android.mk
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright (C) 2019 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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_USE_AAPT2 := true
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_JACK_FLAGS := --multi-dex native
-LOCAL_DX_FLAGS := --multi-dex
-
-LOCAL_PACKAGE_NAME := CarSystemUITests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-LOCAL_STATIC_ANDROID_LIBRARIES := \
- CarSystemUI-tests
-
-LOCAL_MULTILIB := both
-
-LOCAL_JNI_SHARED_LIBRARIES := \
- libdexmakerjvmtiagent \
- libmultiplejvmtiagentsinterferenceagent
-
-LOCAL_JAVA_LIBRARIES := \
- android.test.runner \
- telephony-common \
- android.test.base \
-
-LOCAL_AAPT_FLAGS := --extra-packages com.android.systemui
-
-# sign this with platform cert, so this test is allowed to inject key events into
-# UI it doesn't own. This is necessary to allow screenshots to be taken
-LOCAL_CERTIFICATE := platform
-
-# Provide jack a list of classes to exclude from code coverage.
-# This is needed because the CarSystemUITests compile CarSystemUI source directly, rather than using
-# LOCAL_INSTRUMENTATION_FOR := CarSystemUI.
-#
-# We want to exclude the test classes from code coverage measurements, but they share the same
-# package as the rest of SystemUI so they can't be easily filtered by package name.
-#
-# Generate a comma separated list of patterns based on the test source files under src/
-# SystemUI classes are in ../src/ so they won't be excluded.
-# Example:
-# Input files: src/com/android/systemui/Test.java src/com/android/systemui/AnotherTest.java
-# Generated exclude list: com.android.systemui.Test*,com.android.systemui.AnotherTest*
-
-# Filter all src files under src/ to just java files
-local_java_files := $(filter %.java,$(call all-java-files-under, src))
-
-# Transform java file names into full class names.
-# This only works if the class name matches the file name and the directory structure
-# matches the package.
-local_classes := $(subst /,.,$(patsubst src/%.java,%,$(local_java_files)))
-local_comma := ,
-local_empty :=
-local_space := $(local_empty) $(local_empty)
-
-# Convert class name list to jacoco exclude list
-# This appends a * to all classes and replace the space separators with commas.
-jacoco_exclude := $(subst $(space),$(comma),$(patsubst %,%*,$(local_classes)))
-
-LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.systemui.*,com.android.keyguard.*
-LOCAL_JACK_COVERAGE_EXCLUDE_FILTER := $(jacoco_exclude)
-
-ifeq ($(EXCLUDE_SYSTEMUI_TESTS),)
- include $(BUILD_PACKAGE)
-endif
-
-# Reset variables
-local_java_files :=
-local_classes :=
-local_comma :=
-local_space :=
-jacoco_exclude :=
diff --git a/packages/CarSystemUI/tests/AndroidManifest.xml b/packages/CarSystemUI/tests/AndroidManifest.xml
deleted file mode 100644
index a74bb56..0000000
--- a/packages/CarSystemUI/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:sharedUserId="android.uid.system"
- package="com.android.systemui.tests">
-
- <application android:debuggable="true" android:largeHeap="true">
- <uses-library android:name="android.test.runner" />
-
- <provider
- android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer"
- tools:replace="android:authorities"
- android:authorities="${applicationId}.lifecycle-tests"
- android:exported="false"
- android:enabled="false"
- android:multiprocess="true" />
- </application>
-
- <instrumentation android:name="android.testing.TestableInstrumentation"
- android:targetPackage="com.android.systemui.tests"
- android:label="Tests for CarSystemUI">
- </instrumentation>
-</manifest>
diff --git a/packages/CarSystemUI/tests/AndroidTest.xml b/packages/CarSystemUI/tests/AndroidTest.xml
deleted file mode 100644
index 8685632..0000000
--- a/packages/CarSystemUI/tests/AndroidTest.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 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.
- -->
-<configuration description="Runs Tests for CarSystemUI.">
- <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
- <option name="test-file-name" value="CarSystemUITests.apk" />
- </target_preparer>
-
- <option name="test-suite-tag" value="apct" />
- <option name="test-suite-tag" value="framework-base-presubmit" />
- <option name="test-tag" value="CarSystemUITests" />
- <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="com.android.systemui.tests" />
- <option name="runner" value="android.testing.TestableInstrumentation" />
- <option name="hidden-api-checks" value="false"/>
- </test>
-</configuration>
diff --git a/packages/CarSystemUI/tests/res/layout/button_role_holder_controller_test.xml b/packages/CarSystemUI/tests/res/layout/button_role_holder_controller_test.xml
deleted file mode 100644
index 25ec2c1..0000000
--- a/packages/CarSystemUI/tests/res/layout/button_role_holder_controller_test.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:id="@id/nav_buttons"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:paddingStart="20dp"
- android:paddingEnd="20dp"
- android:gravity="center">
-
- <com.android.systemui.car.navigationbar.AssitantButton
- android:id="@+id/assistant_role_button"
- style="@style/NavigationBarButton"
- systemui:icon="@drawable/car_ic_overview"
- systemui:useDefaultAppIconForRole="true"
- />
-
- <com.android.systemui.car.navigationbar.AssitantButton
- android:id="@+id/assistant_role_disabled_button"
- style="@style/NavigationBarButton"
- systemui:icon="@drawable/car_ic_overview"
- />
-
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/CarSystemUI/tests/res/layout/car_button_selection_state_controller_test.xml b/packages/CarSystemUI/tests/res/layout/car_button_selection_state_controller_test.xml
deleted file mode 100644
index a8e83d6..0000000
--- a/packages/CarSystemUI/tests/res/layout/car_button_selection_state_controller_test.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:id="@id/nav_buttons"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:paddingStart="20dp"
- android:paddingEnd="20dp"
- android:gravity="center">
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/detectable_by_component_name"
- style="@style/NavigationBarButton"
- systemui:componentNames="com.android.car.carlauncher/.CarLauncher"
- systemui:icon="@drawable/car_ic_overview"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
- systemui:highlightWhenSelected="true"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/detectable_by_category"
- style="@style/NavigationBarButton"
- systemui:categories="android.intent.category.APP_MAPS"
- systemui:icon="@drawable/car_ic_navigation"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MAPS;launchFlags=0x14000000;end"
- systemui:highlightWhenSelected="true"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/detectable_by_package"
- style="@style/NavigationBarButton"
- systemui:icon="@drawable/car_ic_phone"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;package=com.android.car.dialer;launchFlags=0x10000000;end"
- systemui:packages="com.android.car.dialer"
- systemui:highlightWhenSelected="true"
- />
-
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/CarSystemUI/tests/res/layout/car_navigation_bar_view_test.xml b/packages/CarSystemUI/tests/res/layout/car_navigation_bar_view_test.xml
deleted file mode 100644
index 94edc4b..0000000
--- a/packages/CarSystemUI/tests/res/layout/car_navigation_bar_view_test.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<!--
- ~ Copyright (C) 2020 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.
- -->
-
-<com.android.systemui.car.navigationbar.CarNavigationBarView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/system_bar_background"
- android:orientation="vertical">
- <!--The 20dp padding is the difference between the background selected icon size and the ripple
- that was chosen, thus it's a hack to make it look pretty and not an official margin value-->
- <LinearLayout
- android:id="@id/nav_buttons"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:paddingStart="20dp"
- android:paddingEnd="20dp"
- android:gravity="center">
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/home"
- style="@style/NavigationBarButton"
- systemui:componentNames="com.android.car.carlauncher/.CarLauncher"
- systemui:icon="@drawable/car_ic_overview"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
- systemui:selectedIcon="@drawable/car_ic_overview_selected"
- systemui:highlightWhenSelected="true"
- />
-
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/lock_screen_nav_buttons"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:paddingStart="@dimen/car_keyline_1"
- android:paddingEnd="@dimen/car_keyline_1"
- android:gravity="center"
- android:visibility="gone"
- />
-
-</com.android.systemui.car.navigationbar.CarNavigationBarView>
diff --git a/packages/CarSystemUI/tests/res/layout/car_navigation_button_test.xml b/packages/CarSystemUI/tests/res/layout/car_navigation_button_test.xml
deleted file mode 100644
index 44f8340..0000000
--- a/packages/CarSystemUI/tests/res/layout/car_navigation_button_test.xml
+++ /dev/null
@@ -1,124 +0,0 @@
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:id="@id/nav_buttons"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:paddingStart="20dp"
- android:paddingEnd="20dp"
- android:gravity="center">
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/default_no_selection_state"
- style="@style/NavigationBarButton"
- systemui:componentNames="com.android.car.carlauncher/.CarLauncher"
- systemui:icon="@drawable/car_ic_overview"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
- systemui:selectedIcon="@drawable/car_ic_overview_selected"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/app_grid_activity"
- style="@style/NavigationBarButton"
- systemui:componentNames="com.android.car.carlauncher/.AppGridActivity"
- systemui:icon="@drawable/car_ic_apps"
- systemui:intent="intent:#Intent;component=com.android.car.carlauncher/.AppGridActivity;launchFlags=0x24000000;end"
- systemui:selectedIcon="@drawable/car_ic_apps_selected"
- systemui:highlightWhenSelected="true"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/long_click_app_grid_activity"
- style="@style/NavigationBarButton"
- systemui:componentNames="com.android.car.carlauncher/.AppGridActivity"
- systemui:icon="@drawable/car_ic_apps"
- systemui:longIntent="intent:#Intent;component=com.android.car.carlauncher/.AppGridActivity;launchFlags=0x24000000;end"
- systemui:selectedIcon="@drawable/car_ic_apps_selected"
- systemui:highlightWhenSelected="true"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/broadcast"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@null"
- systemui:broadcast="true"
- systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/selected_icon_undefined"
- style="@style/NavigationBarButton"
- systemui:componentNames="com.android.car.carlauncher/.CarLauncher"
- systemui:icon="@drawable/car_ic_overview"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/highlightable_no_more_button"
- style="@style/NavigationBarButton"
- systemui:componentNames="com.android.car.carlauncher/.CarLauncher"
- systemui:icon="@drawable/car_ic_overview"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
- systemui:selectedIcon="@drawable/car_ic_overview_selected"
- systemui:highlightWhenSelected="true"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/not_highlightable_more_button"
- style="@style/NavigationBarButton"
- systemui:componentNames="com.android.car.carlauncher/.CarLauncher"
- systemui:icon="@drawable/car_ic_overview"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
- systemui:selectedIcon="@drawable/car_ic_overview_selected"
- systemui:showMoreWhenSelected="true"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/highlightable_more_button"
- style="@style/NavigationBarButton"
- systemui:componentNames="com.android.car.carlauncher/.CarLauncher"
- systemui:icon="@drawable/car_ic_overview"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
- systemui:selectedIcon="@drawable/car_ic_overview_selected"
- systemui:highlightWhenSelected="true"
- systemui:showMoreWhenSelected="true"
- />
-
- <com.android.systemui.car.navigationbar.CarNavigationButton
- android:id="@+id/broadcast"
- style="@style/NavigationBarButton"
- systemui:componentNames="com.android.car.carlauncher/.CarLauncher"
- systemui:icon="@drawable/car_ic_overview"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
- systemui:selectedIcon="@drawable/car_ic_overview_selected"
- systemui:broadcast="true"
- />
-
- <com.android.systemui.car.navigationbar.AssitantButton
- android:id="@+id/role_based_button"
- style="@style/NavigationBarButton"
- systemui:icon="@drawable/car_ic_overview"
- systemui:selectedIcon="@drawable/car_ic_overview_selected"
- systemui:useDefaultAppIconForRole="true"
- systemui:highlightWhenSelected="true"
- />
-
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/CarSystemUI/tests/res/layout/overlay_view_controller_stub.xml b/packages/CarSystemUI/tests/res/layout/overlay_view_controller_stub.xml
deleted file mode 100644
index 5e5efe7..0000000
--- a/packages/CarSystemUI/tests/res/layout/overlay_view_controller_stub.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!--
- ~ Copyright (C) 2020 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:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:id="@+id/overlay_view_controller_test">
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/CarSystemUI/tests/res/layout/overlay_view_controller_test.xml b/packages/CarSystemUI/tests/res/layout/overlay_view_controller_test.xml
deleted file mode 100644
index 165193e..0000000
--- a/packages/CarSystemUI/tests/res/layout/overlay_view_controller_test.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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.
- -->
-
-<!-- Fullscreen views in sysui should be listed here in increasing Z order. -->
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:background="@android:color/transparent"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <ViewStub android:id="@+id/overlay_view_controller_stub"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout="@layout/overlay_view_controller_stub"/>
-
-</FrameLayout>
\ No newline at end of file
diff --git a/packages/CarSystemUI/tests/res/layout/overlay_view_global_state_controller_test.xml b/packages/CarSystemUI/tests/res/layout/overlay_view_global_state_controller_test.xml
deleted file mode 100644
index 03fe0e4..0000000
--- a/packages/CarSystemUI/tests/res/layout/overlay_view_global_state_controller_test.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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.
- -->
-
-<!-- Fullscreen views in sysui should be listed here in increasing Z order. -->
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:background="@android:color/transparent"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <ViewStub android:id="@+id/overlay_view_controller_stub_1"
- android:inflatedId="@+id/overlay_view_controller_1"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout="@layout/overlay_view_controller_stub"/>
-
- <ViewStub android:id="@+id/overlay_view_controller_stub_2"
- android:inflatedId="@+id/overlay_view_controller_2"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout="@layout/overlay_view_controller_stub"/>
-
- <ViewStub android:id="@+id/overlay_view_controller_stub_3"
- android:inflatedId="@+id/overlay_view_controller_3"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout="@layout/overlay_view_controller_stub"/>
-
-</FrameLayout>
\ No newline at end of file
diff --git a/packages/CarSystemUI/tests/res/values/config.xml b/packages/CarSystemUI/tests/res/values/config.xml
deleted file mode 100644
index 0d08ac2..0000000
--- a/packages/CarSystemUI/tests/res/values/config.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 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>
- <!-- Configure which system ui bars should be displayed.
- These can be overwritten within the tests. -->
- <bool name="config_enableLeftNavigationBar">false</bool>
- <bool name="config_enableRightNavigationBar">false</bool>
- <bool name="config_enableBottomNavigationBar">false</bool>
-</resources>
diff --git a/packages/CarSystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java b/packages/CarSystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java
deleted file mode 100644
index 86b86d4..0000000
--- a/packages/CarSystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (C) 2019 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;
-
-import static org.hamcrest.Matchers.empty;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-
-import android.testing.AndroidTestingRunner;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.test.filters.LargeTest;
-import androidx.test.filters.MediumTest;
-import androidx.test.filters.SmallTest;
-import androidx.test.internal.runner.ClassPathScanner;
-import androidx.test.internal.runner.ClassPathScanner.ChainedClassNameFilter;
-import androidx.test.internal.runner.ClassPathScanner.ExternalClassNameFilter;
-
-import com.android.systemui.SysuiBaseFragmentTest;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarSystemUiTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-
-/**
- * This is named AAAPlusPlusVerifySysuiRequiredTestPropertiesTest for two reasons.
- * a) Its so awesome it deserves an AAA++
- * b) It should run first to draw attention to itself.
- *
- * For trues though: this test verifies that all the sysui tests extend the right classes.
- * This matters because including tests with different context implementations in the same
- * test suite causes errors, such as the incorrect settings provider being cached.
- * For an example, see {@link com.android.systemui.DependencyTest}.
- */
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@SmallTest
-public class AAAPlusPlusVerifySysuiRequiredTestPropertiesTest extends SysuiTestCase {
-
- private static final String TAG = "AAA++VerifyTest";
-
- private static final Class[] BASE_CLS_TO_INCLUDE = {
- SysuiTestCase.class,
- SysuiBaseFragmentTest.class,
- };
-
- private static final Class[] SUPPORTED_SIZES = {
- SmallTest.class,
- MediumTest.class,
- LargeTest.class,
- android.test.suitebuilder.annotation.SmallTest.class,
- android.test.suitebuilder.annotation.MediumTest.class,
- android.test.suitebuilder.annotation.LargeTest.class,
- };
-
- @Test
- public void testAllClassInheritance() throws Throwable {
- ArrayList<String> fails = new ArrayList<>();
- for (String className : getClassNamesFromClassPath()) {
- Class<?> cls = Class.forName(className, false, this.getClass().getClassLoader());
- if (!isTestClass(cls)) continue;
-
- boolean hasParent = false;
- for (Class<?> parent : BASE_CLS_TO_INCLUDE) {
- if (parent.isAssignableFrom(cls)) {
- hasParent = true;
- break;
- }
- }
- boolean hasSize = hasSize(cls);
- if (!hasSize) {
- fails.add(cls.getName() + " does not have size annotation, such as @SmallTest");
- }
- if (!hasParent) {
- fails.add(cls.getName() + " does not extend any of " + getClsStr());
- }
- }
-
- assertThat("All sysui test classes must have size and extend one of " + getClsStr(),
- fails, is(empty()));
- }
-
- private boolean hasSize(Class<?> cls) {
- for (int i = 0; i < SUPPORTED_SIZES.length; i++) {
- if (cls.getDeclaredAnnotation(SUPPORTED_SIZES[i]) != null) return true;
- }
- return false;
- }
-
- private Collection<String> getClassNamesFromClassPath() {
- ClassPathScanner scanner = new ClassPathScanner(mContext.getPackageCodePath());
-
- ChainedClassNameFilter filter = new ChainedClassNameFilter();
-
- filter.add(new ExternalClassNameFilter());
- filter.add(s -> s.startsWith("com.android.systemui")
- || s.startsWith("com.android.keyguard"));
-
- try {
- return scanner.getClassPathEntries(filter);
- } catch (IOException e) {
- Log.e(TAG, "Failed to scan classes", e);
- }
- return Collections.emptyList();
- }
-
- private String getClsStr() {
- return TextUtils.join(",", Arrays.asList(BASE_CLS_TO_INCLUDE)
- .stream().map(cls -> cls.getSimpleName()).toArray());
- }
-
- /**
- * Determines if given class is a valid test class.
- *
- * @return <code>true</code> if loadedClass is a test
- */
- private boolean isTestClass(Class<?> loadedClass) {
- try {
- if (Modifier.isAbstract(loadedClass.getModifiers())) {
- logDebug(String.format("Skipping abstract class %s: not a test",
- loadedClass.getName()));
- return false;
- }
- // TODO: try to find upstream junit calls to replace these checks
- if (junit.framework.Test.class.isAssignableFrom(loadedClass)) {
- // ensure that if a TestCase, it has at least one test method otherwise
- // TestSuite will throw error
- if (junit.framework.TestCase.class.isAssignableFrom(loadedClass)) {
- return hasJUnit3TestMethod(loadedClass);
- }
- return true;
- }
- // TODO: look for a 'suite' method?
- if (loadedClass.isAnnotationPresent(RunWith.class)) {
- return true;
- }
- for (Method testMethod : loadedClass.getMethods()) {
- if (testMethod.isAnnotationPresent(Test.class)) {
- return true;
- }
- }
- logDebug(String.format("Skipping class %s: not a test", loadedClass.getName()));
- return false;
- } catch (Exception e) {
- // Defensively catch exceptions - Will throw runtime exception if it cannot load
- // methods.
- // For earlier versions of Android (Pre-ICS), Dalvik might try to initialize a class
- // during getMethods(), fail to do so, hide the error and throw a NoSuchMethodException.
- // Since the java.lang.Class.getMethods does not declare such an exception, resort to a
- // generic catch all.
- // For ICS+, Dalvik will throw a NoClassDefFoundException.
- Log.w(TAG, String.format("%s in isTestClass for %s", e.toString(),
- loadedClass.getName()));
- return false;
- } catch (Error e) {
- // defensively catch Errors too
- Log.w(TAG, String.format("%s in isTestClass for %s", e.toString(),
- loadedClass.getName()));
- return false;
- }
- }
-
- private boolean hasJUnit3TestMethod(Class<?> loadedClass) {
- for (Method testMethod : loadedClass.getMethods()) {
- if (isPublicTestMethod(testMethod)) {
- return true;
- }
- }
- return false;
- }
-
- // copied from junit.framework.TestSuite
- private boolean isPublicTestMethod(Method m) {
- return isTestMethod(m) && Modifier.isPublic(m.getModifiers());
- }
-
- // copied from junit.framework.TestSuite
- private boolean isTestMethod(Method m) {
- return m.getParameterTypes().length == 0 && m.getName().startsWith("test")
- && m.getReturnType().equals(Void.TYPE);
- }
-
- /**
- * Utility method for logging debug messages. Only actually logs a message if TAG is marked
- * as loggable to limit log spam during normal use.
- */
- private void logDebug(String msg) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, msg);
- }
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/AdjustableTemperatureViewTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/AdjustableTemperatureViewTest.java
deleted file mode 100644
index fe071d5..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/AdjustableTemperatureViewTest.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.hvac;
-
-import static android.car.VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;
-import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS;
-import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_SET;
-
-import static com.android.systemui.car.hvac.HvacController.convertToCelsius;
-import static com.android.systemui.car.hvac.HvacController.convertToFahrenheit;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.car.Car;
-import android.car.VehicleUnit;
-import android.car.hardware.property.CarPropertyManager;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.widget.TextView;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarServiceProvider;
-import com.android.systemui.car.CarSystemUiTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.concurrent.Executor;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class AdjustableTemperatureViewTest extends SysuiTestCase {
-
- private static final float TEMP_CELSIUS = 22.0f;
- private final String mFormat = getContext().getString(R.string.hvac_temperature_format);
- private AdjustableTemperatureView mAdjustableTemperatureView;
- private HvacController mHvacController;
-
- @Mock
- private Car mCar;
- @Mock
- private CarPropertyManager mCarPropertyManager;
- @Mock
- private Executor mExecutor;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- when(mCar.isConnected()).thenReturn(true);
- when(mCar.getCarManager(Car.PROPERTY_SERVICE)).thenReturn(mCarPropertyManager);
-
- CarServiceProvider carServiceProvider = new CarServiceProvider(mContext, mCar);
- mHvacController = new HvacController(carServiceProvider, mExecutor);
- mHvacController.connectToCarService();
- mAdjustableTemperatureView = new AdjustableTemperatureView(getContext(), /* attrs= */ null);
- mAdjustableTemperatureView.onFinishInflate();
- mAdjustableTemperatureView.setHvacController(mHvacController);
- }
-
- @Test
- public void addTemperatureViewToController_setsTemperatureView() {
- when(mCarPropertyManager.isPropertyAvailable(eq(HVAC_TEMPERATURE_SET),
- anyInt())).thenReturn(true);
- when(mCarPropertyManager.getFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt())).thenReturn(
- TEMP_CELSIUS);
-
- mHvacController.addTemperatureViewToController(mAdjustableTemperatureView);
-
- TextView tempText = mAdjustableTemperatureView.findViewById(R.id.hvac_temperature_text);
- assertEquals(tempText.getText(), String.format(mFormat, TEMP_CELSIUS));
- }
-
- @Test
- public void setTemp_tempNaN_setsTextToNaNText() {
- when(mCarPropertyManager.isPropertyAvailable(eq(HVAC_TEMPERATURE_SET),
- anyInt())).thenReturn(true);
- when(mCarPropertyManager.getFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt())).thenReturn(
- Float.NaN);
-
- mHvacController.addTemperatureViewToController(mAdjustableTemperatureView);
-
- TextView tempText = mAdjustableTemperatureView.findViewById(R.id.hvac_temperature_text);
- assertEquals(tempText.getText(),
- getContext().getResources().getString(R.string.hvac_null_temp_text));
- }
-
- @Test
- public void setTemp_tempBelowMin_setsTextToMinTempText() {
- when(mCarPropertyManager.isPropertyAvailable(eq(HVAC_TEMPERATURE_SET),
- anyInt())).thenReturn(true);
- when(mCarPropertyManager.getFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt())).thenReturn(
- getContext().getResources().getFloat(R.dimen.hvac_min_value_celsius));
-
- mHvacController.addTemperatureViewToController(mAdjustableTemperatureView);
-
- TextView tempText = mAdjustableTemperatureView.findViewById(R.id.hvac_temperature_text);
- assertEquals(tempText.getText(),
- getContext().getResources().getString(R.string.hvac_min_text));
- }
-
- @Test
- public void setTemp_tempAboveMax_setsTextToMaxTempText() {
- when(mCarPropertyManager.isPropertyAvailable(eq(HVAC_TEMPERATURE_SET),
- anyInt())).thenReturn(true);
- when(mCarPropertyManager.getFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt())).thenReturn(
- getContext().getResources().getFloat(R.dimen.hvac_max_value_celsius));
-
- mHvacController.addTemperatureViewToController(mAdjustableTemperatureView);
-
- TextView tempText = mAdjustableTemperatureView.findViewById(R.id.hvac_temperature_text);
- assertEquals(tempText.getText(),
- getContext().getResources().getString(R.string.hvac_max_text));
- }
-
- @Test
- public void setTemperatureToFahrenheit_callsViewSetDisplayInFahrenheit() {
- when(mCarPropertyManager.isPropertyAvailable(eq(HVAC_TEMPERATURE_SET),
- anyInt())).thenReturn(true);
- when(mCarPropertyManager.getFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt())).thenReturn(
- TEMP_CELSIUS);
- when(mCarPropertyManager.isPropertyAvailable(HVAC_TEMPERATURE_DISPLAY_UNITS,
- VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(true);
- when(mCarPropertyManager.getIntProperty(HVAC_TEMPERATURE_DISPLAY_UNITS,
- VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(VehicleUnit.FAHRENHEIT);
-
- mHvacController.addTemperatureViewToController(mAdjustableTemperatureView);
-
- TextView tempText = mAdjustableTemperatureView.findViewById(R.id.hvac_temperature_text);
- assertEquals(tempText.getText(), String.format(mFormat, convertToFahrenheit(TEMP_CELSIUS)));
- }
-
- @Test
- public void adjustableViewIncreaseButton_setsTempWithCarPropertyManager() {
- when(mCarPropertyManager.isPropertyAvailable(eq(HVAC_TEMPERATURE_SET),
- anyInt())).thenReturn(true);
- when(mCarPropertyManager.getFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt())).thenReturn(
- TEMP_CELSIUS);
- mHvacController.addTemperatureViewToController(mAdjustableTemperatureView);
-
- mAdjustableTemperatureView.findViewById(R.id.hvac_increase_button).callOnClick();
-
- ArgumentCaptor<Runnable> setTempRunnableCaptor = ArgumentCaptor.forClass(Runnable.class);
- verify(mExecutor).execute(setTempRunnableCaptor.capture());
- setTempRunnableCaptor.getValue().run();
- verify(mCarPropertyManager).setFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt(),
- eq(TEMP_CELSIUS + 1));
- }
-
- @Test
- public void adjustableViewDecreaseButton_setsTempWithCarPropertyManager() {
- when(mCarPropertyManager.isPropertyAvailable(eq(HVAC_TEMPERATURE_SET),
- anyInt())).thenReturn(true);
- when(mCarPropertyManager.getFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt())).thenReturn(
- TEMP_CELSIUS);
- mHvacController.addTemperatureViewToController(mAdjustableTemperatureView);
-
- mAdjustableTemperatureView.findViewById(R.id.hvac_decrease_button).callOnClick();
-
- ArgumentCaptor<Runnable> setTempRunnableCaptor = ArgumentCaptor.forClass(Runnable.class);
- verify(mExecutor).execute(setTempRunnableCaptor.capture());
- setTempRunnableCaptor.getValue().run();
- verify(mCarPropertyManager).setFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt(),
- eq(TEMP_CELSIUS - 1));
- }
-
- @Test
- public void adjustableViewIncreaseButton_inFahrenheit_setsTempWithCarPropertyManager() {
- when(mCarPropertyManager.isPropertyAvailable(eq(HVAC_TEMPERATURE_SET),
- anyInt())).thenReturn(true);
- when(mCarPropertyManager.getFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt())).thenReturn(
- TEMP_CELSIUS);
- when(mCarPropertyManager.isPropertyAvailable(HVAC_TEMPERATURE_DISPLAY_UNITS,
- VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(true);
- when(mCarPropertyManager.getIntProperty(HVAC_TEMPERATURE_DISPLAY_UNITS,
- VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(VehicleUnit.FAHRENHEIT);
- mHvacController.addTemperatureViewToController(mAdjustableTemperatureView);
-
- mAdjustableTemperatureView.findViewById(R.id.hvac_increase_button).callOnClick();
-
- ArgumentCaptor<Runnable> setTempRunnableCaptor = ArgumentCaptor.forClass(Runnable.class);
- verify(mExecutor).execute(setTempRunnableCaptor.capture());
- setTempRunnableCaptor.getValue().run();
- verify(mCarPropertyManager).setFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt(),
- eq(convertToCelsius(convertToFahrenheit(TEMP_CELSIUS) + 1)));
- }
-
- @Test
- public void adjustableViewDecreaseButton_inFahrenheit_setsTempWithCarPropertyManager() {
- when(mCarPropertyManager.isPropertyAvailable(eq(HVAC_TEMPERATURE_SET),
- anyInt())).thenReturn(true);
- when(mCarPropertyManager.getFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt())).thenReturn(
- TEMP_CELSIUS);
- when(mCarPropertyManager.isPropertyAvailable(HVAC_TEMPERATURE_DISPLAY_UNITS,
- VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(true);
- when(mCarPropertyManager.getIntProperty(HVAC_TEMPERATURE_DISPLAY_UNITS,
- VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(VehicleUnit.FAHRENHEIT);
- mHvacController.addTemperatureViewToController(mAdjustableTemperatureView);
-
- mAdjustableTemperatureView.findViewById(R.id.hvac_decrease_button).callOnClick();
-
- ArgumentCaptor<Runnable> setTempRunnableCaptor = ArgumentCaptor.forClass(Runnable.class);
- verify(mExecutor).execute(setTempRunnableCaptor.capture());
- setTempRunnableCaptor.getValue().run();
- verify(mCarPropertyManager).setFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt(),
- eq(convertToCelsius(convertToFahrenheit(TEMP_CELSIUS) - 1)));
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/HvacControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/HvacControllerTest.java
deleted file mode 100644
index 52f07df..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/HvacControllerTest.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.hvac;
-
-import static android.car.VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;
-import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS;
-import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_SET;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyFloat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.car.Car;
-import android.car.VehicleUnit;
-import android.car.hardware.property.CarPropertyManager;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarServiceProvider;
-import com.android.systemui.car.CarSystemUiTest;
-import com.android.systemui.util.concurrency.FakeExecutor;
-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.MockitoAnnotations;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class HvacControllerTest extends SysuiTestCase {
-
- private static final int AREA_ID = 1;
- private static final float TEMP = 72.0f;
-
- private HvacController mHvacController;
-
- @Mock
- private Car mCar;
- @Mock
- private CarPropertyManager mCarPropertyManager;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- when(mCar.isConnected()).thenReturn(true);
- when(mCar.getCarManager(Car.PROPERTY_SERVICE)).thenReturn(mCarPropertyManager);
-
- CarServiceProvider carServiceProvider = new CarServiceProvider(mContext, mCar);
- mHvacController = new HvacController(carServiceProvider,
- new FakeExecutor(new FakeSystemClock()));
- mHvacController.connectToCarService();
- }
-
- @Test
- public void connectToCarService_registersCallback() {
- verify(mCarPropertyManager).registerCallback(any(), eq(HVAC_TEMPERATURE_SET), anyFloat());
- verify(mCarPropertyManager).registerCallback(any(), eq(HVAC_TEMPERATURE_DISPLAY_UNITS),
- anyFloat());
- }
-
- @Test
- public void addTemperatureViewToController_usingTemperatureView_registersView() {
- TemperatureTextView v = setupMockTemperatureTextView(AREA_ID, TEMP);
- mHvacController.addTemperatureViewToController(v);
-
- verify(v).setTemp(TEMP);
- }
-
- @Test
- public void addTemperatureViewToController_usingSameTemperatureView_registersFirstView() {
- TemperatureTextView v = setupMockTemperatureTextView(AREA_ID, TEMP);
- mHvacController.addTemperatureViewToController(v);
- verify(v).setTemp(TEMP);
- resetTemperatureView(v, AREA_ID);
-
- mHvacController.addTemperatureViewToController(v);
- verify(v, never()).setTemp(TEMP);
- }
-
- @Test
- public void addTemperatureViewToController_usingDifferentTemperatureView_registersBothViews() {
- TemperatureTextView v1 = setupMockTemperatureTextView(AREA_ID, TEMP);
- mHvacController.addTemperatureViewToController(v1);
- verify(v1).setTemp(TEMP);
-
- TemperatureTextView v2 = setupMockTemperatureTextView(
- AREA_ID + 1,
- TEMP + 1);
- mHvacController.addTemperatureViewToController(v2);
- verify(v2).setTemp(TEMP + 1);
- }
-
- @Test
- public void setTemperatureToFahrenheit_callsViewSetDisplayInFahrenheit() {
- when(mCarPropertyManager.isPropertyAvailable(HVAC_TEMPERATURE_DISPLAY_UNITS,
- VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(true);
- when(mCarPropertyManager.getIntProperty(HVAC_TEMPERATURE_DISPLAY_UNITS,
- VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(VehicleUnit.FAHRENHEIT);
- TemperatureTextView v = setupMockTemperatureTextView(AREA_ID, TEMP);
-
- mHvacController.addTemperatureViewToController(v);
-
- verify(v).setDisplayInFahrenheit(true);
- verify(v).setTemp(TEMP);
- }
-
- private TemperatureTextView setupMockTemperatureTextView(int areaId, float value) {
- TemperatureTextView v = mock(TemperatureTextView.class);
- resetTemperatureView(v, areaId);
- when(mCarPropertyManager.isPropertyAvailable(HVAC_TEMPERATURE_SET, areaId)).thenReturn(
- true);
- when(mCarPropertyManager.getFloatProperty(HVAC_TEMPERATURE_SET, areaId)).thenReturn(value);
- return v;
- }
-
- private void resetTemperatureView(TemperatureTextView view, int areaId) {
- reset(view);
- when(view.getAreaId()).thenReturn(areaId);
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/TemperatureTextViewTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/TemperatureTextViewTest.java
deleted file mode 100644
index 3ed8111..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/TemperatureTextViewTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.hvac;
-
-import static android.car.VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;
-import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS;
-import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_SET;
-
-import static com.android.systemui.car.hvac.HvacController.convertToFahrenheit;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.when;
-
-import android.car.Car;
-import android.car.VehicleUnit;
-import android.car.hardware.property.CarPropertyManager;
-import android.content.Context;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarServiceProvider;
-import com.android.systemui.car.CarSystemUiTest;
-import com.android.systemui.util.concurrency.FakeExecutor;
-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.MockitoAnnotations;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class TemperatureTextViewTest extends SysuiTestCase {
- private static final float TEMP = 72.0f;
- private final String mFormat = getContext().getString(R.string.hvac_temperature_format);
- private HvacController mHvacController;
- private TemperatureTextView mTextView;
-
- @Mock
- private Context mContext;
-
- @Mock
- private Car mCar;
- @Mock
- private CarPropertyManager mCarPropertyManager;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- when(mCar.isConnected()).thenReturn(true);
- when(mCar.getCarManager(Car.PROPERTY_SERVICE)).thenReturn(mCarPropertyManager);
-
- CarServiceProvider carServiceProvider = new CarServiceProvider(mContext, mCar);
- mHvacController = new HvacController(carServiceProvider,
- new FakeExecutor(new FakeSystemClock()));
- mHvacController.connectToCarService();
- mTextView = new TemperatureTextView(getContext(), /* attrs= */ null);
- }
-
- @Test
- public void addTemperatureViewToController_usingTemperatureView_registersView() {
- when(mCarPropertyManager.isPropertyAvailable(eq(HVAC_TEMPERATURE_SET),
- anyInt())).thenReturn(true);
- when(mCarPropertyManager.getFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt())).thenReturn(
- TEMP);
-
- mHvacController.addTemperatureViewToController(mTextView);
-
- assertEquals(mTextView.getText(), String.format(mFormat, TEMP));
- }
-
- @Test
- public void setTemperatureToFahrenheit_callsViewSetDisplayInFahrenheit() {
- when(mCarPropertyManager.isPropertyAvailable(eq(HVAC_TEMPERATURE_SET),
- anyInt())).thenReturn(true);
- when(mCarPropertyManager.getFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt())).thenReturn(
- TEMP);
- when(mCarPropertyManager.isPropertyAvailable(HVAC_TEMPERATURE_DISPLAY_UNITS,
- VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(true);
- when(mCarPropertyManager.getIntProperty(HVAC_TEMPERATURE_DISPLAY_UNITS,
- VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(VehicleUnit.FAHRENHEIT);
-
- mHvacController.addTemperatureViewToController(mTextView);
-
- assertEquals(mTextView.getText(), String.format(mFormat, convertToFahrenheit(TEMP)));
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java
deleted file mode 100644
index 062ab41..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.keyguard;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.os.Handler;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.view.LayoutInflater;
-import android.view.ViewGroup;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.ViewMediatorCallback;
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarServiceProvider;
-import com.android.systemui.car.CarSystemUiTest;
-import com.android.systemui.car.navigationbar.CarNavigationBarController;
-import com.android.systemui.car.window.OverlayViewGlobalStateController;
-import com.android.systemui.statusbar.phone.BiometricUnlockController;
-import com.android.systemui.statusbar.phone.KeyguardBouncer;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class CarKeyguardViewControllerTest extends SysuiTestCase {
-
- private CarKeyguardViewController mCarKeyguardViewController;
-
- @Mock
- private OverlayViewGlobalStateController mOverlayViewGlobalStateController;
- @Mock
- private CarKeyguardViewController.OnKeyguardCancelClickedListener mCancelClickedListener;
- @Mock
- private KeyguardBouncer.Factory mKeyguardBouncerFactory;
- @Mock
- private KeyguardBouncer mBouncer;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- when(mKeyguardBouncerFactory.create(
- any(ViewGroup.class),
- any(KeyguardBouncer.BouncerExpansionCallback.class)))
- .thenReturn(mBouncer);
-
- mCarKeyguardViewController = new CarKeyguardViewController(
- Handler.getMain(),
- mock(CarServiceProvider.class),
- mOverlayViewGlobalStateController,
- mock(KeyguardStateController.class),
- mock(KeyguardUpdateMonitor.class),
- () -> mock(BiometricUnlockController.class),
- mock(ViewMediatorCallback.class),
- mock(CarNavigationBarController.class),
- mKeyguardBouncerFactory
- );
- mCarKeyguardViewController.inflate((ViewGroup) LayoutInflater.from(mContext).inflate(
- R.layout.sysui_overlay_window, /* root= */ null));
- }
-
- @Test
- public void onShow_bouncerIsSecure_showsBouncerWithSecuritySelectionReset() {
- when(mBouncer.isSecure()).thenReturn(true);
- mCarKeyguardViewController.show(/* options= */ null);
-
- verify(mBouncer).show(/* resetSecuritySelection= */ true);
- }
-
- @Test
- public void onShow_bouncerIsSecure_keyguardIsVisible() {
- when(mBouncer.isSecure()).thenReturn(true);
- mCarKeyguardViewController.show(/* options= */ null);
-
- verify(mOverlayViewGlobalStateController).showView(eq(mCarKeyguardViewController), any());
- }
-
- @Test
- public void onShow_bouncerNotSecure_hidesBouncerAndDestroysTheView() {
- when(mBouncer.isSecure()).thenReturn(false);
- mCarKeyguardViewController.show(/* options= */ null);
-
- verify(mBouncer).hide(/* destroyView= */ true);
- }
-
- @Test
- public void onShow_bouncerNotSecure_keyguardIsNotVisible() {
- when(mBouncer.isSecure()).thenReturn(false);
- mCarKeyguardViewController.show(/* options= */ null);
-
- // Here we check for both showView and hideView since the current implementation of show
- // with bouncer being not secure has the following method execution orders:
- // 1) show -> start -> showView
- // 2) show -> reset -> dismissAndCollapse -> hide -> stop -> hideView
- // Hence, we want to make sure that showView is called before hideView and not in any
- // other combination.
- InOrder inOrder = inOrder(mOverlayViewGlobalStateController);
- inOrder.verify(mOverlayViewGlobalStateController).showView(eq(mCarKeyguardViewController),
- any());
- inOrder.verify(mOverlayViewGlobalStateController).hideView(eq(mCarKeyguardViewController),
- any());
- }
-
- @Test
- public void onHide_keyguardShowing_hidesBouncerAndDestroysTheView() {
- when(mBouncer.isSecure()).thenReturn(true);
- mCarKeyguardViewController.show(/* options= */ null);
- mCarKeyguardViewController.hide(/* startTime= */ 0, /* fadeoutDelay= */ 0);
-
- verify(mBouncer).hide(/* destroyView= */ true);
- }
-
- @Test
- public void onHide_keyguardNotShown_doesNotHideOrDestroyBouncer() {
- mCarKeyguardViewController.hide(/* startTime= */ 0, /* fadeoutDelay= */ 0);
-
- verify(mBouncer, never()).hide(anyBoolean());
- }
-
- @Test
- public void onHide_KeyguardNotVisible() {
- when(mBouncer.isSecure()).thenReturn(true);
- mCarKeyguardViewController.show(/* options= */ null);
- mCarKeyguardViewController.hide(/* startTime= */ 0, /* fadeoutDelay= */ 0);
-
- InOrder inOrder = inOrder(mOverlayViewGlobalStateController);
- inOrder.verify(mOverlayViewGlobalStateController).showView(eq(mCarKeyguardViewController),
- any());
- inOrder.verify(mOverlayViewGlobalStateController).hideView(eq(mCarKeyguardViewController),
- any());
- }
-
- @Test
- public void setOccludedFalse_currentlyOccluded_bouncerReset() {
- when(mBouncer.isSecure()).thenReturn(true);
- mCarKeyguardViewController.show(/* options= */ null);
- mCarKeyguardViewController.setOccluded(/* occluded= */ true, /* animate= */ false);
- reset(mBouncer);
-
- mCarKeyguardViewController.setOccluded(/* occluded= */ false, /* animate= */ false);
-
- verify(mBouncer).show(/* resetSecuritySelection= */ true);
- }
-
- @Test
- public void onCancelClicked_callsCancelClickedListener() {
- when(mBouncer.isSecure()).thenReturn(true);
- mCarKeyguardViewController.show(/* options= */ null);
- mCarKeyguardViewController.registerOnKeyguardCancelClickedListener(mCancelClickedListener);
- mCarKeyguardViewController.onCancelClicked();
-
- verify(mCancelClickedListener).onCancelClicked();
- }
-
- @Test
- public void onCancelClicked_hidesBouncerAndDestroysTheView() {
- when(mBouncer.isSecure()).thenReturn(true);
- mCarKeyguardViewController.show(/* options= */ null);
- mCarKeyguardViewController.registerOnKeyguardCancelClickedListener(mCancelClickedListener);
- mCarKeyguardViewController.onCancelClicked();
-
- verify(mBouncer).hide(/* destroyView= */ true);
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonRoleHolderControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonRoleHolderControllerTest.java
deleted file mode 100644
index 4b82680..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonRoleHolderControllerTest.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.navigationbar;
-
-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;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.when;
-
-import android.app.role.RoleManager;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
-import android.os.UserHandle;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.view.LayoutInflater;
-import android.widget.LinearLayout;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.car.CarSystemUiTest;
-import com.android.systemui.tests.R;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.List;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class ButtonRoleHolderControllerTest extends SysuiTestCase {
- private static final String TEST_VALID_PACKAGE_NAME = "foo";
- private static final String TEST_INVALID_PACKAGE_NAME = "bar";
- private static final UserHandle TEST_CURRENT_USER = UserHandle.of(100);
- private static final UserHandle TEST_NON_CURRENT_USER = UserHandle.of(101);
-
- private LinearLayout mTestView;
- private CarNavigationButton mNavButtonDefaultAppIconForRoleWithEnabled;
- private CarNavigationButton mNavButtonDefaultAppIconForRoleWithDisabled;
- private ButtonRoleHolderController mControllerUnderTest;
- private Drawable mAppIcon;
-
- @Mock
- private RoleManager mRoleManager;
- @Mock
- private CarDeviceProvisionedController mDeviceProvisionedController;
- @Mock
- private PackageManager mPackageManager;
- @Mock
- private ApplicationInfo mApplicationInfo;
-
- @Before
- public void setUp() throws PackageManager.NameNotFoundException {
- MockitoAnnotations.initMocks(this);
-
- mTestView = (LinearLayout) LayoutInflater.from(mContext).inflate(
- R.layout.button_role_holder_controller_test, /* root= */ null);
- mNavButtonDefaultAppIconForRoleWithEnabled = mTestView
- .findViewById(R.id.assistant_role_button);
- mNavButtonDefaultAppIconForRoleWithDisabled = mTestView
- .findViewById(R.id.assistant_role_disabled_button);
- mAppIcon = mContext.getDrawable(R.drawable.car_ic_apps);
- when(mApplicationInfo.loadIcon(any())).thenReturn(mAppIcon);
- doThrow(new PackageManager.NameNotFoundException()).when(mPackageManager)
- .getApplicationInfo(any(), anyInt());
- doReturn(mApplicationInfo).when(mPackageManager)
- .getApplicationInfo(eq(TEST_VALID_PACKAGE_NAME), anyInt());
- when(mDeviceProvisionedController
- .getCurrentUser())
- .thenReturn(TEST_CURRENT_USER.getIdentifier());
- mControllerUnderTest = new ButtonRoleHolderController(mContext,
- mPackageManager, mRoleManager, mDeviceProvisionedController);
- }
-
- @Test
- public void addAllButtonsWithRoleName_roleAssigned_appIconEnabled_useAssignedAppIcon() {
- when(mRoleManager.getRoleHoldersAsUser(eq(RoleManager.ROLE_ASSISTANT), any()))
- .thenReturn(List.of(TEST_VALID_PACKAGE_NAME));
-
- mControllerUnderTest.addAllButtonsWithRoleName(mTestView);
-
- assertThat(mNavButtonDefaultAppIconForRoleWithEnabled.getAppIcon()).isEqualTo(mAppIcon);
- }
-
- @Test
- public void addAllButtonsWithRoleName_roleUnassigned_appIconEnabled_useDefaultIcon() {
- when(mRoleManager.getRoleHoldersAsUser(eq(RoleManager.ROLE_ASSISTANT), any()))
- .thenReturn(null);
-
- mControllerUnderTest.addAllButtonsWithRoleName(mTestView);
-
- assertThat(mNavButtonDefaultAppIconForRoleWithEnabled.getAppIcon()).isNull();
- }
-
- @Test
- public void onRoleChanged_currentUser_appIconEnabled_useAssignedAppIcon() {
- when(mRoleManager.getRoleHoldersAsUser(eq(RoleManager.ROLE_ASSISTANT), any()))
- .thenReturn(null);
- mControllerUnderTest.addAllButtonsWithRoleName(mTestView);
- when(mRoleManager
- .getRoleHoldersAsUser(eq(RoleManager.ROLE_ASSISTANT), any()))
- .thenReturn(List.of(TEST_VALID_PACKAGE_NAME));
-
- mControllerUnderTest.onRoleChanged(RoleManager.ROLE_ASSISTANT, TEST_CURRENT_USER);
-
- assertThat(mNavButtonDefaultAppIconForRoleWithEnabled.getAppIcon()).isEqualTo(mAppIcon);
- }
-
- @Test
- public void onRoleChanged_nonCurrentUser_appIconEnabled_iconIsNotUpdated() {
- when(mRoleManager
- .getRoleHoldersAsUser(eq(RoleManager.ROLE_ASSISTANT), any()))
- .thenReturn(null);
- mControllerUnderTest.addAllButtonsWithRoleName(mTestView);
- Drawable beforeIcon = mNavButtonDefaultAppIconForRoleWithEnabled.getAppIcon();
- when(mRoleManager
- .getRoleHoldersAsUser(eq(RoleManager.ROLE_ASSISTANT), any()))
- .thenReturn(List.of(TEST_VALID_PACKAGE_NAME));
-
- mControllerUnderTest.onRoleChanged(RoleManager.ROLE_ASSISTANT, TEST_NON_CURRENT_USER);
-
- Drawable afterIcon = mNavButtonDefaultAppIconForRoleWithEnabled.getAppIcon();
- assertThat(afterIcon).isEqualTo(beforeIcon);
- }
-
- @Test
- public void onRoleChanged_invalidPackage_useDefaultIcon() {
- when(mRoleManager
- .getRoleHoldersAsUser(eq(RoleManager.ROLE_ASSISTANT), any()))
- .thenReturn(List.of(TEST_INVALID_PACKAGE_NAME));
-
- mControllerUnderTest.addAllButtonsWithRoleName(mTestView);
-
- assertThat(mNavButtonDefaultAppIconForRoleWithEnabled.getAppIcon()).isNull();
- }
-
- @Test
- public void addAllButtonsWithRoleName_appIconDisabled_useDefaultIcon() {
- when(mRoleManager
- .getRoleHoldersAsUser(eq(RoleManager.ROLE_ASSISTANT), any()))
- .thenReturn(List.of(TEST_VALID_PACKAGE_NAME));
-
- mControllerUnderTest.addAllButtonsWithRoleName(mTestView);
-
- assertThat(mNavButtonDefaultAppIconForRoleWithDisabled.getAppIcon()).isNull();
- }
-
- @Test
- public void onRoleChanged_roleAssigned_appIconDisabled_useDefaultIcon() {
- when(mRoleManager
- .getRoleHoldersAsUser(eq(RoleManager.ROLE_ASSISTANT), any()))
- .thenReturn(null);
- mControllerUnderTest.addAllButtonsWithRoleName(mTestView);
- assertThat(mNavButtonDefaultAppIconForRoleWithDisabled.getAppIcon()).isNull();
- when(mRoleManager
- .getRoleHoldersAsUser(eq(RoleManager.ROLE_ASSISTANT), any()))
- .thenReturn(List.of(TEST_VALID_PACKAGE_NAME));
-
- mControllerUnderTest.onRoleChanged(RoleManager.ROLE_ASSISTANT, TEST_CURRENT_USER);
-
- assertThat(mNavButtonDefaultAppIconForRoleWithDisabled.getAppIcon()).isNull();
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java
deleted file mode 100644
index bd017cd..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.navigationbar;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.ActivityTaskManager.RootTaskInfo;
-import android.content.ComponentName;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.view.LayoutInflater;
-import android.widget.LinearLayout;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarSystemUiTest;
-import com.android.systemui.tests.R;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class ButtonSelectionStateControllerTest extends SysuiTestCase {
-
- private static final String TEST_COMPONENT_NAME_PACKAGE = "com.android.car.carlauncher";
- private static final String TEST_COMPONENT_NAME_CLASS = ".CarLauncher";
- private static final String TEST_CATEGORY = "com.google.android.apps.maps";
- private static final String TEST_CATEGORY_CLASS = ".APP_MAPS";
- private static final String TEST_PACKAGE = "com.android.car.dialer";
- private static final String TEST_PACKAGE_CLASS = ".Dialer";
-
- // LinearLayout with CarNavigationButtons with different configurations.
- private LinearLayout mTestView;
- private ButtonSelectionStateController mButtonSelectionStateController;
- private ComponentName mComponentName;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- mTestView = (LinearLayout) LayoutInflater.from(mContext).inflate(
- R.layout.car_button_selection_state_controller_test, /* root= */ null);
- mButtonSelectionStateController = new ButtonSelectionStateController(mContext);
- mButtonSelectionStateController.addAllButtonsWithSelectionState(mTestView);
- }
-
- @Test
- public void onTaskChanged_buttonDetectableByComponentName_selectsAssociatedButton() {
- CarNavigationButton testButton = mTestView.findViewById(R.id.detectable_by_component_name);
- mComponentName = new ComponentName(TEST_COMPONENT_NAME_PACKAGE, TEST_COMPONENT_NAME_CLASS);
- List<RootTaskInfo> testStack = createTestStack(mComponentName);
- testButton.setSelected(false);
- mButtonSelectionStateController.taskChanged(testStack, /* validDisplay= */ -1);
-
- assertbuttonSelected(testButton);
- }
-
- @Test
- public void onTaskChanged_buttonDetectableByCategory_selectsAssociatedButton() {
- CarNavigationButton testButton = mTestView.findViewById(R.id.detectable_by_category);
- mComponentName = new ComponentName(TEST_CATEGORY, TEST_CATEGORY_CLASS);
- List<RootTaskInfo> testStack = createTestStack(mComponentName);
- testButton.setSelected(false);
- mButtonSelectionStateController.taskChanged(testStack, /* validDisplay= */ -1);
-
- assertbuttonSelected(testButton);
- }
-
- @Test
- public void onTaskChanged_buttonDetectableByPackage_selectsAssociatedButton() {
- CarNavigationButton testButton = mTestView.findViewById(R.id.detectable_by_package);
- mComponentName = new ComponentName(TEST_PACKAGE, TEST_PACKAGE_CLASS);
- List<RootTaskInfo> testStack = createTestStack(mComponentName);
- testButton.setSelected(false);
- mButtonSelectionStateController.taskChanged(testStack, /* validDisplay= */ -1);
-
- assertbuttonSelected(testButton);
- }
-
- @Test
- public void onTaskChanged_deselectsPreviouslySelectedButton() {
- CarNavigationButton oldButton = mTestView.findViewById(R.id.detectable_by_component_name);
- mComponentName = new ComponentName(TEST_COMPONENT_NAME_PACKAGE, TEST_COMPONENT_NAME_CLASS);
- List<RootTaskInfo> oldStack = createTestStack(mComponentName);
- oldButton.setSelected(false);
- mButtonSelectionStateController.taskChanged(oldStack, /* validDisplay= */ -1);
-
- mComponentName = new ComponentName(TEST_PACKAGE, TEST_PACKAGE_CLASS);
- List<RootTaskInfo> newStack = createTestStack(mComponentName);
- mButtonSelectionStateController.taskChanged(newStack, /* validDisplay= */ -1);
-
- assertButtonUnselected(oldButton);
- }
-
- // Comparing alpha is a valid way to verify button selection state because all test buttons use
- // highlightWhenSelected = true.
- private void assertbuttonSelected(CarNavigationButton button) {
- assertThat(button.getAlpha()).isEqualTo(CarNavigationButton.DEFAULT_SELECTED_ALPHA);
- }
-
- private void assertButtonUnselected(CarNavigationButton button) {
- assertThat(button.getAlpha()).isEqualTo(CarNavigationButton.DEFAULT_UNSELECTED_ALPHA);
- }
-
- private List<RootTaskInfo> createTestStack(ComponentName componentName) {
- RootTaskInfo validStackInfo = new RootTaskInfo();
- validStackInfo.displayId = -1; // No display is assigned to this test view
- validStackInfo.topActivity = componentName;
-
- List<RootTaskInfo> testStack = new ArrayList<>();
- testStack.add(validStackInfo);
-
- return testStack;
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java
deleted file mode 100644
index 5b0bb35..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java
+++ /dev/null
@@ -1,479 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.navigationbar;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.testing.TestableResources;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarSystemUiTest;
-import com.android.systemui.car.hvac.HvacController;
-import com.android.systemui.car.statusbar.UserNameViewController;
-import com.android.systemui.plugins.DarkIconDispatcher;
-import com.android.systemui.statusbar.phone.StatusBarIconController;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class CarNavigationBarControllerTest extends SysuiTestCase {
-
- private static final String TOP_NOTIFICATION_PANEL =
- "com.android.systemui.car.notification.TopNotificationPanelViewMediator";
- private static final String BOTTOM_NOTIFICATION_PANEL =
- "com.android.systemui.car.notification.BottomNotificationPanelViewMediator";
- private CarNavigationBarController mCarNavigationBar;
- private NavigationBarViewFactory mNavigationBarViewFactory;
- private TestableResources mTestableResources;
-
- @Mock
- private ButtonSelectionStateController mButtonSelectionStateController;
- @Mock
- private ButtonRoleHolderController mButtonRoleHolderController;
- @Mock
- private HvacController mHvacController;
- @Mock
- private UserNameViewController mUserNameViewController;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- mNavigationBarViewFactory = new NavigationBarViewFactory(mContext);
- mTestableResources = mContext.getOrCreateTestableResources();
-
- // Needed to inflate top navigation bar.
- mDependency.injectMockDependency(DarkIconDispatcher.class);
- mDependency.injectMockDependency(StatusBarIconController.class);
- }
-
- private CarNavigationBarController createNavigationBarController() {
- return new CarNavigationBarController(mContext, mNavigationBarViewFactory,
- mButtonSelectionStateController, () -> mHvacController,
- () -> mUserNameViewController, mButtonRoleHolderController,
- new SystemBarConfigs(mTestableResources.getResources()));
- }
-
- @Test
- public void testConnectToHvac_callsConnect() {
- mCarNavigationBar = createNavigationBarController();
-
- mCarNavigationBar.connectToHvac();
-
- verify(mHvacController).connectToCarService();
- }
-
- @Test
- public void testRemoveAll_callsHvacControllerRemoveAllComponents() {
- mCarNavigationBar = createNavigationBarController();
-
- mCarNavigationBar.removeAll();
-
- verify(mHvacController).removeAllComponents();
- }
-
-
- @Test
- public void testRemoveAll_callsButtonRoleHolderControllerRemoveAll() {
- mCarNavigationBar = createNavigationBarController();
-
- mCarNavigationBar.removeAll();
-
- verify(mButtonRoleHolderController).removeAll();
- }
-
- @Test
- public void testRemoveAll_callsButtonSelectionStateControllerRemoveAll() {
- mCarNavigationBar = createNavigationBarController();
-
- mCarNavigationBar.removeAll();
-
- verify(mButtonSelectionStateController).removeAll();
- }
-
- @Test
- public void testGetTopWindow_topDisabled_returnsNull() {
- mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, false);
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- // If Top Notification Panel is used but top navigation bar is not enabled, SystemUI is
- // expected to crash.
- mTestableResources.addOverride(R.string.config_notificationPanelViewMediator,
- BOTTOM_NOTIFICATION_PANEL);
- mCarNavigationBar = createNavigationBarController();
-
- ViewGroup window = mCarNavigationBar.getTopWindow();
-
- assertThat(window).isNull();
- }
-
- @Test
- public void testGetTopWindow_topEnabled_returnsWindow() {
- mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- ViewGroup window = mCarNavigationBar.getTopWindow();
-
- assertThat(window).isNotNull();
- }
-
- @Test
- public void testGetTopWindow_topEnabled_calledTwice_returnsSameWindow() {
- mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- ViewGroup window1 = mCarNavigationBar.getTopWindow();
- ViewGroup window2 = mCarNavigationBar.getTopWindow();
-
- assertThat(window1).isEqualTo(window2);
- }
-
- @Test
- public void testGetBottomWindow_bottomDisabled_returnsNull() {
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, false);
- mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
- // If Bottom Notification Panel is used but bottom navigation bar is not enabled,
- // SystemUI is expected to crash.
- mTestableResources.addOverride(R.string.config_notificationPanelViewMediator,
- TOP_NOTIFICATION_PANEL);
- mCarNavigationBar = createNavigationBarController();
-
- ViewGroup window = mCarNavigationBar.getBottomWindow();
-
- assertThat(window).isNull();
- }
-
- @Test
- public void testGetBottomWindow_bottomEnabled_returnsWindow() {
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- ViewGroup window = mCarNavigationBar.getBottomWindow();
-
- assertThat(window).isNotNull();
- }
-
- @Test
- public void testGetBottomWindow_bottomEnabled_calledTwice_returnsSameWindow() {
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- ViewGroup window1 = mCarNavigationBar.getBottomWindow();
- ViewGroup window2 = mCarNavigationBar.getBottomWindow();
-
- assertThat(window1).isEqualTo(window2);
- }
-
- @Test
- public void testGetLeftWindow_leftDisabled_returnsNull() {
- mTestableResources.addOverride(R.bool.config_enableLeftNavigationBar, false);
- mCarNavigationBar = createNavigationBarController();
- ViewGroup window = mCarNavigationBar.getLeftWindow();
- assertThat(window).isNull();
- }
-
- @Test
- public void testGetLeftWindow_leftEnabled_returnsWindow() {
- mTestableResources.addOverride(R.bool.config_enableLeftNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- ViewGroup window = mCarNavigationBar.getLeftWindow();
-
- assertThat(window).isNotNull();
- }
-
- @Test
- public void testGetLeftWindow_leftEnabled_calledTwice_returnsSameWindow() {
- mTestableResources.addOverride(R.bool.config_enableLeftNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- ViewGroup window1 = mCarNavigationBar.getLeftWindow();
- ViewGroup window2 = mCarNavigationBar.getLeftWindow();
-
- assertThat(window1).isEqualTo(window2);
- }
-
- @Test
- public void testGetRightWindow_rightDisabled_returnsNull() {
- mTestableResources.addOverride(R.bool.config_enableRightNavigationBar, false);
- mCarNavigationBar = createNavigationBarController();
-
- ViewGroup window = mCarNavigationBar.getRightWindow();
-
- assertThat(window).isNull();
- }
-
- @Test
- public void testGetRightWindow_rightEnabled_returnsWindow() {
- mTestableResources.addOverride(R.bool.config_enableRightNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- ViewGroup window = mCarNavigationBar.getRightWindow();
-
- assertThat(window).isNotNull();
- }
-
- @Test
- public void testGetRightWindow_rightEnabled_calledTwice_returnsSameWindow() {
- mTestableResources.addOverride(R.bool.config_enableRightNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- ViewGroup window1 = mCarNavigationBar.getRightWindow();
- ViewGroup window2 = mCarNavigationBar.getRightWindow();
-
- assertThat(window1).isEqualTo(window2);
- }
-
- @Test
- public void testSetTopWindowVisibility_setTrue_isVisible() {
- mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- ViewGroup window = mCarNavigationBar.getTopWindow();
- mCarNavigationBar.setTopWindowVisibility(View.VISIBLE);
-
- assertThat(window.getVisibility()).isEqualTo(View.VISIBLE);
- }
-
- @Test
- public void testSetTopWindowVisibility_setFalse_isGone() {
- mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- ViewGroup window = mCarNavigationBar.getTopWindow();
- mCarNavigationBar.setTopWindowVisibility(View.GONE);
-
- assertThat(window.getVisibility()).isEqualTo(View.GONE);
- }
-
- @Test
- public void testSetBottomWindowVisibility_setTrue_isVisible() {
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- ViewGroup window = mCarNavigationBar.getBottomWindow();
- mCarNavigationBar.setBottomWindowVisibility(View.VISIBLE);
-
- assertThat(window.getVisibility()).isEqualTo(View.VISIBLE);
- }
-
- @Test
- public void testSetBottomWindowVisibility_setFalse_isGone() {
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- ViewGroup window = mCarNavigationBar.getBottomWindow();
- mCarNavigationBar.setBottomWindowVisibility(View.GONE);
-
- assertThat(window.getVisibility()).isEqualTo(View.GONE);
- }
-
- @Test
- public void testSetLeftWindowVisibility_setTrue_isVisible() {
- mTestableResources.addOverride(R.bool.config_enableLeftNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- ViewGroup window = mCarNavigationBar.getLeftWindow();
- mCarNavigationBar.setLeftWindowVisibility(View.VISIBLE);
-
- assertThat(window.getVisibility()).isEqualTo(View.VISIBLE);
- }
-
- @Test
- public void testSetLeftWindowVisibility_setFalse_isGone() {
- mTestableResources.addOverride(R.bool.config_enableLeftNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- ViewGroup window = mCarNavigationBar.getLeftWindow();
- mCarNavigationBar.setLeftWindowVisibility(View.GONE);
-
- assertThat(window.getVisibility()).isEqualTo(View.GONE);
- }
-
- @Test
- public void testSetRightWindowVisibility_setTrue_isVisible() {
- mTestableResources.addOverride(R.bool.config_enableRightNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- ViewGroup window = mCarNavigationBar.getRightWindow();
- mCarNavigationBar.setRightWindowVisibility(View.VISIBLE);
-
- assertThat(window.getVisibility()).isEqualTo(View.VISIBLE);
- }
-
- @Test
- public void testSetRightWindowVisibility_setFalse_isGone() {
- mTestableResources.addOverride(R.bool.config_enableRightNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- ViewGroup window = mCarNavigationBar.getRightWindow();
- mCarNavigationBar.setRightWindowVisibility(View.GONE);
-
- assertThat(window.getVisibility()).isEqualTo(View.GONE);
- }
-
- @Test
- public void testRegisterBottomBarTouchListener_createViewFirst_registrationSuccessful() {
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- CarNavigationBarView bottomBar = mCarNavigationBar.getBottomBar(/* isSetUp= */ true);
- View.OnTouchListener controller = bottomBar.getStatusBarWindowTouchListener();
- assertThat(controller).isNull();
- mCarNavigationBar.registerBottomBarTouchListener(mock(View.OnTouchListener.class));
- controller = bottomBar.getStatusBarWindowTouchListener();
-
- assertThat(controller).isNotNull();
- }
-
- @Test
- public void testRegisterBottomBarTouchListener_registerFirst_registrationSuccessful() {
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- mCarNavigationBar.registerBottomBarTouchListener(mock(View.OnTouchListener.class));
- CarNavigationBarView bottomBar = mCarNavigationBar.getBottomBar(/* isSetUp= */ true);
- View.OnTouchListener controller = bottomBar.getStatusBarWindowTouchListener();
-
- assertThat(controller).isNotNull();
- }
-
- @Test
- public void testRegisterNotificationController_createViewFirst_registrationSuccessful() {
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- CarNavigationBarView bottomBar = mCarNavigationBar.getBottomBar(/* isSetUp= */ true);
- CarNavigationBarController.NotificationsShadeController controller =
- bottomBar.getNotificationsPanelController();
- assertThat(controller).isNull();
- mCarNavigationBar.registerNotificationController(
- mock(CarNavigationBarController.NotificationsShadeController.class));
- controller = bottomBar.getNotificationsPanelController();
-
- assertThat(controller).isNotNull();
- }
-
- @Test
- public void testRegisterNotificationController_registerFirst_registrationSuccessful() {
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
-
- mCarNavigationBar.registerNotificationController(
- mock(CarNavigationBarController.NotificationsShadeController.class));
- CarNavigationBarView bottomBar = mCarNavigationBar.getBottomBar(/* isSetUp= */ true);
- CarNavigationBarController.NotificationsShadeController controller =
- bottomBar.getNotificationsPanelController();
-
- assertThat(controller).isNotNull();
- }
-
- @Test
- public void testShowAllKeyguardButtons_bottomEnabled_bottomKeyguardButtonsVisible() {
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
- CarNavigationBarView bottomBar = mCarNavigationBar.getBottomBar(/* isSetUp= */ true);
- View bottomKeyguardButtons = bottomBar.findViewById(R.id.lock_screen_nav_buttons);
-
- mCarNavigationBar.showAllKeyguardButtons(/* isSetUp= */ true);
-
- assertThat(bottomKeyguardButtons.getVisibility()).isEqualTo(View.VISIBLE);
- }
-
- @Test
- public void testShowAllKeyguardButtons_bottomEnabled_bottomNavButtonsGone() {
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
- CarNavigationBarView bottomBar = mCarNavigationBar.getBottomBar(/* isSetUp= */ true);
- View bottomButtons = bottomBar.findViewById(R.id.nav_buttons);
-
- mCarNavigationBar.showAllKeyguardButtons(/* isSetUp= */ true);
-
- assertThat(bottomButtons.getVisibility()).isEqualTo(View.GONE);
- }
-
- @Test
- public void testHideAllKeyguardButtons_bottomEnabled_bottomKeyguardButtonsGone() {
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
- CarNavigationBarView bottomBar = mCarNavigationBar.getBottomBar(/* isSetUp= */ true);
- View bottomKeyguardButtons = bottomBar.findViewById(R.id.lock_screen_nav_buttons);
-
- mCarNavigationBar.showAllKeyguardButtons(/* isSetUp= */ true);
- assertThat(bottomKeyguardButtons.getVisibility()).isEqualTo(View.VISIBLE);
- mCarNavigationBar.hideAllKeyguardButtons(/* isSetUp= */ true);
-
- assertThat(bottomKeyguardButtons.getVisibility()).isEqualTo(View.GONE);
- }
-
- @Test
- public void testHideAllKeyguardButtons_bottomEnabled_bottomNavButtonsVisible() {
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
- CarNavigationBarView bottomBar = mCarNavigationBar.getBottomBar(/* isSetUp= */ true);
- View bottomButtons = bottomBar.findViewById(R.id.nav_buttons);
-
- mCarNavigationBar.showAllKeyguardButtons(/* isSetUp= */ true);
- assertThat(bottomButtons.getVisibility()).isEqualTo(View.GONE);
- mCarNavigationBar.hideAllKeyguardButtons(/* isSetUp= */ true);
-
- assertThat(bottomButtons.getVisibility()).isEqualTo(View.VISIBLE);
- }
-
- @Test
- public void testToggleAllNotificationsUnseenIndicator_bottomEnabled_hasUnseen_setCorrectly() {
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
- CarNavigationBarView bottomBar = mCarNavigationBar.getBottomBar(/* isSetUp= */ true);
- CarNavigationButton notifications = bottomBar.findViewById(R.id.notifications);
-
- boolean hasUnseen = true;
- mCarNavigationBar.toggleAllNotificationsUnseenIndicator(/* isSetUp= */ true,
- hasUnseen);
-
- assertThat(notifications.getUnseen()).isTrue();
- }
-
- @Test
- public void testToggleAllNotificationsUnseenIndicator_bottomEnabled_noUnseen_setCorrectly() {
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- mCarNavigationBar = createNavigationBarController();
- CarNavigationBarView bottomBar = mCarNavigationBar.getBottomBar(/* isSetUp= */ true);
- CarNavigationButton notifications = bottomBar.findViewById(R.id.notifications);
-
- boolean hasUnseen = false;
- mCarNavigationBar.toggleAllNotificationsUnseenIndicator(/* isSetUp= */ true,
- hasUnseen);
-
- assertThat(notifications.getUnseen()).isFalse();
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java
deleted file mode 100644
index 2b5af71..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.navigationbar;
-
-import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.ITYPE_STATUS_BAR;
-import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
-import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_STATUS_BARS;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.graphics.Rect;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.testing.TestableResources;
-import android.util.ArrayMap;
-import android.view.Display;
-import android.view.WindowManager;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.statusbar.RegisterStatusBarResult;
-import com.android.internal.view.AppearanceRegion;
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.car.CarSystemUiTest;
-import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.phone.AutoHideController;
-import com.android.systemui.statusbar.phone.LightBarController;
-import com.android.systemui.statusbar.phone.LightBarTransitionsController;
-import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy;
-import com.android.systemui.statusbar.phone.StatusBarIconController;
-import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.time.FakeSystemClock;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class CarNavigationBarTest extends SysuiTestCase {
-
- private CarNavigationBar mCarNavigationBar;
- private TestableResources mTestableResources;
- private Handler mHandler;
-
- @Mock
- private CarNavigationBarController mCarNavigationBarController;
- @Mock
- private LightBarController mLightBarController;
- @Mock
- private SysuiDarkIconDispatcher mStatusBarIconController;
- @Mock
- private LightBarTransitionsController mLightBarTransitionsController;
- @Mock
- private WindowManager mWindowManager;
- @Mock
- private CarDeviceProvisionedController mDeviceProvisionedController;
- @Mock
- private AutoHideController mAutoHideController;
- @Mock
- private ButtonSelectionStateListener mButtonSelectionStateListener;
- @Mock
- private ButtonRoleHolderController mButtonRoleHolderController;
- @Mock
- private IStatusBarService mBarService;
- @Mock
- private KeyguardStateController mKeyguardStateController;
- @Mock
- private ButtonSelectionStateController mButtonSelectionStateController;
- @Mock
- private PhoneStatusBarPolicy mIconPolicy;
- @Mock
- private StatusBarIconController mIconController;
-
- private RegisterStatusBarResult mBarResult;
- private AppearanceRegion[] mAppearanceRegions;
- private FakeExecutor mUiBgExecutor;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mTestableResources = mContext.getOrCreateTestableResources();
- mHandler = Handler.getMain();
- mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
- when(mStatusBarIconController.getTransitionsController()).thenReturn(
- mLightBarTransitionsController);
- mAppearanceRegions = new AppearanceRegion[] {
- new AppearanceRegion(APPEARANCE_LIGHT_STATUS_BARS, new Rect())
- };
- mBarResult = new RegisterStatusBarResult(
- /* icons= */ new ArrayMap<>(),
- /* disabledFlags1= */ 0,
- /* appearance= */ 0,
- mAppearanceRegions,
- /* imeWindowVis= */ 0,
- /* imeBackDisposition= */ 0,
- /* showImeSwitcher= */ false,
- /* disabledFlags2= */ 0,
- /* imeToken= */ null,
- /* navbarColorMangedByIme= */ false,
- /* appFullscreen= */ false,
- /* appImmersive= */ false,
- /* transientBarTypes= */ new int[]{});
- try {
- when(mBarService.registerStatusBar(any())).thenReturn(mBarResult);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- mCarNavigationBar = new CarNavigationBar(mContext, mTestableResources.getResources(),
- mCarNavigationBarController, mLightBarController, mStatusBarIconController,
- mWindowManager, mDeviceProvisionedController, new CommandQueue(mContext),
- mAutoHideController, mButtonSelectionStateListener, mHandler, mUiBgExecutor,
- mBarService, () -> mKeyguardStateController, () -> mIconPolicy,
- () -> mIconController, new SystemBarConfigs(mTestableResources.getResources()));
- }
-
- @Test
- public void restartNavbars_refreshesTaskChanged() {
- mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- ArgumentCaptor<CarDeviceProvisionedController.DeviceProvisionedListener>
- deviceProvisionedCallbackCaptor = ArgumentCaptor.forClass(
- CarDeviceProvisionedController.DeviceProvisionedListener.class);
- when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
- mCarNavigationBar.start();
- // switching the currentUserSetup value to force restart the navbars.
- when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(false);
- verify(mDeviceProvisionedController).addCallback(deviceProvisionedCallbackCaptor.capture());
-
- deviceProvisionedCallbackCaptor.getValue().onUserSwitched();
- waitForIdleSync(mHandler);
-
- verify(mButtonSelectionStateListener).onTaskStackChanged();
- }
-
- @Test
- public void restartNavBars_newUserNotSetupWithKeyguardShowing_showsKeyguardButtons() {
- mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- ArgumentCaptor<CarDeviceProvisionedController.DeviceProvisionedListener>
- deviceProvisionedCallbackCaptor = ArgumentCaptor.forClass(
- CarDeviceProvisionedController.DeviceProvisionedListener.class);
- when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
- mCarNavigationBar.start();
- when(mKeyguardStateController.isShowing()).thenReturn(true);
- // switching the currentUserSetup value to force restart the navbars.
- when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(false);
- verify(mDeviceProvisionedController).addCallback(deviceProvisionedCallbackCaptor.capture());
-
- deviceProvisionedCallbackCaptor.getValue().onUserSwitched();
- waitForIdleSync(mHandler);
-
- verify(mCarNavigationBarController).showAllKeyguardButtons(false);
- }
-
- @Test
- public void restartNavbars_newUserIsSetupWithKeyguardHidden_hidesKeyguardButtons() {
- mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- ArgumentCaptor<CarDeviceProvisionedController.DeviceProvisionedListener>
- deviceProvisionedCallbackCaptor = ArgumentCaptor.forClass(
- CarDeviceProvisionedController.DeviceProvisionedListener.class);
- when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
- mCarNavigationBar.start();
- when(mKeyguardStateController.isShowing()).thenReturn(true);
- // switching the currentUserSetup value to force restart the navbars.
- when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(false);
- verify(mDeviceProvisionedController).addCallback(deviceProvisionedCallbackCaptor.capture());
- deviceProvisionedCallbackCaptor.getValue().onUserSwitched();
- waitForIdleSync(mHandler);
- when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
- when(mKeyguardStateController.isShowing()).thenReturn(false);
-
- deviceProvisionedCallbackCaptor.getValue().onUserSetupChanged();
- waitForIdleSync(mHandler);
-
- verify(mCarNavigationBarController).hideAllKeyguardButtons(true);
- }
-
- @Test
- public void restartNavBars_lightAppearance_darkensAllIcons() {
- mAppearanceRegions[0] = new AppearanceRegion(APPEARANCE_LIGHT_STATUS_BARS, new Rect());
-
- mCarNavigationBar.start();
-
- verify(mLightBarTransitionsController).setIconsDark(
- /* dark= */ true, /* animate= */ false);
- }
-
- @Test
- public void restartNavBars_opaqueAppearance_lightensAllIcons() {
- mAppearanceRegions[0] = new AppearanceRegion(APPEARANCE_OPAQUE_STATUS_BARS, new Rect());
-
- mCarNavigationBar.start();
-
- verify(mLightBarTransitionsController).setIconsDark(
- /* dark= */ false, /* animate= */ false);
- }
-
- @Test
- public void showTransient_wrongDisplayId_transientModeNotUpdated() {
- mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
- mCarNavigationBar.start();
-
- int randomDisplay = Display.DEFAULT_DISPLAY + 10;
- int[] insetTypes = new int[]{};
- mCarNavigationBar.showTransient(randomDisplay, insetTypes);
-
- assertThat(mCarNavigationBar.isStatusBarTransientShown()).isFalse();
- }
-
- @Test
- public void showTransient_correctDisplayId_noStatusBarInset_transientModeNotUpdated() {
- mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
- mCarNavigationBar.start();
-
- int[] insetTypes = new int[]{};
- mCarNavigationBar.showTransient(Display.DEFAULT_DISPLAY, insetTypes);
-
- assertThat(mCarNavigationBar.isStatusBarTransientShown()).isFalse();
- }
-
- @Test
- public void showTransient_correctDisplayId_statusBarInset_transientModeUpdated() {
- mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
- mCarNavigationBar.start();
-
- int[] insetTypes = new int[]{ITYPE_STATUS_BAR};
- mCarNavigationBar.showTransient(Display.DEFAULT_DISPLAY, insetTypes);
-
- assertThat(mCarNavigationBar.isStatusBarTransientShown()).isTrue();
- }
-
- @Test
- public void showTransient_correctDisplayId_noNavBarInset_transientModeNotUpdated() {
- mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
- mCarNavigationBar.start();
-
- int[] insetTypes = new int[]{};
- mCarNavigationBar.showTransient(Display.DEFAULT_DISPLAY, insetTypes);
-
- assertThat(mCarNavigationBar.isNavBarTransientShown()).isFalse();
- }
-
- @Test
- public void showTransient_correctDisplayId_navBarInset_transientModeUpdated() {
- mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
- mCarNavigationBar.start();
-
- int[] insetTypes = new int[]{ITYPE_NAVIGATION_BAR};
- mCarNavigationBar.showTransient(Display.DEFAULT_DISPLAY, insetTypes);
-
- assertThat(mCarNavigationBar.isNavBarTransientShown()).isTrue();
- }
-
- @Test
- public void abortTransient_wrongDisplayId_transientModeNotCleared() {
- mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
- mCarNavigationBar.start();
- mCarNavigationBar.showTransient(Display.DEFAULT_DISPLAY,
- new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR});
- assertThat(mCarNavigationBar.isStatusBarTransientShown()).isTrue();
- assertThat(mCarNavigationBar.isNavBarTransientShown()).isTrue();
-
- int[] insetTypes = new int[]{};
- int randomDisplay = Display.DEFAULT_DISPLAY + 10;
- mCarNavigationBar.abortTransient(randomDisplay, insetTypes);
-
- // The transient booleans were not cleared.
- assertThat(mCarNavigationBar.isStatusBarTransientShown()).isTrue();
- assertThat(mCarNavigationBar.isNavBarTransientShown()).isTrue();
- }
-
- @Test
- public void abortTransient_correctDisplayId_noInsets_transientModeNotCleared() {
- mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
- mCarNavigationBar.start();
- mCarNavigationBar.showTransient(Display.DEFAULT_DISPLAY,
- new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR});
- assertThat(mCarNavigationBar.isStatusBarTransientShown()).isTrue();
- assertThat(mCarNavigationBar.isNavBarTransientShown()).isTrue();
-
- int[] insetTypes = new int[]{};
- mCarNavigationBar.abortTransient(Display.DEFAULT_DISPLAY, insetTypes);
-
- // The transient booleans were not cleared.
- assertThat(mCarNavigationBar.isStatusBarTransientShown()).isTrue();
- assertThat(mCarNavigationBar.isNavBarTransientShown()).isTrue();
- }
-
- @Test
- public void abortTransient_correctDisplayId_statusBarInset_transientModeCleared() {
- mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
- mCarNavigationBar.start();
- mCarNavigationBar.showTransient(Display.DEFAULT_DISPLAY,
- new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR});
- assertThat(mCarNavigationBar.isStatusBarTransientShown()).isTrue();
- assertThat(mCarNavigationBar.isNavBarTransientShown()).isTrue();
-
- int[] insetTypes = new int[]{ITYPE_STATUS_BAR};
- mCarNavigationBar.abortTransient(Display.DEFAULT_DISPLAY, insetTypes);
-
- // The transient booleans were cleared.
- assertThat(mCarNavigationBar.isStatusBarTransientShown()).isFalse();
- assertThat(mCarNavigationBar.isNavBarTransientShown()).isFalse();
- }
-
- @Test
- public void abortTransient_correctDisplayId_navBarInset_transientModeCleared() {
- mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
- mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
- when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
- mCarNavigationBar.start();
- mCarNavigationBar.showTransient(Display.DEFAULT_DISPLAY,
- new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR});
- assertThat(mCarNavigationBar.isStatusBarTransientShown()).isTrue();
- assertThat(mCarNavigationBar.isNavBarTransientShown()).isTrue();
-
- int[] insetTypes = new int[]{ITYPE_NAVIGATION_BAR};
- mCarNavigationBar.abortTransient(Display.DEFAULT_DISPLAY, insetTypes);
-
- // The transient booleans were cleared.
- assertThat(mCarNavigationBar.isStatusBarTransientShown()).isFalse();
- assertThat(mCarNavigationBar.isNavBarTransientShown()).isFalse();
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarViewTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarViewTest.java
deleted file mode 100644
index 47fd820..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarViewTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.navigationbar;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarSystemUiTest;
-
-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;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class CarNavigationBarViewTest extends SysuiTestCase {
-
- private CarNavigationBarView mNavBarView;
-
- @Mock
- private CarNavigationBarController.NotificationsShadeController mNotificationsShadeController;
-
- @Mock
- private View.OnTouchListener mNavBarTouchListener;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- }
-
- @After
- public void tearDown() {
- getContext().getOrCreateTestableResources().addOverride(
- R.bool.config_consumeNavigationBarTouchWhenNotificationPanelOpen, false);
- }
-
- @Test
- public void dispatchTouch_shadeOpen_flagOff_doesNotConsumeTouch() {
- getContext().getOrCreateTestableResources().addOverride(
- R.bool.config_consumeNavigationBarTouchWhenNotificationPanelOpen, false);
- when(mNotificationsShadeController.isNotificationPanelOpen()).thenReturn(true);
- mNavBarView = (CarNavigationBarView) LayoutInflater.from(getContext()).inflate(
- R.layout.car_navigation_bar_view_test, /* root= */ null);
- mNavBarView.setNotificationsPanelController(mNotificationsShadeController);
- mNavBarView.setStatusBarWindowTouchListener(mNavBarTouchListener);
-
- boolean consume = mNavBarView.onInterceptTouchEvent(
- MotionEvent.obtain(/* downTime= */ 200, /* eventTime= */ 300,
- MotionEvent.ACTION_MOVE, mNavBarView.getX(),
- mNavBarView.getY(), /* metaState= */ 0));
-
- assertThat(consume).isFalse();
- }
-
- @Test
- public void dispatchTouch_shadeOpen_flagOn_consumesTouch() {
- getContext().getOrCreateTestableResources().addOverride(
- R.bool.config_consumeNavigationBarTouchWhenNotificationPanelOpen, true);
- when(mNotificationsShadeController.isNotificationPanelOpen()).thenReturn(true);
- mNavBarView = (CarNavigationBarView) LayoutInflater.from(getContext()).inflate(
- R.layout.car_navigation_bar_view_test, /* root= */ null);
- mNavBarView.setNotificationsPanelController(mNotificationsShadeController);
- mNavBarView.setStatusBarWindowTouchListener(mNavBarTouchListener);
-
- boolean consume = mNavBarView.onInterceptTouchEvent(
- MotionEvent.obtain(/* downTime= */ 200, /* eventTime= */ 300,
- MotionEvent.ACTION_MOVE, mNavBarView.getX(),
- mNavBarView.getY(), /* metaState= */ 0));
-
- assertThat(consume).isTrue();
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationButtonTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationButtonTest.java
deleted file mode 100644
index 173f548..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationButtonTest.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.navigationbar;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarSystemUiTest;
-import com.android.systemui.statusbar.AlphaOptimizedImageView;
-import com.android.systemui.tests.R;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatcher;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class CarNavigationButtonTest extends SysuiTestCase {
-
- private static final String DEFAULT_BUTTON_ACTIVITY_NAME =
- "com.android.car.carlauncher/.CarLauncher";
- private static final String APP_GRID_BUTTON_ACTIVITY_NAME =
- "com.android.car.carlauncher/.AppGridActivity";
- private static final String BROADCAST_ACTION_NAME =
- "android.car.intent.action.TOGGLE_HVAC_CONTROLS";
-
- private ActivityManager mActivityManager;
- // LinearLayout with CarNavigationButtons with different configurations.
- private LinearLayout mTestView;
- // Does not have any selection state which is the default configuration.
- private CarNavigationButton mDefaultButton;
-
- @Before
- public void setUp() {
- mContext = spy(mContext);
- mTestView = (LinearLayout) LayoutInflater.from(mContext).inflate(
- R.layout.car_navigation_button_test, /* root= */ null);
- mDefaultButton = mTestView.findViewById(R.id.default_no_selection_state);
- mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
- }
-
- @Test
- public void onCreate_iconIsVisible() {
- AlphaOptimizedImageView icon = mDefaultButton.findViewById(
- R.id.car_nav_button_icon_image);
-
- assertThat(icon.getDrawable()).isNotNull();
- }
-
- @Test
- public void onSelected_selectedIconDefined_togglesIcon() {
- mDefaultButton.setSelected(true);
- Drawable selectedIconDrawable = ((AlphaOptimizedImageView) mDefaultButton.findViewById(
- R.id.car_nav_button_icon_image)).getDrawable();
-
-
- mDefaultButton.setSelected(false);
- Drawable unselectedIconDrawable = ((AlphaOptimizedImageView) mDefaultButton.findViewById(
- R.id.car_nav_button_icon_image)).getDrawable();
-
- assertThat(selectedIconDrawable).isNotEqualTo(unselectedIconDrawable);
- }
-
- @Test
- public void onSelected_selectedIconUndefined_displaysSameIcon() {
- CarNavigationButton selectedIconUndefinedButton = mTestView.findViewById(
- R.id.selected_icon_undefined);
-
- selectedIconUndefinedButton.setSelected(true);
- Drawable selectedIconDrawable = ((AlphaOptimizedImageView) mDefaultButton.findViewById(
- R.id.car_nav_button_icon_image)).getDrawable();
-
-
- selectedIconUndefinedButton.setSelected(false);
- Drawable unselectedIconDrawable = ((AlphaOptimizedImageView) mDefaultButton.findViewById(
- R.id.car_nav_button_icon_image)).getDrawable();
-
- assertThat(selectedIconDrawable).isEqualTo(unselectedIconDrawable);
- }
-
- @Test
- public void onUnselected_doesNotHighlightWhenSelected_applySelectedAlpha() {
- mDefaultButton.setSelected(false);
-
- assertThat(mDefaultButton.getAlpha()).isEqualTo(
- CarNavigationButton.DEFAULT_SELECTED_ALPHA);
- }
-
- @Test
- public void onSelected_doesNotHighlightWhenSelected_applySelectedAlpha() {
- mDefaultButton.setSelected(true);
-
- assertThat(mDefaultButton.getAlpha()).isEqualTo(
- CarNavigationButton.DEFAULT_SELECTED_ALPHA);
- }
-
- @Test
- public void onUnselected_highlightWhenSelected_applyDefaultUnselectedAlpha() {
- CarNavigationButton highlightWhenSelectedButton = mTestView.findViewById(
- R.id.highlightable_no_more_button);
- highlightWhenSelectedButton.setSelected(false);
-
- assertThat(highlightWhenSelectedButton.getAlpha()).isEqualTo(
- CarNavigationButton.DEFAULT_UNSELECTED_ALPHA);
- }
-
- @Test
- public void onSelected_highlightWhenSelected_applyDefaultSelectedAlpha() {
- CarNavigationButton highlightWhenSelectedButton = mTestView.findViewById(
- R.id.highlightable_no_more_button);
- highlightWhenSelectedButton.setSelected(true);
-
- assertThat(highlightWhenSelectedButton.getAlpha()).isEqualTo(
- CarNavigationButton.DEFAULT_SELECTED_ALPHA);
- }
-
- @Test
- public void onSelected_doesNotShowMoreWhenSelected_doesNotShowMoreIcon() {
- mDefaultButton.setSelected(true);
- AlphaOptimizedImageView moreIcon = mDefaultButton.findViewById(
- R.id.car_nav_button_more_icon);
-
- assertThat(moreIcon.getVisibility()).isEqualTo(View.GONE);
- }
-
- @Test
- public void onSelected_showMoreWhenSelected_showsMoreIcon() {
- CarNavigationButton showMoreWhenSelected = mTestView.findViewById(
- R.id.not_highlightable_more_button);
- showMoreWhenSelected.setSelected(true);
- AlphaOptimizedImageView moreIcon = showMoreWhenSelected.findViewById(
- R.id.car_nav_button_more_icon);
-
- assertThat(moreIcon.getVisibility()).isEqualTo(View.VISIBLE);
- }
-
- @Test
- public void onUnselected_showMoreWhenSelected_doesNotShowMoreIcon() {
- CarNavigationButton showMoreWhenSelected = mTestView.findViewById(
- R.id.highlightable_no_more_button);
- showMoreWhenSelected.setSelected(true);
- showMoreWhenSelected.setSelected(false);
- AlphaOptimizedImageView moreIcon = showMoreWhenSelected.findViewById(
- R.id.car_nav_button_more_icon);
-
- assertThat(moreIcon.getVisibility()).isEqualTo(View.GONE);
- }
-
- @Test
- public void onUnselected_withAppIcon_showsAppIcon() {
- CarNavigationButton roleBasedButton = mTestView.findViewById(R.id.role_based_button);
- Drawable appIcon = getContext().getDrawable(R.drawable.ic_android);
-
- roleBasedButton.setSelected(false);
- roleBasedButton.setAppIcon(appIcon);
-
- Drawable currentDrawable = ((AlphaOptimizedImageView) roleBasedButton.findViewById(
- R.id.car_nav_button_icon_image)).getDrawable();
-
- assertThat(currentDrawable).isEqualTo(appIcon);
- }
-
- @Test
- public void onUnselected_withAppIcon_applyUnselectedAlpha() {
- CarNavigationButton roleBasedButton = mTestView.findViewById(R.id.role_based_button);
-
- roleBasedButton.setSelected(false);
- roleBasedButton.setAppIcon(getContext().getDrawable(R.drawable.ic_android));
-
- assertThat(roleBasedButton.getAlpha()).isEqualTo(
- CarNavigationButton.DEFAULT_UNSELECTED_ALPHA);
- }
-
- @Test
- public void onSelected_withAppIcon_showsAppIconWithSelectedAlpha() {
- CarNavigationButton roleBasedButton = mTestView.findViewById(R.id.role_based_button);
- Drawable appIcon = getContext().getDrawable(R.drawable.ic_android);
-
- roleBasedButton.setSelected(true);
- roleBasedButton.setAppIcon(appIcon);
-
- Drawable currentDrawable = ((AlphaOptimizedImageView) roleBasedButton.findViewById(
- R.id.car_nav_button_icon_image)).getDrawable();
-
- assertThat(currentDrawable).isEqualTo(appIcon);
- }
-
- @Test
- public void onSelected_withAppIcon_applySelectedAlpha() {
- CarNavigationButton roleBasedButton = mTestView.findViewById(R.id.role_based_button);
-
- roleBasedButton.setSelected(true);
- roleBasedButton.setAppIcon(getContext().getDrawable(R.drawable.ic_android));
-
- assertThat(roleBasedButton.getAlpha()).isEqualTo(
- CarNavigationButton.DEFAULT_SELECTED_ALPHA);
- }
-
- @Test
- public void onClick_launchesIntentActivity() {
- mDefaultButton.performClick();
-
- assertThat(getCurrentActivityName()).isEqualTo(DEFAULT_BUTTON_ACTIVITY_NAME);
-
- CarNavigationButton appGridButton = mTestView.findViewById(R.id.app_grid_activity);
- appGridButton.performClick();
-
- assertThat(getCurrentActivityName()).isEqualTo(APP_GRID_BUTTON_ACTIVITY_NAME);
- }
-
- @Test
- public void onLongClick_longIntentDefined_launchesLongIntentActivity() {
- mDefaultButton.performClick();
-
- assertThat(getCurrentActivityName()).isEqualTo(DEFAULT_BUTTON_ACTIVITY_NAME);
-
- CarNavigationButton appGridButton = mTestView.findViewById(
- R.id.long_click_app_grid_activity);
- appGridButton.performLongClick();
-
- assertThat(getCurrentActivityName()).isEqualTo(APP_GRID_BUTTON_ACTIVITY_NAME);
- }
-
- @Test
- public void onClick_useBroadcast_broadcastsIntent() {
- CarNavigationButton appGridButton = mTestView.findViewById(R.id.broadcast);
- appGridButton.performClick();
-
- verify(mContext).sendBroadcastAsUser(argThat(new ArgumentMatcher<Intent>() {
- @Override
- public boolean matches(Intent argument) {
- return argument.getAction().equals(BROADCAST_ACTION_NAME);
- }
- }), any());
- }
-
- @Test
- public void onSetUnseen_hasUnseen_showsUnseenIndicator() {
- mDefaultButton.setUnseen(true);
- ImageView hasUnseenIndicator = mDefaultButton.findViewById(R.id.car_nav_button_unseen_icon);
-
- assertThat(hasUnseenIndicator.getVisibility()).isEqualTo(View.VISIBLE);
- }
-
- @Test
- public void onSetUnseen_doesNotHaveUnseen_hidesUnseenIndicator() {
- mDefaultButton.setUnseen(false);
- ImageView hasUnseenIndicator = mDefaultButton.findViewById(R.id.car_nav_button_unseen_icon);
-
- assertThat(hasUnseenIndicator.getVisibility()).isEqualTo(View.GONE);
- }
-
- private String getCurrentActivityName() {
- return mActivityManager.getRunningTasks(1).get(0).topActivity.flattenToShortString();
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/SystemBarConfigsTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/SystemBarConfigsTest.java
deleted file mode 100644
index 0c62f8b..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/SystemBarConfigsTest.java
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.navigationbar;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.when;
-
-import android.content.res.Resources;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.util.ArrayMap;
-import android.view.WindowManager;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.car.CarSystemUiTest;
-import com.android.systemui.car.notification.NotificationPanelViewController;
-import com.android.systemui.car.notification.NotificationPanelViewMediator;
-import com.android.systemui.car.notification.PowerManagerHelper;
-import com.android.systemui.car.notification.TopNotificationPanelViewMediator;
-import com.android.systemui.statusbar.policy.ConfigurationController;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class SystemBarConfigsTest extends SysuiTestCase {
- private static final int SYSTEM_BAR_GIRTH = 100;
-
- private SystemBarConfigs mSystemBarConfigs;
- @Mock
- private Resources mResources;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- setDefaultValidConfig();
- }
-
- @Test
- public void onInit_allSystemBarsEnabled_eachHasUniqueBarTypes_doesNotThrowException() {
- mSystemBarConfigs = new SystemBarConfigs(mResources);
- }
-
- @Test(expected = RuntimeException.class)
- public void onInit_allSystemBarsEnabled_twoBarsHaveDuplicateType_throwsRuntimeException() {
- when(mResources.getInteger(R.integer.config_topSystemBarType)).thenReturn(0);
- when(mResources.getInteger(R.integer.config_bottomSystemBarType)).thenReturn(0);
-
- mSystemBarConfigs = new SystemBarConfigs(mResources);
- }
-
- @Test
- public void onInit_allSystemBarsEnabled_systemBarSidesSortedByZOrder() {
- mSystemBarConfigs = new SystemBarConfigs(mResources);
- List<Integer> actualOrder = mSystemBarConfigs.getSystemBarSidesByZOrder();
- List<Integer> expectedOrder = new ArrayList<>();
- expectedOrder.add(SystemBarConfigs.LEFT);
- expectedOrder.add(SystemBarConfigs.RIGHT);
- expectedOrder.add(SystemBarConfigs.TOP);
- expectedOrder.add(SystemBarConfigs.BOTTOM);
-
- assertTrue(actualOrder.equals(expectedOrder));
- }
-
- @Test(expected = RuntimeException.class)
- public void onInit_intersectingBarsHaveSameZOrder_throwsRuntimeException() {
- when(mResources.getInteger(R.integer.config_topSystemBarZOrder)).thenReturn(33);
- when(mResources.getInteger(R.integer.config_leftSystemBarZOrder)).thenReturn(33);
-
- mSystemBarConfigs = new SystemBarConfigs(mResources);
- }
-
- @Test(expected = RuntimeException.class)
- public void onInit_hideBottomSystemBarForKeyboardValueDoNotSync_throwsRuntimeException() {
- when(mResources.getBoolean(R.bool.config_hideBottomSystemBarForKeyboard)).thenReturn(false);
- when(mResources.getBoolean(
- com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard)).thenReturn(
- true);
-
- mSystemBarConfigs = new SystemBarConfigs(mResources);
- }
-
- @Test
- public void onInit_topNotifPanelViewMediatorUsed_topBarEnabled_doesNotThrowException() {
- when(mResources.getBoolean(R.bool.config_enableTopNavigationBar)).thenReturn(true);
- when(mResources.getString(R.string.config_notificationPanelViewMediator)).thenReturn(
- TestTopNotificationPanelViewMediator.class.getName());
-
- mSystemBarConfigs = new SystemBarConfigs(mResources);
- }
-
- @Test(expected = RuntimeException.class)
- public void onInit_topNotifPanelViewMediatorUsed_topBarNotEnabled_throwsRuntimeException() {
- when(mResources.getBoolean(R.bool.config_enableTopNavigationBar)).thenReturn(false);
- when(mResources.getString(R.string.config_notificationPanelViewMediator)).thenReturn(
- TestTopNotificationPanelViewMediator.class.getName());
-
- mSystemBarConfigs = new SystemBarConfigs(mResources);
- }
-
- @Test
- public void onInit_notificationPanelViewMediatorUsed_topBarNotEnabled_doesNotThrowException() {
- when(mResources.getBoolean(R.bool.config_enableTopNavigationBar)).thenReturn(false);
- when(mResources.getString(R.string.config_notificationPanelViewMediator)).thenReturn(
- NotificationPanelViewMediator.class.getName());
-
- mSystemBarConfigs = new SystemBarConfigs(mResources);
- }
-
- @Test
- public void getTopSystemBarLayoutParams_topBarEnabled_returnsTopSystemBarLayoutParams() {
- mSystemBarConfigs = new SystemBarConfigs(mResources);
- WindowManager.LayoutParams lp = mSystemBarConfigs.getLayoutParamsBySide(
- SystemBarConfigs.TOP);
-
- assertNotNull(lp);
- }
-
- @Test
- public void getTopSystemBarLayoutParams_topBarNotEnabled_returnsNull() {
- when(mResources.getBoolean(R.bool.config_enableTopNavigationBar)).thenReturn(false);
- mSystemBarConfigs = new SystemBarConfigs(mResources);
- WindowManager.LayoutParams lp = mSystemBarConfigs.getLayoutParamsBySide(
- SystemBarConfigs.TOP);
-
- assertNull(lp);
- }
-
- @Test
- public void getTopSystemBarHideForKeyboard_hideBarForKeyboard_returnsTrue() {
- when(mResources.getBoolean(R.bool.config_hideTopSystemBarForKeyboard)).thenReturn(true);
- mSystemBarConfigs = new SystemBarConfigs(mResources);
-
- boolean hideKeyboard = mSystemBarConfigs.getHideForKeyboardBySide(SystemBarConfigs.TOP);
-
- assertTrue(hideKeyboard);
- }
-
- @Test
- public void getTopSystemBarHideForKeyboard_topBarNotEnabled_returnsFalse() {
- when(mResources.getBoolean(R.bool.config_enableTopNavigationBar)).thenReturn(false);
- mSystemBarConfigs = new SystemBarConfigs(mResources);
-
- boolean hideKeyboard = mSystemBarConfigs.getHideForKeyboardBySide(SystemBarConfigs.TOP);
-
- assertFalse(hideKeyboard);
- }
-
- @Test
- public void topSystemBarHasHigherZOrderThanHuns_topSystemBarIsNavigationBarPanelType() {
- when(mResources.getInteger(R.integer.config_topSystemBarZOrder)).thenReturn(
- SystemBarConfigs.getHunZOrder() + 1);
- mSystemBarConfigs = new SystemBarConfigs(mResources);
- WindowManager.LayoutParams lp = mSystemBarConfigs.getLayoutParamsBySide(
- SystemBarConfigs.TOP);
-
- assertEquals(lp.type, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL);
- }
-
- @Test
- public void topSystemBarHasLowerZOrderThanHuns_topSystemBarIsStatusBarAdditionalType() {
- when(mResources.getInteger(R.integer.config_topSystemBarZOrder)).thenReturn(
- SystemBarConfigs.getHunZOrder() - 1);
- mSystemBarConfigs = new SystemBarConfigs(mResources);
- WindowManager.LayoutParams lp = mSystemBarConfigs.getLayoutParamsBySide(
- SystemBarConfigs.TOP);
-
- assertEquals(lp.type, WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL);
- }
-
- @Test
- public void updateInsetPaddings_overlappingBarWithHigherZOrderDisappeared_removesInset() {
- mSystemBarConfigs = new SystemBarConfigs(mResources);
- CarNavigationBarView leftBar = new CarNavigationBarView(mContext, /* attrs= */ null);
- Map<Integer, Boolean> visibilities = new ArrayMap<>();
- visibilities.put(SystemBarConfigs.TOP, false);
- visibilities.put(SystemBarConfigs.BOTTOM, true);
- visibilities.put(SystemBarConfigs.LEFT, true);
- visibilities.put(SystemBarConfigs.RIGHT, true);
-
- mSystemBarConfigs.updateInsetPaddings(SystemBarConfigs.LEFT, visibilities);
- mSystemBarConfigs.insetSystemBar(SystemBarConfigs.LEFT, leftBar);
-
- assertEquals(0, leftBar.getPaddingTop());
- }
-
- @Test
- public void updateInsetPaddings_overlappingBarWithHigherZOrderReappeared_addsInset() {
- mSystemBarConfigs = new SystemBarConfigs(mResources);
- CarNavigationBarView leftBar = new CarNavigationBarView(mContext, /* attrs= */ null);
- Map<Integer, Boolean> visibilities = new ArrayMap<>();
- visibilities.put(SystemBarConfigs.TOP, false);
- visibilities.put(SystemBarConfigs.BOTTOM, true);
- visibilities.put(SystemBarConfigs.LEFT, true);
- visibilities.put(SystemBarConfigs.RIGHT, true);
-
- mSystemBarConfigs.updateInsetPaddings(SystemBarConfigs.LEFT, visibilities);
- mSystemBarConfigs.insetSystemBar(SystemBarConfigs.LEFT, leftBar);
- visibilities.put(SystemBarConfigs.TOP, true);
- mSystemBarConfigs.updateInsetPaddings(SystemBarConfigs.LEFT, visibilities);
- mSystemBarConfigs.insetSystemBar(SystemBarConfigs.LEFT, leftBar);
-
- assertEquals(SYSTEM_BAR_GIRTH, leftBar.getPaddingTop());
- }
-
- // Set valid config where all system bars are enabled.
- private void setDefaultValidConfig() {
- when(mResources.getBoolean(R.bool.config_enableTopNavigationBar)).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_enableBottomNavigationBar)).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_enableLeftNavigationBar)).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_enableRightNavigationBar)).thenReturn(true);
-
- when(mResources.getDimensionPixelSize(
- com.android.internal.R.dimen.status_bar_height)).thenReturn(SYSTEM_BAR_GIRTH);
- when(mResources.getDimensionPixelSize(
- com.android.internal.R.dimen.navigation_bar_height)).thenReturn(SYSTEM_BAR_GIRTH);
- when(mResources.getDimensionPixelSize(R.dimen.car_left_navigation_bar_width)).thenReturn(
- SYSTEM_BAR_GIRTH);
- when(mResources.getDimensionPixelSize(R.dimen.car_right_navigation_bar_width)).thenReturn(
- SYSTEM_BAR_GIRTH);
-
- when(mResources.getInteger(R.integer.config_topSystemBarType)).thenReturn(0);
- when(mResources.getInteger(R.integer.config_bottomSystemBarType)).thenReturn(1);
- when(mResources.getInteger(R.integer.config_leftSystemBarType)).thenReturn(2);
- when(mResources.getInteger(R.integer.config_rightSystemBarType)).thenReturn(3);
-
- when(mResources.getInteger(R.integer.config_topSystemBarZOrder)).thenReturn(5);
- when(mResources.getInteger(R.integer.config_bottomSystemBarZOrder)).thenReturn(10);
- when(mResources.getInteger(R.integer.config_leftSystemBarZOrder)).thenReturn(2);
- when(mResources.getInteger(R.integer.config_rightSystemBarZOrder)).thenReturn(3);
-
- when(mResources.getBoolean(R.bool.config_hideTopSystemBarForKeyboard)).thenReturn(false);
- when(mResources.getBoolean(
- com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard)).thenReturn(
- false);
- when(mResources.getBoolean(R.bool.config_hideLeftSystemBarForKeyboard)).thenReturn(
- false);
- when(mResources.getBoolean(R.bool.config_hideRightSystemBarForKeyboard)).thenReturn(
- false);
- }
-
- // Intentionally using a subclass of TopNotificationPanelViewMediator for testing purposes to
- // ensure that OEM's will be able to implement and use their own NotificationPanelViewMediator.
- private class TestTopNotificationPanelViewMediator extends
- TopNotificationPanelViewMediator {
- TestTopNotificationPanelViewMediator(
- CarNavigationBarController carNavigationBarController,
- NotificationPanelViewController notificationPanelViewController,
- PowerManagerHelper powerManagerHelper,
- BroadcastDispatcher broadcastDispatcher,
- CarDeviceProvisionedController carDeviceProvisionedController,
- ConfigurationController configurationController) {
- super(carNavigationBarController, notificationPanelViewController, powerManagerHelper,
- broadcastDispatcher, carDeviceProvisionedController, configurationController);
- }
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainerTest.java
deleted file mode 100644
index 384888a..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainerTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.notification;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.testing.TestableResources;
-import android.view.View;
-import android.view.WindowManager;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.car.CarSystemUiTest;
-import com.android.systemui.car.window.OverlayViewGlobalStateController;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class CarHeadsUpNotificationSystemContainerTest extends SysuiTestCase {
- private CarHeadsUpNotificationSystemContainer mCarHeadsUpNotificationSystemContainer;
- @Mock
- private CarDeviceProvisionedController mCarDeviceProvisionedController;
- @Mock
- private OverlayViewGlobalStateController mOverlayViewGlobalStateController;
- @Mock
- private WindowManager mWindowManager;
-
- @Mock
- private View mNotificationView;
- @Mock
- private View mNotificationView2;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(/* testClass= */this);
-
- when(mOverlayViewGlobalStateController.shouldShowHUN()).thenReturn(true);
- when(mCarDeviceProvisionedController.isCurrentUserFullySetup()).thenReturn(true);
-
- TestableResources testableResources = mContext.getOrCreateTestableResources();
-
- mCarHeadsUpNotificationSystemContainer = new CarHeadsUpNotificationSystemContainer(mContext,
- testableResources.getResources(), mCarDeviceProvisionedController, mWindowManager,
- mOverlayViewGlobalStateController);
- }
-
- @Test
- public void testDisplayNotification_firstNotification_isVisible() {
- mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
- assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isTrue();
- }
-
- @Test
- public void testRemoveNotification_lastNotification_isInvisible() {
- mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
- mCarHeadsUpNotificationSystemContainer.removeNotification(mNotificationView);
- assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isFalse();
- }
-
- @Test
- public void testRemoveNotification_nonLastNotification_isVisible() {
- mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
- mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView2);
- mCarHeadsUpNotificationSystemContainer.removeNotification(mNotificationView);
- assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isTrue();
- }
-
- @Test
- public void testDisplayNotification_userFullySetupTrue_isInvisible() {
- mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
- assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isTrue();
-
- }
-
- @Test
- public void testDisplayNotification_userFullySetupFalse_isInvisible() {
- when(mCarDeviceProvisionedController.isCurrentUserFullySetup()).thenReturn(false);
- mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
- assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isFalse();
- }
-
- @Test
- public void testDisplayNotification_overlayWindowStateShouldShowHUNFalse_isInvisible() {
- when(mOverlayViewGlobalStateController.shouldShowHUN()).thenReturn(false);
- mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
- assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isFalse();
- }
-
- @Test
- public void testDisplayNotification_overlayWindowStateShouldShowHUNTrue_isVisible() {
- mCarHeadsUpNotificationSystemContainer.displayNotification(mNotificationView);
- assertThat(mCarHeadsUpNotificationSystemContainer.isVisible()).isTrue();
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/NotificationVisibilityLoggerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/NotificationVisibilityLoggerTest.java
deleted file mode 100644
index d51aeb1..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/NotificationVisibilityLoggerTest.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.notification;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Notification;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.service.notification.StatusBarNotification;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.car.notification.AlertEntry;
-import com.android.car.notification.NotificationDataManager;
-import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarSystemUiTest;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.time.FakeSystemClock;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Collections;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class NotificationVisibilityLoggerTest extends SysuiTestCase {
-
- private static final String PKG = "package_1";
- private static final String OP_PKG = "OpPackage";
- private static final int ID = 1;
- private static final String TAG = "Tag";
- private static final int UID = 2;
- private static final int INITIAL_PID = 3;
- private static final String CHANNEL_ID = "CHANNEL_ID";
- private static final String CONTENT_TITLE = "CONTENT_TITLE";
- private static final String OVERRIDE_GROUP_KEY = "OVERRIDE_GROUP_KEY";
- private static final long POST_TIME = 12345L;
- private static final UserHandle USER_HANDLE = new UserHandle(12);
-
- @Mock
- private IStatusBarService mBarService;
- @Mock
- private NotificationDataManager mNotificationDataManager;
-
- private NotificationVisibilityLogger mNotificationVisibilityLogger;
- private FakeExecutor mUiBgExecutor;
- private AlertEntry mMessageNotification;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(/* testClass= */this);
-
- mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
- Notification.Builder mNotificationBuilder1 = new Notification.Builder(mContext, CHANNEL_ID)
- .setContentTitle(CONTENT_TITLE);
- mMessageNotification = new AlertEntry(new StatusBarNotification(PKG, OP_PKG,
- ID, TAG, UID, INITIAL_PID, mNotificationBuilder1.build(), USER_HANDLE,
- OVERRIDE_GROUP_KEY, POST_TIME));
-
- when(mNotificationDataManager.getVisibleNotifications()).thenReturn(
- Collections.singletonList(mMessageNotification));
-
- mNotificationVisibilityLogger = new NotificationVisibilityLogger(
- mUiBgExecutor, mBarService, mNotificationDataManager);
- }
-
- @Test
- public void log_notifiesStatusBarService() throws RemoteException {
- mNotificationVisibilityLogger.log(/* isVisible= */ true);
- mUiBgExecutor.runNextReady();
-
- verify(mBarService).onNotificationVisibilityChanged(
- any(NotificationVisibility[].class), any(NotificationVisibility[].class));
- }
-
- @Test
- public void log_isVisibleIsTrue_notifiesOfNewlyVisibleItems() throws RemoteException {
- ArgumentCaptor<NotificationVisibility[]> newlyVisibleCaptor =
- ArgumentCaptor.forClass(NotificationVisibility[].class);
- ArgumentCaptor<NotificationVisibility[]> previouslyVisibleCaptor =
- ArgumentCaptor.forClass(NotificationVisibility[].class);
-
- mNotificationVisibilityLogger.log(/* isVisible= */ true);
- mUiBgExecutor.runNextReady();
-
- verify(mBarService).onNotificationVisibilityChanged(
- newlyVisibleCaptor.capture(), previouslyVisibleCaptor.capture());
- assertThat(newlyVisibleCaptor.getValue().length).isEqualTo(1);
- assertThat(previouslyVisibleCaptor.getValue().length).isEqualTo(0);
- }
-
- @Test
- public void log_isVisibleIsFalse_notifiesOfPreviouslyVisibleItems() throws RemoteException {
- ArgumentCaptor<NotificationVisibility[]> newlyVisibleCaptor =
- ArgumentCaptor.forClass(NotificationVisibility[].class);
- ArgumentCaptor<NotificationVisibility[]> previouslyVisibleCaptor =
- ArgumentCaptor.forClass(NotificationVisibility[].class);
- mNotificationVisibilityLogger.log(/* isVisible= */ true);
- mUiBgExecutor.runNextReady();
- reset(mBarService);
-
- mNotificationVisibilityLogger.log(/* isVisible= */ false);
- mUiBgExecutor.runNextReady();
-
- verify(mBarService).onNotificationVisibilityChanged(
- newlyVisibleCaptor.capture(), previouslyVisibleCaptor.capture());
- assertThat(previouslyVisibleCaptor.getValue().length).isEqualTo(1);
- assertThat(newlyVisibleCaptor.getValue().length).isEqualTo(0);
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/rvc/RearViewCameraViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/rvc/RearViewCameraViewControllerTest.java
deleted file mode 100644
index a6160ec..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/rvc/RearViewCameraViewControllerTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.rvc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.verify;
-
-import android.app.ActivityView;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.testing.TestableLooper;
-import android.view.LayoutInflater;
-import android.view.ViewGroup;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarSystemUiTest;
-import com.android.systemui.car.window.OverlayViewGlobalStateController;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-@CarSystemUiTest
-@RunWith(MockitoJUnitRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class RearViewCameraViewControllerTest extends SysuiTestCase {
- private static final String TEST_ACTIVITY_NAME = "testPackage/testActivity";
- private RearViewCameraViewController mRearViewCameraViewController;
-
- @Mock
- private OverlayViewGlobalStateController mOverlayViewGlobalStateController;
- @Mock
- private ActivityView mMockActivityView;
- @Captor
- private ArgumentCaptor<Intent> mIntentCaptor;
-
- private void setUpRearViewCameraViewController(String testActivityName) {
- mContext.getOrCreateTestableResources().addOverride(
- R.string.config_rearViewCameraActivity, testActivityName);
- mRearViewCameraViewController = new RearViewCameraViewController(
- mContext.getOrCreateTestableResources().getResources(),
- mOverlayViewGlobalStateController);
- mRearViewCameraViewController.inflate((ViewGroup) LayoutInflater.from(mContext).inflate(
- R.layout.sysui_overlay_window, /* root= */ null));
- }
-
- @Test
- public void testEmptyResourceDisablesController() {
- setUpRearViewCameraViewController("");
-
- assertThat(mRearViewCameraViewController.isEnabled()).isFalse();
- }
-
- @Test
- public void testNonEmptyResourceEnablesController() {
- setUpRearViewCameraViewController(TEST_ACTIVITY_NAME);
-
- assertThat(mRearViewCameraViewController.isEnabled()).isTrue();
- }
-
- @Test
- public void testShowInternal() {
- setUpRearViewCameraViewController(TEST_ACTIVITY_NAME);
- assertThat(mRearViewCameraViewController.isShown()).isFalse();
- assertThat(mRearViewCameraViewController.mActivityView).isNull();
-
- mRearViewCameraViewController.showInternal();
-
- assertThat(mRearViewCameraViewController.isShown()).isTrue();
- assertThat(mRearViewCameraViewController.mActivityView).isNotNull();
- }
-
- @Test
- public void testHideInternal() {
- setUpRearViewCameraViewController(TEST_ACTIVITY_NAME);
- assertThat(mRearViewCameraViewController.isShown()).isFalse();
- mRearViewCameraViewController.showInternal();
- assertThat(mRearViewCameraViewController.isShown()).isTrue();
-
- mRearViewCameraViewController.hideInternal();
-
- assertThat(mRearViewCameraViewController.isShown()).isFalse();
- assertThat(mRearViewCameraViewController.mActivityView).isNull();
- }
-
- @Test
- public void testOnActivityViewReady_fireIntent() {
- setUpRearViewCameraViewController(TEST_ACTIVITY_NAME);
- mRearViewCameraViewController.mActivityViewCallback.onActivityViewReady(mMockActivityView);
-
- verify(mMockActivityView).startActivity(mIntentCaptor.capture());
- ComponentName expectedComponent = ComponentName.unflattenFromString(TEST_ACTIVITY_NAME);
- assertThat(mIntentCaptor.getValue().getComponent()).isEqualTo(expectedComponent);
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/rvc/RearViewCameraViewMediatorTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/rvc/RearViewCameraViewMediatorTest.java
deleted file mode 100644
index 5be8f91..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/rvc/RearViewCameraViewMediatorTest.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.rvc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyFloat;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.car.Car;
-import android.car.VehicleAreaType;
-import android.car.VehicleGear;
-import android.car.VehiclePropertyIds;
-import android.car.hardware.CarPropertyValue;
-import android.car.hardware.property.CarPropertyManager;
-import android.car.hardware.property.CarPropertyManager.CarPropertyEventCallback;
-import android.content.BroadcastReceiver;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.testing.TestableLooper;
-import android.util.Log;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.car.CarServiceProvider;
-import com.android.systemui.car.CarServiceProvider.CarServiceOnConnectedListener;
-import com.android.systemui.car.CarSystemUiTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-@CarSystemUiTest
-@RunWith(MockitoJUnitRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class RearViewCameraViewMediatorTest extends SysuiTestCase {
- private static final String TAG = RearViewCameraViewMediatorTest.class.getSimpleName();
-
- private RearViewCameraViewMediator mRearViewCameraViewMediator;
-
- @Mock
- private CarServiceProvider mCarServiceProvider;
- @Mock
- private Car mCar;
- @Mock
- private CarPropertyManager mCarPropertyManager;
- @Captor
- private ArgumentCaptor<CarPropertyEventCallback> mCarPropertyEventCallbackCaptor;
-
- @Mock
- private BroadcastDispatcher mBroadcastDispatcher;
- @Captor
- private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
- @Captor
- private ArgumentCaptor<IntentFilter> mIntentFilterCaptor;
-
- @Mock
- private RearViewCameraViewController mRearViewCameraViewController;
-
- @Before
- public void setUp() throws Exception {
- mRearViewCameraViewMediator = new RearViewCameraViewMediator(
- mRearViewCameraViewController, mCarServiceProvider, mBroadcastDispatcher);
- }
-
- public void setUpListener() {
- doAnswer(invocation -> {
- CarServiceOnConnectedListener listener = invocation.getArgument(0);
- listener.onConnected(mCar);
- return null;
- }).when(mCarServiceProvider).addListener(any(CarServiceOnConnectedListener.class));
- when(mCar.getCarManager(Car.PROPERTY_SERVICE)).thenReturn(mCarPropertyManager);
- when(mRearViewCameraViewController.isEnabled()).thenReturn(true);
-
- mRearViewCameraViewMediator.registerListeners();
-
- verify(mCarPropertyManager).registerCallback(mCarPropertyEventCallbackCaptor.capture(),
- eq(VehiclePropertyIds.GEAR_SELECTION), anyFloat());
- verify(mBroadcastDispatcher).registerReceiver(mBroadcastReceiverCaptor.capture(),
- mIntentFilterCaptor.capture(), any(), any());
- assertThat(mIntentFilterCaptor.getValue().getAction(0)).isEqualTo(
- Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
- }
-
- @Test
- public void testDoesnNotRegisterListenersWhenRearViewCameraViewControllerIsDisabled() {
- when(mRearViewCameraViewController.isEnabled()).thenReturn(false);
-
- mRearViewCameraViewMediator.registerListeners();
-
- verify(mCarPropertyManager, never()).registerCallback(any(), anyInt(), anyFloat());
- verify(mBroadcastDispatcher, never()).registerReceiver(any(), any(), any());
- }
-
- @Test
- public void testGearReverseStartsRearViewCamera() {
- setUpListener();
-
- CarPropertyValue<Integer> gearReverse = new CarPropertyValue(
- VehiclePropertyIds.GEAR_SELECTION, VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL,
- VehicleGear.GEAR_REVERSE);
- mCarPropertyEventCallbackCaptor.getValue().onChangeEvent(gearReverse);
-
- verify(mRearViewCameraViewController, times(1)).start();
- }
-
- @Test
- public void testGearNonReverseStopsRearViewCamera() {
- setUpListener();
-
- int[] nonReverseVehicleGears = new int[]{
- VehicleGear.GEAR_NEUTRAL, VehicleGear.GEAR_PARK, VehicleGear.GEAR_DRIVE,
- VehicleGear.GEAR_FIRST
- };
- for (int i = 0; i < nonReverseVehicleGears.length; ++i) {
- Log.i(TAG, "testGearNonReverseStopsRearViewCamera: gear=" + nonReverseVehicleGears[i]);
- CarPropertyValue<Integer> propertyGear = new CarPropertyValue(
- VehiclePropertyIds.GEAR_SELECTION, VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL,
- nonReverseVehicleGears[i]);
- mCarPropertyEventCallbackCaptor.getValue().onChangeEvent(propertyGear);
-
- verify(mRearViewCameraViewController, times(i + 1)).stop();
- }
- }
-
- @Test
- public void testBroadcastIntentStopsRearViewCamera() {
- setUpListener();
- when(mRearViewCameraViewController.isShown()).thenReturn(true);
-
- Intent randomIntent = new Intent(Intent.ACTION_MAIN);
- mBroadcastReceiverCaptor.getValue().onReceive(mContext, randomIntent);
-
- verify(mRearViewCameraViewController, never()).stop();
-
- Intent actionCloseSystemDialogs = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
- mBroadcastReceiverCaptor.getValue().onReceive(mContext, actionCloseSystemDialogs);
-
- verify(mRearViewCameraViewController, times(1)).stop();
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppDetectorTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppDetectorTest.java
deleted file mode 100644
index bf9ac30..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppDetectorTest.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.sideloaded;
-
-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;
-import static org.mockito.Mockito.when;
-
-import android.app.ActivityTaskManager.RootTaskInfo;
-import android.content.ComponentName;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.InstallSourceInfo;
-import android.content.pm.PackageManager;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.testing.TestableResources;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.car.CarSystemUiTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class SideLoadedAppDetectorTest extends SysuiTestCase {
-
- private static final String SAFE_VENDOR = "com.safe.vendor";
- private static final String UNSAFE_VENDOR = "com.unsafe.vendor";
- private static final String APP_PACKAGE_NAME = "com.test";
- private static final String APP_CLASS_NAME = ".TestClass";
-
- private SideLoadedAppDetector mSideLoadedAppDetector;
-
- @Mock
- private PackageManager mPackageManager;
- @Mock
- private CarDeviceProvisionedController mCarDeviceProvisionedController;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- TestableResources testableResources = mContext.getOrCreateTestableResources();
- String[] allowedAppInstallSources = new String[] {SAFE_VENDOR};
- testableResources.addOverride(R.array.config_allowedAppInstallSources,
- allowedAppInstallSources);
-
- mSideLoadedAppDetector = new SideLoadedAppDetector(testableResources.getResources(),
- mPackageManager,
- mCarDeviceProvisionedController);
- }
-
- @Test
- public void isSafe_systemApp_returnsTrue() throws Exception {
- RootTaskInfo taskInfo = new RootTaskInfo();
- taskInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME);
-
- ApplicationInfo applicationInfo = new ApplicationInfo();
- applicationInfo.packageName = APP_PACKAGE_NAME;
- applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
-
- when(mPackageManager.getApplicationInfoAsUser(eq(APP_PACKAGE_NAME), anyInt(), any()))
- .thenReturn(applicationInfo);
-
- assertThat(mSideLoadedAppDetector.isSafe(taskInfo)).isTrue();
- }
-
- @Test
- public void isSafe_updatedSystemApp_returnsTrue() throws Exception {
- RootTaskInfo taskInfo = new RootTaskInfo();
- taskInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME);
-
- ApplicationInfo applicationInfo = new ApplicationInfo();
- applicationInfo.packageName = APP_PACKAGE_NAME;
- applicationInfo.flags = ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
-
- when(mPackageManager.getApplicationInfoAsUser(eq(APP_PACKAGE_NAME), anyInt(), any()))
- .thenReturn(applicationInfo);
-
- assertThat(mSideLoadedAppDetector.isSafe(taskInfo)).isTrue();
- }
-
- @Test
- public void isSafe_nonSystemApp_withSafeSource_returnsTrue() throws Exception {
- InstallSourceInfo sourceInfo = new InstallSourceInfo(SAFE_VENDOR,
- /* initiatingPackageSigningInfo= */null,
- /* originatingPackageName= */ null,
- /* installingPackageName= */ null);
- RootTaskInfo taskInfo = new RootTaskInfo();
- taskInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME);
-
- ApplicationInfo applicationInfo = new ApplicationInfo();
- applicationInfo.packageName = APP_PACKAGE_NAME;
-
- when(mPackageManager.getApplicationInfoAsUser(eq(APP_PACKAGE_NAME), anyInt(), any()))
- .thenReturn(applicationInfo);
- when(mPackageManager.getInstallSourceInfo(APP_PACKAGE_NAME)).thenReturn(sourceInfo);
-
- assertThat(mSideLoadedAppDetector.isSafe(taskInfo)).isTrue();
- }
-
- @Test
- public void isSafe_nonSystemApp_withUnsafeSource_returnsFalse() throws Exception {
- InstallSourceInfo sourceInfo = new InstallSourceInfo(UNSAFE_VENDOR,
- /* initiatingPackageSigningInfo= */null,
- /* originatingPackageName= */ null,
- /* installingPackageName= */ null);
- RootTaskInfo taskInfo = new RootTaskInfo();
- taskInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME);
-
- ApplicationInfo applicationInfo = new ApplicationInfo();
- applicationInfo.packageName = APP_PACKAGE_NAME;
-
- when(mPackageManager.getApplicationInfoAsUser(eq(APP_PACKAGE_NAME), anyInt(), any()))
- .thenReturn(applicationInfo);
- when(mPackageManager.getInstallSourceInfo(APP_PACKAGE_NAME)).thenReturn(sourceInfo);
-
- assertThat(mSideLoadedAppDetector.isSafe(taskInfo)).isFalse();
- }
-
- @Test
- public void isSafe_nonSystemApp_withoutSource_returnsFalse() throws Exception {
- InstallSourceInfo sourceInfo = new InstallSourceInfo(null,
- /* initiatingPackageSigningInfo= */null,
- /* originatingPackageName= */ null,
- /* installingPackageName= */ null);
- RootTaskInfo taskInfo = new RootTaskInfo();
- taskInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME);
-
- ApplicationInfo applicationInfo = new ApplicationInfo();
- applicationInfo.packageName = APP_PACKAGE_NAME;
-
- when(mPackageManager.getApplicationInfoAsUser(eq(APP_PACKAGE_NAME), anyInt(), any()))
- .thenReturn(applicationInfo);
- when(mPackageManager.getInstallSourceInfo(APP_PACKAGE_NAME)).thenReturn(sourceInfo);
-
- assertThat(mSideLoadedAppDetector.isSafe(taskInfo)).isFalse();
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java
deleted file mode 100644
index 0b5f68f..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.sideloaded;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.ActivityTaskManager.RootTaskInfo;
-import android.app.IActivityTaskManager;
-import android.content.ComponentName;
-import android.hardware.display.DisplayManager;
-import android.hardware.display.DisplayManagerGlobal;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.view.Display;
-import android.view.DisplayAdjustments;
-import android.view.DisplayInfo;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarSystemUiTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class SideLoadedAppListenerTest extends SysuiTestCase {
-
- private static final String APP_PACKAGE_NAME = "com.test";
- private static final String APP_CLASS_NAME = ".TestClass";
-
- private SideLoadedAppListener mSideLoadedAppListener;
-
- @Mock
- private SideLoadedAppDetector mSideLoadedAppDetector;
- @Mock
- private DisplayManager mDisplayManager;
- @Mock
- private IActivityTaskManager mActivityTaskManager;
- @Mock
- private SideLoadedAppStateController mSideLoadedAppStateController;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- mSideLoadedAppListener = new SideLoadedAppListener(mSideLoadedAppDetector,
- mActivityTaskManager, mDisplayManager, mSideLoadedAppStateController);
- }
-
- @Test
- public void onTaskCreated_safeTask_callsNoMethods() throws Exception {
- int taskId = 999;
- int displayId = 123;
- ComponentName componentName = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME);
-
- RootTaskInfo taskInfo1 = createTask(1, /* isVisible= */ true);
- taskInfo1.childTaskIds = new int[] { 11, 22, 33 };
-
- RootTaskInfo taskInfo2 = createTask(2, /* isVisible= */ true);
- taskInfo2.childTaskIds = new int[] { 111, 222, 333, taskId };
- taskInfo2.displayId = displayId;
-
- List<RootTaskInfo> taskInfoList = Arrays.asList(taskInfo1, taskInfo2);
-
- when(mActivityTaskManager.getAllRootTaskInfos()).thenReturn(taskInfoList);
- when(mSideLoadedAppDetector.isSafe(taskInfo2)).thenReturn(true);
-
- mSideLoadedAppListener.onTaskCreated(taskId, componentName);
-
- verify(mSideLoadedAppDetector, never()).isSafe(taskInfo1);
- verify(mSideLoadedAppDetector).isSafe(taskInfo2);
-
- verify(mSideLoadedAppStateController, never()).onUnsafeTaskCreatedOnDisplay(any());
- verify(mSideLoadedAppStateController, never()).onSafeTaskDisplayedOnDisplay(any());
- verify(mSideLoadedAppStateController, never()).onUnsafeTaskDisplayedOnDisplay(any());
- }
-
- @Test
- public void onTaskCreated_unsafeTask_callsUnsafeTaskCreated() throws Exception {
- int taskId = 999;
- int displayId = 123;
- ComponentName componentName = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME);
-
- RootTaskInfo taskInfo1 = createTask(1, /* isVisible= */ true);
- taskInfo1.childTaskIds = new int[] { 11, 22, 33 };
- RootTaskInfo taskInfo2 = createTask(2, /* isVisible= */ true);
- taskInfo2.childTaskIds = new int[] { 111, 222, 333, taskId };
- taskInfo2.displayId = displayId;
- List<RootTaskInfo> taskInfoList = Arrays.asList(taskInfo1, taskInfo2);
-
- Display display = createDisplay(displayId);
-
- when(mActivityTaskManager.getAllRootTaskInfos()).thenReturn(taskInfoList);
- when(mSideLoadedAppDetector.isSafe(taskInfo2)).thenReturn(false);
- when(mDisplayManager.getDisplay(displayId)).thenReturn(display);
-
- mSideLoadedAppListener.onTaskCreated(taskId, componentName);
-
- verify(mSideLoadedAppDetector, never()).isSafe(taskInfo1);
- verify(mSideLoadedAppDetector).isSafe(taskInfo2);
-
- verify(mSideLoadedAppStateController).onUnsafeTaskCreatedOnDisplay(display);
- verify(mSideLoadedAppStateController, never()).onSafeTaskDisplayedOnDisplay(any());
- verify(mSideLoadedAppStateController, never()).onUnsafeTaskDisplayedOnDisplay(any());
- }
-
- @Test
- public void onTaskStackChanged_safeTask_callsSafeTaskDisplayed() throws Exception {
- Display display = createDisplay(123);
- RootTaskInfo taskInfo1 = createTask(1, /* isVisible= */ false);
- RootTaskInfo taskInfo2 = createTask(2, /* isVisible= */ true);
- RootTaskInfo taskInfo3 = createTask(3, /* isVisible= */ true);
- List<RootTaskInfo> taskInfoList = Arrays.asList(taskInfo1, taskInfo2, taskInfo3);
-
- when(mActivityTaskManager.getAllRootTaskInfosOnDisplay(display.getDisplayId()))
- .thenReturn(taskInfoList);
- when(mSideLoadedAppDetector.isSafe(taskInfo2)).thenReturn(true);
- when(mDisplayManager.getDisplays()).thenReturn(new Display[] { display });
-
- mSideLoadedAppListener.onTaskStackChanged();
-
- verify(mSideLoadedAppDetector, never()).isSafe(taskInfo1);
- verify(mSideLoadedAppDetector).isSafe(taskInfo2);
- verify(mSideLoadedAppDetector, never()).isSafe(taskInfo3);
-
- verify(mSideLoadedAppStateController, never()).onUnsafeTaskCreatedOnDisplay(any());
- verify(mSideLoadedAppStateController).onSafeTaskDisplayedOnDisplay(display);
- verify(mSideLoadedAppStateController, never()).onUnsafeTaskDisplayedOnDisplay(any());
- }
-
- @Test
- public void onTaskStackChanged_unsafeTask_callsUnsafeTaskDisplayed() throws Exception {
- Display display = createDisplay(123);
- RootTaskInfo taskInfo1 = createTask(1, /* isVisible= */ false);
- RootTaskInfo taskInfo2 = createTask(2, /* isVisible= */ true);
- RootTaskInfo taskInfo3 = createTask(3, /* isVisible= */ true);
- List<RootTaskInfo> taskInfoList = Arrays.asList(taskInfo1, taskInfo2, taskInfo3);
-
- when(mActivityTaskManager.getAllRootTaskInfosOnDisplay(display.getDisplayId()))
- .thenReturn(taskInfoList);
- when(mSideLoadedAppDetector.isSafe(taskInfo2)).thenReturn(false);
- when(mDisplayManager.getDisplays()).thenReturn(new Display[] { display });
-
- mSideLoadedAppListener.onTaskStackChanged();
-
- verify(mSideLoadedAppDetector, never()).isSafe(taskInfo1);
- verify(mSideLoadedAppDetector).isSafe(taskInfo2);
- verify(mSideLoadedAppDetector, never()).isSafe(taskInfo3);
-
- verify(mSideLoadedAppStateController, never()).onUnsafeTaskCreatedOnDisplay(any());
- verify(mSideLoadedAppStateController, never()).onSafeTaskDisplayedOnDisplay(any());
- verify(mSideLoadedAppStateController).onUnsafeTaskDisplayedOnDisplay(display);
- }
-
- @Test
- public void onTaskStackChanged_multiDisplay_callsTasksDisplayed() throws Exception {
- Display display1 = createDisplay(1);
- RootTaskInfo taskInfo1 = createTask(1, /* isVisible= */ false);
- RootTaskInfo taskInfo2 = createTask(2, /* isVisible= */ true);
- RootTaskInfo taskInfo3 = createTask(3, /* isVisible= */ true);
- List<RootTaskInfo> display1Tasks = Arrays.asList(taskInfo1, taskInfo2, taskInfo3);
-
- Display display2 = createDisplay(2);
- RootTaskInfo taskInfo4 = createTask(4, /* isVisible= */ true);
- List<RootTaskInfo> display2Tasks = Collections.singletonList(taskInfo4);
-
- Display display3 = createDisplay(3);
- RootTaskInfo taskInfo5 = createTask(5, /* isVisible= */ true);
- List<RootTaskInfo> display3Tasks = Collections.singletonList(taskInfo5);
-
- when(mActivityTaskManager.getAllRootTaskInfosOnDisplay(display1.getDisplayId()))
- .thenReturn(display1Tasks);
- when(mActivityTaskManager.getAllRootTaskInfosOnDisplay(display2.getDisplayId()))
- .thenReturn(display2Tasks);
- when(mActivityTaskManager.getAllRootTaskInfosOnDisplay(display3.getDisplayId()))
- .thenReturn(display3Tasks);
-
- when(mSideLoadedAppDetector.isSafe(taskInfo2)).thenReturn(true);
- when(mSideLoadedAppDetector.isSafe(taskInfo4)).thenReturn(false);
- when(mSideLoadedAppDetector.isSafe(taskInfo5)).thenReturn(true);
-
- when(mDisplayManager.getDisplays())
- .thenReturn(new Display[] { display1, display2, display3});
-
- mSideLoadedAppListener.onTaskStackChanged();
-
- verify(mSideLoadedAppDetector, never()).isSafe(taskInfo1);
- verify(mSideLoadedAppDetector).isSafe(taskInfo2);
- verify(mSideLoadedAppDetector, never()).isSafe(taskInfo3);
- verify(mSideLoadedAppDetector).isSafe(taskInfo4);
- verify(mSideLoadedAppDetector).isSafe(taskInfo5);
-
- verify(mSideLoadedAppStateController, never()).onUnsafeTaskCreatedOnDisplay(any());
- verify(mSideLoadedAppStateController).onSafeTaskDisplayedOnDisplay(display1);
- verify(mSideLoadedAppStateController).onUnsafeTaskDisplayedOnDisplay(display2);
- verify(mSideLoadedAppStateController).onSafeTaskDisplayedOnDisplay(display3);
- verify(mSideLoadedAppStateController, never()).onUnsafeTaskDisplayedOnDisplay(display1);
- verify(mSideLoadedAppStateController).onUnsafeTaskDisplayedOnDisplay(display2);
- verify(mSideLoadedAppStateController, never()).onUnsafeTaskDisplayedOnDisplay(display3);
- }
-
- private Display createDisplay(int id) {
- return new Display(DisplayManagerGlobal.getInstance(),
- id,
- new DisplayInfo(),
- DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
- }
-
- private RootTaskInfo createTask(int id, boolean isVisible) {
- RootTaskInfo taskInfo = new RootTaskInfo();
- taskInfo.taskId = id;
- taskInfo.visible = isVisible;
- return taskInfo;
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/statusbar/UserNameViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/statusbar/UserNameViewControllerTest.java
deleted file mode 100644
index ac7edd3..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/statusbar/UserNameViewControllerTest.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.statusbar;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-import android.car.Car;
-import android.car.user.CarUserManager;
-import android.content.BroadcastReceiver;
-import android.content.Intent;
-import android.content.pm.UserInfo;
-import android.os.UserManager;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.view.View;
-import android.widget.TextView;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.car.CarServiceProvider;
-import com.android.systemui.car.CarSystemUiTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class UserNameViewControllerTest extends SysuiTestCase {
-
- private final UserInfo mUserInfo1 = new UserInfo(/* id= */ 0, "Test User Name", /* flags= */ 0);
- private final UserInfo mUserInfo2 = new UserInfo(/* id= */ 1, "Another User", /* flags= */ 0);
- private TextView mTextView;
- private UserNameViewController mUserNameViewController;
-
- @Mock
- private Car mCar;
- @Mock
- private CarUserManager mCarUserManager;
- @Mock
- private UserManager mUserManager;
- @Mock
- private CarDeviceProvisionedController mCarDeviceProvisionedController;
- @Mock
- private BroadcastDispatcher mBroadcastDispatcher;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- when(mUserManager.getUserInfo(mUserInfo1.id)).thenReturn(mUserInfo1);
- when(mUserManager.getUserInfo(mUserInfo2.id)).thenReturn(mUserInfo2);
- when(mCar.isConnected()).thenReturn(true);
- when(mCar.getCarManager(Car.CAR_USER_SERVICE)).thenReturn(mCarUserManager);
-
- CarServiceProvider carServiceProvider = new CarServiceProvider(mContext, mCar);
- mUserNameViewController = new UserNameViewController(getContext(), carServiceProvider,
- mUserManager, mBroadcastDispatcher, mCarDeviceProvisionedController);
-
- mTextView = new TextView(getContext());
- mTextView.setId(R.id.user_name_text);
- }
-
- @Test
- public void addUserNameViewToController_updatesUserNameView() {
- when(mCarDeviceProvisionedController.getCurrentUser()).thenReturn(mUserInfo1.id);
-
- mUserNameViewController.addUserNameView(mTextView);
-
- assertEquals(mTextView.getText(), mUserInfo1.name);
- }
-
- @Test
- public void addUserNameViewToController_withNoTextView_doesNotUpdate() {
- View nullView = new View(getContext());
- mUserNameViewController.addUserNameView(nullView);
-
- assertEquals(mTextView.getText(), "");
- verifyZeroInteractions(mCarDeviceProvisionedController);
- verifyZeroInteractions(mCarUserManager);
- verifyZeroInteractions(mUserManager);
- }
-
- @Test
- public void removeAll_withNoRegisteredListener_doesNotUnregister() {
- mUserNameViewController.removeAll();
-
- verifyZeroInteractions(mCarUserManager);
- }
-
- @Test
- public void userLifecycleListener_onUserSwitchLifecycleEvent_updatesUserNameView() {
- ArgumentCaptor<CarUserManager.UserLifecycleListener> userLifecycleListenerArgumentCaptor =
- ArgumentCaptor.forClass(CarUserManager.UserLifecycleListener.class);
- when(mCarDeviceProvisionedController.getCurrentUser()).thenReturn(mUserInfo1.id);
- // Add the initial TextView, which registers the UserLifecycleListener
- mUserNameViewController.addUserNameView(mTextView);
- assertEquals(mTextView.getText(), mUserInfo1.name);
- verify(mCarUserManager).addListener(any(), userLifecycleListenerArgumentCaptor.capture());
-
- CarUserManager.UserLifecycleEvent event = new CarUserManager.UserLifecycleEvent(
- CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING, /* from= */ mUserInfo1.id,
- /* to= */ mUserInfo2.id);
- userLifecycleListenerArgumentCaptor.getValue().onEvent(event);
-
- assertEquals(mTextView.getText(), mUserInfo2.name);
- }
-
- @Test
- public void userInfoChangedBroadcast_withoutInitializingUserNameView_doesNothing() {
- getContext().sendBroadcast(new Intent(Intent.ACTION_USER_INFO_CHANGED));
-
- assertEquals(mTextView.getText(), "");
- verifyZeroInteractions(mCarDeviceProvisionedController);
- }
-
- @Test
- public void userInfoChangedBroadcast_withUserNameViewInitialized_updatesUserNameView() {
- ArgumentCaptor<BroadcastReceiver> broadcastReceiverArgumentCaptor = ArgumentCaptor.forClass(
- BroadcastReceiver.class);
- when(mCarDeviceProvisionedController.getCurrentUser()).thenReturn(mUserInfo1.id);
- mUserNameViewController.addUserNameView(mTextView);
- assertEquals(mTextView.getText(), mUserInfo1.name);
- verify(mBroadcastDispatcher).registerReceiver(broadcastReceiverArgumentCaptor.capture(),
- any(), any(), any());
-
- reset(mCarDeviceProvisionedController);
- when(mCarDeviceProvisionedController.getCurrentUser()).thenReturn(mUserInfo2.id);
- broadcastReceiverArgumentCaptor.getValue().onReceive(getContext(),
- new Intent(Intent.ACTION_USER_INFO_CHANGED));
-
- assertEquals(mTextView.getText(), mUserInfo2.name);
- verify(mCarDeviceProvisionedController).getCurrentUser();
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewControllerTest.java
deleted file mode 100644
index 2e9d43b..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewControllerTest.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.userswitcher;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.Handler;
-import android.os.UserManager;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.testing.TestableResources;
-import android.view.IWindowManager;
-import android.view.LayoutInflater;
-import android.view.ViewGroup;
-
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarSystemUiTest;
-import com.android.systemui.car.window.OverlayViewGlobalStateController;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class UserSwitchTransitionViewControllerTest extends SysuiTestCase {
- private static final int TEST_USER_1 = 100;
- private static final int TEST_USER_2 = 110;
-
- private TestableUserSwitchTransitionViewController mCarUserSwitchingDialogController;
- private TestableResources mTestableResources;
- @Mock
- private OverlayViewGlobalStateController mOverlayViewGlobalStateController;
- @Mock
- private IWindowManager mWindowManagerService;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mTestableResources = mContext.getOrCreateTestableResources();
- mCarUserSwitchingDialogController = new TestableUserSwitchTransitionViewController(
- mContext,
- Handler.getMain(),
- mTestableResources.getResources(),
- (UserManager) mContext.getSystemService(Context.USER_SERVICE),
- mWindowManagerService,
- mOverlayViewGlobalStateController
- );
-
- mCarUserSwitchingDialogController.inflate((ViewGroup) LayoutInflater.from(mContext).inflate(
- R.layout.sysui_overlay_window, /* root= */ null));
- }
-
- @Test
- public void onHandleShow_newUserSelected_showsDialog() {
- mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
-
- verify(mOverlayViewGlobalStateController).showView(eq(mCarUserSwitchingDialogController),
- any());
- }
-
- @Test
- public void onHandleShow_alreadyShowing_ignoresRequest() {
- mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
- mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_2);
-
- // Verify that the request was processed only once.
- verify(mOverlayViewGlobalStateController).showView(eq(mCarUserSwitchingDialogController),
- any());
- }
-
- @Test
- public void onHandleShow_sameUserSelected_ignoresRequest() {
- mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
- mCarUserSwitchingDialogController.handleHide();
- mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
-
- // Verify that the request was processed only once.
- verify(mOverlayViewGlobalStateController).showView(eq(mCarUserSwitchingDialogController),
- any());
- }
-
- @Test
- public void onHide_currentlyShowing_hidesDialog() {
- mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
- mCarUserSwitchingDialogController.handleHide();
-
- verify(mOverlayViewGlobalStateController).hideView(eq(mCarUserSwitchingDialogController),
- any());
- }
-
- @Test
- public void onHide_notShowing_ignoresRequest() {
- mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
- mCarUserSwitchingDialogController.handleHide();
- mCarUserSwitchingDialogController.handleHide();
-
- // Verify that the request was processed only once.
- verify(mOverlayViewGlobalStateController).hideView(eq(mCarUserSwitchingDialogController),
- any());
- }
-
- @Test
- public void onWindowShownTimeoutPassed_viewNotHidden_hidesUserSwitchTransitionView() {
- mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
- reset(mOverlayViewGlobalStateController);
-
- getContext().getMainThreadHandler().postDelayed(() -> {
- verify(mOverlayViewGlobalStateController).hideView(
- eq(mCarUserSwitchingDialogController), any());
- }, mCarUserSwitchingDialogController.getWindowShownTimeoutMs() + 10);
- }
-
- @Test
- public void onWindowShownTimeoutPassed_viewHidden_doesNotHideUserSwitchTransitionViewAgain() {
- mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
- mCarUserSwitchingDialogController.handleHide();
- reset(mOverlayViewGlobalStateController);
-
- getContext().getMainThreadHandler().postDelayed(() -> {
- verify(mOverlayViewGlobalStateController, never()).hideView(
- eq(mCarUserSwitchingDialogController), any());
- }, mCarUserSwitchingDialogController.getWindowShownTimeoutMs() + 10);
- }
-
- private final class TestableUserSwitchTransitionViewController extends
- UserSwitchTransitionViewController {
-
- private final Handler mHandler;
-
- TestableUserSwitchTransitionViewController(Context context, Handler handler,
- Resources resources, UserManager userManager,
- IWindowManager windowManagerService,
- OverlayViewGlobalStateController overlayViewGlobalStateController) {
- super(context, handler, resources, userManager, windowManagerService,
- overlayViewGlobalStateController);
- mHandler = handler;
- }
-
- @Override
- public void handleShow(int currentUserId) {
- super.handleShow(currentUserId);
- waitForIdleSync(mHandler);
- }
-
- @Override
- public void handleHide() {
- super.handleHide();
- waitForIdleSync(mHandler);
- }
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediatorTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediatorTest.java
deleted file mode 100644
index 7aeffce..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediatorTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.userswitcher;
-
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.car.user.CarUserManager;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.car.CarServiceProvider;
-import com.android.systemui.car.CarSystemUiTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class UserSwitchTransitionViewMediatorTest extends SysuiTestCase {
- private static final int TEST_USER = 100;
-
- private UserSwitchTransitionViewMediator mUserSwitchTransitionViewMediator;
- @Mock
- private CarServiceProvider mCarServiceProvider;
- @Mock
- private CarDeviceProvisionedController mCarDeviceProvisionedController;
- @Mock
- private UserSwitchTransitionViewController mUserSwitchTransitionViewController;
- @Mock
- private CarUserManager.UserLifecycleEvent mUserLifecycleEvent;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- mUserSwitchTransitionViewMediator = new UserSwitchTransitionViewMediator(
- mCarServiceProvider, mCarDeviceProvisionedController,
- mUserSwitchTransitionViewController);
- when(mCarDeviceProvisionedController.getCurrentUser()).thenReturn(TEST_USER);
- }
-
- @Test
- public void onUserLifecycleEvent_userStarting_isCurrentUser_callsHandleShow() {
- when(mUserLifecycleEvent.getEventType()).thenReturn(
- CarUserManager.USER_LIFECYCLE_EVENT_TYPE_STARTING);
- when(mUserLifecycleEvent.getUserId()).thenReturn(TEST_USER);
-
- mUserSwitchTransitionViewMediator.handleUserLifecycleEvent(mUserLifecycleEvent);
-
- verify(mUserSwitchTransitionViewController).handleShow(TEST_USER);
- }
-
- @Test
- public void onUserLifecycleEvent_userStarting_isNotCurrentUser_doesNotCallHandleShow() {
- when(mUserLifecycleEvent.getEventType()).thenReturn(
- CarUserManager.USER_LIFECYCLE_EVENT_TYPE_STARTING);
- when(mUserLifecycleEvent.getUserId()).thenReturn(TEST_USER);
- when(mCarDeviceProvisionedController.getCurrentUser()).thenReturn(TEST_USER + 1);
-
- mUserSwitchTransitionViewMediator.handleUserLifecycleEvent(mUserLifecycleEvent);
-
- verify(mUserSwitchTransitionViewController, never()).handleShow(TEST_USER);
- }
-
- @Test
- public void onUserLifecycleEvent_userSwitching_callsHandleHide() {
- when(mUserLifecycleEvent.getEventType()).thenReturn(
- CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING);
- mUserSwitchTransitionViewMediator.handleUserLifecycleEvent(mUserLifecycleEvent);
-
- verify(mUserSwitchTransitionViewController).handleHide();
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifierTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifierTest.java
deleted file mode 100644
index f77294e..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifierTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.voicerecognition;
-
-import static com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier.INVALID_VALUE;
-import static com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier.VOICE_RECOGNITION_STARTED;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHeadsetClient;
-import android.content.Intent;
-import android.os.Handler;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarSystemUiTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-// TODO(b/162866441): Refactor to use the Executor pattern instead.
-public class ConnectedDeviceVoiceRecognitionNotifierTest extends SysuiTestCase {
-
- private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
- private static final String BLUETOOTH_REMOTE_ADDRESS = "00:11:22:33:44:55";
-
- private ConnectedDeviceVoiceRecognitionNotifier mVoiceRecognitionNotifier;
- private TestableLooper mTestableLooper;
- private Handler mHandler;
- private Handler mTestHandler;
- private BluetoothDevice mBluetoothDevice;
-
- @Before
- public void setUp() throws Exception {
- mTestableLooper = TestableLooper.get(this);
- mHandler = new Handler(mTestableLooper.getLooper());
- mTestHandler = spy(mHandler);
- mBluetoothDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(
- BLUETOOTH_REMOTE_ADDRESS);
- mVoiceRecognitionNotifier = new ConnectedDeviceVoiceRecognitionNotifier(
- mContext, mTestHandler);
- mVoiceRecognitionNotifier.onBootCompleted();
- }
-
- @Test
- public void testReceiveIntent_started_showToast() {
- Intent intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT);
- intent.putExtra(BluetoothHeadsetClient.EXTRA_VOICE_RECOGNITION, VOICE_RECOGNITION_STARTED);
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice);
-
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- mTestableLooper.processAllMessages();
- waitForIdleSync();
-
- mHandler.post(() -> {
- ArgumentCaptor<Runnable> argumentCaptor = ArgumentCaptor.forClass(Runnable.class);
- verify(mTestHandler).post(argumentCaptor.capture());
- assertThat(argumentCaptor.getValue()).isNotNull();
- assertThat(argumentCaptor.getValue()).isNotEqualTo(this);
- });
- }
-
- @Test
- public void testReceiveIntent_invalidExtra_noToast() {
- Intent intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT);
- intent.putExtra(BluetoothHeadsetClient.EXTRA_VOICE_RECOGNITION, INVALID_VALUE);
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice);
-
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- mTestableLooper.processAllMessages();
- waitForIdleSync();
-
- mHandler.post(() -> {
- verify(mTestHandler, never()).post(any());
- });
- }
-
- @Test
- public void testReceiveIntent_noExtra_noToast() {
- Intent intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT);
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice);
-
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- mTestableLooper.processAllMessages();
- waitForIdleSync();
-
- mHandler.post(() -> {
- verify(mTestHandler, never()).post(any());
- });
- }
-
- @Test
- public void testReceiveIntent_invalidIntent_noToast() {
- Intent intent = new Intent(BluetoothHeadsetClient.ACTION_AUDIO_STATE_CHANGED);
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice);
-
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- mTestableLooper.processAllMessages();
- waitForIdleSync();
-
- mHandler.post(() -> {
- verify(mTestHandler, never()).post(any());
- });
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayPanelViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayPanelViewControllerTest.java
deleted file mode 100644
index f5f3ea3..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayPanelViewControllerTest.java
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.window;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyFloat;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.animation.Animator;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Rect;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.car.CarSystemUiTest;
-import com.android.systemui.tests.R;
-import com.android.wm.shell.animation.FlingAnimationUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class OverlayPanelViewControllerTest extends SysuiTestCase {
- private TestOverlayPanelViewController mOverlayPanelViewController;
- private ViewGroup mBaseLayout;
-
- @Mock
- private OverlayViewGlobalStateController mOverlayViewGlobalStateController;
- @Mock
- private FlingAnimationUtils.Builder mFlingAnimationUtilsBuilder;
- @Mock
- private FlingAnimationUtils mFlingAnimationUtils;
- @Mock
- private CarDeviceProvisionedController mCarDeviceProvisionedController;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- mBaseLayout = (ViewGroup) LayoutInflater.from(mContext).inflate(
- R.layout.overlay_view_controller_test, /* root= */ null);
-
- when(mFlingAnimationUtilsBuilder.setMaxLengthSeconds(anyFloat())).thenReturn(
- mFlingAnimationUtilsBuilder);
- when(mFlingAnimationUtilsBuilder.setSpeedUpFactor(anyFloat())).thenReturn(
- mFlingAnimationUtilsBuilder);
- when(mFlingAnimationUtilsBuilder.build()).thenReturn(mFlingAnimationUtils);
- mOverlayPanelViewController = new TestOverlayPanelViewController(
- getContext(),
- getContext().getOrCreateTestableResources().getResources(),
- R.id.overlay_view_controller_stub,
- mOverlayViewGlobalStateController,
- mFlingAnimationUtilsBuilder,
- mCarDeviceProvisionedController);
- }
-
- @Test
- public void toggle_notInflated_inflates() {
- assertThat(mOverlayPanelViewController.isInflated()).isFalse();
-
- mOverlayPanelViewController.toggle();
-
- verify(mOverlayViewGlobalStateController).inflateView(mOverlayPanelViewController);
- }
-
- @Test
- public void toggle_inflated_doesNotInflate() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- assertThat(mOverlayPanelViewController.isInflated()).isTrue();
-
- mOverlayPanelViewController.toggle();
-
- verify(mOverlayViewGlobalStateController, never()).inflateView(mOverlayPanelViewController);
- }
-
- @Test
- public void toggle_notExpanded_panelExpands() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- mOverlayPanelViewController.setPanelExpanded(false);
-
- mOverlayPanelViewController.toggle();
-
- assertThat(mOverlayPanelViewController.mAnimateExpandPanelCalled).isTrue();
- }
-
- @Test
- public void toggle_expanded_panelCollapses() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- mOverlayPanelViewController.setPanelExpanded(true);
-
- mOverlayPanelViewController.toggle();
-
- assertThat(mOverlayPanelViewController.mAnimateCollapsePanelCalled).isTrue();
- }
-
- @Test
- public void animateCollapsePanel_shouldNotAnimateCollapsePanel_doesNotCollapse() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- mOverlayPanelViewController.setShouldAnimateCollapsePanel(false);
-
- mOverlayPanelViewController.animateCollapsePanel();
-
- assertThat(mOverlayPanelViewController.mAnimateCollapsePanelCalled).isTrue();
- assertThat(mOverlayPanelViewController.mOnAnimateCollapsePanelCalled).isFalse();
- }
-
- @Test
- public void animateCollapsePanel_isNotExpanded_doesNotCollapse() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- mOverlayPanelViewController.setShouldAnimateCollapsePanel(true);
- mOverlayPanelViewController.setPanelExpanded(false);
-
- mOverlayPanelViewController.animateCollapsePanel();
-
- assertThat(mOverlayPanelViewController.mAnimateCollapsePanelCalled).isTrue();
- assertThat(mOverlayPanelViewController.mOnAnimateCollapsePanelCalled).isFalse();
- }
-
- @Test
- public void animateCollapsePanel_isNotVisible_doesNotCollapse() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- mOverlayPanelViewController.setShouldAnimateCollapsePanel(true);
- mOverlayPanelViewController.setPanelExpanded(true);
- mOverlayPanelViewController.setPanelVisible(false);
-
- mOverlayPanelViewController.animateCollapsePanel();
-
- assertThat(mOverlayPanelViewController.mAnimateCollapsePanelCalled).isTrue();
- assertThat(mOverlayPanelViewController.mOnAnimateCollapsePanelCalled).isFalse();
- }
-
- @Test
- public void animateCollapsePanel_collapses() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- mOverlayPanelViewController.setShouldAnimateCollapsePanel(true);
- mOverlayPanelViewController.setPanelExpanded(true);
- mOverlayPanelViewController.setPanelVisible(true);
-
- mOverlayPanelViewController.animateCollapsePanel();
-
- assertThat(mOverlayPanelViewController.mOnAnimateCollapsePanelCalled).isTrue();
- }
-
- @Test
- public void animateCollapsePanel_withOverlayFromTopBar_collapsesTowardsTopBar() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- // Mock a panel that has layout size 50 and where the panel is opened.
- int size = 50;
- mockPanelWithSize(size);
- mOverlayPanelViewController.getLayout().setClipBounds(
- new Rect(0, 0, size, size));
- mOverlayPanelViewController.setShouldAnimateCollapsePanel(true);
- mOverlayPanelViewController.setPanelExpanded(true);
- mOverlayPanelViewController.setPanelVisible(true);
- mOverlayPanelViewController.setOverlayDirection(
- OverlayPanelViewController.OVERLAY_FROM_TOP_BAR);
-
- mOverlayPanelViewController.animateCollapsePanel();
-
- ArgumentCaptor<Float> endValueCaptor = ArgumentCaptor.forClass(Float.class);
- verify(mFlingAnimationUtils).apply(
- any(Animator.class), anyFloat(), endValueCaptor.capture(), anyFloat());
- assertThat(endValueCaptor.getValue().intValue()).isEqualTo(0);
- }
-
- @Test
- public void animateCollapsePanel_withOverlayFromBottomBar_collapsesTowardsBottomBar() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- // Mock a panel that has layout size 50 and where the panel is opened.
- int size = 50;
- mockPanelWithSize(size);
- mOverlayPanelViewController.getLayout().setClipBounds(
- new Rect(0, 0, size, size));
- mOverlayPanelViewController.setShouldAnimateCollapsePanel(true);
- mOverlayPanelViewController.setPanelExpanded(true);
- mOverlayPanelViewController.setPanelVisible(true);
- mOverlayPanelViewController.setOverlayDirection(
- OverlayPanelViewController.OVERLAY_FROM_BOTTOM_BAR);
-
- mOverlayPanelViewController.animateCollapsePanel();
-
- ArgumentCaptor<Float> endValueCaptor = ArgumentCaptor.forClass(Float.class);
- verify(mFlingAnimationUtils).apply(
- any(Animator.class), anyFloat(), endValueCaptor.capture(), anyFloat());
- assertThat(endValueCaptor.getValue().intValue()).isEqualTo(
- mOverlayPanelViewController.getLayout().getHeight());
- }
-
- @Test
- public void animateExpandPanel_shouldNotAnimateExpandPanel_doesNotExpand() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- mOverlayPanelViewController.setShouldAnimateExpandPanel(false);
-
- mOverlayPanelViewController.animateExpandPanel();
-
- assertThat(mOverlayPanelViewController.mAnimateExpandPanelCalled).isTrue();
- assertThat(mOverlayPanelViewController.mOnAnimateExpandPanelCalled).isFalse();
- }
-
- @Test
- public void animateExpandPanel_userNotSetup_doesNotExpand() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- mOverlayPanelViewController.setShouldAnimateExpandPanel(true);
- when(mCarDeviceProvisionedController.isCurrentUserFullySetup()).thenReturn(false);
-
- mOverlayPanelViewController.animateExpandPanel();
-
- assertThat(mOverlayPanelViewController.mAnimateExpandPanelCalled).isTrue();
- assertThat(mOverlayPanelViewController.mOnAnimateExpandPanelCalled).isFalse();
- }
-
- @Test
- public void animateExpandPanel_expands() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- mOverlayPanelViewController.setShouldAnimateExpandPanel(true);
- when(mCarDeviceProvisionedController.isCurrentUserFullySetup()).thenReturn(true);
-
- mOverlayPanelViewController.animateExpandPanel();
-
- assertThat(mOverlayPanelViewController.mOnAnimateExpandPanelCalled).isTrue();
- }
-
- @Test
- public void animateExpandPanel_withOverlayFromTopBar_expandsToBottom() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- // Mock a panel that has layout size 50 and where the panel is not opened.
- int size = 50;
- mockPanelWithSize(size);
- mOverlayPanelViewController.getLayout().setClipBounds(
- new Rect(0, 0, size, 0));
- mOverlayPanelViewController.setShouldAnimateExpandPanel(true);
- when(mCarDeviceProvisionedController.isCurrentUserFullySetup()).thenReturn(true);
- mOverlayPanelViewController.setOverlayDirection(
- OverlayPanelViewController.OVERLAY_FROM_TOP_BAR);
-
- mOverlayPanelViewController.animateExpandPanel();
-
- ArgumentCaptor<Float> endValueCaptor = ArgumentCaptor.forClass(Float.class);
- verify(mFlingAnimationUtils).apply(
- any(Animator.class), anyFloat(), endValueCaptor.capture(), anyFloat());
- assertThat(endValueCaptor.getValue().intValue()).isEqualTo(
- mOverlayPanelViewController.getLayout().getHeight());
- }
-
- @Test
- public void animateExpandPanel_withOverlayFromBottomBar_expandsToTop() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- // Mock a panel that has layout size 50 and where the panel is not opened.
- int size = 50;
- mockPanelWithSize(size);
- mOverlayPanelViewController.getLayout().setClipBounds(
- new Rect(0, size, size, size));
- mOverlayPanelViewController.setShouldAnimateExpandPanel(true);
- when(mCarDeviceProvisionedController.isCurrentUserFullySetup()).thenReturn(true);
- mOverlayPanelViewController.setOverlayDirection(
- OverlayPanelViewController.OVERLAY_FROM_BOTTOM_BAR);
-
- mOverlayPanelViewController.animateExpandPanel();
-
- ArgumentCaptor<Float> endValueCaptor = ArgumentCaptor.forClass(Float.class);
- verify(mFlingAnimationUtils).apply(
- any(Animator.class), anyFloat(), endValueCaptor.capture(), anyFloat());
- assertThat(endValueCaptor.getValue().intValue()).isEqualTo(0);
- }
-
- @Test
- public void animateExpandPanel_setsPanelVisible() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- mOverlayPanelViewController.setShouldAnimateExpandPanel(true);
- when(mCarDeviceProvisionedController.isCurrentUserFullySetup()).thenReturn(true);
-
- mOverlayPanelViewController.animateExpandPanel();
-
- assertThat(mOverlayPanelViewController.isPanelVisible()).isTrue();
- }
-
- @Test
- public void animateExpandPanel_setsPanelExpanded() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- mOverlayPanelViewController.setShouldAnimateExpandPanel(true);
- when(mCarDeviceProvisionedController.isCurrentUserFullySetup()).thenReturn(true);
-
- mOverlayPanelViewController.animateExpandPanel();
-
- assertThat(mOverlayPanelViewController.isPanelExpanded()).isTrue();
- }
-
- @Test
- public void setPanelVisible_setTrue_windowNotVisible_setsWindowVisible() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- when(mOverlayViewGlobalStateController.isWindowVisible()).thenReturn(false);
-
- mOverlayPanelViewController.setPanelVisible(true);
-
- verify(mOverlayViewGlobalStateController).showView(mOverlayPanelViewController);
- }
-
- @Test
- public void setPanelVisible_setTrue_windowVisible_doesNotSetWindowVisible() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- when(mOverlayViewGlobalStateController.isWindowVisible()).thenReturn(true);
-
- mOverlayPanelViewController.setPanelVisible(true);
-
- verify(mOverlayViewGlobalStateController, never()).showView(mOverlayPanelViewController);
- }
-
- @Test
- public void setPanelVisible_setTrue_setLayoutVisible() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- mOverlayPanelViewController.getLayout().setVisibility(View.INVISIBLE);
-
- mOverlayPanelViewController.setPanelVisible(true);
-
- assertThat(mOverlayPanelViewController.getLayout().getVisibility()).isEqualTo(View.VISIBLE);
- }
-
- @Test
- public void setPanelVisible_setFalse_windowVisible_setsWindowNotVisible() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- when(mOverlayViewGlobalStateController.isWindowVisible()).thenReturn(true);
-
- mOverlayPanelViewController.setPanelVisible(false);
-
- verify(mOverlayViewGlobalStateController).hideView(mOverlayPanelViewController);
- }
-
- @Test
- public void setPanelVisible_setFalse_windowNotVisible_doesNotSetWindowNotVisible() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- when(mOverlayViewGlobalStateController.isWindowVisible()).thenReturn(false);
-
- mOverlayPanelViewController.setPanelVisible(false);
-
- verify(mOverlayViewGlobalStateController, never()).hideView(mOverlayPanelViewController);
- }
-
- @Test
- public void setPanelVisible_setFalse_setLayoutInvisible() {
- mOverlayPanelViewController.inflate(mBaseLayout);
- mOverlayPanelViewController.getLayout().setVisibility(View.VISIBLE);
-
- mOverlayPanelViewController.setPanelVisible(false);
-
- assertThat(mOverlayPanelViewController.getLayout().getVisibility()).isEqualTo(
- View.INVISIBLE);
- }
-
- @Test
- public void dragOpenTouchListener_isNotInflated_inflatesView() {
- when(mCarDeviceProvisionedController.isCurrentUserFullySetup()).thenReturn(true);
- assertThat(mOverlayPanelViewController.isInflated()).isFalse();
-
- mOverlayPanelViewController.getDragOpenTouchListener().onTouch(/* v= */ null,
- MotionEvent.obtain(/* downTime= */ 200, /* eventTime= */ 300,
- MotionEvent.ACTION_MOVE, /* x= */ 0, /* y= */ 0, /* metaState= */ 0));
-
- verify(mOverlayViewGlobalStateController).inflateView(mOverlayPanelViewController);
- }
-
- private void mockPanelWithSize(int size) {
- mOverlayPanelViewController.getLayout().setLeftTopRightBottom(0, 0, size, size);
- }
-
- private static class TestOverlayPanelViewController extends OverlayPanelViewController {
-
- boolean mOnAnimateCollapsePanelCalled;
- boolean mAnimateCollapsePanelCalled;
- boolean mOnAnimateExpandPanelCalled;
- boolean mAnimateExpandPanelCalled;
- boolean mOnCollapseAnimationEndCalled;
- boolean mOnExpandAnimationEndCalled;
- boolean mOnOpenScrollStartEnd;
- List<Integer> mOnScrollHeights;
- private boolean mShouldAnimateCollapsePanel;
- private boolean mShouldAnimateExpandPanel;
- private boolean mShouldAllowClosingScroll;
-
- TestOverlayPanelViewController(
- Context context,
- Resources resources,
- int stubId,
- OverlayViewGlobalStateController overlayViewGlobalStateController,
- FlingAnimationUtils.Builder flingAnimationUtilsBuilder,
- CarDeviceProvisionedController carDeviceProvisionedController) {
- super(context, resources, stubId, overlayViewGlobalStateController,
- flingAnimationUtilsBuilder,
- carDeviceProvisionedController);
-
- mOnScrollHeights = new ArrayList<>();
- }
-
- public void setShouldAnimateCollapsePanel(boolean shouldAnimate) {
- mShouldAnimateCollapsePanel = shouldAnimate;
- }
-
- @Override
- protected boolean shouldAnimateCollapsePanel() {
- return mShouldAnimateCollapsePanel;
- }
-
- @Override
- protected void animateCollapsePanel() {
- super.animateCollapsePanel();
- mAnimateCollapsePanelCalled = true;
- }
-
- @Override
- protected void onAnimateCollapsePanel() {
- mOnAnimateCollapsePanelCalled = true;
- }
-
- public void setShouldAnimateExpandPanel(boolean shouldAnimate) {
- mShouldAnimateExpandPanel = shouldAnimate;
- }
-
- @Override
- protected boolean shouldAnimateExpandPanel() {
- return mShouldAnimateExpandPanel;
- }
-
- @Override
- protected void animateExpandPanel() {
- super.animateExpandPanel();
- mAnimateExpandPanelCalled = true;
- }
-
- @Override
- protected void onAnimateExpandPanel() {
- mOnAnimateExpandPanelCalled = true;
- }
-
- @Override
- protected void onCollapseAnimationEnd() {
- mOnCollapseAnimationEndCalled = true;
- }
-
- @Override
- protected void onExpandAnimationEnd() {
- mOnExpandAnimationEndCalled = true;
- }
-
- @Override
- protected void onScroll(int height) {
- mOnScrollHeights.add(height);
- }
-
- @Override
- protected void onOpenScrollStart() {
- mOnOpenScrollStartEnd = true;
- }
-
- public void setShouldAllowClosingScroll(boolean shouldAllow) {
- mShouldAllowClosingScroll = shouldAllow;
- }
-
- @Override
- protected boolean shouldAllowClosingScroll() {
- return mShouldAllowClosingScroll;
- }
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewControllerTest.java
deleted file mode 100644
index e784761..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewControllerTest.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.window;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.verify;
-
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.view.LayoutInflater;
-import android.view.ViewGroup;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarSystemUiTest;
-import com.android.systemui.tests.R;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class OverlayViewControllerTest extends SysuiTestCase {
- private TestOverlayViewController mOverlayViewController;
- private ViewGroup mBaseLayout;
-
- @Mock
- private OverlayViewGlobalStateController mOverlayViewGlobalStateController;
-
- @Captor
- private ArgumentCaptor<Runnable> mRunnableArgumentCaptor;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(/* testClass= */ this);
-
- mOverlayViewController = new TestOverlayViewController(R.id.overlay_view_controller_stub,
- mOverlayViewGlobalStateController);
-
- mBaseLayout = (ViewGroup) LayoutInflater.from(mContext).inflate(
- R.layout.overlay_view_controller_test, /* root= */ null);
- }
-
- @Test
- public void inflate_layoutInitialized() {
- mOverlayViewController.inflate(mBaseLayout);
-
- assertThat(mOverlayViewController.getLayout().getId()).isEqualTo(
- R.id.overlay_view_controller_test);
- }
-
- @Test
- public void inflate_onFinishInflateCalled() {
- mOverlayViewController.inflate(mBaseLayout);
-
- assertThat(mOverlayViewController.mOnFinishInflateCalled).isTrue();
- }
-
- @Test
- public void start_viewInflated_viewShown() {
- mOverlayViewController.inflate(mBaseLayout);
-
- mOverlayViewController.start();
-
- verify(mOverlayViewGlobalStateController).showView(eq(mOverlayViewController),
- mRunnableArgumentCaptor.capture());
-
- mRunnableArgumentCaptor.getValue().run();
-
- assertThat(mOverlayViewController.mShowInternalCalled).isTrue();
- }
-
- @Test
- public void stop_viewInflated_viewHidden() {
- mOverlayViewController.inflate(mBaseLayout);
-
- mOverlayViewController.stop();
-
- verify(mOverlayViewGlobalStateController).hideView(eq(mOverlayViewController),
- mRunnableArgumentCaptor.capture());
-
- mRunnableArgumentCaptor.getValue().run();
-
- assertThat(mOverlayViewController.mHideInternalCalled).isTrue();
- }
-
- @Test
- public void start_viewNotInflated_viewNotShown() {
- mOverlayViewController.start();
-
- verify(mOverlayViewGlobalStateController).showView(eq(mOverlayViewController),
- mRunnableArgumentCaptor.capture());
-
- mRunnableArgumentCaptor.getValue().run();
-
- assertThat(mOverlayViewController.mShowInternalCalled).isFalse();
- }
-
- @Test
- public void stop_viewNotInflated_viewNotHidden() {
- mOverlayViewController.stop();
-
- verify(mOverlayViewGlobalStateController).hideView(eq(mOverlayViewController),
- mRunnableArgumentCaptor.capture());
-
- mRunnableArgumentCaptor.getValue().run();
-
- assertThat(mOverlayViewController.mHideInternalCalled).isFalse();
- }
-
- private static class TestOverlayViewController extends OverlayViewController {
- boolean mOnFinishInflateCalled = false;
- boolean mShowInternalCalled = false;
- boolean mHideInternalCalled = false;
-
- TestOverlayViewController(int stubId,
- OverlayViewGlobalStateController overlayViewGlobalStateController) {
- super(stubId, overlayViewGlobalStateController);
- }
-
- @Override
- protected void onFinishInflate() {
- mOnFinishInflateCalled = true;
- }
-
- @Override
- protected void showInternal() {
- mShowInternalCalled = true;
- }
-
- @Override
- protected void hideInternal() {
- mHideInternalCalled = true;
- }
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java
deleted file mode 100644
index 9c2931a..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java
+++ /dev/null
@@ -1,985 +0,0 @@
-/*
- * Copyright (C) 2020 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.car.window;
-
-import static android.view.WindowInsets.Type.navigationBars;
-import static android.view.WindowInsets.Type.statusBars;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewStub;
-import android.view.WindowInsets;
-import android.view.WindowInsetsController;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.car.CarSystemUiTest;
-import com.android.systemui.tests.R;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Arrays;
-
-@CarSystemUiTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class OverlayViewGlobalStateControllerTest extends SysuiTestCase {
- private static final int OVERLAY_VIEW_CONTROLLER_1_Z_ORDER = 0;
- private static final int OVERLAY_VIEW_CONTROLLER_2_Z_ORDER = 1;
- private static final int OVERLAY_PANEL_VIEW_CONTROLLER_Z_ORDER = 2;
-
- private OverlayViewGlobalStateController mOverlayViewGlobalStateController;
- private ViewGroup mBaseLayout;
-
- @Mock
- private SystemUIOverlayWindowController mSystemUIOverlayWindowController;
- @Mock
- private OverlayViewMediator mOverlayViewMediator;
- @Mock
- private OverlayViewController mOverlayViewController1;
- @Mock
- private OverlayViewController mOverlayViewController2;
- @Mock
- private OverlayPanelViewController mOverlayPanelViewController;
- @Mock
- private Runnable mRunnable;
- @Mock
- private WindowInsetsController mWindowInsetsController;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(/* testClass= */ this);
-
- mBaseLayout = spy((ViewGroup) LayoutInflater.from(mContext).inflate(
- R.layout.overlay_view_global_state_controller_test, /* root= */ null));
-
- when(mBaseLayout.getWindowInsetsController()).thenReturn(mWindowInsetsController);
-
- when(mSystemUIOverlayWindowController.getBaseLayout()).thenReturn(mBaseLayout);
-
- mOverlayViewGlobalStateController = new OverlayViewGlobalStateController(
- mSystemUIOverlayWindowController);
-
- verify(mSystemUIOverlayWindowController).attach();
- }
-
- @Test
- public void registerMediator_overlayViewMediatorListenersRegistered() {
- mOverlayViewGlobalStateController.registerMediator(mOverlayViewMediator);
-
- verify(mOverlayViewMediator).registerListeners();
- }
-
- @Test
- public void registerMediator_overlayViewMediatorViewControllerSetup() {
- mOverlayViewGlobalStateController.registerMediator(mOverlayViewMediator);
-
- verify(mOverlayViewMediator).setupOverlayContentViewControllers();
- }
-
- @Test
- public void showView_nothingVisible_windowNotFocusable_shouldShowNavBar_navBarsVisible() {
- setupOverlayViewController1();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(false);
- when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(true);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mWindowInsetsController).show(navigationBars());
- }
-
- @Test
- public void showView_nothingVisible_windowNotFocusable_shouldHideNavBar_notHidden() {
- setupOverlayViewController1();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(false);
- when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(false);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mWindowInsetsController, never()).hide(navigationBars());
- }
-
- @Test
- public void showView_nothingVisible_windowNotFocusable_shouldShowStatusBar_statusBarsVisible() {
- setupOverlayViewController1();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(false);
- when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(true);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mWindowInsetsController).show(statusBars());
- }
-
- @Test
- public void showView_nothingVisible_windowNotFocusable_shouldHideStatusBar_notHidden() {
- setupOverlayViewController1();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(false);
- when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(false);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mWindowInsetsController, never()).hide(statusBars());
- }
-
- @Test
- public void showView_nothingAlreadyShown_shouldShowNavBarFalse_navigationBarsHidden() {
- setupOverlayViewController1();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(false);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mWindowInsetsController).hide(navigationBars());
- }
-
- @Test
- public void showView_nothingAlreadyShown_shouldShowNavBarTrue_navigationBarsShown() {
- setupOverlayViewController1();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(true);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mWindowInsetsController).show(navigationBars());
- }
-
- @Test
- public void showView_nothingAlreadyShown_shouldShowStatusBarFalse_statusBarsHidden() {
- setupOverlayViewController1();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(false);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mWindowInsetsController).hide(statusBars());
- }
-
- @Test
- public void showView_nothingAlreadyShown_shouldShowStatusBarTrue_statusBarsShown() {
- setupOverlayViewController1();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(true);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mWindowInsetsController).show(statusBars());
- }
-
- @Test
- public void showView_nothingAlreadyShown_fitsNavBarInsets_insetsAdjusted() {
- setupOverlayViewController1();
- when(mOverlayViewController1.getInsetTypesToFit()).thenReturn(navigationBars());
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mSystemUIOverlayWindowController).setFitInsetsTypes(navigationBars());
- }
-
- @Test
- public void showView_nothingAlreadyShown_windowIsSetVisible() {
- setupOverlayViewController1();
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mSystemUIOverlayWindowController).setWindowVisible(true);
- }
-
- @Test
- public void showView_nothingAlreadyShown_newHighestZOrder() {
- setupOverlayViewController1();
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- assertThat(mOverlayViewGlobalStateController.mHighestZOrder).isEqualTo(
- mOverlayViewController1);
- }
-
- @Test
- public void showView_nothingAlreadyShown_newHighestZOrder_isVisible() {
- setupOverlayViewController1();
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.containsKey(
- OVERLAY_VIEW_CONTROLLER_1_Z_ORDER)).isTrue();
- }
-
- @Test
- public void showView_newHighestZOrder() {
- setupOverlayViewController1();
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- setupOverlayViewController2();
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable);
-
- assertThat(mOverlayViewGlobalStateController.mHighestZOrder).isEqualTo(
- mOverlayViewController2);
- }
-
- @Test
- public void showView_newHighestZOrder_shouldShowNavBarFalse_navigationBarsHidden() {
- setupOverlayViewController1();
- setupOverlayViewController2();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true);
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- when(mOverlayViewController2.shouldShowNavigationBarInsets()).thenReturn(false);
- reset(mWindowInsetsController);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable);
-
- verify(mWindowInsetsController).hide(navigationBars());
- }
-
- @Test
- public void showView_newHighestZOrder_shouldShowNavBarTrue_navigationBarsShown() {
- setupOverlayViewController1();
- setupOverlayViewController2();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true);
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- when(mOverlayViewController2.shouldShowNavigationBarInsets()).thenReturn(true);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable);
-
- verify(mWindowInsetsController).show(navigationBars());
- }
-
- @Test
- public void showView_newHighestZOrder_shouldShowStatusBarFalse_statusBarsHidden() {
- setupOverlayViewController1();
- setupOverlayViewController2();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true);
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- when(mOverlayViewController2.shouldShowStatusBarInsets()).thenReturn(false);
- reset(mWindowInsetsController);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable);
-
- verify(mWindowInsetsController).hide(statusBars());
- }
-
- @Test
- public void showView_newHighestZOrder_shouldShowStatusBarTrue_statusBarsShown() {
- setupOverlayViewController1();
- setupOverlayViewController2();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true);
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- when(mOverlayViewController2.shouldShowStatusBarInsets()).thenReturn(true);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable);
-
- verify(mWindowInsetsController).show(statusBars());
- }
-
- @Test
- public void showView_newHighestZOrder_fitsNavBarInsets_insetsAdjusted() {
- setupOverlayViewController1();
- when(mOverlayViewController1.getInsetTypesToFit()).thenReturn(statusBars());
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- setupOverlayViewController2();
- when(mOverlayViewController2.getInsetTypesToFit()).thenReturn(navigationBars());
- reset(mWindowInsetsController);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable);
-
- verify(mSystemUIOverlayWindowController).setFitInsetsTypes(navigationBars());
- }
-
- @Test
- public void showView_newHighestZOrder_correctViewsShown() {
- setupOverlayViewController1();
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- setupOverlayViewController2();
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable);
-
- assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.keySet().toArray())
- .isEqualTo(Arrays.asList(OVERLAY_VIEW_CONTROLLER_1_Z_ORDER,
- OVERLAY_VIEW_CONTROLLER_2_Z_ORDER).toArray());
- }
-
- @Test
- public void showView_oldHighestZOrder() {
- setupOverlayViewController2();
- setOverlayViewControllerAsShowing(mOverlayViewController2);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- assertThat(mOverlayViewGlobalStateController.mHighestZOrder).isEqualTo(
- mOverlayViewController2);
- }
-
- @Test
- public void showView_oldHighestZOrder_shouldShowNavBarFalse_navigationBarsHidden() {
- setupOverlayViewController2();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true);
- setOverlayViewControllerAsShowing(mOverlayViewController2);
- when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(true);
- when(mOverlayViewController2.shouldShowNavigationBarInsets()).thenReturn(false);
- reset(mWindowInsetsController);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mWindowInsetsController).hide(navigationBars());
- }
-
- @Test
- public void showView_oldHighestZOrder_shouldShowNavBarTrue_navigationBarsShown() {
- setupOverlayViewController2();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true);
- setOverlayViewControllerAsShowing(mOverlayViewController2);
- when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(false);
- when(mOverlayViewController2.shouldShowNavigationBarInsets()).thenReturn(true);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mWindowInsetsController).show(navigationBars());
- }
-
- @Test
- public void showView_oldHighestZOrder_shouldShowStatusBarFalse_statusBarsHidden() {
- setupOverlayViewController2();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true);
- setOverlayViewControllerAsShowing(mOverlayViewController2);
- when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(true);
- when(mOverlayViewController2.shouldShowStatusBarInsets()).thenReturn(false);
- reset(mWindowInsetsController);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mWindowInsetsController).hide(statusBars());
- }
-
- @Test
- public void showView_oldHighestZOrder_shouldShowStatusBarTrue_statusBarsShown() {
- setupOverlayViewController2();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true);
- setOverlayViewControllerAsShowing(mOverlayViewController2);
- when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(false);
- when(mOverlayViewController2.shouldShowStatusBarInsets()).thenReturn(true);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mWindowInsetsController).show(statusBars());
- }
-
- @Test
- public void showView_oldHighestZOrder_fitsNavBarInsets_insetsAdjusted() {
- setupOverlayViewController2();
- setOverlayViewControllerAsShowing(mOverlayViewController2);
- when(mOverlayViewController1.getInsetTypesToFit()).thenReturn(statusBars());
- when(mOverlayViewController2.getInsetTypesToFit()).thenReturn(navigationBars());
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mSystemUIOverlayWindowController).setFitInsetsTypes(navigationBars());
- }
-
- @Test
- public void showView_oldHighestZOrder_correctViewsShown() {
- setupOverlayViewController1();
- setupOverlayViewController2();
- setOverlayViewControllerAsShowing(mOverlayViewController2);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.keySet().toArray())
- .isEqualTo(Arrays.asList(OVERLAY_VIEW_CONTROLLER_1_Z_ORDER,
- OVERLAY_VIEW_CONTROLLER_2_Z_ORDER).toArray());
- }
-
- @Test
- public void showView_somethingAlreadyShown_windowVisibleNotCalled() {
- setupOverlayViewController1();
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- setupOverlayViewController2();
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable);
-
- verify(mSystemUIOverlayWindowController, never()).setWindowVisible(true);
- }
-
- @Test
- public void showView_viewControllerNotInflated_inflateViewController() {
- setupOverlayViewController2();
- when(mOverlayViewController2.isInflated()).thenReturn(false);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable);
-
- verify(mOverlayViewController2).inflate(mBaseLayout);
- }
-
- @Test
- public void showView_viewControllerInflated_inflateViewControllerNotCalled() {
- setupOverlayViewController2();
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable);
-
- verify(mOverlayViewController2, never()).inflate(mBaseLayout);
- }
-
- @Test
- public void showView_panelViewController_inflateViewControllerNotCalled() {
- setupOverlayPanelViewController();
-
- mOverlayViewGlobalStateController.showView(mOverlayPanelViewController, mRunnable);
-
- verify(mOverlayPanelViewController, never()).inflate(mBaseLayout);
- verify(mOverlayPanelViewController, never()).isInflated();
- }
-
- @Test
- public void showView_showRunnableCalled() {
- setupOverlayViewController1();
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mRunnable).run();
- }
-
- @Test
- public void hideView_viewControllerNotInflated_hideRunnableNotCalled() {
- when(mOverlayViewController2.isInflated()).thenReturn(false);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
-
- verify(mRunnable, never()).run();
- }
-
- @Test
- public void hideView_nothingShown_hideRunnableNotCalled() {
- when(mOverlayViewController2.isInflated()).thenReturn(true);
- mOverlayViewGlobalStateController.mZOrderMap.clear();
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
-
- verify(mRunnable, never()).run();
- }
-
- @Test
- public void hideView_viewControllerNotShown_hideRunnableNotCalled() {
- setupOverlayViewController1();
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- when(mOverlayViewController2.isInflated()).thenReturn(true);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
-
- verify(mRunnable, never()).run();
- }
-
- @Test
- public void hideView_viewControllerShown_hideRunnableCalled() {
- setupOverlayViewController1();
- setOverlayViewControllerAsShowing(mOverlayViewController1);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
-
- verify(mRunnable).run();
- }
-
- @Test
- public void hideView_viewControllerOnlyShown_noHighestZOrder() {
- setupOverlayViewController1();
- setOverlayViewControllerAsShowing(mOverlayViewController1);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
-
- assertThat(mOverlayViewGlobalStateController.mHighestZOrder).isNull();
- }
-
- @Test
- public void hideView_viewControllerOnlyShown_nothingShown() {
- setupOverlayViewController1();
- setOverlayViewControllerAsShowing(mOverlayViewController1);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
-
- assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.isEmpty()).isTrue();
- }
-
- @Test
- public void hideView_viewControllerOnlyShown_viewControllerNotShown() {
- setupOverlayViewController1();
- setOverlayViewControllerAsShowing(mOverlayViewController1);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
-
- assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.containsKey(
- OVERLAY_VIEW_CONTROLLER_1_Z_ORDER)).isFalse();
- }
-
- @Test
- public void hideView_newHighestZOrder_twoViewsShown() {
- setupOverlayViewController1();
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- setupOverlayViewController2();
- setOverlayViewControllerAsShowing(mOverlayViewController2);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
-
- assertThat(mOverlayViewGlobalStateController.mHighestZOrder).isEqualTo(
- mOverlayViewController1);
- }
-
- @Test
- public void hideView_newHighestZOrder_threeViewsShown() {
- setupOverlayViewController1();
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- setupOverlayViewController2();
- setOverlayViewControllerAsShowing(mOverlayViewController2);
- setupOverlayPanelViewController();
- setOverlayViewControllerAsShowing(mOverlayPanelViewController);
-
- mOverlayViewGlobalStateController.hideView(mOverlayPanelViewController, mRunnable);
-
- assertThat(mOverlayViewGlobalStateController.mHighestZOrder).isEqualTo(
- mOverlayViewController2);
- }
-
- @Test
- public void hideView_newHighestZOrder_shouldShowNavBarFalse_navigationBarHidden() {
- setupOverlayViewController1();
- setupOverlayViewController2();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true);
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- setOverlayViewControllerAsShowing(mOverlayViewController2);
- when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(false);
- reset(mWindowInsetsController);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
-
- verify(mWindowInsetsController).hide(navigationBars());
- }
-
- @Test
- public void hideView_newHighestZOrder_shouldShowNavBarTrue_navigationBarShown() {
- setupOverlayViewController1();
- setupOverlayViewController2();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true);
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- setOverlayViewControllerAsShowing(mOverlayViewController2);
- when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(true);
- reset(mWindowInsetsController);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
-
- verify(mWindowInsetsController).show(navigationBars());
- }
-
- @Test
- public void hideView_newHighestZOrder_shouldShowStatusBarFalse_statusBarHidden() {
- setupOverlayViewController1();
- setupOverlayViewController2();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true);
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- setOverlayViewControllerAsShowing(mOverlayViewController2);
- when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(false);
- reset(mWindowInsetsController);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
-
- verify(mWindowInsetsController).hide(statusBars());
- }
-
- @Test
- public void hideView_newHighestZOrder_shouldShowStatusBarTrue_statusBarShown() {
- setupOverlayViewController1();
- setupOverlayViewController2();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true);
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- setOverlayViewControllerAsShowing(mOverlayViewController2);
- when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(true);
- reset(mWindowInsetsController);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
-
- verify(mWindowInsetsController).show(statusBars());
- }
-
- @Test
- public void hideView_newHighestZOrder_fitsNavBarInsets_insetsAdjusted() {
- setupOverlayViewController1();
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- setupOverlayViewController2();
- setOverlayViewControllerAsShowing(mOverlayViewController2);
- when(mOverlayViewController1.getInsetTypesToFit()).thenReturn(navigationBars());
- when(mOverlayViewController2.getInsetTypesToFit()).thenReturn(statusBars());
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
-
- verify(mSystemUIOverlayWindowController).setFitInsetsTypes(navigationBars());
- }
-
- @Test
- public void hideView_oldHighestZOrder() {
- setupOverlayViewController1();
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- setupOverlayViewController2();
- setOverlayViewControllerAsShowing(mOverlayViewController2);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
-
- assertThat(mOverlayViewGlobalStateController.mHighestZOrder).isEqualTo(
- mOverlayViewController2);
- }
-
- @Test
- public void hideView_oldHighestZOrder_shouldShowNavBarFalse_navigationBarHidden() {
- setupOverlayViewController1();
- setupOverlayViewController2();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true);
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- setOverlayViewControllerAsShowing(mOverlayViewController2);
- when(mOverlayViewController2.shouldShowNavigationBarInsets()).thenReturn(false);
- reset(mWindowInsetsController);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
-
- verify(mWindowInsetsController).hide(navigationBars());
- }
-
- @Test
- public void hideView_oldHighestZOrder_shouldShowNavBarTrue_navigationBarShown() {
- setupOverlayViewController1();
- setupOverlayViewController2();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true);
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- setOverlayViewControllerAsShowing(mOverlayViewController2);
- when(mOverlayViewController2.shouldShowNavigationBarInsets()).thenReturn(true);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
-
- verify(mWindowInsetsController).show(navigationBars());
- }
-
- @Test
- public void hideView_oldHighestZOrder_shouldShowStatusBarFalse_statusBarHidden() {
- setupOverlayViewController1();
- setupOverlayViewController2();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true);
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- setOverlayViewControllerAsShowing(mOverlayViewController2);
- when(mOverlayViewController2.shouldShowStatusBarInsets()).thenReturn(false);
- reset(mWindowInsetsController);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
-
- verify(mWindowInsetsController).hide(statusBars());
- }
-
- @Test
- public void hideView_oldHighestZOrder_shouldShowStatusBarTrue_statusBarShown() {
- setupOverlayViewController1();
- setupOverlayViewController2();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true);
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- setOverlayViewControllerAsShowing(mOverlayViewController2);
- when(mOverlayViewController2.shouldShowStatusBarInsets()).thenReturn(true);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
-
- verify(mWindowInsetsController).show(statusBars());
- }
-
- @Test
- public void hideView_oldHighestZOrder_fitsNavBarInsets_insetsAdjusted() {
- setupOverlayViewController1();
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- setupOverlayViewController2();
- setOverlayViewControllerAsShowing(mOverlayViewController2);
- when(mOverlayViewController1.getInsetTypesToFit()).thenReturn(statusBars());
- when(mOverlayViewController2.getInsetTypesToFit()).thenReturn(navigationBars());
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
-
- verify(mSystemUIOverlayWindowController).setFitInsetsTypes(navigationBars());
- }
-
- @Test
- public void hideView_viewControllerNotOnlyShown_windowNotCollapsed() {
- setupOverlayViewController1();
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- setupOverlayViewController2();
- setOverlayViewControllerAsShowing(mOverlayViewController2);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable);
-
- verify(mSystemUIOverlayWindowController, never()).setWindowVisible(false);
- }
-
- @Test
- public void hideView_viewControllerOnlyShown_navigationBarShown() {
- setupOverlayViewController1();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- setOverlayViewControllerAsShowing(mOverlayViewController1);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
-
- verify(mWindowInsetsController).show(navigationBars());
- }
-
- @Test
- public void hideView_viewControllerOnlyShown_statusBarShown() {
- setupOverlayViewController1();
- when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true);
- setOverlayViewControllerAsShowing(mOverlayViewController1);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
-
- verify(mWindowInsetsController).show(statusBars());
- }
-
- @Test
- public void hideView_viewControllerOnlyShown_insetsAdjustedToDefault() {
- setupOverlayViewController1();
- setOverlayViewControllerAsShowing(mOverlayViewController1);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
-
- verify(mSystemUIOverlayWindowController).setFitInsetsTypes(statusBars());
- }
-
- @Test
- public void hideView_viewControllerOnlyShown_windowCollapsed() {
- setupOverlayViewController1();
- setOverlayViewControllerAsShowing(mOverlayViewController1);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable);
-
- verify(mSystemUIOverlayWindowController).setWindowVisible(false);
- }
-
- @Test
- public void setOccludedTrue_viewToHideWhenOccludedVisible_viewHidden() {
- setupOverlayViewController1();
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- when(mOverlayViewController1.shouldShowWhenOccluded()).thenReturn(false);
-
- mOverlayViewGlobalStateController.setOccluded(true);
-
- assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.containsValue(
- mOverlayViewController1)).isFalse();
- }
-
- @Test
- public void setOccludedTrue_viewToNotHideWhenOccludedVisible_viewShown() {
- setupOverlayViewController1();
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- when(mOverlayViewController1.shouldShowWhenOccluded()).thenReturn(true);
-
- mOverlayViewGlobalStateController.setOccluded(true);
-
- assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.containsValue(
- mOverlayViewController1)).isTrue();
- }
-
- @Test
- public void hideViewAndThenSetOccludedTrue_viewHiddenForOcclusion_viewHiddenAfterOcclusion() {
- setupOverlayViewController1();
- setOverlayViewControllerAsShowing(mOverlayViewController1);
- when(mOverlayViewController1.shouldShowWhenOccluded()).thenReturn(false);
- mOverlayViewGlobalStateController.setOccluded(true);
-
- mOverlayViewGlobalStateController.hideView(mOverlayViewController1, /* runnable= */ null);
- mOverlayViewGlobalStateController.setOccluded(false);
-
- assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.containsValue(
- mOverlayViewController1)).isFalse();
- }
-
- @Test
- public void setOccludedTrueAndThenShowView_viewToNotHideForOcclusion_viewShown() {
- setupOverlayViewController1();
- when(mOverlayViewController1.shouldShowWhenOccluded()).thenReturn(true);
-
- mOverlayViewGlobalStateController.setOccluded(true);
- setOverlayViewControllerAsShowing(mOverlayViewController1);
-
- assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.containsValue(
- mOverlayViewController1)).isTrue();
- }
-
- @Test
- public void setOccludedTrueAndThenShowView_viewToHideForOcclusion_viewHidden() {
- setupOverlayViewController1();
- when(mOverlayViewController1.shouldShowWhenOccluded()).thenReturn(false);
-
- mOverlayViewGlobalStateController.setOccluded(true);
- setOverlayViewControllerAsShowing(mOverlayViewController1);
-
- assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.containsValue(
- mOverlayViewController1)).isFalse();
- }
-
- @Test
- public void setOccludedFalse_viewShownAfterSetOccludedTrue_viewToHideForOcclusion_viewShown() {
- setupOverlayViewController1();
- when(mOverlayViewController1.shouldShowWhenOccluded()).thenReturn(false);
- mOverlayViewGlobalStateController.setOccluded(true);
- setOverlayViewControllerAsShowing(mOverlayViewController1);
-
- mOverlayViewGlobalStateController.setOccluded(false);
-
- assertThat(mOverlayViewGlobalStateController.mZOrderVisibleSortedMap.containsValue(
- mOverlayViewController1)).isTrue();
- }
-
- @Test
- public void inflateView_notInflated_inflates() {
- when(mOverlayViewController2.isInflated()).thenReturn(false);
-
- mOverlayViewGlobalStateController.inflateView(mOverlayViewController2);
-
- verify(mOverlayViewController2).inflate(mBaseLayout);
- }
-
- @Test
- public void inflateView_alreadyInflated_doesNotInflate() {
- when(mOverlayViewController2.isInflated()).thenReturn(true);
-
- mOverlayViewGlobalStateController.inflateView(mOverlayViewController2);
-
- verify(mOverlayViewController2, never()).inflate(mBaseLayout);
- }
-
- @Test
- public void showView_setInsetsToFitByType_setsFitInsetsType() {
- int insetTypeToFit = WindowInsets.Type.navigationBars();
- setupOverlayViewController1();
- when(mOverlayViewController1.getInsetTypesToFit()).thenReturn(insetTypeToFit);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mSystemUIOverlayWindowController).setFitInsetsTypes(insetTypeToFit);
- }
-
- @Test
- public void refreshInsetsToFit_setInsetsToFitBySide_setsFitInsetsSides() {
- int insetSidesToFit = WindowInsets.Side.LEFT;
- setupOverlayViewController1();
- when(mOverlayViewController1.getInsetSidesToFit()).thenReturn(insetSidesToFit);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mSystemUIOverlayWindowController).setFitInsetsSides(insetSidesToFit);
- }
-
- @Test
- public void refreshInsetsToFit_setInsetsToFitBySideUsed_firstFitsAllSystemBars() {
- int insetSidesToFit = WindowInsets.Side.LEFT;
- setupOverlayViewController1();
- when(mOverlayViewController1.getInsetSidesToFit()).thenReturn(insetSidesToFit);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mSystemUIOverlayWindowController).setFitInsetsTypes(WindowInsets.Type.systemBars());
- }
-
- @Test
- public void refreshInsetsToFit_bothInsetTypeAndSideDefined_insetSideTakesPrecedence() {
- int insetTypesToFit = WindowInsets.Type.navigationBars();
- int insetSidesToFit = WindowInsets.Side.LEFT;
- setupOverlayViewController1();
- when(mOverlayViewController1.getInsetTypesToFit()).thenReturn(insetTypesToFit);
- when(mOverlayViewController1.getInsetSidesToFit()).thenReturn(insetSidesToFit);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mSystemUIOverlayWindowController).setFitInsetsSides(insetSidesToFit);
- }
-
- @Test
- public void refreshInsetsToFit_bothInsetTypeAndSideDefined_insetTypeIgnored() {
- int insetTypesToFit = WindowInsets.Type.navigationBars();
- int insetSidesToFit = WindowInsets.Side.LEFT;
- setupOverlayViewController1();
- when(mOverlayViewController1.getInsetTypesToFit()).thenReturn(insetTypesToFit);
- when(mOverlayViewController1.getInsetSidesToFit()).thenReturn(insetSidesToFit);
-
- mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable);
-
- verify(mSystemUIOverlayWindowController, never()).setFitInsetsTypes(insetTypesToFit);
- }
-
- private void setupOverlayViewController1() {
- setupOverlayViewController(mOverlayViewController1, R.id.overlay_view_controller_stub_1,
- R.id.overlay_view_controller_1);
- }
-
- private void setupOverlayViewController2() {
- setupOverlayViewController(mOverlayViewController2, R.id.overlay_view_controller_stub_2,
- R.id.overlay_view_controller_2);
- }
-
- private void setupOverlayPanelViewController() {
- setupOverlayViewController(mOverlayPanelViewController, R.id.overlay_view_controller_stub_3,
- R.id.overlay_view_controller_3);
- }
-
- private void setupOverlayViewController(OverlayViewController overlayViewController,
- int stubId, int inflatedId) {
- ViewStub viewStub = mBaseLayout.findViewById(stubId);
- View layout;
- if (viewStub == null) {
- layout = mBaseLayout.findViewById(inflatedId);
- } else {
- layout = viewStub.inflate();
- }
- when(overlayViewController.getLayout()).thenReturn(layout);
- when(overlayViewController.isInflated()).thenReturn(true);
- when(overlayViewController.getInsetSidesToFit()).thenReturn(
- OverlayViewController.INVALID_INSET_SIDE);
- }
-
- private void setOverlayViewControllerAsShowing(OverlayViewController overlayViewController) {
- mOverlayViewGlobalStateController.showView(overlayViewController, /* show= */ null);
- reset(mSystemUIOverlayWindowController);
- when(mSystemUIOverlayWindowController.getBaseLayout()).thenReturn(mBaseLayout);
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/wm/BarControlPolicyTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/wm/BarControlPolicyTest.java
deleted file mode 100644
index da7cb8e..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/wm/BarControlPolicyTest.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2020 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.wm;
-
-import static android.view.WindowInsets.Type.navigationBars;
-import static android.view.WindowInsets.Type.statusBars;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.car.settings.CarSettings;
-import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class BarControlPolicyTest extends SysuiTestCase {
-
- private static final String PACKAGE_NAME = "sample.app";
-
- @Before
- public void setUp() {
- BarControlPolicy.reset();
- }
-
- @After
- public void tearDown() {
- Settings.Global.clearProviderForTest();
- }
-
- @Test
- public void reloadFromSetting_notSet_doesNotSetFilters() {
- BarControlPolicy.reloadFromSetting(mContext);
-
- assertThat(BarControlPolicy.sImmersiveStatusFilter).isNull();
- }
-
- @Test
- public void reloadFromSetting_invalidPolicyControlString_doesNotSetFilters() {
- String text = "sample text";
- Settings.Global.putString(
- mContext.getContentResolver(),
- CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE,
- text
- );
-
- BarControlPolicy.reloadFromSetting(mContext);
-
- assertThat(BarControlPolicy.sImmersiveStatusFilter).isNull();
- }
-
- @Test
- public void reloadFromSetting_validPolicyControlString_setsFilters() {
- String text = "immersive.status=" + PACKAGE_NAME;
- Settings.Global.putString(
- mContext.getContentResolver(),
- CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE,
- text
- );
-
- BarControlPolicy.reloadFromSetting(mContext);
-
- assertThat(BarControlPolicy.sImmersiveStatusFilter).isNotNull();
- }
-
- @Test
- public void reloadFromSetting_filtersSet_doesNotSetFiltersAgain() {
- String text = "immersive.status=" + PACKAGE_NAME;
- Settings.Global.putString(
- mContext.getContentResolver(),
- CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE,
- text
- );
-
- BarControlPolicy.reloadFromSetting(mContext);
-
- assertThat(BarControlPolicy.reloadFromSetting(mContext)).isFalse();
- }
-
- @Test
- public void getBarVisibilities_policyControlNotSet_showsSystemBars() {
- int[] visibilities = BarControlPolicy.getBarVisibilities(PACKAGE_NAME);
-
- assertThat(visibilities[0]).isEqualTo(statusBars() | navigationBars());
- assertThat(visibilities[1]).isEqualTo(0);
- }
-
- @Test
- public void getBarVisibilities_immersiveStatusForAppAndMatchingApp_hidesStatusBar() {
- Settings.Global.putString(
- mContext.getContentResolver(),
- CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE,
- "immersive.status=" + PACKAGE_NAME);
- BarControlPolicy.reloadFromSetting(mContext);
-
- int[] visibilities = BarControlPolicy.getBarVisibilities(PACKAGE_NAME);
-
- assertThat(visibilities[0]).isEqualTo(navigationBars());
- assertThat(visibilities[1]).isEqualTo(statusBars());
- }
-
- @Test
- public void getBarVisibilities_immersiveStatusForAppAndNonMatchingApp_showsSystemBars() {
- Settings.Global.putString(
- mContext.getContentResolver(),
- CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE,
- "immersive.status=" + PACKAGE_NAME);
- BarControlPolicy.reloadFromSetting(mContext);
-
- int[] visibilities = BarControlPolicy.getBarVisibilities("sample2.app");
-
- assertThat(visibilities[0]).isEqualTo(statusBars() | navigationBars());
- assertThat(visibilities[1]).isEqualTo(0);
- }
-
- @Test
- public void getBarVisibilities_immersiveStatusForAppsAndNonApp_showsSystemBars() {
- Settings.Global.putString(
- mContext.getContentResolver(),
- CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE,
- "immersive.status=apps");
- BarControlPolicy.reloadFromSetting(mContext);
-
- int[] visibilities = BarControlPolicy.getBarVisibilities(PACKAGE_NAME);
-
- assertThat(visibilities[0]).isEqualTo(statusBars() | navigationBars());
- assertThat(visibilities[1]).isEqualTo(0);
- }
-
- @Test
- public void getBarVisibilities_immersiveFullForAppAndMatchingApp_hidesSystemBars() {
- Settings.Global.putString(
- mContext.getContentResolver(),
- CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE,
- "immersive.full=" + PACKAGE_NAME);
- BarControlPolicy.reloadFromSetting(mContext);
-
- int[] visibilities = BarControlPolicy.getBarVisibilities(PACKAGE_NAME);
-
- assertThat(visibilities[0]).isEqualTo(0);
- assertThat(visibilities[1]).isEqualTo(statusBars() | navigationBars());
- }
-
- @Test
- public void getBarVisibilities_immersiveFullForAppAndNonMatchingApp_showsSystemBars() {
- Settings.Global.putString(
- mContext.getContentResolver(),
- CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE,
- "immersive.full=" + PACKAGE_NAME);
- BarControlPolicy.reloadFromSetting(mContext);
-
- int[] visibilities = BarControlPolicy.getBarVisibilities("sample2.app");
-
- assertThat(visibilities[0]).isEqualTo(statusBars() | navigationBars());
- assertThat(visibilities[1]).isEqualTo(0);
- }
-
- @Test
- public void getBarVisibilities_immersiveFullForAppsAndNonApp_showsSystemBars() {
- Settings.Global.putString(
- mContext.getContentResolver(),
- CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE,
- "immersive.full=apps");
- BarControlPolicy.reloadFromSetting(mContext);
-
- int[] visibilities = BarControlPolicy.getBarVisibilities(PACKAGE_NAME);
-
- assertThat(visibilities[0]).isEqualTo(statusBars() | navigationBars());
- assertThat(visibilities[1]).isEqualTo(0);
- }
-}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/wm/DisplaySystemBarsControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/wm/DisplaySystemBarsControllerTest.java
deleted file mode 100644
index 391f75e..0000000
--- a/packages/CarSystemUI/tests/src/com/android/systemui/wm/DisplaySystemBarsControllerTest.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2020 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.wm;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.verify;
-
-import android.car.settings.CarSettings;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.view.IWindowManager;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.TransactionPool;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class DisplaySystemBarsControllerTest extends SysuiTestCase {
-
- private DisplaySystemBarsController mController;
-
- private static final int DISPLAY_ID = 1;
-
- @Mock
- private IWindowManager mIWindowManager;
- @Mock
- private DisplayController mDisplayController;
- @Mock
- private Handler mHandler;
- @Mock
- private TransactionPool mTransactionPool;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- mController = new DisplaySystemBarsController(
- mContext,
- mIWindowManager,
- mDisplayController,
- mHandler,
- mTransactionPool
- );
- }
-
- @Test
- public void onDisplayAdded_setsDisplayWindowInsetsControllerOnWMService()
- throws RemoteException {
- mController.onDisplayAdded(DISPLAY_ID);
-
- verify(mIWindowManager).setDisplayWindowInsetsController(
- eq(DISPLAY_ID), any(DisplaySystemBarsController.PerDisplay.class));
- }
-
- @Test
- public void onDisplayAdded_loadsBarControlPolicyFilters() {
- String text = "sample text";
- Settings.Global.putString(
- mContext.getContentResolver(),
- CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE,
- text
- );
-
- mController.onDisplayAdded(DISPLAY_ID);
-
- assertThat(BarControlPolicy.sSettingValue).isEqualTo(text);
- }
-
- @Test
- public void onDisplayRemoved_unsetsDisplayWindowInsetsControllerInWMService()
- throws RemoteException {
- mController.onDisplayAdded(DISPLAY_ID);
-
- mController.onDisplayRemoved(DISPLAY_ID);
-
- verify(mIWindowManager).setDisplayWindowInsetsController(
- DISPLAY_ID, /* displayWindowInsetsController= */ null);
- }
-}
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
index c5876af..c653c73 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -87,7 +87,9 @@
private BluetoothAdapter mBluetoothAdapter;
private WifiManager mWifiManager;
@Nullable private BluetoothLeScanner mBLEScanner;
- private ScanSettings mDefaultScanSettings = new ScanSettings.Builder().build();
+ private ScanSettings mDefaultScanSettings = new ScanSettings.Builder()
+ .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
+ .build();
private List<DeviceFilter<?>> mFilters;
private List<BluetoothLeDeviceFilter> mBLEFilters;
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothDiscoverableTimeoutReceiver.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothDiscoverableTimeoutReceiver.java
index 9ea7a4a..6ce72bb 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothDiscoverableTimeoutReceiver.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothDiscoverableTimeoutReceiver.java
@@ -38,7 +38,7 @@
Intent intent = new Intent(INTENT_DISCOVERABLE_TIMEOUT);
intent.setClass(context, BluetoothDiscoverableTimeoutReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(
- context, 0, intent, 0);
+ context, 0, intent, PendingIntent.FLAG_IMMUTABLE);
AlarmManager alarmManager =
(AlarmManager) context.getSystemService (Context.ALARM_SERVICE);
@@ -47,8 +47,7 @@
alarmManager.cancel(pending);
Log.d(TAG, "setDiscoverableAlarm(): cancel prev alarm");
}
- pending = PendingIntent.getBroadcast(
- context, 0, intent, 0);
+ pending = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE);
alarmManager.set(AlarmManager.RTC_WAKEUP, alarmTime, pending);
}
@@ -59,7 +58,7 @@
Intent intent = new Intent(INTENT_DISCOVERABLE_TIMEOUT);
intent.setClass(context, BluetoothDiscoverableTimeoutReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(
- context, 0, intent, PendingIntent.FLAG_NO_CREATE);
+ context, 0, intent, PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_IMMUTABLE);
if (pending != null) {
// Cancel any previous alarms that do the same thing.
AlarmManager alarmManager =
diff --git a/packages/SettingsProvider/src/android/provider/settings/OWNERS b/packages/SettingsProvider/src/android/provider/settings/OWNERS
index 7e7710b..0f88811 100644
--- a/packages/SettingsProvider/src/android/provider/settings/OWNERS
+++ b/packages/SettingsProvider/src/android/provider/settings/OWNERS
@@ -1,4 +1,4 @@
# Bug component: 656484
-include platform/frameworks/base/services/backup:/OWNERS
+include platform/frameworks/base:/services/backup/OWNERS
diff --git a/packages/SettingsProvider/test/src/android/provider/OWNERS b/packages/SettingsProvider/test/src/android/provider/OWNERS
index 7e7710b..0f88811 100644
--- a/packages/SettingsProvider/test/src/android/provider/OWNERS
+++ b/packages/SettingsProvider/test/src/android/provider/OWNERS
@@ -1,4 +1,4 @@
# Bug component: 656484
-include platform/frameworks/base/services/backup:/OWNERS
+include platform/frameworks/base:/services/backup/OWNERS
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 39a6ed1..3de0fbd 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -669,7 +669,7 @@
</activity>
<activity
- android:name=".settings.BrightnessDialog"
+ android:name=".settings.brightness.BrightnessDialog"
android:label="@string/quick_settings_brightness_dialog_title"
android:theme="@*android:style/Theme.DeviceDefault.QuickSettings.Dialog"
android:finishOnCloseSystemDialogs="true"
diff --git a/packages/SystemUI/res/drawable/brightness_progress_drawable_thick.xml b/packages/SystemUI/res/drawable/brightness_progress_drawable_thick.xml
new file mode 100644
index 0000000..ca56ec1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/brightness_progress_drawable_thick.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2020 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.
+ -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
+ android:paddingMode="stack">
+ <item android:id="@android:id/progress"
+ android:gravity="center_vertical|fill_horizontal">
+ <clip
+ android:drawable="@drawable/brightness_progress_full_drawable"
+ android:clipOrientation="horizontal"
+ android:gravity="left"
+ />
+ </item>
+ <item android:id="@android:id/background"
+ android:gravity="center_vertical|fill_horizontal">
+ <shape android:shape="rectangle"
+ android:tint="?android:attr/colorControlNormal">
+ <size android:height="48dp" />
+ <solid android:color="@color/white_disabled" />
+ <corners android:radius="24dp" />
+ </shape>
+ </item>
+</layer-list>
\ No newline at end of file
diff --git a/packages/CarSystemUI/samples/sample3/rro/res/drawable/system_bar_background.xml b/packages/SystemUI/res/drawable/brightness_progress_full_drawable.xml
similarity index 76%
rename from packages/CarSystemUI/samples/sample3/rro/res/drawable/system_bar_background.xml
rename to packages/SystemUI/res/drawable/brightness_progress_full_drawable.xml
index 66da21c..a38b8b4 100644
--- a/packages/CarSystemUI/samples/sample3/rro/res/drawable/system_bar_background.xml
+++ b/packages/SystemUI/res/drawable/brightness_progress_full_drawable.xml
@@ -14,8 +14,11 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
- <solid
- android:color="#404040"
- />
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle"
+ android:tint="?android:attr/colorControlActivated">
+ <size android:height="48dp" />
+ <solid android:color="@android:color/white" />
+ <corners android:radius="24dp"/>
</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_brightness.xml b/packages/SystemUI/res/drawable/ic_brightness.xml
new file mode 100644
index 0000000..f443332
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_brightness.xml
@@ -0,0 +1,29 @@
+<!--
+Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+
+ <path
+ android:pathData="M18,14.48V18h-3.52L12,20.48L9.52,18H6v-3.52L3.52,12L6,9.52V6h3.52L12,3.52L14.48,6H18v3.52L20.48,12L18,14.48z"
+ />
+
+ <path
+ android:pathData=" M20,8.69 V4h-4.69L12,0.69L8.69,4H4v4.69L0.69,12L4,15.31V20h4.69L12,23.31L15.31,20H20v-4.69L23.31,12L20,8.69z M18,14.48V18h-3.52L12,20.48L9.52,18H6v-3.52L3.52,12L6,9.52V6h3.52L12,3.52L14.48,6H18v3.52L20.48,12L18,14.48z M12,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5s5,-2.24 5,-5S14.76,7 12,7z"
+ android:fillColor="#FFFFFF" />
+</vector>
diff --git a/packages/SystemUI/res/layout/brightness_mirror.xml b/packages/SystemUI/res/layout/brightness_mirror.xml
index e3440b5..8b47ab9 100644
--- a/packages/SystemUI/res/layout/brightness_mirror.xml
+++ b/packages/SystemUI/res/layout/brightness_mirror.xml
@@ -21,12 +21,5 @@
android:layout_height="@dimen/brightness_mirror_height"
android:layout_gravity="@integer/notification_panel_layout_gravity"
android:visibility="invisible">
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginLeft="@dimen/notification_side_paddings"
- android:layout_marginRight="@dimen/notification_side_paddings"
- android:background="@drawable/brightness_mirror_background">
- <include layout="@layout/quick_settings_brightness_dialog" />
- </FrameLayout>
+
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
index 12127f5..11814a1 100644
--- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
+++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
@@ -20,7 +20,7 @@
android:layout_gravity="center_vertical"
style="@style/BrightnessDialogContainer">
- <com.android.systemui.settings.ToggleSliderView
+ <com.android.systemui.settings.brightness.BrightnessSliderView
android:id="@+id/brightness_slider"
android:layout_width="0dp"
android:layout_height="48dp"
@@ -28,6 +28,54 @@
android:layout_weight="1"
android:contentDescription="@string/accessibility_brightness"
android:importantForAccessibility="no"
- systemui:text="@string/status_bar_settings_auto_brightness_label" />
+ systemui:text="@string/status_bar_settings_auto_brightness_label" >
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <CheckBox
+ android:id="@+id/toggle"
+ android:layout_width="48dp"
+ android:layout_height="0dp"
+ android:layout_alignParentStart="true"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentBottom="true"
+ android:button="@null"
+ android:background="@*android:drawable/switch_track_material"
+ android:visibility="gone"
+ />
+ <com.android.systemui.settings.brightness.ToggleSeekBar
+ android:id="@+id/slider"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_toEndOf="@id/toggle"
+ android:layout_centerVertical="true"
+ android:layout_alignParentStart="true"
+ android:layout_alignParentEnd="true"
+ android:paddingStart="20dp"
+ android:paddingEnd="20dp"
+ android:paddingTop="16dp"
+ android:paddingBottom="16dp"
+ android:thumb="@drawable/ic_brightness_thumb"
+ android:progressDrawable="@drawable/brightness_progress_drawable"
+ android:splitTrack="false"
+ />
+ <TextView
+ android:id="@+id/label"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_alignStart="@id/toggle"
+ android:layout_alignEnd="@id/toggle"
+ android:layout_centerVertical="true"
+ android:gravity="center"
+ android:paddingTop="26dp"
+ android:textColor="#666666"
+ android:textSize="12sp"
+ android:visibility="gone"
+ />
+
+ </RelativeLayout>
+ </com.android.systemui.settings.brightness.BrightnessSliderView>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog_thick.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog_thick.xml
new file mode 100644
index 0000000..e08b44a
--- /dev/null
+++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog_thick.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_gravity="center"
+ style="@style/BrightnessDialogContainer">
+
+ <com.android.systemui.settings.brightness.BrightnessSliderView
+ android:id="@+id/brightness_slider"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/brightness_mirror_height"
+ android:layout_gravity="center_vertical"
+ android:contentDescription="@string/accessibility_brightness"
+ android:importantForAccessibility="no" >
+
+ <com.android.systemui.settings.brightness.ToggleSeekBar
+ android:id="@+id/slider"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:minHeight="48dp"
+ android:thumb="@null"
+ android:background="@null"
+ android:progressDrawable="@drawable/brightness_progress_drawable_thick"
+ android:splitTrack="false"
+ />
+
+ <ImageView
+ android:id="@+id/image"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_marginLeft="48dp"
+ android:layout_gravity="center_vertical"
+ android:src="@drawable/ic_brightness"
+ android:tint="?android:attr/textColorTertiary"
+ android:visibility="visible"
+ />
+ </com.android.systemui.settings.brightness.BrightnessSliderView>
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout/status_bar_toggle_slider.xml b/packages/SystemUI/res/layout/status_bar_toggle_slider.xml
deleted file mode 100644
index 942f3dd..0000000
--- a/packages/SystemUI/res/layout/status_bar_toggle_slider.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2010 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.
--->
-
-<!-- android:background="@drawable/status_bar_closed_default_background" -->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <CheckBox
- android:id="@+id/toggle"
- android:layout_width="48dp"
- android:layout_height="0dp"
- android:layout_alignParentStart="true"
- android:layout_alignParentTop="true"
- android:layout_alignParentBottom="true"
- android:button="@null"
- android:background="@*android:drawable/switch_track_material"
- android:visibility="gone"
- />
- <com.android.systemui.settings.ToggleSeekBar
- android:id="@+id/slider"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_toEndOf="@id/toggle"
- android:layout_centerVertical="true"
- android:layout_alignParentStart="true"
- android:layout_alignParentEnd="true"
- android:paddingStart="20dp"
- android:paddingEnd="20dp"
- android:paddingTop="16dp"
- android:paddingBottom="16dp"
- android:thumb="@drawable/ic_brightness_thumb"
- android:progressDrawable="@drawable/brightness_progress_drawable"
- android:splitTrack="false"
- />
- <TextView
- android:id="@+id/label"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_alignStart="@id/toggle"
- android:layout_alignEnd="@id/toggle"
- android:layout_centerVertical="true"
- android:gravity="center"
- android:paddingTop="26dp"
- android:textColor="#666666"
- android:textSize="12sp"
- android:visibility="gone"
- />
-</merge>
diff --git a/packages/SystemUI/res/layout/super_notification_shade.xml b/packages/SystemUI/res/layout/super_notification_shade.xml
index d322e09..0ba546e 100644
--- a/packages/SystemUI/res/layout/super_notification_shade.xml
+++ b/packages/SystemUI/res/layout/super_notification_shade.xml
@@ -43,6 +43,12 @@
android:visibility="invisible" />
</com.android.systemui.statusbar.BackDropView>
+ <com.android.systemui.statusbar.LightRevealScrim
+ android:id="@+id/light_reveal_scrim"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone" />
+
<com.android.systemui.statusbar.ScrimView
android:id="@+id/scrim_behind"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/tv_pip_control_button.xml b/packages/SystemUI/res/layout/tv_pip_control_button.xml
deleted file mode 100644
index b9b0154..0000000
--- a/packages/SystemUI/res/layout/tv_pip_control_button.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2016, 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.
-*/
--->
-
-<!-- Layout for {@link com.android.systemui.pip.tv.PipControlButtonView}. -->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-
- <ImageView android:id="@+id/button"
- android:layout_width="34dp"
- android:layout_height="34dp"
- android:layout_alignParentTop="true"
- android:layout_centerHorizontal="true"
- android:focusable="true"
- android:src="@drawable/tv_pip_button_focused"
- android:importantForAccessibility="yes" />
-
- <ImageView android:id="@+id/icon"
- android:layout_width="34dp"
- android:layout_height="34dp"
- android:layout_alignParentTop="true"
- android:layout_centerHorizontal="true"
- android:padding="5dp"
- android:importantForAccessibility="no" />
-
- <TextView android:id="@+id/desc"
- android:layout_width="100dp"
- android:layout_height="wrap_content"
- android:layout_below="@id/icon"
- android:layout_centerHorizontal="true"
- android:layout_marginTop="3dp"
- android:gravity="center"
- android:text="@string/pip_fullscreen"
- android:alpha="0"
- android:fontFamily="sans-serif"
- android:textSize="12sp"
- android:textColor="#EEEEEE"
- android:importantForAccessibility="no" />
-</merge>
diff --git a/packages/SystemUI/res/layout/tv_pip_controls.xml b/packages/SystemUI/res/layout/tv_pip_controls.xml
deleted file mode 100644
index 0b7bce1..0000000
--- a/packages/SystemUI/res/layout/tv_pip_controls.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2016, 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.
-*/
--->
-
-<!-- Layout for {@link com.android.systemui.pip.tv.PipControlsView}. -->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-
- <com.android.systemui.pip.tv.PipControlButtonView
- android:id="@+id/full_button"
- android:layout_width="@dimen/picture_in_picture_button_width"
- android:layout_height="wrap_content"
- android:src="@drawable/ic_fullscreen_white_24dp"
- android:text="@string/pip_fullscreen" />
-
- <com.android.systemui.pip.tv.PipControlButtonView
- android:id="@+id/close_button"
- android:layout_width="@dimen/picture_in_picture_button_width"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/picture_in_picture_button_start_margin"
- android:src="@drawable/ic_close_white"
- android:text="@string/pip_close" />
-
- <com.android.systemui.pip.tv.PipControlButtonView
- android:id="@+id/play_pause_button"
- android:layout_width="@dimen/picture_in_picture_button_width"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/picture_in_picture_button_start_margin"
- android:src="@drawable/ic_pause_white"
- android:text="@string/pip_pause"
- android:visibility="gone" />
-</merge>
diff --git a/packages/SystemUI/res/values-h740dp-port/dimens.xml b/packages/SystemUI/res/values-h740dp-port/dimens.xml
index 966066f..4a23ee6 100644
--- a/packages/SystemUI/res/values-h740dp-port/dimens.xml
+++ b/packages/SystemUI/res/values-h740dp-port/dimens.xml
@@ -19,9 +19,9 @@
<dimen name="qs_tile_margin_vertical">24dp</dimen>
<!-- The height of the qs customize header. Should be
- (qs_panel_padding_top (48dp) + brightness_mirror_height (48dp) + qs_tile_margin_top (18dp)) -
+ (qs_panel_padding_top (48dp) + brightness_mirror_height (56dp) + qs_tile_margin_top (18dp)) -
(Toolbar_minWidth (56dp) + qs_tile_margin_top_bottom (12dp))
-->
- <dimen name="qs_customize_header_min_height">46dp</dimen>
+ <dimen name="qs_customize_header_min_height">54dp</dimen>
<dimen name="qs_tile_margin_top">18dp</dimen>
</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index e45f4eb..51d7b8e 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -22,8 +22,6 @@
<dimen name="docked_divider_handle_width">2dp</dimen>
<dimen name="docked_divider_handle_height">16dp</dimen>
- <dimen name="brightness_mirror_height">40dp</dimen>
-
<dimen name="qs_tile_margin_top">8dp</dimen>
<dimen name="qs_tile_margin_vertical">0dp</dimen>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 1a72fc2..4707537 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -114,7 +114,7 @@
<!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
<string name="quick_settings_tiles_stock" translatable="false">
- wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,dark,work,cast,night,screenrecord,reverse
+ wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,dark,work,cast,night,screenrecord,reverse,reduce_brightness
</string>
<!-- The tiles to display in QuickSettings -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 4a5e890..d946f7c 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -430,7 +430,7 @@
<dimen name="notification_panel_width">@dimen/match_parent</dimen>
- <dimen name="brightness_mirror_height">48dp</dimen>
+ <dimen name="brightness_mirror_height">56dp</dimen>
<!-- The width of the panel that holds the quick settings. -->
<dimen name="qs_panel_width">@dimen/notification_panel_width</dimen>
@@ -496,10 +496,10 @@
<dimen name="qs_tile_margin_top_bottom">12dp</dimen>
<dimen name="qs_tile_margin_top_bottom_negative">-12dp</dimen>
<!-- The height of the qs customize header. Should be
- (qs_panel_padding_top (48dp) + brightness_mirror_height (48dp) + qs_tile_margin_top (0dp)) -
+ (qs_panel_padding_top (48dp) + brightness_mirror_height (56dp) + qs_tile_margin_top (0dp)) -
(Toolbar_minWidth (56dp) + qs_tile_margin_top_bottom (12dp))
-->
- <dimen name="qs_customize_header_min_height">28dp</dimen>
+ <dimen name="qs_customize_header_min_height">36dp</dimen>
<dimen name="qs_tile_margin_top">0dp</dimen>
<dimen name="qs_tile_icon_background_stroke_width">-1dp</dimen>
<dimen name="qs_tile_background_size">44dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 773ef7d..ea1258f 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1014,6 +1014,11 @@
<string name="quick_settings_dark_mode_secondary_label_on_at">On at <xliff:g id="time" example="10 pm">%s</xliff:g></string>
<!-- QuickSettings: Secondary text for when the Dark theme or some other tile will be on until some user-selected time. [CHAR LIMIT=20] -->
<string name="quick_settings_dark_mode_secondary_label_until">Until <xliff:g id="time" example="7 am">%s</xliff:g></string>
+ <!-- TODO(b/170970602): remove translatable=false when RBC has official name and strings -->
+ <!-- QuickSettings: Label for the toggle that controls whether Reduce Bright Colors is enabled. [CHAR LIMIT=NONE] -->
+ <string name="quick_settings_reduce_bright_colors_label" translatable="false">Reduce Bright Colors</string>
+ <!-- QuickSettings: Secondary text for intensity level of Reduce Bright Colors. [CHAR LIMIT=NONE] -->
+ <string name="quick_settings_reduce_bright_colors_secondary_label" translatable="false"> <xliff:g id="intensity" example="50">%d</xliff:g>%% reduction</string>
<!-- QuickSettings: NFC tile [CHAR LIMIT=NONE] -->
<string name="quick_settings_nfc_label">NFC</string>
@@ -2816,8 +2821,12 @@
<!-- Text to display when copying the build number off QS [CHAR LIMIT=NONE]-->
<string name="build_number_copy_toast">Build number copied to clipboard.</string>
- <!-- Status for last interaction [CHAR LIMIT=120] -->
+ <!-- Status for last interaction with exact time [CHAR LIMIT=120] -->
<string name="last_interaction_status" translatable="false">You last chatted <xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string>
+ <!-- Status for last interaction when less than a certain time window [CHAR LIMIT=120] -->
+ <string name="last_interaction_status_less_than" translatable="false">You last chatted less than <xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string>
+ <!-- Status for last interaction when over a certain time window [CHAR LIMIT=120] -->
+ <string name="last_interaction_status_over" translatable="false">You last chatted over <xliff:g id="duration" example="1 week">%1$s</xliff:g> ago</string>
<!-- Status for conversation without interaction data [CHAR LIMIT=120] -->
<string name="basic_status" translatable="false">Open conversation</string>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
index cc8bf4f..2cdd7f1 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
@@ -154,8 +154,8 @@
}
mView.resetPasswordText(true /* animate */,
/* announce */
- result.getType() != PinResult.PIN_RESULT_TYPE_SUCCESS);
- if (result.getType() == PinResult.PIN_RESULT_TYPE_SUCCESS) {
+ result.getResult() != PinResult.PIN_RESULT_TYPE_SUCCESS);
+ if (result.getResult() == PinResult.PIN_RESULT_TYPE_SUCCESS) {
mKeyguardUpdateMonitor.reportSimUnlocked(mSubId);
mRemainingAttempts = -1;
mShowDefaultMessage = true;
@@ -163,7 +163,7 @@
true, KeyguardUpdateMonitor.getCurrentUser());
} else {
mShowDefaultMessage = false;
- if (result.getType() == PinResult.PIN_RESULT_TYPE_INCORRECT) {
+ if (result.getResult() == PinResult.PIN_RESULT_TYPE_INCORRECT) {
if (result.getAttemptsRemaining() <= 2) {
// this is getting critical - show dialog
getSimRemainingAttemptsDialog(
@@ -289,20 +289,14 @@
@Override
public void run() {
if (DEBUG) {
- Log.v(TAG, "call supplyPinReportResultForSubscriber(subid=" + mSubId + ")");
+ Log.v(TAG, "call supplyIccLockPin(subid=" + mSubId + ")");
}
- TelephonyManager telephonyManager =
- mTelephonyManager.createForSubscriptionId(mSubId);
- final PinResult result = telephonyManager.supplyPinReportPinResult(mPin);
- if (result == null) {
- Log.e(TAG, "Error result for supplyPinReportResult.");
- mView.post(() -> onSimCheckResponse(PinResult.getDefaultFailedResult()));
- } else {
- if (DEBUG) {
- Log.v(TAG, "supplyPinReportResult returned: " + result.toString());
- }
- mView.post(() -> onSimCheckResponse(result));
+ TelephonyManager telephonyManager = mTelephonyManager.createForSubscriptionId(mSubId);
+ final PinResult result = telephonyManager.supplyIccLockPin(mPin);
+ if (DEBUG) {
+ Log.v(TAG, "supplyIccLockPin returned: " + result.toString());
}
+ mView.post(() -> onSimCheckResponse(result));
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
index a873749..adb4c13 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
@@ -267,8 +267,8 @@
}
mView.resetPasswordText(true /* animate */,
/* announce */
- result.getType() != PinResult.PIN_RESULT_TYPE_SUCCESS);
- if (result.getType() == PinResult.PIN_RESULT_TYPE_SUCCESS) {
+ result.getResult() != PinResult.PIN_RESULT_TYPE_SUCCESS);
+ if (result.getResult() == PinResult.PIN_RESULT_TYPE_SUCCESS) {
mKeyguardUpdateMonitor.reportSimUnlocked(mSubId);
mRemainingAttempts = -1;
mShowDefaultMessage = true;
@@ -277,7 +277,7 @@
true, KeyguardUpdateMonitor.getCurrentUser());
} else {
mShowDefaultMessage = false;
- if (result.getType() == PinResult.PIN_RESULT_TYPE_INCORRECT) {
+ if (result.getResult() == PinResult.PIN_RESULT_TYPE_INCORRECT) {
// show message
mMessageAreaController.setMessage(mView.getPukPasswordErrorMessage(
result.getAttemptsRemaining(), false,
@@ -390,23 +390,15 @@
@Override
public void run() {
- if (DEBUG) Log.v(TAG, "call supplyPukReportResult()");
- TelephonyManager telephonyManager = mTelephonyManager.createForSubscriptionId(mSubId);
- final PinResult result = telephonyManager.supplyPukReportPinResult(mPuk, mPin);
- if (result == null) {
- Log.e(TAG, "Error result for supplyPukReportResult.");
- mView.post(() -> onSimLockChangedResponse(PinResult.getDefaultFailedResult()));
- } else {
- if (DEBUG) {
- Log.v(TAG, "supplyPukReportResult returned: " + result.toString());
- }
- mView.post(new Runnable() {
- @Override
- public void run() {
- onSimLockChangedResponse(result);
- }
- });
+ if (DEBUG) {
+ Log.v(TAG, "call supplyIccLockPuk(subid=" + mSubId + ")");
}
+ TelephonyManager telephonyManager = mTelephonyManager.createForSubscriptionId(mSubId);
+ final PinResult result = telephonyManager.supplyIccLockPuk(mPuk, mPin);
+ if (DEBUG) {
+ Log.v(TAG, "supplyIccLockPuk returned: " + result.toString());
+ }
+ mView.post(() -> onSimLockChangedResponse(result));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index f073ced..7e48edf 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -109,6 +109,7 @@
.setSplitScreen(mWMComponent.getSplitScreen())
.setOneHanded(mWMComponent.getOneHanded())
.setBubbles(mWMComponent.getBubbles())
+ .setHideDisplayCutout(mWMComponent.getHideDisplayCutout())
.setShellDump(mWMComponent.getShellDump());
} else {
// TODO: Call on prepareSysUIComponentBuilder but not with real components.
@@ -116,6 +117,7 @@
.setSplitScreen(Optional.ofNullable(null))
.setOneHanded(Optional.ofNullable(null))
.setBubbles(Optional.ofNullable(null))
+ .setHideDisplayCutout(Optional.ofNullable(null))
.setShellDump(Optional.ofNullable(null));
}
mSysUIComponent = builder.build();
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
index d13e194..13ff3f5 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
@@ -21,7 +21,7 @@
import com.android.systemui.ForegroundServicesDialog;
import com.android.systemui.keyguard.WorkLockActivity;
import com.android.systemui.screenrecord.ScreenRecordDialog;
-import com.android.systemui.settings.BrightnessDialog;
+import com.android.systemui.settings.brightness.BrightnessDialog;
import com.android.systemui.tuner.TunerActivity;
import com.android.systemui.usb.UsbDebuggingActivity;
import com.android.systemui.usb.UsbDebuggingSecondaryUserActivity;
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index b3e6033..7127f26 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -23,6 +23,7 @@
import android.app.INotificationManager;
import android.content.Context;
import android.content.SharedPreferences;
+import android.content.om.OverlayManager;
import android.hardware.display.AmbientDisplayConfiguration;
import android.os.Handler;
import android.os.HandlerThread;
@@ -43,6 +44,7 @@
import com.android.keyguard.ViewMediatorCallback;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.systemui.Prefs;
+import com.android.systemui.R;
import com.android.systemui.accessibility.ModeSwitchesController;
import com.android.systemui.accessibility.SystemActions;
import com.android.systemui.assist.AssistManager;
@@ -78,6 +80,7 @@
import com.android.systemui.statusbar.policy.DataSaverController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.theme.ThemeOverlayApplier;
import com.android.systemui.util.leak.LeakDetector;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.splitscreen.SplitScreen;
@@ -194,6 +197,17 @@
}
/** */
+ @SysUISingleton
+ @Provides
+ static ThemeOverlayApplier provideThemeOverlayManager(Context context,
+ @Background Executor bgExecutor, OverlayManager overlayManager,
+ DumpManager dumpManager) {
+ return new ThemeOverlayApplier(overlayManager, bgExecutor,
+ context.getString(R.string.launcher_overlayable_package),
+ context.getString(R.string.themepicker_overlayable_package), dumpManager);
+ }
+
+ /** */
@Provides
@SysUISingleton
public NavigationBarController provideNavigationBarController(Context context,
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
index 9705551..c3f2e18 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
@@ -31,6 +31,7 @@
import android.app.trust.TrustManager;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.om.OverlayManager;
import android.content.pm.IPackageManager;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
@@ -351,7 +352,7 @@
@Provides
static WallpaperManager provideWallpaperManager(Context context) {
- return (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE);
+ return context.getSystemService(WallpaperManager.class);
}
@Provides
@@ -363,6 +364,12 @@
@Provides
@Singleton
+ static OverlayManager provideOverlayManager(Context context) {
+ return context.getSystemService(OverlayManager.class);
+ }
+
+ @Provides
+ @Singleton
static WindowManager provideWindowManager(Context context) {
return context.getSystemService(WindowManager.class);
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index 54aeab5..02c3c2f 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -26,6 +26,7 @@
import com.android.systemui.util.InjectionInflationController;
import com.android.wm.shell.ShellDump;
import com.android.wm.shell.bubbles.Bubbles;
+import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.splitscreen.SplitScreen;
@@ -66,6 +67,9 @@
Builder setBubbles(Optional<Bubbles> b);
@BindsInstance
+ Builder setHideDisplayCutout(Optional<HideDisplayCutout> h);
+
+ @BindsInstance
Builder setShellDump(Optional<ShellDump> shellDump);
SysUIComponent build();
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
index 9154ddb..b3e62e52 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
@@ -20,6 +20,7 @@
import com.android.wm.shell.ShellDump;
import com.android.wm.shell.ShellInit;
import com.android.wm.shell.bubbles.Bubbles;
+import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.splitscreen.SplitScreen;
@@ -71,4 +72,7 @@
@WMSingleton
Optional<Bubbles> getBubbles();
+
+ @WMSingleton
+ Optional<HideDisplayCutout> getHideDisplayCutout();
}
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
index 6a78c64..c2ba6d5 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
@@ -69,12 +69,10 @@
*/
private void setTileViewsWithPriorityConversations() {
try {
- List<ShortcutInfo> shortcutInfos =
- PeopleSpaceUtils.getShortcutInfos(
- mContext, mNotificationManager, mPeopleManager);
+ List<ShortcutInfo> shortcutInfos = PeopleSpaceUtils.getShortcutInfos(mContext,
+ mNotificationManager, mPeopleManager);
for (ShortcutInfo conversation : shortcutInfos) {
- PeopleSpaceTileView tileView = new PeopleSpaceTileView(mContext,
- mPeopleSpaceLayout,
+ PeopleSpaceTileView tileView = new PeopleSpaceTileView(mContext, mPeopleSpaceLayout,
conversation.getId());
setTileView(tileView, conversation);
}
@@ -84,20 +82,14 @@
}
/** Sets {@code tileView} with the data in {@code conversation}. */
- private void setTileView(PeopleSpaceTileView tileView,
- ShortcutInfo shortcutInfo) {
+ private void setTileView(PeopleSpaceTileView tileView, ShortcutInfo shortcutInfo) {
try {
- int userId = UserHandle.getUserHandleForUid(
- shortcutInfo.getUserId()).getIdentifier();
+ int userId = UserHandle.getUserHandleForUid(shortcutInfo.getUserId()).getIdentifier();
String pkg = shortcutInfo.getPackage();
- long lastInteraction = mPeopleManager.getLastInteraction(
- pkg, userId,
+ long lastInteraction = mPeopleManager.getLastInteraction(pkg, userId,
shortcutInfo.getId());
- String status = lastInteraction != 0l ? mContext.getString(
- R.string.last_interaction_status,
- PeopleSpaceUtils.getLastInteractionString(
- lastInteraction)) : mContext.getString(R.string.basic_status);
+ String status = PeopleSpaceUtils.getLastInteractionString(mContext, lastInteraction);
tileView.setStatus(status);
tileView.setName(shortcutInfo.getLabel().toString());
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
index 1a9dd71..c983147 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
@@ -31,6 +31,8 @@
import android.provider.Settings;
import android.service.notification.ConversationChannelWrapper;
+import com.android.systemui.R;
+
import java.time.Duration;
import java.util.List;
import java.util.Locale;
@@ -38,25 +40,24 @@
/** Utils class for People Space. */
public class PeopleSpaceUtils {
- private static final String TAG = "PeopleSpaceUtils";
-
/** Turns on debugging information about People Space. */
public static final boolean DEBUG = true;
+ private static final String TAG = "PeopleSpaceUtils";
+ private static final int DAYS_IN_A_WEEK = 7;
+ private static final int MIN_HOUR = 1;
+ private static final int ONE_DAY = 1;
/** Returns a list of {@link ShortcutInfo} corresponding to user's conversations. */
- public static List<ShortcutInfo> getShortcutInfos(
- Context context,
- INotificationManager notificationManager,
- IPeopleManager peopleManager
- ) throws Exception {
+ public static List<ShortcutInfo> getShortcutInfos(Context context,
+ INotificationManager notificationManager, IPeopleManager peopleManager)
+ throws Exception {
boolean showAllConversations = Settings.Global.getInt(context.getContentResolver(),
Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0) == 0;
- List<ConversationChannelWrapper> conversations =
- notificationManager.getConversations(
- !showAllConversations /* priority only */).getList();
+ List<ConversationChannelWrapper> conversations = notificationManager.getConversations(
+ !showAllConversations /* priority only */).getList();
List<ShortcutInfo> shortcutInfos = conversations.stream().filter(
- c -> shouldKeepConversation(c)).map(
- c -> c.getShortcutInfo()).collect(Collectors.toList());
+ c -> shouldKeepConversation(c)).map(c -> c.getShortcutInfo()).collect(
+ Collectors.toList());
if (showAllConversations) {
List<ConversationChannel> recentConversations =
peopleManager.getRecentConversations().getList();
@@ -85,11 +86,8 @@
bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
// Single color bitmap will be created of 1x1 pixel
} else {
- bitmap = Bitmap.createBitmap(
- drawable.getIntrinsicWidth(),
- drawable.getIntrinsicHeight(),
- Bitmap.Config.ARGB_8888
- );
+ bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
+ drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(bitmap);
@@ -98,28 +96,31 @@
return bitmap;
}
- /** Returns a readable representation of {@code lastInteraction}. */
- public static String getLastInteractionString(long lastInteraction) {
+ /** Returns a readable status describing the {@code lastInteraction}. */
+ public static String getLastInteractionString(Context context, long lastInteraction) {
+ if (lastInteraction == 0L) {
+ return context.getString(R.string.basic_status);
+ }
long now = System.currentTimeMillis();
- Duration durationSinceLastInteraction = Duration.ofMillis(
- now - lastInteraction);
+ Duration durationSinceLastInteraction = Duration.ofMillis(now - lastInteraction);
MeasureFormat formatter = MeasureFormat.getInstance(Locale.getDefault(),
MeasureFormat.FormatWidth.WIDE);
- if (durationSinceLastInteraction.toDays() >= 1) {
- return
- formatter
- .formatMeasures(new Measure(durationSinceLastInteraction.toDays(),
- MeasureUnit.DAY));
- } else if (durationSinceLastInteraction.toHours() >= 1) {
- return formatter.formatMeasures(new Measure(durationSinceLastInteraction.toHours(),
- MeasureUnit.HOUR));
- } else if (durationSinceLastInteraction.toMinutes() >= 1) {
- return formatter.formatMeasures(new Measure(durationSinceLastInteraction.toMinutes(),
- MeasureUnit.MINUTE));
+ if (durationSinceLastInteraction.toHours() < MIN_HOUR) {
+ return context.getString(R.string.last_interaction_status_less_than,
+ formatter.formatMeasures(new Measure(MIN_HOUR, MeasureUnit.HOUR)));
+ } else if (durationSinceLastInteraction.toDays() < ONE_DAY) {
+ return context.getString(R.string.last_interaction_status, formatter.formatMeasures(
+ new Measure(durationSinceLastInteraction.toHours(), MeasureUnit.HOUR)));
+ } else if (durationSinceLastInteraction.toDays() < DAYS_IN_A_WEEK) {
+ return context.getString(R.string.last_interaction_status, formatter.formatMeasures(
+ new Measure(durationSinceLastInteraction.toDays(), MeasureUnit.DAY)));
} else {
- return formatter.formatMeasures(
- new Measure(durationSinceLastInteraction.toMillis() / 1000,
- MeasureUnit.SECOND));
+ return context.getString(durationSinceLastInteraction.toDays() == DAYS_IN_A_WEEK
+ ? R.string.last_interaction_status :
+ R.string.last_interaction_status_over,
+ formatter.formatMeasures(
+ new Measure(durationSinceLastInteraction.toDays() / DAYS_IN_A_WEEK,
+ MeasureUnit.WEEK)));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetRemoteViewsFactory.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetRemoteViewsFactory.java
index c68c306..d869986 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetRemoteViewsFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetRemoteViewsFactory.java
@@ -46,7 +46,7 @@
private PackageManager mPackageManager;
private LauncherApps mLauncherApps;
private List<ShortcutInfo> mShortcutInfos = new ArrayList<>();
- private Context mContext;
+ private final Context mContext;
public PeopleSpaceWidgetRemoteViewsFactory(Context context, Intent intent) {
this.mContext = context;
@@ -55,9 +55,8 @@
@Override
public void onCreate() {
if (DEBUG) Log.d(TAG, "onCreate called");
- mNotificationManager =
- INotificationManager.Stub.asInterface(
- ServiceManager.getService(Context.NOTIFICATION_SERVICE));
+ mNotificationManager = INotificationManager.Stub.asInterface(
+ ServiceManager.getService(Context.NOTIFICATION_SERVICE));
mPackageManager = mContext.getPackageManager();
mPeopleManager = IPeopleManager.Stub.asInterface(
ServiceManager.getService(Context.PEOPLE_SERVICE));
@@ -71,9 +70,8 @@
*/
private void setTileViewsWithPriorityConversations() {
try {
- mShortcutInfos =
- PeopleSpaceUtils.getShortcutInfos(
- mContext, mNotificationManager, mPeopleManager);
+ mShortcutInfos = PeopleSpaceUtils.getShortcutInfos(mContext, mNotificationManager,
+ mPeopleManager);
} catch (Exception e) {
Log.e(TAG, "Couldn't retrieve conversations", e);
}
@@ -99,21 +97,16 @@
public RemoteViews getViewAt(int i) {
if (DEBUG) Log.d(TAG, "getViewAt called, index: " + i);
- RemoteViews personView =
- new RemoteViews(mContext.getPackageName(), R.layout.people_space_widget_item);
+ RemoteViews personView = new RemoteViews(mContext.getPackageName(),
+ R.layout.people_space_widget_item);
try {
ShortcutInfo shortcutInfo = mShortcutInfos.get(i);
- int userId = UserHandle.getUserHandleForUid(
- shortcutInfo.getUserId()).getIdentifier();
+ int userId = UserHandle.getUserHandleForUid(shortcutInfo.getUserId()).getIdentifier();
String pkg = shortcutInfo.getPackage();
- long lastInteraction = mPeopleManager.getLastInteraction(
- pkg, userId,
+ long lastInteraction = mPeopleManager.getLastInteraction(pkg, userId,
shortcutInfo.getId());
- String status = lastInteraction != 0L ? mContext.getString(
- R.string.last_interaction_status,
- PeopleSpaceUtils.getLastInteractionString(
- lastInteraction)) : mContext.getString(R.string.basic_status);
+ String status = PeopleSpaceUtils.getLastInteractionString(mContext, lastInteraction);
personView.setTextViewText(R.id.status, status);
personView.setTextViewText(R.id.name, shortcutInfo.getLabel().toString());
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 758e0c5..08f38a8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -47,9 +47,8 @@
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.qs.logging.QSLogger;
-import com.android.systemui.settings.ToggleSliderView;
+import com.android.systemui.settings.brightness.BrightnessSlider;
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
-import com.android.systemui.statusbar.policy.BrightnessMirrorController.BrightnessMirrorListener;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
import com.android.systemui.util.animation.DisappearParameters;
@@ -62,7 +61,7 @@
import javax.inject.Named;
/** View that represents the quick settings tile panel (when expanded/pulled down). **/
-public class QSPanel extends LinearLayout implements Tunable, BrightnessMirrorListener {
+public class QSPanel extends LinearLayout implements Tunable {
public static final String QS_SHOW_BRIGHTNESS = "qs_show_brightness";
public static final String QS_SHOW_HEADER = "qs_show_header";
@@ -75,10 +74,12 @@
/**
* The index where the content starts that needs to be moved between parents
*/
- private final int mMovableContentStartIndex;
+ private int mMovableContentStartIndex;
@Nullable
protected View mBrightnessView;
+ @Nullable
+ protected BrightnessSlider mToggleSliderController;
private final H mHandler = new H();
private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
@@ -153,7 +154,6 @@
setOrientation(VERTICAL);
- addViewsAboveTiles();
mMovableContentStartIndex = getChildCount();
mRegularTileLayout = createRegularTileLayout();
mTileLayout = mRegularTileLayout;
@@ -191,10 +191,19 @@
}
}
- protected void addViewsAboveTiles() {
- mBrightnessView = LayoutInflater.from(mContext).inflate(
- R.layout.quick_settings_brightness_dialog, this, false);
- addView(mBrightnessView);
+ /**
+ * Add brightness view above the tile layout.
+ *
+ * Used to add the brightness slider after construction.
+ */
+ public void setBrightnessView(@NonNull View view) {
+ if (mBrightnessView != null) {
+ removeView(mBrightnessView);
+ mMovableContentStartIndex--;
+ }
+ addView(view, 0);
+ mBrightnessView = view;
+ mMovableContentStartIndex++;
}
/** */
@@ -321,22 +330,6 @@
}
}
- public void setBrightnessMirror(BrightnessMirrorController c) {
- if (mBrightnessMirrorController != null) {
- mBrightnessMirrorController.removeCallback(this);
- }
- mBrightnessMirrorController = c;
- if (mBrightnessMirrorController != null) {
- mBrightnessMirrorController.addCallback(this);
- }
- updateBrightnessMirror();
- }
-
- @Override
- public void onBrightnessMirrorReinflated(View brightnessMirror) {
- updateBrightnessMirror();
- }
-
@Nullable
View getBrightnessView() {
return mBrightnessView;
@@ -415,8 +408,6 @@
super.onConfigurationChanged(newConfig);
mOnConfigurationChangedListeners.forEach(
listener -> listener.onConfigurationChange(newConfig));
-
- updateBrightnessMirror();
}
@Override
@@ -578,16 +569,6 @@
}
}
- public void updateBrightnessMirror() {
- if (mBrightnessMirrorController != null) {
- ToggleSliderView brightnessSlider = findViewById(R.id.brightness_slider);
- ToggleSliderView mirrorSlider = mBrightnessMirrorController.getMirror()
- .findViewById(R.id.brightness_slider);
- brightnessSlider.setMirror(mirrorSlider);
- brightnessSlider.setMirrorController(mBrightnessMirrorController);
- }
- }
-
public void setExpanded(boolean expanded) {
if (mExpanded == expanded) return;
mQSLogger.logPanelExpanded(expanded, getDumpableTag());
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
index eef7e39..addaf7e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -26,14 +26,14 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.R;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.media.MediaHost;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.qs.customize.QSCustomizerController;
import com.android.systemui.qs.dagger.QSScope;
-import com.android.systemui.settings.BrightnessController;
+import com.android.systemui.settings.brightness.BrightnessController;
+import com.android.systemui.settings.brightness.BrightnessSlider;
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
import com.android.systemui.tuner.TunerService;
@@ -50,6 +50,8 @@
private final TunerService mTunerService;
private final QSCustomizerController mQsCustomizerController;
private final BrightnessController mBrightnessController;
+ private final BrightnessSlider.Factory mBrightnessSliderFactory;
+ private final BrightnessSlider mBrightnessSlider;
private final QSPanel.OnConfigurationChangedListener mOnConfigurationChangedListener =
new QSPanel.OnConfigurationChangedListener() {
@@ -60,29 +62,39 @@
if (mView.isListening()) {
refreshAllTiles();
}
+ updateBrightnessMirror();
}
};
private BrightnessMirrorController mBrightnessMirrorController;
+ private final BrightnessMirrorController.BrightnessMirrorListener mBrightnessMirrorListener =
+ mirror -> updateBrightnessMirror();
+
@Inject
QSPanelController(QSPanel view, QSSecurityFooter qsSecurityFooter, TunerService tunerService,
QSTileHost qstileHost, QSCustomizerController qsCustomizerController,
QSTileRevealController.Factory qsTileRevealControllerFactory,
DumpManager dumpManager, MetricsLogger metricsLogger, UiEventLogger uiEventLogger,
- BrightnessController.Factory brightnessControllerFactory) {
+ BrightnessController.Factory brightnessControllerFactory,
+ BrightnessSlider.Factory brightnessSliderFactory) {
super(view, qstileHost, qsCustomizerController, qsTileRevealControllerFactory,
metricsLogger, uiEventLogger, dumpManager);
mQsSecurityFooter = qsSecurityFooter;
mTunerService = tunerService;
mQsCustomizerController = qsCustomizerController;
mQsSecurityFooter.setHostEnvironment(qstileHost);
- mBrightnessController = brightnessControllerFactory.create(
- mView.findViewById(R.id.brightness_slider));
+ mBrightnessSliderFactory = brightnessSliderFactory;
+
+ mBrightnessSlider = mBrightnessSliderFactory.create(getContext(), mView);
+ mView.setBrightnessView(mBrightnessSlider.getRootView());
+
+ mBrightnessController = brightnessControllerFactory.create(mBrightnessSlider);
}
@Override
public void onInit() {
mQsCustomizerController.init();
+ mBrightnessSlider.init();
}
@Override
@@ -97,7 +109,7 @@
mView.setSecurityFooter(mQsSecurityFooter.getView());
switchTileLayout(true);
if (mBrightnessMirrorController != null) {
- mBrightnessMirrorController.addCallback(mView);
+ mBrightnessMirrorController.addCallback(mBrightnessMirrorListener);
}
}
@@ -106,7 +118,7 @@
mTunerService.removeTunable(mView);
mView.removeOnConfigurationChangedListener(mOnConfigurationChangedListener);
if (mBrightnessMirrorController != null) {
- mBrightnessMirrorController.removeCallback(mView);
+ mBrightnessMirrorController.removeCallback(mBrightnessMirrorListener);
}
super.onViewDetached();
}
@@ -154,7 +166,20 @@
/** */
public void setBrightnessMirror(BrightnessMirrorController brightnessMirrorController) {
mBrightnessMirrorController = brightnessMirrorController;
- mView.setBrightnessMirror(brightnessMirrorController);
+ if (mBrightnessMirrorController != null) {
+ mBrightnessMirrorController.removeCallback(mBrightnessMirrorListener);
+ }
+ mBrightnessMirrorController = brightnessMirrorController;
+ if (mBrightnessMirrorController != null) {
+ mBrightnessMirrorController.addCallback(mBrightnessMirrorListener);
+ }
+ updateBrightnessMirror();
+ }
+
+ private void updateBrightnessMirror() {
+ if (mBrightnessMirrorController != null) {
+ mBrightnessSlider.setMirrorControllerAndMirror(mBrightnessMirrorController);
+ }
}
/** Get the QSTileHost this panel uses. */
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 9c421b0..dde9a1f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -75,8 +75,8 @@
}
@Override
- protected void addViewsAboveTiles() {
- // Nothing to add above the tiles
+ public void setBrightnessView(View view) {
+ // Don't add brightness view
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
index 8e33496..24c0fd7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
@@ -40,6 +40,7 @@
import com.android.systemui.qs.tiles.LocationTile;
import com.android.systemui.qs.tiles.NfcTile;
import com.android.systemui.qs.tiles.NightDisplayTile;
+import com.android.systemui.qs.tiles.ReduceBrightColorsTile;
import com.android.systemui.qs.tiles.RotationLockTile;
import com.android.systemui.qs.tiles.ScreenRecordTile;
import com.android.systemui.qs.tiles.UiModeNightTile;
@@ -78,6 +79,7 @@
private final Provider<GarbageMonitor.MemoryTile> mMemoryTileProvider;
private final Provider<UiModeNightTile> mUiModeNightTileProvider;
private final Provider<ScreenRecordTile> mScreenRecordTileProvider;
+ private final Provider<ReduceBrightColorsTile> mReduceBrightColorsTileProvider;
private final Lazy<QSHost> mQsHostLazy;
private final Provider<CustomTile.Builder> mCustomTileBuilderProvider;
@@ -105,7 +107,8 @@
Provider<NfcTile> nfcTileProvider,
Provider<GarbageMonitor.MemoryTile> memoryTileProvider,
Provider<UiModeNightTile> uiModeNightTileProvider,
- Provider<ScreenRecordTile> screenRecordTileProvider) {
+ Provider<ScreenRecordTile> screenRecordTileProvider,
+ Provider<ReduceBrightColorsTile> reduceBrightColorsTileProvider) {
mQsHostLazy = qsHostLazy;
mCustomTileBuilderProvider = customTileBuilderProvider;
@@ -129,6 +132,7 @@
mMemoryTileProvider = memoryTileProvider;
mUiModeNightTileProvider = uiModeNightTileProvider;
mScreenRecordTileProvider = screenRecordTileProvider;
+ mReduceBrightColorsTileProvider = reduceBrightColorsTileProvider;
}
public QSTile createTile(String tileSpec) {
@@ -180,6 +184,8 @@
return mUiModeNightTileProvider.get();
case "screenrecord":
return mScreenRecordTileProvider.get();
+ case "reduce_brightness":
+ return mReduceBrightColorsTileProvider.get();
}
// Custom tiles
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java
new file mode 100644
index 0000000..84c7611
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles;
+
+import android.content.Intent;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.Settings;
+import android.service.quicksettings.Tile;
+import android.text.TextUtils;
+import android.widget.Switch;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.qs.QSTile;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.qs.QSHost;
+import com.android.systemui.qs.SecureSetting;
+import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.settings.UserTracker;
+import com.android.systemui.util.settings.SecureSettings;
+
+import javax.inject.Inject;
+
+/** Quick settings tile: Reduce Bright Colors **/
+public class ReduceBrightColorsTile extends QSTileImpl<QSTile.BooleanState> {
+
+ //TODO(b/170973645): get icon drawable
+ private final Icon mIcon = null;
+ private final SecureSetting mActivatedSetting;
+
+ @Inject
+ public ReduceBrightColorsTile(
+ QSHost host,
+ @Background Looper backgroundLooper,
+ @Main Handler mainHandler,
+ MetricsLogger metricsLogger,
+ StatusBarStateController statusBarStateController,
+ ActivityStarter activityStarter,
+ QSLogger qsLogger,
+ UserTracker userTracker,
+ SecureSettings secureSettings
+ ) {
+ super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController,
+ activityStarter, qsLogger);
+
+ mActivatedSetting = new SecureSetting(secureSettings, mainHandler,
+ Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, userTracker.getUserId()) {
+ @Override
+ protected void handleValueChanged(int value, boolean observedChange) {
+ refreshState();
+ }
+ };
+ }
+ @Override
+ public boolean isAvailable() {
+ // TODO(b/170970675): Call into ColorDisplayService to get availability/config status
+ return true;
+ }
+
+ @Override
+ protected void handleDestroy() {
+ super.handleDestroy();
+ mActivatedSetting.setListening(false);
+ }
+
+ @Override
+ public BooleanState newTileState() {
+ return new BooleanState();
+ }
+
+ @Override
+ public void handleSetListening(boolean listening) {
+ super.handleSetListening(listening);
+ mActivatedSetting.setListening(listening);
+ }
+
+ @Override
+ protected void handleUserSwitch(int newUserId) {
+ mActivatedSetting.setUserId(newUserId);
+ refreshState();
+ }
+
+ @Override
+ public Intent getLongClickIntent() {
+ return new Intent(Settings.ACTION_REDUCE_BRIGHT_COLORS_SETTINGS);
+ }
+
+ @Override
+ protected void handleClick() {
+ mActivatedSetting.setValue(mState.value ? 0 : 1);
+ }
+
+ @Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_reduce_bright_colors_label);
+ }
+
+ @Override
+ protected void handleUpdateState(BooleanState state, Object arg) {
+ state.value = mActivatedSetting.getValue() == 1;
+ state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
+ state.label = mContext.getString(R.string.quick_settings_reduce_bright_colors_label);
+ state.expandedAccessibilityClassName = Switch.class.getName();
+ state.contentDescription = state.label;
+
+ final int intensity = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.REDUCE_BRIGHT_COLORS_LEVEL, 0, mActivatedSetting.getCurrentUser());
+ state.secondaryLabel = state.value ? mContext.getString(
+ R.string.quick_settings_reduce_bright_colors_secondary_label, intensity) : "";
+
+ state.contentDescription = TextUtils.isEmpty(state.secondaryLabel)
+ ? state.label
+ : TextUtils.concat(state.label, ", ", state.secondaryLabel);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return 0;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 07a5839..35874cd 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -154,7 +154,6 @@
private SaveImageInBackgroundTask mSaveInBgTask;
private Animator mScreenshotAnimation;
- private Animator mDismissAnimation;
private Runnable mOnCompleteRunnable;
private boolean mInDarkMode;
@@ -168,7 +167,6 @@
case MESSAGE_CORNER_TIMEOUT:
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_INTERACTION_TIMEOUT);
ScreenshotController.this.dismissScreenshot(false);
- mOnCompleteRunnable.run();
break;
default:
break;
@@ -279,30 +277,22 @@
rect -> takeScreenshotInternal(finisher, rect));
}
- boolean isDismissing() {
- return (mDismissAnimation != null && mDismissAnimation.isRunning());
- }
-
/**
* Clears current screenshot
*/
void dismissScreenshot(boolean immediate) {
- Log.v(TAG, "clearing screenshot");
+ // If we're already animating out, don't restart the animation
+ // (but do obey an immediate dismissal)
+ if (!immediate && mScreenshotView.isDismissing()) {
+ Log.v(TAG, "Already dismissing, ignoring duplicate command");
+ return;
+ }
+ Log.v(TAG, "Clearing screenshot");
mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT);
- mScreenshotView.getViewTreeObserver().removeOnComputeInternalInsetsListener(
- mScreenshotView);
- if (!immediate) {
- mDismissAnimation = mScreenshotView.createScreenshotDismissAnimation();
- mDismissAnimation.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- clearScreenshot();
- }
- });
- mDismissAnimation.start();
+ if (immediate) {
+ resetScreenshotView();
} else {
- clearScreenshot();
+ mScreenshotView.animateDismissal();
}
}
@@ -373,6 +363,7 @@
// Inflate the screenshot layout
mScreenshotView = (ScreenshotView)
LayoutInflater.from(mContext).inflate(R.layout.global_screenshot, null);
+ mScreenshotView.init(mUiEventLogger, this::resetScreenshotView);
// TODO(159460485): Remove this when focus is handled properly in the system
mScreenshotView.setOnTouchListener((v, event) -> {
@@ -438,10 +429,10 @@
if (mScreenshotView.isAttachedToWindow()) {
// if we didn't already dismiss for another reason
- if (mDismissAnimation == null || !mDismissAnimation.isRunning()) {
+ if (!mScreenshotView.isDismissing()) {
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_REENTERED);
}
- dismissScreenshot(true);
+ mScreenshotView.reset();
}
mScreenBitmap = screenshot;
@@ -459,10 +450,6 @@
onConfigChanged(mContext.getResources().getConfiguration());
- if (mDismissAnimation != null && mDismissAnimation.isRunning()) {
- mDismissAnimation.cancel();
- }
-
// The window is focusable by default
setWindowFocusable(true);
@@ -474,7 +461,8 @@
mScrollCaptureClient.request(DEFAULT_DISPLAY, (connection) ->
mScreenshotView.showScrollChip(() ->
runScrollCapture(connection,
- () -> dismissScreenshot(true))));
+ () -> mScreenshotHandler.post(
+ () -> dismissScreenshot(false)))));
}
}
@@ -519,6 +507,7 @@
*/
private void startAnimation(final Consumer<Uri> finisher, Rect screenRect, Insets screenInsets,
boolean showFlash) {
+ mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT);
mScreenshotHandler.post(() -> {
if (!mScreenshotView.isAttachedToWindow()) {
mWindowManager.addView(mScreenshotView, mWindowLayoutParams);
@@ -531,8 +520,7 @@
mScreenshotView);
mScreenshotAnimation =
- mScreenshotView.createScreenshotDropInAnimation(screenRect, showFlash,
- this::onElementTapped);
+ mScreenshotView.createScreenshotDropInAnimation(screenRect, showFlash);
saveScreenshotInWorkerThread(finisher,
new ScreenshotController.ActionsReadyListener() {
@@ -551,6 +539,14 @@
});
}
+ private void resetScreenshotView() {
+ if (mScreenshotView.isAttachedToWindow()) {
+ mWindowManager.removeView(mScreenshotView);
+ }
+ mScreenshotView.reset();
+ mOnCompleteRunnable.run();
+ }
+
/**
* Creates a new worker thread and saves the screenshot to the media store.
*/
@@ -590,7 +586,6 @@
SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS,
AccessibilityManager.FLAG_CONTENT_CONTROLS);
- mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT);
mScreenshotHandler.sendMessageDelayed(
mScreenshotHandler.obtainMessage(MESSAGE_CORNER_TIMEOUT),
timeoutMs);
@@ -602,24 +597,16 @@
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
- mScreenshotView.setChipIntents(
- imageData, event -> onElementTapped(event));
+ mScreenshotView.setChipIntents(imageData);
}
});
} else {
- mScreenshotView.setChipIntents(
- imageData, this::onElementTapped);
+ mScreenshotView.setChipIntents(imageData);
}
});
}
}
- private void onElementTapped(ScreenshotEvent event) {
- mUiEventLogger.log(event);
- dismissScreenshot(false);
- mOnCompleteRunnable.run();
- }
-
/**
* Logs success/failure of the screenshot saving task, and shows an error if it failed.
*/
@@ -633,20 +620,11 @@
}
}
- private void clearScreenshot() {
- if (mScreenshotView.isAttachedToWindow()) {
- mWindowManager.removeView(mScreenshotView);
- }
-
- mScreenshotView.reset();
- }
-
private boolean isUserSetupComplete() {
return Settings.Secure.getInt(mContext.getContentResolver(),
SETTINGS_SECURE_USER_SETUP_COMPLETE, 0) == 1;
}
-
/**
* Updates the window focusability. If the window is already showing, then it updates the
* window immediately, otherwise the layout params will be applied when the window is next
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index 3383f80..2b4eacb 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -60,6 +60,7 @@
import android.widget.ImageView;
import android.widget.LinearLayout;
+import com.android.internal.logging.UiEventLogger;
import com.android.systemui.R;
import com.android.systemui.shared.system.QuickStepContract;
@@ -115,6 +116,10 @@
private ScreenshotActionChip mEditChip;
private ScreenshotActionChip mScrollChip;
+ private UiEventLogger mUiEventLogger;
+ private Runnable mOnDismissRunnable;
+ private Animator mDismissAnimation;
+
private final ArrayList<ScreenshotActionChip> mSmartChips = new ArrayList<>();
private PendingInteraction mPendingInteraction;
@@ -161,7 +166,7 @@
public void showScrollChip(Runnable onClick) {
mScrollChip.setVisibility(VISIBLE);
mScrollChip.setOnClickListener((v) ->
- onClick.run()
+ onClick.run()
// TODO Logging, store event consumer to a field
//onElementTapped.accept(ScreenshotEvent.SCREENSHOT_SCROLL_TAPPED);
);
@@ -248,6 +253,17 @@
requestFocus();
}
+ /**
+ * Set up the logger and callback on dismissal.
+ *
+ * Note: must be called before any other (non-constructor) method or null pointer exceptions
+ * may occur.
+ */
+ void init(UiEventLogger uiEventLogger, Runnable onDismissRunnable) {
+ mUiEventLogger = uiEventLogger;
+ mOnDismissRunnable = onDismissRunnable;
+ }
+
void takePartialScreenshot(Consumer<Rect> onPartialScreenshotSelected) {
mScreenshotSelectorView.setOnScreenshotSelected(onPartialScreenshotSelected);
mScreenshotSelectorView.setVisibility(View.VISIBLE);
@@ -260,8 +276,7 @@
mScreenshotPreview.setVisibility(View.INVISIBLE);
}
- AnimatorSet createScreenshotDropInAnimation(Rect bounds, boolean showFlash,
- Consumer<ScreenshotEvent> onElementTapped) {
+ AnimatorSet createScreenshotDropInAnimation(Rect bounds, boolean showFlash) {
mScreenshotPreview.setLayerType(View.LAYER_TYPE_HARDWARE, null);
mScreenshotPreview.buildLayer();
@@ -362,8 +377,10 @@
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
- mDismissButton.setOnClickListener(view ->
- onElementTapped.accept(ScreenshotEvent.SCREENSHOT_EXPLICIT_DISMISSAL));
+ mDismissButton.setOnClickListener(view -> {
+ mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_EXPLICIT_DISMISSAL);
+ animateDismissal();
+ });
mDismissButton.setAlpha(1);
float dismissOffset = mDismissButton.getWidth() / 2f;
float finalDismissX = mDirectionLTR
@@ -460,19 +477,25 @@
return animator;
}
- void setChipIntents(ScreenshotController.SavedImageData imageData,
- Consumer<ScreenshotEvent> onElementTapped) {
+ void setChipIntents(ScreenshotController.SavedImageData imageData) {
mShareChip.setPendingIntent(imageData.shareAction.actionIntent,
- () -> onElementTapped.accept(ScreenshotEvent.SCREENSHOT_SHARE_TAPPED));
+ () -> {
+ mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SHARE_TAPPED);
+ animateDismissal();
+ });
mEditChip.setPendingIntent(imageData.editAction.actionIntent,
- () -> onElementTapped.accept(ScreenshotEvent.SCREENSHOT_EDIT_TAPPED));
+ () -> {
+ mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_EDIT_TAPPED);
+ animateDismissal();
+ });
mScreenshotPreview.setOnClickListener(v -> {
try {
imageData.editAction.actionIntent.send();
} catch (PendingIntent.CanceledException e) {
Log.e(TAG, "Intent cancelled", e);
}
- onElementTapped.accept(ScreenshotEvent.SCREENSHOT_PREVIEW_TAPPED);
+ mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_PREVIEW_TAPPED);
+ animateDismissal();
});
if (mPendingInteraction != null) {
@@ -496,43 +519,49 @@
actionChip.setText(smartAction.title);
actionChip.setIcon(smartAction.getIcon(), false);
actionChip.setPendingIntent(smartAction.actionIntent,
- () -> onElementTapped.accept(
- ScreenshotEvent.SCREENSHOT_SMART_ACTION_TAPPED));
+ () -> {
+ mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SMART_ACTION_TAPPED);
+ animateDismissal();
+ });
mActionsView.addView(actionChip);
mSmartChips.add(actionChip);
}
}
}
+ boolean isDismissing() {
+ return (mDismissAnimation != null && mDismissAnimation.isRunning());
+ }
- AnimatorSet createScreenshotDismissAnimation() {
- ValueAnimator alphaAnim = ValueAnimator.ofFloat(0, 1);
- alphaAnim.setStartDelay(SCREENSHOT_DISMISS_ALPHA_OFFSET_MS);
- alphaAnim.setDuration(SCREENSHOT_DISMISS_ALPHA_DURATION_MS);
- alphaAnim.addUpdateListener(animation -> {
- setAlpha(1 - animation.getAnimatedFraction());
+ void animateDismissal() {
+ getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
+ mDismissAnimation = createScreenshotDismissAnimation();
+ mDismissAnimation.addListener(new AnimatorListenerAdapter() {
+ private boolean mCancelled = false;
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ super.onAnimationCancel(animation);
+ mCancelled = true;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ if (!mCancelled) {
+ mOnDismissRunnable.run();
+ }
+ }
});
-
- ValueAnimator yAnim = ValueAnimator.ofFloat(0, 1);
- yAnim.setInterpolator(mAccelerateInterpolator);
- yAnim.setDuration(SCREENSHOT_DISMISS_Y_DURATION_MS);
- float screenshotStartY = mScreenshotPreview.getTranslationY();
- float dismissStartY = mDismissButton.getTranslationY();
- yAnim.addUpdateListener(animation -> {
- float yDelta = MathUtils.lerp(0, mDismissDeltaY, animation.getAnimatedFraction());
- mScreenshotPreview.setTranslationY(screenshotStartY + yDelta);
- mDismissButton.setTranslationY(dismissStartY + yDelta);
- mActionsContainer.setTranslationY(yDelta);
- mActionsContainerBackground.setTranslationY(yDelta);
- });
-
- AnimatorSet animSet = new AnimatorSet();
- animSet.play(yAnim).with(alphaAnim);
-
- return animSet;
+ mDismissAnimation.start();
}
void reset() {
+ if (mDismissAnimation != null && mDismissAnimation.isRunning()) {
+ mDismissAnimation.cancel();
+ }
+ // Make sure we clean up the view tree observer
+ getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
// Clear any references to the bitmap
mScreenshotPreview.setImageDrawable(null);
mActionsContainerBackground.setVisibility(View.GONE);
@@ -561,6 +590,33 @@
mScreenshotSelectorView.stop();
}
+ private AnimatorSet createScreenshotDismissAnimation() {
+ ValueAnimator alphaAnim = ValueAnimator.ofFloat(0, 1);
+ alphaAnim.setStartDelay(SCREENSHOT_DISMISS_ALPHA_OFFSET_MS);
+ alphaAnim.setDuration(SCREENSHOT_DISMISS_ALPHA_DURATION_MS);
+ alphaAnim.addUpdateListener(animation -> {
+ setAlpha(1 - animation.getAnimatedFraction());
+ });
+
+ ValueAnimator yAnim = ValueAnimator.ofFloat(0, 1);
+ yAnim.setInterpolator(mAccelerateInterpolator);
+ yAnim.setDuration(SCREENSHOT_DISMISS_Y_DURATION_MS);
+ float screenshotStartY = mScreenshotPreview.getTranslationY();
+ float dismissStartY = mDismissButton.getTranslationY();
+ yAnim.addUpdateListener(animation -> {
+ float yDelta = MathUtils.lerp(0, mDismissDeltaY, animation.getAnimatedFraction());
+ mScreenshotPreview.setTranslationY(screenshotStartY + yDelta);
+ mDismissButton.setTranslationY(dismissStartY + yDelta);
+ mActionsContainer.setTranslationY(yDelta);
+ mActionsContainerBackground.setTranslationY(yDelta);
+ });
+
+ AnimatorSet animSet = new AnimatorSet();
+ animSet.play(yAnim).with(alphaAnim);
+
+ return animSet;
+ }
+
/**
* Create a drawable using the size of the bitmap and insets as the fractional inset parameters.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
index 4e22833..5f35e60 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
@@ -144,7 +144,7 @@
@Override
public boolean onUnbind(Intent intent) {
- if (mScreenshot != null && !mScreenshot.isDismissing()) {
+ if (mScreenshot != null) {
mScreenshot.dismissScreenshot(true);
}
unregisterReceiver(mBroadcastReceiver);
diff --git a/packages/SystemUI/src/com/android/systemui/settings/ToggleSliderView.java b/packages/SystemUI/src/com/android/systemui/settings/ToggleSliderView.java
deleted file mode 100644
index 90744a6..0000000
--- a/packages/SystemUI/src/com/android/systemui/settings/ToggleSliderView.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-import android.widget.RelativeLayout;
-import android.widget.SeekBar;
-import android.widget.SeekBar.OnSeekBarChangeListener;
-import android.widget.TextView;
-
-import com.android.settingslib.RestrictedLockUtils;
-import com.android.systemui.R;
-import com.android.systemui.statusbar.policy.BrightnessMirrorController;
-
-public class ToggleSliderView extends RelativeLayout implements ToggleSlider {
- private Listener mListener;
- private boolean mTracking;
-
- private CompoundButton mToggle;
- private ToggleSeekBar mSlider;
- private TextView mLabel;
-
- private ToggleSliderView mMirror;
- private BrightnessMirrorController mMirrorController;
-
- public ToggleSliderView(Context context) {
- this(context, null);
- }
-
- public ToggleSliderView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public ToggleSliderView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
-
- View.inflate(context, R.layout.status_bar_toggle_slider, this);
-
- final Resources res = context.getResources();
- final TypedArray a = context.obtainStyledAttributes(
- attrs, R.styleable.ToggleSliderView, defStyle, 0);
-
- mToggle = findViewById(R.id.toggle);
- mToggle.setOnCheckedChangeListener(mCheckListener);
-
- mSlider = findViewById(R.id.slider);
- mSlider.setOnSeekBarChangeListener(mSeekListener);
-
- mLabel = findViewById(R.id.label);
- mLabel.setText(a.getString(R.styleable.ToggleSliderView_text));
-
- mSlider.setAccessibilityLabel(getContentDescription().toString());
-
- a.recycle();
- }
-
- public void setMirror(ToggleSliderView toggleSlider) {
- mMirror = toggleSlider;
- if (mMirror != null) {
- mMirror.setChecked(mToggle.isChecked());
- mMirror.setMax(mSlider.getMax());
- mMirror.setValue(mSlider.getProgress());
- }
- }
-
- public void setMirrorController(BrightnessMirrorController c) {
- mMirrorController = c;
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- if (mListener != null) {
- mListener.onInit(this);
- }
- }
-
- public void setEnforcedAdmin(RestrictedLockUtils.EnforcedAdmin admin) {
- mToggle.setEnabled(admin == null);
- mSlider.setEnabled(admin == null);
- mSlider.setEnforcedAdmin(admin);
- }
-
- public void setOnChangedListener(Listener l) {
- mListener = l;
- }
-
- @Override
- public void setChecked(boolean checked) {
- mToggle.setChecked(checked);
- }
-
- @Override
- public boolean isChecked() {
- return mToggle.isChecked();
- }
-
- @Override
- public void setMax(int max) {
- mSlider.setMax(max);
- if (mMirror != null) {
- mMirror.setMax(max);
- }
- }
-
- @Override
- public void setValue(int value) {
- mSlider.setProgress(value);
- if (mMirror != null) {
- mMirror.setValue(value);
- }
- }
-
- @Override
- public int getValue() {
- return mSlider.getProgress();
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- if (mMirror != null) {
- MotionEvent copy = ev.copy();
- mMirror.dispatchTouchEvent(copy);
- copy.recycle();
- }
- return super.dispatchTouchEvent(ev);
- }
-
- private final OnCheckedChangeListener mCheckListener = new OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton toggle, boolean checked) {
- mSlider.setEnabled(!checked);
-
- if (mListener != null) {
- mListener.onChanged(
- ToggleSliderView.this, mTracking, checked, mSlider.getProgress(), false);
- }
-
- if (mMirror != null) {
- mMirror.mToggle.setChecked(checked);
- }
- }
- };
-
- private final OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- if (mListener != null) {
- mListener.onChanged(
- ToggleSliderView.this, mTracking, mToggle.isChecked(), progress, false);
- }
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- mTracking = true;
-
- if (mListener != null) {
- mListener.onChanged(ToggleSliderView.this, mTracking, mToggle.isChecked(),
- mSlider.getProgress(), false);
- }
-
- mToggle.setChecked(false);
-
- if (mMirrorController != null) {
- mMirrorController.showMirror();
- mMirrorController.setLocation((View) getParent());
- }
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- mTracking = false;
-
- if (mListener != null) {
- mListener.onChanged(ToggleSliderView.this, mTracking, mToggle.isChecked(),
- mSlider.getProgress(), true);
- }
-
- if (mMirrorController != null) {
- mMirrorController.hideMirror();
- }
- }
- };
-}
-
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
rename to packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
index 72034f8..be10c26 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.settings;
+package com.android.systemui.settings.brightness;
import static com.android.settingslib.display.BrightnessUtils.GAMMA_SPACE_MAX;
import static com.android.settingslib.display.BrightnessUtils.convertGammaToLinearFloat;
@@ -47,6 +47,7 @@
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.systemui.Dependency;
import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.settings.CurrentUserTracker;
import java.util.ArrayList;
@@ -100,13 +101,14 @@
private ValueAnimator mSliderAnimator;
public interface BrightnessStateChangeCallback {
- public void onBrightnessLevelChanged();
+ /** Indicates that some of the brightness settings have changed */
+ void onBrightnessLevelChanged();
}
/** ContentObserver to watch brightness */
private class BrightnessObserver extends ContentObserver {
- public BrightnessObserver(Handler handler) {
+ BrightnessObserver(Handler handler) {
super(handler);
}
@@ -339,11 +341,6 @@
return mChangeCallbacks.remove(cb);
}
- @Override
- public void onInit(ToggleSlider control) {
- // Do nothing
- }
-
public void registerCallbacks() {
mBackgroundHandler.post(mStartListeningRunnable);
}
@@ -355,7 +352,7 @@
}
@Override
- public void onChanged(ToggleSlider toggleSlider, boolean tracking, boolean automatic,
+ public void onChanged(boolean tracking, boolean automatic,
int value, boolean stopTracking) {
if (mExternalChange) return;
@@ -409,7 +406,7 @@
mBackgroundHandler.post(new Runnable() {
@Override
public void run() {
- ((ToggleSliderView)mControl).setEnforcedAdmin(
+ mControl.setEnforcedAdmin(
RestrictedLockUtilsInternal.checkIfRestrictionEnforced(mContext,
UserManager.DISALLOW_CONFIG_BRIGHTNESS,
mUserTracker.getCurrentUserId()));
@@ -493,4 +490,5 @@
return new BrightnessController(mContext, toggleSlider, mBroadcastDispatcher);
}
}
+
}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessControllerSettings.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessControllerSettings.java
new file mode 100644
index 0000000..a151fd0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessControllerSettings.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 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 com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.util.settings.SecureSettings;
+
+import javax.inject.Inject;
+
+/**
+ * Settings for prototyping thick brightness slider
+ */
+@SysUISingleton
+public class BrightnessControllerSettings {
+
+ private static final String THICK_BRIGHTNESS_SLIDER = "sysui_thick_brighthness";
+ private final boolean mUseThickSlider;
+ private final boolean mUseMirrorOnThickSlider;
+
+ @Inject
+ public BrightnessControllerSettings(SecureSettings settings) {
+ mUseThickSlider = settings.getInt(THICK_BRIGHTNESS_SLIDER, 0) != 0;
+ mUseMirrorOnThickSlider = settings.getInt(THICK_BRIGHTNESS_SLIDER, 0) != 2;
+ }
+
+ // Changing this setting between zero and non-zero may crash systemui down the line. Better to
+ // restart systemui after changing it.
+ /** */
+ boolean useThickSlider() {
+ return mUseThickSlider;
+ }
+
+ /** */
+ boolean useMirrorOnThickSlider() {
+ return mUseMirrorOnThickSlider;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
similarity index 70%
rename from packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
rename to packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
index 70c2531..1961bfc 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,20 +14,17 @@
* limitations under the License.
*/
-package com.android.systemui.settings;
+package com.android.systemui.settings.brightness;
import android.app.Activity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
import javax.inject.Inject;
@@ -36,11 +33,15 @@
public class BrightnessDialog extends Activity {
private BrightnessController mBrightnessController;
+ private final BrightnessSlider.Factory mToggleSliderFactory;
private final BroadcastDispatcher mBroadcastDispatcher;
@Inject
- public BrightnessDialog(BroadcastDispatcher broadcastDispatcher) {
+ public BrightnessDialog(
+ BroadcastDispatcher broadcastDispatcher,
+ BrightnessSlider.Factory factory) {
mBroadcastDispatcher = broadcastDispatcher;
+ mToggleSliderFactory = factory;
}
@@ -50,16 +51,21 @@
final Window window = getWindow();
- window.setGravity(Gravity.TOP);
+ window.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL);
window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
window.requestFeature(Window.FEATURE_NO_TITLE);
- View v = LayoutInflater.from(this).inflate(
- R.layout.quick_settings_brightness_dialog, null);
- setContentView(v);
+ // Calling this creates the decor View, so setLayout takes proper effect
+ // (see Dialog#onWindowAttributesChanged)
+ window.getDecorView();
+ window.setLayout(
+ WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);
- final ToggleSliderView slider = findViewById(R.id.brightness_slider);
- mBrightnessController = new BrightnessController(this, slider, mBroadcastDispatcher);
+
+ BrightnessSlider controller = mToggleSliderFactory.create(this, null);
+ controller.init();
+ setContentView(controller.getRootView());
+ mBrightnessController = new BrightnessController(this, controller, mBroadcastDispatcher);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java
new file mode 100644
index 0000000..6c4f808
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2020 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.content.Context;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CompoundButton;
+import android.widget.SeekBar;
+
+import androidx.annotation.Nullable;
+
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.BrightnessMirrorController;
+import com.android.systemui.util.ViewController;
+
+import javax.inject.Inject;
+
+/**
+ * {@code ViewController} for a {@code BrightnessSliderView}
+ *
+ * This class allows to control the views of a {@code BrightnessSliderViewView} and get callbacks
+ * when the views change value. It also propagates and manipulates another {@link ToggleSlider} as a
+ * mirror.
+ *
+ * @see BrightnessMirrorController
+ */
+public class BrightnessSlider
+ extends ViewController<View>
+ implements ToggleSlider {
+
+ private Listener mListener;
+ private ToggleSlider mMirror;
+ private final BrightnessSliderView mBrightnessSliderView;
+ private BrightnessMirrorController mMirrorController;
+ private boolean mTracking;
+ private final boolean mUseMirror;
+
+ BrightnessSlider(
+ View rootView,
+ BrightnessSliderView brightnessSliderView,
+ boolean useMirror
+ ) {
+ super(rootView);
+ mBrightnessSliderView = brightnessSliderView;
+ mUseMirror = useMirror;
+ }
+
+ /**
+ * Returns a top level view in the hierarchy that can be attached where necessary
+ */
+ public View getRootView() {
+ return mView;
+ }
+
+ private void enableSlider(boolean enable) {
+ mBrightnessSliderView.enableSlider(enable);
+ }
+
+ @Override
+ protected void onViewAttached() {
+ mBrightnessSliderView.setOnSeekBarChangeListener(mSeekListener);
+ mBrightnessSliderView.setOnCheckedChangeListener(mCheckListener);
+ }
+
+ @Override
+ protected void onViewDetached() {
+ mBrightnessSliderView.setOnSeekBarChangeListener(null);
+ mBrightnessSliderView.setOnCheckedChangeListener(null);
+ mBrightnessSliderView.setOnDispatchTouchEventListener(null);
+ }
+
+ @Override
+ public boolean mirrorTouchEvent(MotionEvent ev) {
+ if (mMirror != null) {
+ return copyEventToMirror(ev);
+ } else {
+ // We are the mirror, so we have to dispatch the event
+ return mBrightnessSliderView.dispatchTouchEvent(ev);
+ }
+ }
+
+ private boolean copyEventToMirror(MotionEvent ev) {
+ MotionEvent copy = ev.copy();
+ boolean out = mMirror.mirrorTouchEvent(copy);
+ copy.recycle();
+ return out;
+ }
+
+ @Override
+ public void setEnforcedAdmin(RestrictedLockUtils.EnforcedAdmin admin) {
+ mBrightnessSliderView.setEnforcedAdmin(admin);
+ }
+
+ private void setMirror(ToggleSlider toggleSlider) {
+ mMirror = toggleSlider;
+ if (mMirror != null) {
+ mMirror.setChecked(mBrightnessSliderView.isChecked());
+ mMirror.setMax(mBrightnessSliderView.getMax());
+ mMirror.setValue(mBrightnessSliderView.getValue());
+ mBrightnessSliderView.setOnDispatchTouchEventListener(this::mirrorTouchEvent);
+ } else {
+ // If there's no mirror, we may be the ones dispatching, events but we should not mirror
+ // them
+ mBrightnessSliderView.setOnDispatchTouchEventListener(null);
+ }
+ }
+
+ /**
+ * This will set the mirror from the controller using
+ * {@link BrightnessMirrorController#getToggleSlider} as a side-effect.
+ * @param c
+ */
+ @Override
+ public void setMirrorControllerAndMirror(BrightnessMirrorController c) {
+ if (!mUseMirror) return;
+ mMirrorController = c;
+ if (c != null) {
+ setMirror(c.getToggleSlider());
+ } else {
+ // If there's no mirror, we may be the ones dispatching, events but we should not mirror
+ // them
+ mBrightnessSliderView.setOnDispatchTouchEventListener(null);
+ }
+ }
+
+ @Override
+ public void setOnChangedListener(Listener l) {
+ mListener = l;
+ }
+
+ @Override
+ public void setChecked(boolean checked) {
+ mBrightnessSliderView.setChecked(checked);
+ }
+
+ @Override
+ public boolean isChecked() {
+ return mBrightnessSliderView.isChecked();
+ }
+
+ @Override
+ public void setMax(int max) {
+ mBrightnessSliderView.setMax(max);
+ if (mMirror != null) {
+ mMirror.setMax(max);
+ }
+ }
+
+ @Override
+ public int getMax() {
+ return mBrightnessSliderView.getMax();
+ }
+
+ @Override
+ public void setValue(int value) {
+ mBrightnessSliderView.setValue(value);
+ if (mMirror != null) {
+ mMirror.setValue(value);
+ }
+ }
+
+ @Override
+ public int getValue() {
+ return mBrightnessSliderView.getValue();
+ }
+
+ private final SeekBar.OnSeekBarChangeListener mSeekListener =
+ new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ if (mListener != null) {
+ mListener.onChanged(mTracking, isChecked(), progress, false);
+ }
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ mTracking = true;
+
+ if (mListener != null) {
+ mListener.onChanged(mTracking, isChecked(),
+ getValue(), false);
+ }
+
+ setChecked(false);
+
+ if (mMirrorController != null) {
+ mMirrorController.showMirror();
+ mMirrorController.setLocation((View) mBrightnessSliderView.getParent());
+ }
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ mTracking = false;
+
+ if (mListener != null) {
+ mListener.onChanged(mTracking, isChecked(),
+ getValue(), true);
+ }
+
+ if (mMirrorController != null) {
+ mMirrorController.hideMirror();
+ }
+ }
+ };
+
+ private final CompoundButton.OnCheckedChangeListener mCheckListener =
+ new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton toggle, boolean checked) {
+ enableSlider(!checked);
+
+ if (mListener != null) {
+ mListener.onChanged(mTracking, checked, getValue(), false);
+ }
+
+ if (mMirror != null) {
+ mMirror.setChecked(checked);
+ }
+ }
+ };
+
+ /**
+ * Creates a {@link BrightnessSlider} with its associated view.
+ *
+ * The views inflated are determined by {@link BrightnessControllerSettings#useThickSlider()}.
+ */
+ public static class Factory {
+
+ BrightnessControllerSettings mSettings;
+
+ @Inject
+ public Factory(BrightnessControllerSettings settings) {
+ mSettings = settings;
+ }
+
+ /**
+ * Creates the view hierarchy and controller
+ *
+ * @param context a {@link Context} to inflate the hierarchy
+ * @param viewRoot the {@link ViewGroup} that will contain the hierarchy. The inflated
+ * hierarchy will not be attached
+ */
+ public BrightnessSlider create(Context context, @Nullable ViewGroup viewRoot) {
+ int layout = getLayout();
+ ViewGroup root = (ViewGroup) LayoutInflater.from(context)
+ .inflate(layout, viewRoot, false);
+ return fromTree(root, mSettings.useMirrorOnThickSlider());
+ }
+
+ private BrightnessSlider fromTree(ViewGroup root, boolean useMirror) {
+ BrightnessSliderView v = root.requireViewById(R.id.brightness_slider);
+ return new BrightnessSlider(root, v, useMirror);
+ }
+
+ /** Get the layout to inflate based on what slider to use */
+ public int getLayout() {
+ return mSettings.useThickSlider()
+ ? R.layout.quick_settings_brightness_dialog_thick
+ : R.layout.quick_settings_brightness_dialog;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java
new file mode 100644
index 0000000..cbf4e88
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2020 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.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.FrameLayout;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.systemui.R;
+
+/**
+ * {@code FrameLayout} used to show and manipulate a {@link ToggleSeekBar}.
+ *
+ * It can additionally control a {@link CompoundButton} and display a label. For the class to work,
+ * add children before inflation with the following ids:
+ * <ul>
+ * <li>{@code @id/slider} of type {@link ToggleSeekBar}</li>
+ * <li>{@code @id/toggle} of type {@link CompoundButton} (optional)</li>
+ * <li>{@code @id/label} of type {@link TextView} (optional)</li>
+ * </ul>
+ */
+public class BrightnessSliderView extends FrameLayout {
+
+ @Nullable
+ private CompoundButton mToggle;
+ @NonNull
+ private ToggleSeekBar mSlider;
+ @Nullable
+ private TextView mLabel;
+ private final CharSequence mText;
+ private DispatchTouchEventListener mListener;
+
+ public BrightnessSliderView(Context context) {
+ this(context, null);
+ }
+
+ public BrightnessSliderView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public BrightnessSliderView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ final TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.ToggleSliderView, defStyle, 0);
+ mText = a.getString(R.styleable.ToggleSliderView_text);
+
+ a.recycle();
+ }
+
+ // Inflated from quick_settings_brightness_dialog or quick_settings_brightness_dialog_thick
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mToggle = findViewById(R.id.toggle);
+
+ mSlider = requireViewById(R.id.slider);
+
+ mLabel = findViewById(R.id.label);
+ if (mLabel != null) {
+ mLabel.setText(mText);
+ }
+ mSlider.setAccessibilityLabel(getContentDescription().toString());
+ }
+
+ /**
+ * Attaches a listener to relay touch events.
+ * @param listener use {@code null} to remove listener
+ */
+ public void setOnDispatchTouchEventListener(
+ DispatchTouchEventListener listener) {
+ mListener = listener;
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ if (mListener != null) {
+ mListener.onDispatchTouchEvent(ev);
+ }
+ return super.dispatchTouchEvent(ev);
+ }
+
+ /**
+ * Attaches a listener to the {@link ToggleSeekBar} in the view so changes can be observed
+ * @param seekListener use {@code null} to remove listener
+ */
+ public void setOnSeekBarChangeListener(OnSeekBarChangeListener seekListener) {
+ mSlider.setOnSeekBarChangeListener(seekListener);
+ }
+
+ /**
+ * Attaches a listener to the {@link CompoundButton} in the view (if present) so changes to its
+ * state can be observed
+ * @param checkListener use {@code null} to remove listener
+ */
+ public void setOnCheckedChangeListener(OnCheckedChangeListener checkListener) {
+ if (mToggle != null) {
+ mToggle.setOnCheckedChangeListener(checkListener);
+ }
+ }
+
+ /**
+ * Enforces admin rules for toggling auto-brightness and changing value of brightness
+ * @param admin
+ * @see ToggleSeekBar#setEnforcedAdmin
+ */
+ public void setEnforcedAdmin(RestrictedLockUtils.EnforcedAdmin admin) {
+ if (mToggle != null) {
+ mToggle.setEnabled(admin == null);
+ }
+ mSlider.setEnabled(admin == null);
+ mSlider.setEnforcedAdmin(admin);
+ }
+
+ /**
+ * Enables or disables the slider
+ * @param enable
+ */
+ public void enableSlider(boolean enable) {
+ mSlider.setEnabled(enable);
+ }
+
+ /**
+ * Sets the state of the {@link CompoundButton} if present
+ * @param checked
+ */
+ public void setChecked(boolean checked) {
+ if (mToggle != null) {
+ mToggle.setChecked(checked);
+ }
+ }
+
+ /**
+ * @return the state of the {@link CompoundButton} if present, or {@code true} if not.
+ */
+ public boolean isChecked() {
+ if (mToggle != null) {
+ return mToggle.isChecked();
+ }
+ return true;
+ }
+
+ /**
+ * @return the maximum value of the {@link ToggleSeekBar}.
+ */
+ public int getMax() {
+ return mSlider.getMax();
+ }
+
+ /**
+ * Sets the maximum value of the {@link ToggleSeekBar}.
+ * @param max
+ */
+ public void setMax(int max) {
+ mSlider.setMax(max);
+ }
+
+ /**
+ * Sets the current value of the {@link ToggleSeekBar}.
+ * @param value
+ */
+ public void setValue(int value) {
+ mSlider.setProgress(value);
+ }
+
+ /**
+ * @return the current value of the {@link ToggleSeekBar}
+ */
+ public int getValue() {
+ return mSlider.getProgress();
+ }
+
+ /**
+ * Interface to attach a listener for {@link View#dispatchTouchEvent}.
+ */
+ @FunctionalInterface
+ interface DispatchTouchEventListener {
+ boolean onDispatchTouchEvent(MotionEvent ev);
+ }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/settings/ToggleSeekBar.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/ToggleSeekBar.java
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/settings/ToggleSeekBar.java
rename to packages/SystemUI/src/com/android/systemui/settings/brightness/ToggleSeekBar.java
index 8ed4c75..a5a0ae7 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/ToggleSeekBar.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/ToggleSeekBar.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.settings;
+package com.android.systemui.settings.brightness;
import android.content.Context;
import android.content.Intent;
diff --git a/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/ToggleSlider.java
similarity index 60%
rename from packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java
rename to packages/SystemUI/src/com/android/systemui/settings/brightness/ToggleSlider.java
index 135f89d..71e4818 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/ToggleSlider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -11,22 +11,31 @@
* 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
+ * limitations under the License.
*/
-package com.android.systemui.settings;
+package com.android.systemui.settings.brightness;
+
+import android.view.MotionEvent;
+
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.systemui.statusbar.policy.BrightnessMirrorController;
public interface ToggleSlider {
interface Listener {
- void onInit(ToggleSlider control);
- void onChanged(ToggleSlider slider, boolean tracking, boolean automatic, int value,
+ void onChanged(boolean tracking, boolean automatic, int value,
boolean stopTracking);
}
+ void setEnforcedAdmin(RestrictedLockUtils.EnforcedAdmin admin);
+ void setMirrorControllerAndMirror(BrightnessMirrorController c);
+ boolean mirrorTouchEvent(MotionEvent ev);
+
void setOnChangedListener(Listener l);
default void setChecked(boolean checked) {}
default boolean isChecked() { return false; }
void setMax(int max);
+ int getMax();
void setValue(int value);
int getValue();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
new file mode 100644
index 0000000..86377fb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
@@ -0,0 +1,207 @@
+package com.android.systemui.statusbar
+
+import android.content.Context
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.Matrix
+import android.graphics.Paint
+import android.graphics.PointF
+import android.graphics.PorterDuff
+import android.graphics.PorterDuffColorFilter
+import android.graphics.PorterDuffXfermode
+import android.graphics.RadialGradient
+import android.graphics.Shader
+import android.os.SystemProperties
+import android.util.AttributeSet
+import android.view.View
+import com.android.systemui.Interpolators
+
+val enableLightReveal =
+ SystemProperties.getBoolean("persist.sysui.show_new_screen_on_transitions", false)
+
+/**
+ * Provides methods to modify the various properties of a [LightRevealScrim] to reveal between 0% to
+ * 100% of the view(s) underneath the scrim.
+ */
+interface LightRevealEffect {
+ fun setRevealAmountOnScrim(amount: Float, scrim: LightRevealScrim)
+
+ companion object {
+
+ /**
+ * Returns the percent that the given value is past the threshold value. For example, 0.9 is
+ * 50% of the way past 0.8.
+ */
+ fun getPercentPastThreshold(value: Float, threshold: Float): Float {
+ return (value - threshold).coerceAtLeast(0f) * (1f / (1f - threshold))
+ }
+ }
+}
+
+/**
+ * Light reveal effect that shows light entering the phone from the bottom of the screen. The light
+ * enters from the bottom-middle as a narrow oval, and moves upward, eventually widening to fill the
+ * screen.
+ */
+object LiftReveal : LightRevealEffect {
+
+ /** Widen the oval of light after 35%, so it will eventually fill the screen. */
+ private const val WIDEN_OVAL_THRESHOLD = 0.35f
+
+ /** After 85%, fade out the black color at the end of the gradient. */
+ private const val FADE_END_COLOR_OUT_THRESHOLD = 0.85f
+
+ /** The initial width of the light oval, in percent of scrim width. */
+ private const val OVAL_INITIAL_WIDTH_PERCENT = 0.5f
+
+ /** The initial top value of the light oval, in percent of scrim height. */
+ private const val OVAL_INITIAL_TOP_PERCENT = 1.05f
+
+ /** The initial bottom value of the light oval, in percent of scrim height. */
+ private const val OVAL_INITIAL_BOTTOM_PERCENT = 1.2f
+
+ /** Interpolator to use for the reveal amount. */
+ private val INTERPOLATOR = Interpolators.FAST_OUT_SLOW_IN_REVERSE
+
+ override fun setRevealAmountOnScrim(amount: Float, scrim: LightRevealScrim) {
+ val interpolatedAmount = INTERPOLATOR.getInterpolation(amount)
+ val ovalWidthIncreaseAmount =
+ LightRevealEffect.getPercentPastThreshold(interpolatedAmount, WIDEN_OVAL_THRESHOLD)
+
+ val initialWidthMultiplier = (1f - OVAL_INITIAL_WIDTH_PERCENT) / 2f
+
+ with(scrim) {
+ revealGradientEndColorAlpha = 1f - LightRevealEffect.getPercentPastThreshold(
+ amount, FADE_END_COLOR_OUT_THRESHOLD)
+ setRevealGradientBounds(
+ scrim.width * initialWidthMultiplier +
+ -scrim.width * ovalWidthIncreaseAmount,
+ scrim.height * OVAL_INITIAL_TOP_PERCENT -
+ scrim.height * interpolatedAmount,
+ scrim.width * (1f - initialWidthMultiplier) +
+ scrim.width * ovalWidthIncreaseAmount,
+ scrim.height * OVAL_INITIAL_BOTTOM_PERCENT +
+ scrim.height * interpolatedAmount)
+ }
+ }
+}
+
+/**
+ * Scrim view that partially reveals the content underneath it using a [RadialGradient] with a
+ * transparent center. The center position, size, and stops of the gradient can be manipulated to
+ * reveal views below the scrim as if they are being 'lit up'.
+ */
+class LightRevealScrim(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
+
+ /**
+ * How much of the underlying views are revealed, in percent. 0 means they will be completely
+ * obscured and 1 means they'll be fully visible.
+ */
+ var revealAmount: Float = 0f
+ set(value) {
+ if (field != value) {
+ field = value
+
+ revealEffect.setRevealAmountOnScrim(value, this)
+ invalidate()
+ }
+ }
+
+ /**
+ * The [LightRevealEffect] used to manipulate the radial gradient whenever [revealAmount]
+ * changes.
+ */
+ var revealEffect: LightRevealEffect = LiftReveal
+ set(value) {
+ if (field != value) {
+ field = value
+
+ revealEffect.setRevealAmountOnScrim(revealAmount, this)
+ invalidate()
+ }
+ }
+
+ var revealGradientCenter = PointF()
+ var revealGradientWidth: Float = 0f
+ var revealGradientHeight: Float = 0f
+
+ var revealGradientEndColor: Int = Color.BLACK
+ set(value) {
+ if (field != value) {
+ field = value
+ setPaintColorFilter()
+ }
+ }
+
+ var revealGradientEndColorAlpha = 0f
+ set(value) {
+ if (field != value) {
+ field = value
+ setPaintColorFilter()
+ }
+ }
+
+ /**
+ * Paint used to draw a transparent-to-white radial gradient. This will be scaled and translated
+ * via local matrix in [onDraw] so we never need to construct a new shader.
+ */
+ private val gradientPaint = Paint().apply {
+ shader = RadialGradient(
+ 0f, 0f, 1f,
+ intArrayOf(Color.TRANSPARENT, Color.WHITE), floatArrayOf(0f, 1f),
+ Shader.TileMode.CLAMP)
+
+ // SRC_OVER ensures that we draw the semitransparent pixels over other views in the same
+ // window, rather than outright replacing them.
+ xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)
+ }
+
+ /**
+ * Matrix applied to [gradientPaint]'s RadialGradient shader to move the gradient to
+ * [revealGradientCenter] and set its size to [revealGradientWidth]/[revealGradientHeight],
+ * without needing to construct a new shader each time those properties change.
+ */
+ private val shaderGradientMatrix = Matrix()
+
+ /**
+ * Sets bounds for the transparent oval gradient that reveals the views below the scrim. This is
+ * simply a helper method that sets [revealGradientCenter], [revealGradientWidth], and
+ * [revealGradientHeight] for you.
+ *
+ * This method does not call [invalidate] - you should do so once you're done changing
+ * properties.
+ */
+ public fun setRevealGradientBounds(left: Float, top: Float, right: Float, bottom: Float) {
+ revealGradientWidth = right - left
+ revealGradientHeight = bottom - top
+
+ revealGradientCenter.x = left + (revealGradientWidth / 2f)
+ revealGradientCenter.y = top + (revealGradientHeight / 2f)
+ }
+
+ override fun onDraw(canvas: Canvas?) {
+ if (canvas == null || revealGradientWidth <= 0 || revealGradientHeight <= 0) {
+ return
+ }
+
+ with(shaderGradientMatrix) {
+ setScale(revealGradientWidth, revealGradientHeight, 0f, 0f)
+ postTranslate(revealGradientCenter.x, revealGradientCenter.y)
+
+ gradientPaint.shader.setLocalMatrix(this)
+ }
+
+ // Draw the gradient over the screen, then multiply the end color by it.
+ canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), gradientPaint)
+ }
+
+ private fun setPaintColorFilter() {
+ gradientPaint.colorFilter = PorterDuffColorFilter(
+ Color.argb(
+ (revealGradientEndColorAlpha * 255).toInt(),
+ Color.red(revealGradientEndColor),
+ Color.green(revealGradientEndColor),
+ Color.blue(revealGradientEndColor)),
+ PorterDuff.Mode.MULTIPLY)
+ }
+}
\ No newline at end of file
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 3622f1c..e40c262 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -53,6 +53,7 @@
public static final String WORK = "work";
public static final String NIGHT = "night";
public static final String CAST = "cast";
+ public static final String BRIGHTNESS = "reduce_brightness";
static final String SETTING_SEPARATOR = ":";
private UserHandle mCurrentUser;
@@ -124,6 +125,9 @@
mCastController.addCallback(mCastCallback);
}
+ // TODO(b/170970675): Set a listener/controller and callback for Reduce Bright Colors
+ // state changes. Call into ColorDisplayService to get availability/config status
+
int settingsN = mAutoAddSettingList.size();
for (int i = 0; i < settingsN; i++) {
if (!mAutoTracker.isAdded(mAutoAddSettingList.get(i).mSpec)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 5c7f54b..09de575 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -35,6 +35,7 @@
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING;
import static com.android.systemui.shared.system.WindowManagerWrapper.NAV_BAR_POS_INVALID;
+import static com.android.systemui.statusbar.LightRevealScrimKt.getEnableLightReveal;
import static com.android.systemui.statusbar.NotificationLockscreenUserManager.PERMISSION_SELF;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
@@ -172,6 +173,7 @@
import com.android.systemui.qs.QSFragment;
import com.android.systemui.qs.QSPanelController;
import com.android.systemui.recents.ScreenPinningRequest;
+import com.android.systemui.settings.brightness.BrightnessSlider;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.shared.system.WindowManagerWrapper;
import com.android.systemui.statusbar.AutoHideUiElement;
@@ -181,6 +183,8 @@
import com.android.systemui.statusbar.GestureRecorder;
import com.android.systemui.statusbar.KeyboardShortcuts;
import com.android.systemui.statusbar.KeyguardIndicationController;
+import com.android.systemui.statusbar.LiftReveal;
+import com.android.systemui.statusbar.LightRevealScrim;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationPresenter;
@@ -367,6 +371,7 @@
DozeServiceHost mDozeServiceHost;
private boolean mWakeUpComingFromTouch;
private PointF mWakeUpTouchLocation;
+ private LightRevealScrim mLightRevealScrim;
private final Object mQueueLock = new Object();
@@ -428,6 +433,7 @@
private final NotificationViewHierarchyManager mViewHierarchyManager;
private final KeyguardViewMediator mKeyguardViewMediator;
protected final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
+ private final BrightnessSlider.Factory mBrightnessSliderFactory;
// for disabling the status bar
private int mDisabled1 = 0;
@@ -740,7 +746,8 @@
DemoModeController demoModeController,
Lazy<NotificationShadeDepthController> notificationShadeDepthControllerLazy,
StatusBarTouchableRegionManager statusBarTouchableRegionManager,
- NotificationIconAreaController notificationIconAreaController) {
+ NotificationIconAreaController notificationIconAreaController,
+ BrightnessSlider.Factory brightnessSliderFactory) {
super(context);
mNotificationsController = notificationsController;
mLightBarController = lightBarController;
@@ -817,6 +824,7 @@
mDismissCallbackRegistry = dismissCallbackRegistry;
mDemoModeController = demoModeController;
mNotificationIconAreaController = notificationIconAreaController;
+ mBrightnessSliderFactory = brightnessSliderFactory;
mBubbleExpandListener =
(isExpanding, key) -> {
@@ -1155,6 +1163,13 @@
});
mScrimController.attachViews(scrimBehind, scrimInFront, scrimForBubble);
+ mLightRevealScrim = mNotificationShadeWindowView.findViewById(R.id.light_reveal_scrim);
+
+ if (getEnableLightReveal()) {
+ mLightRevealScrim.setVisibility(View.VISIBLE);
+ mLightRevealScrim.setRevealEffect(LiftReveal.INSTANCE);
+ }
+
mNotificationPanelViewController.initDependencies(
this,
mNotificationShelfController);
@@ -1194,6 +1209,7 @@
mNotificationShadeWindowView,
mNotificationPanelViewController,
mNotificationShadeDepthControllerLazy.get(),
+ mBrightnessSliderFactory,
(visible) -> {
mBrightnessMirrorVisible = visible;
updateScrimController();
@@ -3619,6 +3635,13 @@
}
@Override
+ public void onDozeAmountChanged(float linear, float eased) {
+ if (getEnableLightReveal()) {
+ mLightRevealScrim.setRevealAmount(1f - linear);
+ }
+ }
+
+ @Override
public void onDozingChanged(boolean isDozing) {
Trace.beginSection("StatusBar#updateDozing");
mDozing = isDozing;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index 13d5bf5..f6631ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -43,6 +43,7 @@
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.PluginDependencyProvider;
import com.android.systemui.recents.ScreenPinningRequest;
+import com.android.systemui.settings.brightness.BrightnessSlider;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardIndicationController;
@@ -198,7 +199,8 @@
Lazy<NotificationShadeDepthController> notificationShadeDepthController,
DismissCallbackRegistry dismissCallbackRegistry,
StatusBarTouchableRegionManager statusBarTouchableRegionManager,
- NotificationIconAreaController notificationIconAreaController) {
+ NotificationIconAreaController notificationIconAreaController,
+ BrightnessSlider.Factory brightnessSliderFactory) {
return new StatusBar(
context,
notificationsController,
@@ -276,6 +278,7 @@
demoModeController,
notificationShadeDepthController,
statusBarTouchableRegionManager,
- notificationIconAreaController);
+ notificationIconAreaController,
+ brightnessSliderFactory);
}
}
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 a0b03e1..07d3f01 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -17,13 +17,18 @@
package com.android.systemui.statusbar.policy;
import android.annotation.NonNull;
+import android.content.Context;
import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
import android.util.ArraySet;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.android.systemui.R;
+import com.android.systemui.settings.brightness.BrightnessSlider;
+import com.android.systemui.settings.brightness.ToggleSlider;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
@@ -42,15 +47,20 @@
private final NotificationPanelViewController mNotificationPanel;
private final NotificationShadeDepthController mDepthController;
private final ArraySet<BrightnessMirrorListener> mBrightnessMirrorListeners = new ArraySet<>();
+ private final BrightnessSlider.Factory mToggleSliderFactory;
+ private BrightnessSlider mToggleSliderController;
private final int[] mInt2Cache = new int[2];
- private View mBrightnessMirror;
+ private FrameLayout mBrightnessMirror;
public BrightnessMirrorController(NotificationShadeWindowView statusBarWindow,
NotificationPanelViewController notificationPanelViewController,
NotificationShadeDepthController notificationShadeDepthController,
+ BrightnessSlider.Factory factory,
@NonNull Consumer<Boolean> visibilityCallback) {
mStatusBarWindow = statusBarWindow;
+ mToggleSliderFactory = factory;
mBrightnessMirror = statusBarWindow.findViewById(R.id.brightness_mirror);
+ mToggleSliderController = setMirrorLayout();
mNotificationPanel = notificationPanelViewController;
mDepthController = notificationShadeDepthController;
mNotificationPanel.setPanelAlphaEndAction(() -> {
@@ -88,8 +98,8 @@
mBrightnessMirror.setTranslationY(originalY - mirrorY);
}
- public View getMirror() {
- return mBrightnessMirror;
+ public ToggleSlider getToggleSlider() {
+ return mToggleSliderController;
}
public void updateResources() {
@@ -110,11 +120,33 @@
reinflate();
}
+ private BrightnessSlider setMirrorLayout() {
+ Context context = mBrightnessMirror.getContext();
+ BrightnessSlider controller = mToggleSliderFactory.create(context, mBrightnessMirror);
+ controller.init();
+ Drawable mirrorBackground = context.getDrawable(R.drawable.brightness_mirror_background);
+
+ View rootView = controller.getRootView();
+ rootView.setBackground(mirrorBackground);
+
+ ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) rootView.getLayoutParams();
+ lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
+ lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
+ int margin = context.getResources()
+ .getDimensionPixelSize(R.dimen.notification_side_paddings);
+ lp.leftMargin = margin;
+ lp.rightMargin = margin;
+ mBrightnessMirror.addView(rootView, lp);
+
+ return controller;
+ }
+
private void reinflate() {
int index = mStatusBarWindow.indexOfChild(mBrightnessMirror);
mStatusBarWindow.removeView(mBrightnessMirror);
- mBrightnessMirror = LayoutInflater.from(mBrightnessMirror.getContext()).inflate(
- R.layout.brightness_mirror, mStatusBarWindow, false);
+ mBrightnessMirror = (FrameLayout) LayoutInflater.from(mBrightnessMirror.getContext())
+ .inflate(R.layout.brightness_mirror, mStatusBarWindow, false);
+ mToggleSliderController = setMirrorLayout();
mStatusBarWindow.addView(mBrightnessMirror, index);
for (int i = 0; i < mBrightnessMirrorListeners.size(); i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java
similarity index 64%
rename from packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java
rename to packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java
index 665cb63..0aa2a73 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java
@@ -21,11 +21,18 @@
import android.util.ArrayMap;
import android.util.Log;
+import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
+import com.android.systemui.Dumpable;
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dump.DumpManager;
+
import com.google.android.collect.Lists;
import com.google.android.collect.Sets;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -34,9 +41,19 @@
import java.util.concurrent.Executor;
import java.util.stream.Collectors;
-class ThemeOverlayManager {
+/**
+ * Responsible for orchestrating overlays, based on user preferences and other inputs from
+ * {@link ThemeOverlayController}.
+ */
+@SysUISingleton
+public class ThemeOverlayApplier implements Dumpable {
private static final String TAG = "ThemeOverlayManager";
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ @VisibleForTesting
+ static final String MONET_ACCENT_COLOR_PACKAGE = "com.android.theme.accentcolor.color";
+ @VisibleForTesting
+ static final String MONET_SYSTEM_PALETTE_PACKAGE = "com.android.theme.systemcolors.color";
@VisibleForTesting
static final String ANDROID_PACKAGE = "android";
@@ -46,7 +63,11 @@
static final String SYSUI_PACKAGE = "com.android.systemui";
@VisibleForTesting
- static final String OVERLAY_CATEGORY_COLOR = "android.theme.customization.accent_color";
+ static final String OVERLAY_CATEGORY_ACCENT_COLOR =
+ "android.theme.customization.accent_color";
+ @VisibleForTesting
+ static final String OVERLAY_CATEGORY_SYSTEM_PALETTE =
+ "android.theme.customization.system_palette";
@VisibleForTesting
static final String OVERLAY_CATEGORY_FONT = "android.theme.customization.font";
@VisibleForTesting
@@ -73,24 +94,36 @@
* starts with launcher and grouped by target package.
*/
static final List<String> THEME_CATEGORIES = Lists.newArrayList(
+ OVERLAY_CATEGORY_SYSTEM_PALETTE,
OVERLAY_CATEGORY_ICON_LAUNCHER,
OVERLAY_CATEGORY_SHAPE,
OVERLAY_CATEGORY_FONT,
- OVERLAY_CATEGORY_COLOR,
+ OVERLAY_CATEGORY_ACCENT_COLOR,
OVERLAY_CATEGORY_ICON_ANDROID,
OVERLAY_CATEGORY_ICON_SYSUI,
OVERLAY_CATEGORY_ICON_SETTINGS,
OVERLAY_CATEGORY_ICON_THEME_PICKER);
- /* Categories that need to applied to the current user as well as the system user. */
+ /* Categories that need to be applied to the current user as well as the system user. */
@VisibleForTesting
static final Set<String> SYSTEM_USER_CATEGORIES = Sets.newHashSet(
- OVERLAY_CATEGORY_COLOR,
+ OVERLAY_CATEGORY_SYSTEM_PALETTE,
+ OVERLAY_CATEGORY_ACCENT_COLOR,
OVERLAY_CATEGORY_FONT,
OVERLAY_CATEGORY_SHAPE,
OVERLAY_CATEGORY_ICON_ANDROID,
OVERLAY_CATEGORY_ICON_SYSUI);
+ /**
+ * List of main colors of Monet themes. These are extracted from overlays installed
+ * on the system.
+ */
+ private final ArrayList<Integer> mMainSystemColors = new ArrayList<>();
+ /**
+ * Same as above, but providing accent colors instead of a system palette.
+ */
+ private final ArrayList<Integer> mAccentColors = new ArrayList<>();
+
/* Allowed overlay categories for each target package. */
private final Map<String, Set<String>> mTargetPackageToCategories = new ArrayMap<>();
/* Target package for each overlay category. */
@@ -100,15 +133,15 @@
private final String mLauncherPackage;
private final String mThemePickerPackage;
- ThemeOverlayManager(OverlayManager overlayManager, Executor executor,
- String launcherPackage, String themePickerPackage) {
+ public ThemeOverlayApplier(OverlayManager overlayManager, Executor executor,
+ String launcherPackage, String themePickerPackage, DumpManager dumpManager) {
mOverlayManager = overlayManager;
mExecutor = executor;
mLauncherPackage = launcherPackage;
mThemePickerPackage = themePickerPackage;
mTargetPackageToCategories.put(ANDROID_PACKAGE, Sets.newHashSet(
- OVERLAY_CATEGORY_COLOR, OVERLAY_CATEGORY_FONT,
- OVERLAY_CATEGORY_SHAPE, OVERLAY_CATEGORY_ICON_ANDROID));
+ OVERLAY_CATEGORY_SYSTEM_PALETTE, OVERLAY_CATEGORY_ACCENT_COLOR,
+ OVERLAY_CATEGORY_FONT, OVERLAY_CATEGORY_SHAPE, OVERLAY_CATEGORY_ICON_ANDROID));
mTargetPackageToCategories.put(SYSUI_PACKAGE,
Sets.newHashSet(OVERLAY_CATEGORY_ICON_SYSUI));
mTargetPackageToCategories.put(SETTINGS_PACKAGE,
@@ -117,7 +150,7 @@
Sets.newHashSet(OVERLAY_CATEGORY_ICON_LAUNCHER));
mTargetPackageToCategories.put(mThemePickerPackage,
Sets.newHashSet(OVERLAY_CATEGORY_ICON_THEME_PICKER));
- mCategoryToTargetPackage.put(OVERLAY_CATEGORY_COLOR, ANDROID_PACKAGE);
+ mCategoryToTargetPackage.put(OVERLAY_CATEGORY_ACCENT_COLOR, ANDROID_PACKAGE);
mCategoryToTargetPackage.put(OVERLAY_CATEGORY_FONT, ANDROID_PACKAGE);
mCategoryToTargetPackage.put(OVERLAY_CATEGORY_SHAPE, ANDROID_PACKAGE);
mCategoryToTargetPackage.put(OVERLAY_CATEGORY_ICON_ANDROID, ANDROID_PACKAGE);
@@ -125,6 +158,54 @@
mCategoryToTargetPackage.put(OVERLAY_CATEGORY_ICON_SETTINGS, SETTINGS_PACKAGE);
mCategoryToTargetPackage.put(OVERLAY_CATEGORY_ICON_LAUNCHER, mLauncherPackage);
mCategoryToTargetPackage.put(OVERLAY_CATEGORY_ICON_THEME_PICKER, mThemePickerPackage);
+
+ collectMonetSystemOverlays();
+ dumpManager.registerDumpable(TAG, this);
+ }
+
+ /**
+ * List of accent colors available as Monet overlays.
+ */
+ List<Integer> getAvailableAccentColors() {
+ return mAccentColors;
+ }
+
+ /**
+ * List of main system colors available as Monet overlays.
+ */
+ List<Integer> getAvailableSystemColors() {
+ return mMainSystemColors;
+ }
+
+ private void collectMonetSystemOverlays() {
+ List<OverlayInfo> androidOverlays = mOverlayManager
+ .getOverlayInfosForTarget(ANDROID_PACKAGE, UserHandle.SYSTEM);
+ for (OverlayInfo overlayInfo : androidOverlays) {
+ String packageName = overlayInfo.packageName;
+ if (DEBUG) {
+ Log.d(TAG, "Processing overlay " + packageName);
+ }
+ if (OVERLAY_CATEGORY_SYSTEM_PALETTE.equals(overlayInfo.category)
+ && packageName.startsWith(MONET_SYSTEM_PALETTE_PACKAGE)) {
+ try {
+ String color = packageName.replace(MONET_SYSTEM_PALETTE_PACKAGE, "");
+ mMainSystemColors.add(Integer.parseInt(color, 16));
+ } catch (NumberFormatException e) {
+ Log.w(TAG, "Invalid package name for overlay " + packageName, e);
+ }
+ } else if (OVERLAY_CATEGORY_ACCENT_COLOR.equals(overlayInfo.category)
+ && packageName.startsWith(MONET_ACCENT_COLOR_PACKAGE)) {
+ try {
+ String color = packageName.replace(MONET_ACCENT_COLOR_PACKAGE, "");
+ mAccentColors.add(Integer.parseInt(color, 16));
+ } catch (NumberFormatException e) {
+ Log.w(TAG, "Invalid package name for overlay " + packageName, e);
+ }
+ } else if (DEBUG) {
+ Log.d(TAG, "Unknown overlay: " + packageName + " category: "
+ + overlayInfo.category);
+ }
+ }
}
/**
@@ -184,4 +265,13 @@
}
});
}
+
+ /**
+ * @inherit
+ */
+ @Override
+ public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
+ pw.println("mMainSystemColors=" + mMainSystemColors.size());
+ pw.println("mAccentColors=" + mAccentColors.size());
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index 132e092..c4e2b5d 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -15,16 +15,20 @@
*/
package com.android.systemui.theme;
+import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ACCENT_COLOR;
+import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_SYSTEM_PALETTE;
+
import android.app.ActivityManager;
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.om.OverlayManager;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
+import android.graphics.Color;
import android.net.Uri;
-import android.os.AsyncTask;
import android.os.Handler;
import android.os.UserHandle;
import android.os.UserManager;
@@ -33,20 +37,32 @@
import android.util.ArrayMap;
import android.util.Log;
-import com.android.systemui.R;
+import androidx.annotation.NonNull;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.graphics.ColorUtils;
+import com.android.systemui.Dumpable;
import com.android.systemui.SystemUI;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dump.DumpManager;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.settings.SecureSettings;
import com.google.android.collect.Sets;
import org.json.JSONException;
import org.json.JSONObject;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.Collection;
+import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -60,49 +76,76 @@
* associated work profiles
*/
@SysUISingleton
-public class ThemeOverlayController extends SystemUI {
+public class ThemeOverlayController extends SystemUI implements Dumpable {
private static final String TAG = "ThemeOverlayController";
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private ThemeOverlayManager mThemeManager;
- private UserManager mUserManager;
- private BroadcastDispatcher mBroadcastDispatcher;
+ // If lock screen wallpaper colors should also be considered when selecting the theme.
+ // Doing this has performance impact, given that overlays would need to be swapped when
+ // the device unlocks.
+ @VisibleForTesting
+ static final boolean USE_LOCK_SCREEN_WALLPAPER = false;
+
+ private final ThemeOverlayApplier mThemeManager;
+ private final UserManager mUserManager;
+ private final BroadcastDispatcher mBroadcastDispatcher;
+ private final Executor mBgExecutor;
+ private final SecureSettings mSecureSettings;
+ private final Executor mMainExecutor;
private final Handler mBgHandler;
+ private final WallpaperManager mWallpaperManager;
+ private final KeyguardStateController mKeyguardStateController;
+ private WallpaperColors mLockColors;
+ private WallpaperColors mSystemColors;
+ // Color extracted from wallpaper, NOT the color used on the overlay
+ private int mMainWallpaperColor = Color.TRANSPARENT;
+ // Color extracted from wallpaper, NOT the color used on the overlay
+ private int mWallpaperAccentColor = Color.TRANSPARENT;
+ // Main system color that maps to an overlay color
+ private int mSystemOverlayColor = Color.TRANSPARENT;
+ // Accent color that maps to an overlay color
+ private int mAccentOverlayColor = Color.TRANSPARENT;
@Inject
public ThemeOverlayController(Context context, BroadcastDispatcher broadcastDispatcher,
- @Background Handler bgHandler) {
+ @Background Handler bgHandler, @Main Executor mainExecutor,
+ @Background Executor bgExecutor, ThemeOverlayApplier themeOverlayApplier,
+ SecureSettings secureSettings, WallpaperManager wallpaperManager,
+ UserManager userManager, KeyguardStateController keyguardStateController,
+ DumpManager dumpManager) {
super(context);
+
mBroadcastDispatcher = broadcastDispatcher;
+ mUserManager = userManager;
+ mBgExecutor = bgExecutor;
+ mMainExecutor = mainExecutor;
mBgHandler = bgHandler;
+ mThemeManager = themeOverlayApplier;
+ mSecureSettings = secureSettings;
+ mWallpaperManager = wallpaperManager;
+ mKeyguardStateController = keyguardStateController;
+ dumpManager.registerDumpable(TAG, this);
}
@Override
public void start() {
if (DEBUG) Log.d(TAG, "Start");
- mUserManager = mContext.getSystemService(UserManager.class);
- mThemeManager = new ThemeOverlayManager(
- mContext.getSystemService(OverlayManager.class),
- AsyncTask.THREAD_POOL_EXECUTOR,
- mContext.getString(R.string.launcher_overlayable_package),
- mContext.getString(R.string.themepicker_overlayable_package));
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_SWITCHED);
filter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
- mBroadcastDispatcher.registerReceiverWithHandler(new BroadcastReceiver() {
+ mBroadcastDispatcher.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (DEBUG) Log.d(TAG, "Updating overlays for user switch / profile added.");
updateThemeOverlays();
}
- }, filter, mBgHandler, UserHandle.ALL);
- mContext.getContentResolver().registerContentObserver(
+ }, filter, mBgExecutor, UserHandle.ALL);
+ mSecureSettings.registerContentObserverForUser(
Settings.Secure.getUriFor(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES),
false,
new ContentObserver(mBgHandler) {
-
@Override
- public void onChange(boolean selfChange, Collection<Uri> uris, int flags,
+ public void onChange(boolean selfChange, Collection<Uri> collection, int flags,
int userId) {
if (DEBUG) Log.d(TAG, "Overlay changed for user: " + userId);
if (ActivityManager.getCurrentUser() == userId) {
@@ -111,20 +154,147 @@
}
},
UserHandle.USER_ALL);
+
+ // Upon boot, make sure we have the most up to date colors
+ mBgExecutor.execute(() -> {
+ WallpaperColors lockColors = mWallpaperManager.getWallpaperColors(
+ WallpaperManager.FLAG_LOCK);
+ WallpaperColors systemColor = mWallpaperManager.getWallpaperColors(
+ WallpaperManager.FLAG_SYSTEM);
+ mMainExecutor.execute(() -> {
+ if (USE_LOCK_SCREEN_WALLPAPER) {
+ mLockColors = lockColors;
+ }
+ mSystemColors = systemColor;
+ reevaluateSystemTheme();
+ });
+ });
+ if (USE_LOCK_SCREEN_WALLPAPER) {
+ mKeyguardStateController.addCallback(new KeyguardStateController.Callback() {
+ @Override
+ public void onKeyguardShowingChanged() {
+ if (mLockColors == null) {
+ return;
+ }
+ // It's possible that the user has a lock screen wallpaper. On this case we'll
+ // end up with different colors after unlocking.
+ reevaluateSystemTheme();
+ }
+ });
+ }
+ mWallpaperManager.addOnColorsChangedListener((wallpaperColors, which) -> {
+ if (USE_LOCK_SCREEN_WALLPAPER && (which & WallpaperManager.FLAG_LOCK) != 0) {
+ mLockColors = wallpaperColors;
+ if (DEBUG) {
+ Log.d(TAG, "got new lock colors: " + wallpaperColors + " where: " + which);
+ }
+ }
+ if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
+ mSystemColors = wallpaperColors;
+ if (DEBUG) {
+ Log.d(TAG, "got new lock colors: " + wallpaperColors + " where: " + which);
+ }
+ }
+ reevaluateSystemTheme();
+ }, null, UserHandle.USER_ALL);
+ }
+
+ private void reevaluateSystemTheme() {
+ if (mLockColors == null && mSystemColors == null) {
+ Log.w(TAG, "Cannot update theme, colors are null");
+ return;
+ }
+ WallpaperColors currentColor =
+ mKeyguardStateController.isShowing() && mLockColors != null
+ ? mLockColors : mSystemColors;
+ int mainColor = currentColor.getPrimaryColor().toArgb();
+
+ //TODO(b/172860591) implement more complex logic for picking accent color.
+ //For now, picking the secondary should be enough.
+ Color accentCandidate = currentColor.getSecondaryColor();
+ if (accentCandidate == null) {
+ accentCandidate = currentColor.getTertiaryColor();
+ }
+ if (accentCandidate == null) {
+ accentCandidate = currentColor.getPrimaryColor();
+ }
+
+ if (mMainWallpaperColor == mainColor && mWallpaperAccentColor == accentCandidate.toArgb()) {
+ return;
+ }
+
+ mMainWallpaperColor = mainColor;
+ mWallpaperAccentColor = accentCandidate.toArgb();
+
+ // Let's compare these colors to our finite set of overlays, and then pick an overlay.
+ List<Integer> systemColors = mThemeManager.getAvailableSystemColors();
+ List<Integer> accentColors = mThemeManager.getAvailableAccentColors();
+
+ if (systemColors.size() == 0 || accentColors.size() == 0) {
+ if (DEBUG) {
+ Log.d(TAG, "Cannot apply system theme, palettes are unavailable");
+ }
+ return;
+ }
+
+ mSystemOverlayColor = getClosest(systemColors, mMainWallpaperColor);
+ mAccentOverlayColor = getClosest(accentColors, mWallpaperAccentColor);
+
+ updateThemeOverlays();
+ }
+
+ /**
+ * Given a color and a list of candidates, return the candidate that's the most similar to the
+ * given color.
+ */
+ private static int getClosest(List<Integer> candidates, int color) {
+ float[] hslMain = new float[3];
+ float[] hslCandidate = new float[3];
+
+ ColorUtils.RGBToHSL(Color.red(color), Color.green(color), Color.blue(color), hslMain);
+ hslMain[0] /= 360f;
+
+ float minDistance = Float.MAX_VALUE;
+ int closestColor = Color.TRANSPARENT;
+ for (int candidate: candidates) {
+ ColorUtils.RGBToHSL(Color.red(candidate), Color.green(candidate), Color.blue(candidate),
+ hslCandidate);
+ hslCandidate[0] /= 360f;
+
+ float sqDistance = squared(hslCandidate[0] - hslMain[0])
+ + squared(hslCandidate[1] - hslMain[1])
+ + squared(hslCandidate[2] - hslMain[2]);
+ if (sqDistance < minDistance) {
+ minDistance = sqDistance;
+ closestColor = candidate;
+ }
+ }
+ return closestColor;
+ }
+
+ private static float squared(float f) {
+ return f * f;
}
private void updateThemeOverlays() {
final int currentUser = ActivityManager.getCurrentUser();
- final String overlayPackageJson = Settings.Secure.getStringForUser(
- mContext.getContentResolver(), Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
+ final String overlayPackageJson = mSecureSettings.getStringForUser(
+ Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
currentUser);
if (DEBUG) Log.d(TAG, "updateThemeOverlays: " + overlayPackageJson);
+ boolean hasSystemPalette = false;
+ boolean hasAccentColor = false;
final Map<String, String> categoryToPackage = new ArrayMap<>();
if (!TextUtils.isEmpty(overlayPackageJson)) {
try {
JSONObject object = new JSONObject(overlayPackageJson);
- for (String category : ThemeOverlayManager.THEME_CATEGORIES) {
+ for (String category : ThemeOverlayApplier.THEME_CATEGORIES) {
if (object.has(category)) {
+ if (category.equals(OVERLAY_CATEGORY_ACCENT_COLOR)) {
+ hasAccentColor = true;
+ } else if (category.equals(OVERLAY_CATEGORY_SYSTEM_PALETTE)) {
+ hasSystemPalette = true;
+ }
categoryToPackage.put(category, object.getString(category));
}
}
@@ -132,6 +302,20 @@
Log.i(TAG, "Failed to parse THEME_CUSTOMIZATION_OVERLAY_PACKAGES.", e);
}
}
+
+ // Let's apply the system palette, but only if it was not overridden by the style picker.
+ if (!hasSystemPalette && mSystemOverlayColor != Color.TRANSPARENT) {
+ categoryToPackage.put(OVERLAY_CATEGORY_SYSTEM_PALETTE,
+ ThemeOverlayApplier.MONET_SYSTEM_PALETTE_PACKAGE
+ + Integer.toHexString(mSystemOverlayColor).toUpperCase());
+ }
+ // Same for the accent color
+ if (!hasAccentColor && mAccentOverlayColor != Color.TRANSPARENT) {
+ categoryToPackage.put(OVERLAY_CATEGORY_ACCENT_COLOR,
+ ThemeOverlayApplier.MONET_ACCENT_COLOR_PACKAGE
+ + Integer.toHexString(mAccentOverlayColor).toUpperCase());
+ }
+
Set<UserHandle> userHandles = Sets.newHashSet(UserHandle.of(currentUser));
for (UserInfo userInfo : mUserManager.getEnabledProfiles(currentUser)) {
if (userInfo.isManagedProfile()) {
@@ -140,4 +324,14 @@
}
mThemeManager.applyCurrentUserOverlays(categoryToPackage, userHandles);
}
+
+ @Override
+ public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
+ pw.println("mLockColors=" + mLockColors);
+ pw.println("mSystemColors=" + mSystemColors);
+ pw.println("mMainWallpaperColor=" + Integer.toHexString(mMainWallpaperColor));
+ pw.println("mWallpaperAccentColor=" + Integer.toHexString(mWallpaperAccentColor));
+ pw.println("mSystemOverlayColor=" + Integer.toHexString(mSystemOverlayColor));
+ pw.println("mAccentOverlayColor=" + Integer.toHexString(mAccentOverlayColor));
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index 7a24438..04f1f86 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -16,8 +16,6 @@
package com.android.systemui.wmshell;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
@@ -29,21 +27,14 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
-import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import android.app.ActivityManager;
-import android.app.ActivityTaskManager;
-import android.app.ActivityTaskManager.RootTaskInfo;
-import android.content.ComponentName;
import android.content.Context;
+import android.content.res.Configuration;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.inputmethodservice.InputMethodService;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.util.Log;
-import android.util.Pair;
import android.view.KeyEvent;
import com.android.internal.annotations.VisibleForTesting;
@@ -55,8 +46,6 @@
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.model.SysUiState;
import com.android.systemui.navigationbar.NavigationModeController;
-import com.android.systemui.shared.system.TaskStackChangeListener;
-import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.systemui.shared.tracing.ProtoTraceable;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -64,6 +53,7 @@
import com.android.systemui.tracing.ProtoTracer;
import com.android.systemui.tracing.nano.SystemUiTraceProto;
import com.android.wm.shell.ShellDump;
+import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.nano.WmShellTraceProto;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.onehanded.OneHandedEvents;
@@ -105,6 +95,7 @@
private final Optional<Pip> mPipOptional;
private final Optional<SplitScreen> mSplitScreenOptional;
private final Optional<OneHanded> mOneHandedOptional;
+ private final Optional<HideDisplayCutout> mHideDisplayCutoutOptional;
private final ProtoTracer mProtoTracer;
private final Optional<ShellDump> mShellDump;
@@ -123,6 +114,7 @@
Optional<Pip> pipOptional,
Optional<SplitScreen> splitScreenOptional,
Optional<OneHanded> oneHandedOptional,
+ Optional<HideDisplayCutout> hideDisplayCutoutOptional,
ProtoTracer protoTracer,
Optional<ShellDump> shellDump) {
super(context);
@@ -135,6 +127,7 @@
mPipOptional = pipOptional;
mSplitScreenOptional = splitScreenOptional;
mOneHandedOptional = oneHandedOptional;
+ mHideDisplayCutoutOptional = hideDisplayCutoutOptional;
mProtoTracer = protoTracer;
mProtoTracer.add(this);
mShellDump = shellDump;
@@ -146,6 +139,7 @@
mPipOptional.ifPresent(this::initPip);
mSplitScreenOptional.ifPresent(this::initSplitScreen);
mOneHandedOptional.ifPresent(this::initOneHanded);
+ mHideDisplayCutoutOptional.ifPresent(this::initHideDisplayCutout);
}
@VisibleForTesting
@@ -284,6 +278,16 @@
});
}
+ @VisibleForTesting
+ void initHideDisplayCutout(HideDisplayCutout hideDisplayCutout) {
+ mConfigurationController.addCallback(new ConfigurationController.ConfigurationListener() {
+ @Override
+ public void onConfigChanged(Configuration newConfig) {
+ hideDisplayCutout.onConfigurationChanged(newConfig);
+ }
+ });
+ }
+
@Override
public void writeToProto(SystemUiTraceProto proto) {
if (proto.wmShell == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
index 6546ed5..8c2980f 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
@@ -28,7 +28,6 @@
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.dagger.WMSingleton;
import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.shared.system.InputConsumerController;
import com.android.wm.shell.ShellDump;
import com.android.wm.shell.ShellInit;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -46,6 +45,8 @@
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.draganddrop.DragAndDropController;
+import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
+import com.android.wm.shell.hidedisplaycutout.HideDisplayCutoutController;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.onehanded.OneHandedController;
import com.android.wm.shell.pip.Pip;
@@ -90,9 +91,10 @@
static Optional<ShellDump> provideShellDump(ShellTaskOrganizer shellTaskOrganizer,
Optional<SplitScreen> splitScreenOptional,
Optional<Pip> pipOptional,
- Optional<OneHanded> oneHandedOptional) {
+ Optional<OneHanded> oneHandedOptional,
+ Optional<HideDisplayCutout> hideDisplayCutout) {
return Optional.of(new ShellDump(shellTaskOrganizer, splitScreenOptional, pipOptional,
- oneHandedOptional));
+ oneHandedOptional, hideDisplayCutout));
}
@WMSingleton
@@ -171,9 +173,9 @@
@WMSingleton
@Provides
static ShellTaskOrganizer provideShellTaskOrganizer(SyncTransactionQueue syncQueue,
- ShellExecutor mainExecutor, TransactionPool transactionPool) {
+ ShellExecutor mainExecutor, TransactionPool transactionPool, Context context) {
return new ShellTaskOrganizer(syncQueue, transactionPool,
- mainExecutor, AnimationThread.instance().getExecutor());
+ mainExecutor, AnimationThread.instance().getExecutor(), context);
}
@WMSingleton
@@ -215,4 +217,10 @@
return new HandlerExecutor(handler);
}
+ @WMSingleton
+ @Provides
+ static Optional<HideDisplayCutout> provideHideDisplayCutoutController(Context context,
+ DisplayController displayController) {
+ return Optional.ofNullable(HideDisplayCutoutController.create(context, displayController));
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java
index bce376a..f57e3c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java
@@ -37,8 +37,9 @@
import com.android.systemui.plugins.qs.QSTileView;
import com.android.systemui.qs.customize.QSCustomizerController;
import com.android.systemui.qs.tileimpl.QSTileImpl;
-import com.android.systemui.settings.BrightnessController;
-import com.android.systemui.settings.ToggleSlider;
+import com.android.systemui.settings.brightness.BrightnessController;
+import com.android.systemui.settings.brightness.BrightnessSlider;
+import com.android.systemui.settings.brightness.ToggleSlider;
import com.android.systemui.tuner.TunerService;
import org.junit.Before;
@@ -79,6 +80,10 @@
@Mock
private BrightnessController mBrightnessController;
@Mock
+ private BrightnessSlider.Factory mToggleSliderViewControllerFactory;
+ @Mock
+ private BrightnessSlider mBrightnessSlider;
+ @Mock
QSTileImpl mQSTile;
@Mock
QSTileView mQSTileView;
@@ -98,13 +103,16 @@
when(mQSPanel.createRegularTileLayout()).thenReturn(mPagedTileLayout);
when(mQSTileHost.getTiles()).thenReturn(Collections.singleton(mQSTile));
when(mQSTileHost.createTileView(eq(mQSTile), anyBoolean())).thenReturn(mQSTileView);
+ when(mToggleSliderViewControllerFactory.create(any(), any()))
+ .thenReturn(mBrightnessSlider);
when(mBrightnessControllerFactory.create(any(ToggleSlider.class)))
.thenReturn(mBrightnessController);
when(mQSTileRevealControllerFactory.create(any())).thenReturn(mQSTileRevealController);
mController = new QSPanelController(mQSPanel, mQSSecurityFooter, mTunerService,
mQSTileHost, mQSCustomizerController, mQSTileRevealControllerFactory, mDumpManager,
- mMetricsLogger, mUiEventLogger, mBrightnessControllerFactory);
+ mMetricsLogger, mUiEventLogger, mBrightnessControllerFactory,
+ mToggleSliderViewControllerFactory);
mController.init();
}
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
new file mode 100644
index 0000000..78af20f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.Mockito.when;
+
+import android.os.Handler;
+import android.provider.Settings;
+import android.service.quicksettings.Tile;
+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.SysuiTestCase;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.settings.UserTracker;
+import com.android.systemui.util.settings.FakeSettings;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+public class ReduceBrightColorsTileTest extends SysuiTestCase {
+ @Mock
+ private QSTileHost mHost;
+ @Mock
+ private MetricsLogger mMetricsLogger;
+ @Mock
+ private StatusBarStateController mStatusBarStateController;
+ @Mock
+ private ActivityStarter mActivityStarter;
+ @Mock
+ private QSLogger mQSLogger;
+ @Mock
+ private UserTracker mUserTracker;
+
+ private FakeSettings mFakeSettings;
+ private TestableLooper mTestableLooper;
+ private ReduceBrightColorsTile mTile;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ mTestableLooper = TestableLooper.get(this);
+
+ when(mHost.getContext()).thenReturn(mContext);
+ mFakeSettings = new FakeSettings();
+
+ mTile = new ReduceBrightColorsTile(
+ mHost,
+ mTestableLooper.getLooper(),
+ new Handler(mTestableLooper.getLooper()),
+ mMetricsLogger,
+ mStatusBarStateController,
+ mActivityStarter,
+ mQSLogger,
+ mUserTracker,
+ mFakeSettings
+ );
+ }
+
+ @Test
+ public void testNotActive() {
+ mTile.refreshState();
+ mTestableLooper.processAllMessages();
+
+ assertEquals(Tile.STATE_INACTIVE, mTile.getState().state);
+ assertEquals(mTile.getState().label.toString(),
+ mContext.getString(R.string.quick_settings_reduce_bright_colors_label));
+ assertEquals(mTile.getState().secondaryLabel.toString(), "");
+ }
+
+ @Test
+ public void testActive() {
+ mFakeSettings.putIntForUser(
+ Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED,
+ 1,
+ mUserTracker.getUserId());
+ mTile.refreshState();
+ mTestableLooper.processAllMessages();
+
+ assertActiveState();
+ }
+
+ @Test
+ public void testActive_clicked_isActive() {
+ mTile.refreshState();
+ mTestableLooper.processAllMessages();
+ // Validity check
+ assertEquals(Tile.STATE_INACTIVE, mTile.getState().state);
+
+ mTile.handleClick();
+ mTile.refreshState();
+ mTestableLooper.processAllMessages();
+
+ assertActiveState();
+ }
+
+ private void assertActiveState() {
+ assertEquals(Tile.STATE_ACTIVE, mTile.getState().state);
+ assertEquals(mTile.getState().label.toString(),
+ mContext.getString(R.string.quick_settings_reduce_bright_colors_label));
+
+ final int intensity = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.REDUCE_BRIGHT_COLORS_LEVEL, 0, mUserTracker.getUserId());
+
+ assertEquals(
+ mContext.getString(
+ R.string.quick_settings_reduce_bright_colors_secondary_label, intensity),
+ mTile.getState().secondaryLabel.toString());
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderTest.kt
new file mode 100644
index 0000000..0cc2072
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderTest.kt
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2020 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.testing.AndroidTestingRunner
+import android.view.MotionEvent
+import android.view.View
+import android.view.ViewGroup
+import android.widget.CompoundButton
+import android.widget.SeekBar
+import androidx.test.filters.SmallTest
+import com.android.settingslib.RestrictedLockUtils
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.policy.BrightnessMirrorController
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.eq
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.isNull
+import org.mockito.Mockito.mock
+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
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class BrightnessSliderTest : SysuiTestCase() {
+
+ @Mock
+ private lateinit var rootView: View
+ @Mock
+ private lateinit var brightnessSliderView: BrightnessSliderView
+ @Mock
+ private lateinit var enforcedAdmin: RestrictedLockUtils.EnforcedAdmin
+ @Mock
+ private lateinit var mirrorController: BrightnessMirrorController
+ @Mock
+ private lateinit var mirror: ToggleSlider
+ @Mock
+ private lateinit var motionEvent: MotionEvent
+ @Mock
+ private lateinit var listener: ToggleSlider.Listener
+
+ @Captor
+ private lateinit var seekBarChangeCaptor: ArgumentCaptor<SeekBar.OnSeekBarChangeListener>
+ @Mock
+ private lateinit var seekBar: SeekBar
+ @Captor
+ private lateinit var checkedChangeCaptor: ArgumentCaptor<CompoundButton.OnCheckedChangeListener>
+ @Mock
+ private lateinit var compoundButton: CompoundButton
+
+ private lateinit var mController: BrightnessSlider
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ whenever(mirrorController.toggleSlider).thenReturn(mirror)
+ whenever(motionEvent.copy()).thenReturn(motionEvent)
+
+ mController = BrightnessSlider(rootView, brightnessSliderView, true)
+ mController.init()
+ mController.setOnChangedListener(listener)
+ }
+
+ @After
+ fun tearDown() {
+ mController.onViewDetached()
+ }
+
+ @Test
+ fun testListenersAddedOnAttach() {
+ mController.onViewAttached()
+
+ verify(brightnessSliderView).setOnCheckedChangeListener(notNull())
+ verify(brightnessSliderView).setOnSeekBarChangeListener(notNull())
+ }
+
+ @Test
+ fun testAllListenersRemovedOnDettach() {
+ mController.onViewAttached()
+ mController.onViewDetached()
+
+ verify(brightnessSliderView).setOnSeekBarChangeListener(isNull())
+ verify(brightnessSliderView).setOnCheckedChangeListener(isNull())
+ verify(brightnessSliderView).setOnDispatchTouchEventListener(isNull())
+ }
+
+ @Test
+ fun testEnforceAdminRelayed() {
+ mController.setEnforcedAdmin(enforcedAdmin)
+ verify(brightnessSliderView).setEnforcedAdmin(enforcedAdmin)
+ }
+
+ @Test
+ fun testNullMirrorControllerNotTrackingTouch() {
+ mController.setMirrorControllerAndMirror(null)
+
+ verify(brightnessSliderView, never()).max
+ verify(brightnessSliderView, never()).value
+ verify(brightnessSliderView, never()).isChecked
+ verify(brightnessSliderView).setOnDispatchTouchEventListener(isNull())
+ }
+
+ @Test
+ fun testNullMirrorNotTrackingTouch() {
+ whenever(mirrorController.toggleSlider).thenReturn(null)
+
+ mController.setMirrorControllerAndMirror(mirrorController)
+
+ verify(brightnessSliderView, never()).max
+ verify(brightnessSliderView, never()).value
+ verify(brightnessSliderView, never()).isChecked
+ verify(brightnessSliderView).setOnDispatchTouchEventListener(isNull())
+ }
+
+ @Test
+ fun testSettingMirrorControllerReliesValuesAndSetsTouchTracking() {
+ val maxValue = 100
+ val progress = 30
+ val checked = true
+ whenever(brightnessSliderView.max).thenReturn(maxValue)
+ whenever(brightnessSliderView.value).thenReturn(progress)
+ whenever(brightnessSliderView.isChecked).thenReturn(checked)
+
+ mController.setMirrorControllerAndMirror(mirrorController)
+
+ verify(mirror).max = maxValue
+ verify(mirror).isChecked = checked
+ verify(mirror).value = progress
+ verify(brightnessSliderView).setOnDispatchTouchEventListener(notNull())
+ }
+
+ @Test
+ fun testSettingMirrorWhenNotUseMirrorIsNoOp() {
+ val otherController = BrightnessSlider(rootView, brightnessSliderView, false)
+ otherController.init()
+
+ otherController.setMirrorControllerAndMirror(mirrorController)
+
+ verify(brightnessSliderView, never()).max
+ verify(brightnessSliderView, never()).value
+ verify(brightnessSliderView, never()).isChecked
+ verify(brightnessSliderView, never()).setOnDispatchTouchEventListener(
+ any(BrightnessSliderView.DispatchTouchEventListener::class.java))
+ }
+
+ @Test
+ fun testSetCheckedRelayed_true() {
+ mController.isChecked = true
+ verify(brightnessSliderView).isChecked = true
+ }
+
+ @Test
+ fun testSetCheckedRelayed_false() {
+ mController.isChecked = false
+ verify(brightnessSliderView).isChecked = false
+ }
+
+ @Test
+ fun testGetChecked() {
+ whenever(brightnessSliderView.isChecked).thenReturn(true)
+
+ assertThat(mController.isChecked).isTrue()
+
+ whenever(brightnessSliderView.isChecked).thenReturn(false)
+
+ assertThat(mController.isChecked).isFalse()
+ }
+
+ @Test
+ fun testSetMaxRelayed() {
+ mController.max = 120
+ verify(brightnessSliderView).max = 120
+ }
+
+ @Test
+ fun testGetMax() {
+ whenever(brightnessSliderView.max).thenReturn(40)
+
+ assertThat(mController.max).isEqualTo(40)
+ }
+
+ @Test
+ fun testSetValue() {
+ mController.value = 30
+ verify(brightnessSliderView).value = 30
+ }
+
+ @Test
+ fun testGetValue() {
+ whenever(brightnessSliderView.value).thenReturn(20)
+
+ assertThat(mController.value).isEqualTo(20)
+ }
+
+ @Test
+ fun testMirrorEventWithMirror() {
+ mController.setMirrorControllerAndMirror(mirrorController)
+
+ mController.mirrorTouchEvent(motionEvent)
+
+ verify(mirror).mirrorTouchEvent(motionEvent)
+ verify(brightnessSliderView, never()).dispatchTouchEvent(any(MotionEvent::class.java))
+ }
+
+ @Test
+ fun testMirrorEventWithoutMirror_dispatchToView() {
+ mController.mirrorTouchEvent(motionEvent)
+
+ verify(brightnessSliderView).dispatchTouchEvent(motionEvent)
+ }
+
+ @Test
+ fun testSeekBarProgressChanged() {
+ mController.onViewAttached()
+ whenever(brightnessSliderView.isChecked).thenReturn(true)
+
+ verify(brightnessSliderView).setOnSeekBarChangeListener(capture(seekBarChangeCaptor))
+
+ seekBarChangeCaptor.value.onProgressChanged(seekBar, 23, true)
+
+ verify(listener).onChanged(anyBoolean(), eq(true), eq(23), eq(false))
+ }
+
+ @Test
+ fun testSeekBarTrackingStarted() {
+ val parent = mock(ViewGroup::class.java)
+ whenever(brightnessSliderView.value).thenReturn(42)
+ whenever(brightnessSliderView.parent).thenReturn(parent)
+ whenever(brightnessSliderView.isChecked).thenReturn(true)
+
+ mController.onViewAttached()
+ mController.setMirrorControllerAndMirror(mirrorController)
+ verify(brightnessSliderView).setOnSeekBarChangeListener(capture(seekBarChangeCaptor))
+
+ seekBarChangeCaptor.value.onStartTrackingTouch(seekBar)
+
+ verify(listener).onChanged(eq(true), eq(true), eq(42), eq(false))
+ verify(mirrorController).showMirror()
+ verify(mirrorController).setLocation(parent)
+ }
+
+ @Test
+ fun testSeekBarTrackingStopped() {
+ whenever(brightnessSliderView.value).thenReturn(23)
+ whenever(brightnessSliderView.isChecked).thenReturn(true)
+
+ mController.onViewAttached()
+ mController.setMirrorControllerAndMirror(mirrorController)
+ verify(brightnessSliderView).setOnSeekBarChangeListener(capture(seekBarChangeCaptor))
+
+ seekBarChangeCaptor.value.onStopTrackingTouch(seekBar)
+
+ verify(listener).onChanged(eq(false), eq(true), eq(23), eq(true))
+ verify(mirrorController).hideMirror()
+ }
+
+ @Test
+ fun testButtonCheckedChanged_false() {
+ val checked = false
+
+ mController.onViewAttached()
+ mController.setMirrorControllerAndMirror(mirrorController)
+ verify(brightnessSliderView).setOnCheckedChangeListener(capture(checkedChangeCaptor))
+
+ checkedChangeCaptor.value.onCheckedChanged(compoundButton, checked)
+
+ verify(brightnessSliderView).enableSlider(!checked)
+ verify(listener).onChanged(anyBoolean(), eq(checked), anyInt(), eq(false))
+ // Called once with false when the mirror is set
+ verify(mirror, times(2)).isChecked = checked
+ }
+
+ @Test
+ fun testButtonCheckedChanged_true() {
+ val checked = true
+
+ mController.onViewAttached()
+ mController.setMirrorControllerAndMirror(mirrorController)
+ verify(brightnessSliderView).setOnCheckedChangeListener(capture(checkedChangeCaptor))
+
+ checkedChangeCaptor.value.onCheckedChanged(compoundButton, checked)
+
+ verify(brightnessSliderView).enableSlider(!checked)
+ verify(listener).onChanged(anyBoolean(), eq(checked), anyInt(), eq(false))
+ verify(mirror).isChecked = checked
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 2f9b601..710122d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -97,6 +97,7 @@
import com.android.systemui.plugins.PluginDependencyProvider;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.ScreenPinningRequest;
+import com.android.systemui.settings.brightness.BrightnessSlider;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardIndicationController;
@@ -260,6 +261,7 @@
@Mock private PhoneStatusBarPolicy mPhoneStatusBarPolicy;
@Mock private DemoModeController mDemoModeController;
@Mock private Lazy<NotificationShadeDepthController> mNotificationShadeDepthControllerLazy;
+ @Mock private BrightnessSlider.Factory mBrightnessSliderFactory;
private ShadeController mShadeController;
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
private InitController mInitController = new InitController();
@@ -419,7 +421,8 @@
mDemoModeController,
mNotificationShadeDepthControllerLazy,
mStatusBarTouchableRegionManager,
- mNotificationIconAreaController);
+ mNotificationIconAreaController,
+ mBrightnessSliderFactory);
when(mNotificationShadeWindowView.findViewById(R.id.lock_icon_container)).thenReturn(
mLockIconContainer);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java
similarity index 85%
rename from packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayManagerTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java
index c99deb6..edaff5f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java
@@ -15,22 +15,24 @@
*/
package com.android.systemui.theme;
-import static com.android.systemui.theme.ThemeOverlayManager.ANDROID_PACKAGE;
-import static com.android.systemui.theme.ThemeOverlayManager.OVERLAY_CATEGORY_COLOR;
-import static com.android.systemui.theme.ThemeOverlayManager.OVERLAY_CATEGORY_FONT;
-import static com.android.systemui.theme.ThemeOverlayManager.OVERLAY_CATEGORY_ICON_ANDROID;
-import static com.android.systemui.theme.ThemeOverlayManager.OVERLAY_CATEGORY_ICON_LAUNCHER;
-import static com.android.systemui.theme.ThemeOverlayManager.OVERLAY_CATEGORY_ICON_SETTINGS;
-import static com.android.systemui.theme.ThemeOverlayManager.OVERLAY_CATEGORY_ICON_SYSUI;
-import static com.android.systemui.theme.ThemeOverlayManager.OVERLAY_CATEGORY_ICON_THEME_PICKER;
-import static com.android.systemui.theme.ThemeOverlayManager.OVERLAY_CATEGORY_SHAPE;
-import static com.android.systemui.theme.ThemeOverlayManager.SETTINGS_PACKAGE;
-import static com.android.systemui.theme.ThemeOverlayManager.SYSTEM_USER_CATEGORIES;
-import static com.android.systemui.theme.ThemeOverlayManager.SYSUI_PACKAGE;
-import static com.android.systemui.theme.ThemeOverlayManager.THEME_CATEGORIES;
+import static com.android.systemui.theme.ThemeOverlayApplier.ANDROID_PACKAGE;
+import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ACCENT_COLOR;
+import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_FONT;
+import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ICON_ANDROID;
+import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ICON_LAUNCHER;
+import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ICON_SETTINGS;
+import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ICON_SYSUI;
+import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ICON_THEME_PICKER;
+import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_SHAPE;
+import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_SYSTEM_PALETTE;
+import static com.android.systemui.theme.ThemeOverlayApplier.SETTINGS_PACKAGE;
+import static com.android.systemui.theme.ThemeOverlayApplier.SYSTEM_USER_CATEGORIES;
+import static com.android.systemui.theme.ThemeOverlayApplier.SYSUI_PACKAGE;
+import static com.android.systemui.theme.ThemeOverlayApplier.THEME_CATEGORIES;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -44,6 +46,7 @@
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dump.DumpManager;
import com.google.android.collect.Maps;
import com.google.common.collect.Lists;
@@ -63,7 +66,7 @@
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
-public class ThemeOverlayManagerTest extends SysuiTestCase {
+public class ThemeOverlayApplierTest extends SysuiTestCase {
private static final String TEST_DISABLED_PREFIX = "com.example.";
private static final String TEST_ENABLED_PREFIX = "com.example.enabled.";
@@ -82,26 +85,32 @@
@Mock
OverlayManager mOverlayManager;
+ @Mock
+ DumpManager mDumpManager;
- private ThemeOverlayManager mManager;
+ private ThemeOverlayApplier mManager;
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
- mManager = new ThemeOverlayManager(mOverlayManager, MoreExecutors.directExecutor(),
- LAUNCHER_PACKAGE, THEMEPICKER_PACKAGE);
+ mManager = new ThemeOverlayApplier(mOverlayManager, MoreExecutors.directExecutor(),
+ LAUNCHER_PACKAGE, THEMEPICKER_PACKAGE, mDumpManager);
when(mOverlayManager.getOverlayInfosForTarget(ANDROID_PACKAGE, UserHandle.SYSTEM))
.thenReturn(Lists.newArrayList(
- createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_COLOR,
- ANDROID_PACKAGE, OVERLAY_CATEGORY_COLOR, false),
+ createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_ACCENT_COLOR,
+ ANDROID_PACKAGE, OVERLAY_CATEGORY_ACCENT_COLOR, false),
+ createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_SYSTEM_PALETTE,
+ ANDROID_PACKAGE, OVERLAY_CATEGORY_SYSTEM_PALETTE, false),
createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_FONT,
ANDROID_PACKAGE, OVERLAY_CATEGORY_FONT, false),
createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_SHAPE,
ANDROID_PACKAGE, OVERLAY_CATEGORY_SHAPE, false),
createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_ICON_ANDROID,
ANDROID_PACKAGE, OVERLAY_CATEGORY_ICON_ANDROID, false),
- createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_COLOR,
- ANDROID_PACKAGE, OVERLAY_CATEGORY_COLOR, true),
+ createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ACCENT_COLOR,
+ ANDROID_PACKAGE, OVERLAY_CATEGORY_ACCENT_COLOR, true),
+ createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_SYSTEM_PALETTE,
+ ANDROID_PACKAGE, OVERLAY_CATEGORY_SYSTEM_PALETTE, true),
createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_FONT,
ANDROID_PACKAGE, OVERLAY_CATEGORY_FONT, true),
createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_SHAPE,
@@ -132,6 +141,8 @@
THEMEPICKER_PACKAGE, OVERLAY_CATEGORY_ICON_THEME_PICKER, false),
createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ICON_THEME_PICKER,
THEMEPICKER_PACKAGE, OVERLAY_CATEGORY_ICON_THEME_PICKER, true)));
+ clearInvocations(mOverlayManager);
+ verify(mDumpManager).registerDumpable(any(), any());
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
new file mode 100644
index 0000000..aee8840
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2020 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.theme;
+
+import static com.android.systemui.theme.ThemeOverlayApplier.MONET_ACCENT_COLOR_PACKAGE;
+import static com.android.systemui.theme.ThemeOverlayApplier.MONET_SYSTEM_PALETTE_PACKAGE;
+import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ACCENT_COLOR;
+import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_SYSTEM_PALETTE;
+import static com.android.systemui.theme.ThemeOverlayController.USE_LOCK_SCREEN_WALLPAPER;
+
+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;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
+import android.graphics.Color;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.dump.DumpManager;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.settings.SecureSettings;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class ThemeOverlayControllerTest extends SysuiTestCase {
+
+ private ThemeOverlayController mThemeOverlayController;
+ @Mock
+ private Executor mBgExecutor;
+ @Mock
+ private Executor mMainExecutor;
+ @Mock
+ private BroadcastDispatcher mBroadcastDispatcher;
+ @Mock
+ private Handler mBgHandler;
+ @Mock
+ private ThemeOverlayApplier mThemeOverlayApplier;
+ @Mock
+ private SecureSettings mSecureSettings;
+ @Mock
+ private WallpaperManager mWallpaperManager;
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private KeyguardStateController mKeyguardStateController;
+ @Mock
+ private DumpManager mDumpManager;
+ @Captor
+ private ArgumentCaptor<KeyguardStateController.Callback> mKeyguardStateControllerCallback;
+ @Captor
+ private ArgumentCaptor<WallpaperManager.OnColorsChangedListener> mColorsListener;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mThemeOverlayController = new ThemeOverlayController(null /* context */,
+ mBroadcastDispatcher, mBgHandler, mMainExecutor, mBgExecutor, mThemeOverlayApplier,
+ mSecureSettings, mWallpaperManager, mUserManager, mKeyguardStateController,
+ mDumpManager);
+
+ mThemeOverlayController.start();
+ if (USE_LOCK_SCREEN_WALLPAPER) {
+ verify(mKeyguardStateController).addCallback(
+ mKeyguardStateControllerCallback.capture());
+ }
+ verify(mWallpaperManager).addOnColorsChangedListener(mColorsListener.capture(), eq(null),
+ eq(UserHandle.USER_ALL));
+ verify(mDumpManager).registerDumpable(any(), any());
+
+ List<Integer> colorList = List.of(Color.RED, Color.BLUE);
+ when(mThemeOverlayApplier.getAvailableAccentColors()).thenReturn(colorList);
+ when(mThemeOverlayApplier.getAvailableSystemColors()).thenReturn(colorList);
+ }
+
+ @Test
+ public void start_checksWallpaper() {
+ ArgumentCaptor<Runnable> registrationRunnable = ArgumentCaptor.forClass(Runnable.class);
+ verify(mBgExecutor).execute(registrationRunnable.capture());
+
+ registrationRunnable.getValue().run();
+ verify(mWallpaperManager).getWallpaperColors(eq(WallpaperManager.FLAG_LOCK));
+ verify(mWallpaperManager).getWallpaperColors(eq(WallpaperManager.FLAG_SYSTEM));
+ }
+
+ @Test
+ public void onWallpaperColorsChanged_setsTheme() {
+ // Should ask for a new theme when wallpaper colors change
+ WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
+ Color.valueOf(Color.BLUE), null);
+ mColorsListener.getValue().onColorsChanged(mainColors, WallpaperManager.FLAG_SYSTEM);
+ ArgumentCaptor<Map<String, String>> themeOverlays = ArgumentCaptor.forClass(Map.class);
+
+ verify(mThemeOverlayApplier).getAvailableSystemColors();
+ verify(mThemeOverlayApplier).getAvailableAccentColors();
+ verify(mThemeOverlayApplier).applyCurrentUserOverlays(themeOverlays.capture(), any());
+
+ // Assert that we received the colors that we were expecting
+ assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_SYSTEM_PALETTE))
+ .isEqualTo(MONET_SYSTEM_PALETTE_PACKAGE
+ + Integer.toHexString(Color.RED).toUpperCase());
+ assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_ACCENT_COLOR))
+ .isEqualTo(MONET_ACCENT_COLOR_PACKAGE
+ + Integer.toHexString(Color.BLUE).toUpperCase());
+
+ // Should not ask again if changed to same value
+ mColorsListener.getValue().onColorsChanged(mainColors, WallpaperManager.FLAG_SYSTEM);
+ verifyNoMoreInteractions(mThemeOverlayApplier);
+ }
+
+ @Test
+ public void onWallpaperColorsChanged_preservesWallpaperPickerTheme() {
+ // Should ask for a new theme when wallpaper colors change
+ WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
+ Color.valueOf(Color.BLUE), null);
+
+ String jsonString =
+ "{\"android.theme.customization.system_palette\":\"override.package.name\"}";
+ when(mSecureSettings.getStringForUser(
+ eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), anyInt()))
+ .thenReturn(jsonString);
+
+ mColorsListener.getValue().onColorsChanged(mainColors, WallpaperManager.FLAG_SYSTEM);
+ ArgumentCaptor<Map<String, String>> themeOverlays = ArgumentCaptor.forClass(Map.class);
+
+ verify(mThemeOverlayApplier).getAvailableSystemColors();
+ verify(mThemeOverlayApplier).getAvailableAccentColors();
+ verify(mThemeOverlayApplier).applyCurrentUserOverlays(themeOverlays.capture(), any());
+
+ // Assert that we received the colors that we were expecting
+ assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_SYSTEM_PALETTE))
+ .isEqualTo("override.package.name");
+ }
+}
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 a46e563..230aeab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -45,9 +45,6 @@
import android.app.Notification;
import android.app.PendingIntent;
import android.content.pm.LauncherApps;
-import android.content.res.Configuration;
-import android.graphics.Insets;
-import android.graphics.Rect;
import android.hardware.display.AmbientDisplayConfiguration;
import android.hardware.face.FaceManager;
import android.os.Handler;
@@ -99,7 +96,7 @@
import com.android.wm.shell.bubbles.BubbleDataRepository;
import com.android.wm.shell.bubbles.BubbleEntry;
import com.android.wm.shell.bubbles.BubbleLogger;
-import com.android.wm.shell.bubbles.BubblePositioner;
+import com.android.wm.shell.bubbles.BubbleOverflow;
import com.android.wm.shell.bubbles.BubbleStackView;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.common.FloatingContentCoordinator;
@@ -206,8 +203,8 @@
private WindowManagerShellWrapper mWindowManagerShellWrapper;
@Mock
private BubbleLogger mBubbleLogger;
- @Mock
- private BubblePositioner mPositioner;
+
+ private TestableBubblePositioner mPositioner;
private BubbleData mBubbleData;
@@ -255,12 +252,8 @@
mSysUiStateBubblesExpanded =
(sysUiFlags & QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED) != 0);
- mBubbleData = new BubbleData(mContext, mBubbleLogger);
-
- Rect availableRect = new Rect(0, 0, 1000, 5000);
- when(mPositioner.getAvailableRect()).thenReturn(availableRect);
- when(mPositioner.getOrientation()).thenReturn(Configuration.ORIENTATION_PORTRAIT);
- when(mPositioner.getInsets()).thenReturn(Insets.of(0, 0, 0, 0));
+ mPositioner = new TestableBubblePositioner(mContext, mWindowManager);
+ mBubbleData = new BubbleData(mContext, mBubbleLogger, mPositioner);
TestableNotificationInterruptStateProviderImpl interruptionStateProvider =
new TestableNotificationInterruptStateProviderImpl(mContext.getContentResolver(),
@@ -585,7 +578,7 @@
}
@Test
- public void testRemoveLastExpandedCollapses() {
+ public void testRemoveLastExpanded_selectsOverflow() {
// Mark it as a bubble and add it explicitly
mEntryListener.onPendingEntryAdded(mRow.getEntry());
mEntryListener.onPendingEntryAdded(mRow2.getEntry());
@@ -625,10 +618,38 @@
stackView.getExpandedBubble().getKey()).getKey(),
Bubbles.DISMISS_USER_GESTURE);
- // Make sure state changes and collapse happens
+ // Overflow should be selected
+ assertEquals(mBubbleData.getSelectedBubble().getKey(), BubbleOverflow.KEY);
+ verify(mBubbleExpandListener).onBubbleExpandChanged(true, BubbleOverflow.KEY);
+ assertTrue(mBubbleController.hasBubbles());
+ assertTrue(mSysUiStateBubblesExpanded);
+ }
+
+ @Test
+ public void testRemoveLastExpandedEmptyOverflow_collapses() {
+ // Mark it as a bubble and add it explicitly
+ mEntryListener.onPendingEntryAdded(mRow.getEntry());
+ mBubbleController.updateBubble(mBubbleEntry);
+
+ // Expand
+ BubbleStackView stackView = mBubbleController.getStackView();
+ mBubbleData.setExpanded(true);
+
+ assertTrue(mSysUiStateBubblesExpanded);
+ assertTrue(mBubbleController.isStackExpanded());
+ verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey());
+
+ // Block the bubble so it won't be in the overflow
+ mBubbleController.removeBubble(
+ mBubbleData.getBubbleInStackWithKey(
+ stackView.getExpandedBubble().getKey()).getKey(),
+ Bubbles.DISMISS_BLOCKED);
+
+ verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().getKey());
+
+ // We should be collapsed
verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().getKey());
assertFalse(mBubbleController.hasBubbles());
-
assertFalse(mSysUiStateBubblesExpanded);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
index d8033db..bbcc30a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
@@ -42,9 +42,6 @@
import android.app.Notification;
import android.app.PendingIntent;
import android.content.pm.LauncherApps;
-import android.content.res.Configuration;
-import android.graphics.Insets;
-import android.graphics.Rect;
import android.hardware.display.AmbientDisplayConfiguration;
import android.os.Handler;
import android.os.PowerManager;
@@ -92,7 +89,7 @@
import com.android.wm.shell.bubbles.BubbleDataRepository;
import com.android.wm.shell.bubbles.BubbleEntry;
import com.android.wm.shell.bubbles.BubbleLogger;
-import com.android.wm.shell.bubbles.BubblePositioner;
+import com.android.wm.shell.bubbles.BubbleOverflow;
import com.android.wm.shell.bubbles.BubbleStackView;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.common.FloatingContentCoordinator;
@@ -188,8 +185,8 @@
private WindowManagerShellWrapper mWindowManagerShellWrapper;
@Mock
private BubbleLogger mBubbleLogger;
- @Mock
- private BubblePositioner mPositioner;
+
+ private TestableBubblePositioner mPositioner;
private BubbleData mBubbleData;
@@ -224,12 +221,8 @@
mZenModeConfig.suppressedVisualEffects = 0;
when(mZenModeController.getConfig()).thenReturn(mZenModeConfig);
- mBubbleData = new BubbleData(mContext, mBubbleLogger);
-
- Rect availableRect = new Rect(0, 0, 1000, 5000);
- when(mPositioner.getAvailableRect()).thenReturn(availableRect);
- when(mPositioner.getOrientation()).thenReturn(Configuration.ORIENTATION_PORTRAIT);
- when(mPositioner.getInsets()).thenReturn(Insets.of(0, 0, 0, 0));
+ mPositioner = new TestableBubblePositioner(mContext, mWindowManager);
+ mBubbleData = new BubbleData(mContext, mBubbleLogger, mPositioner);
TestableNotificationInterruptStateProviderImpl interruptionStateProvider =
new TestableNotificationInterruptStateProviderImpl(mContext.getContentResolver(),
@@ -516,7 +509,7 @@
}
@Test
- public void testRemoveLastExpandedCollapses() {
+ public void testRemoveLastExpanded_selectsOverflow() {
// Mark it as a bubble and add it explicitly
mEntryListener.onEntryAdded(mRow.getEntry());
mEntryListener.onEntryAdded(mRow2.getEntry());
@@ -554,11 +547,39 @@
stackView.getExpandedBubble().getKey()).getKey(),
Bubbles.DISMISS_USER_GESTURE);
- // Make sure state changes and collapse happens
+ // Overflow should be selected
+ assertEquals(mBubbleData.getSelectedBubble().getKey(), BubbleOverflow.KEY);
+ verify(mBubbleExpandListener).onBubbleExpandChanged(true, BubbleOverflow.KEY);
+ assertTrue(mBubbleController.hasBubbles());
+ }
+
+ @Test
+ public void testRemoveLastExpandedEmptyOverflow_collapses() {
+ // Mark it as a bubble and add it explicitly
+ mEntryListener.onEntryAdded(mRow.getEntry());
+ mBubbleController.updateBubble(mBubbleEntry);
+
+ // Expand
+ BubbleStackView stackView = mBubbleController.getStackView();
+ mBubbleData.setExpanded(true);
+
+ assertTrue(mBubbleController.isStackExpanded());
+ verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey());
+
+ // Block the bubble so it won't be in the overflow
+ mBubbleController.removeBubble(
+ mBubbleData.getBubbleInStackWithKey(
+ stackView.getExpandedBubble().getKey()).getKey(),
+ Bubbles.DISMISS_BLOCKED);
+
+ verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().getKey());
+
+ // We should be collapsed
verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().getKey());
assertFalse(mBubbleController.hasBubbles());
}
+
@Test
public void testAutoExpand_fails_noFlag() {
assertFalse(mBubbleController.isStackExpanded());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubblePositioner.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubblePositioner.java
new file mode 100644
index 0000000..24a7cd5
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubblePositioner.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 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.wmshell;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Insets;
+import android.graphics.Rect;
+import android.view.WindowManager;
+
+import com.android.wm.shell.bubbles.BubblePositioner;
+
+public class TestableBubblePositioner extends BubblePositioner {
+
+ public TestableBubblePositioner(Context context,
+ WindowManager windowManager) {
+ super(context, windowManager);
+
+ updateInternal(Configuration.ORIENTATION_PORTRAIT,
+ Insets.of(0, 0, 0, 0),
+ new Rect(0, 0, 500, 1000));
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
index 6a303a9..34889ff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
@@ -20,7 +20,6 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.content.pm.PackageManager;
import android.test.suitebuilder.annotation.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -31,13 +30,11 @@
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.model.SysUiState;
import com.android.systemui.navigationbar.NavigationModeController;
-import com.android.systemui.shared.system.InputConsumerController;
-import com.android.systemui.shared.system.TaskStackChangeListener;
-import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.tracing.ProtoTracer;
import com.android.wm.shell.ShellDump;
+import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.onehanded.OneHandedGestureHandler;
import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
@@ -56,13 +53,11 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
public class WMShellTest extends SysuiTestCase {
- InputConsumerController mInputConsumerController;
WMShell mWMShell;
@Mock CommandQueue mCommandQueue;
@Mock ConfigurationController mConfigurationController;
@Mock KeyguardUpdateMonitor mKeyguardUpdateMonitor;
- @Mock InputConsumerController mMockInputConsumerController;
@Mock NavigationModeController mNavigationModeController;
@Mock ScreenLifecycle mScreenLifecycle;
@Mock SysUiState mSysUiState;
@@ -70,6 +65,7 @@
@Mock PipTouchHandler mPipTouchHandler;
@Mock SplitScreen mSplitScreen;
@Mock OneHanded mOneHanded;
+ @Mock HideDisplayCutout mHideDisplayCutout;
@Mock ProtoTracer mProtoTracer;
@Mock ShellDump mShellDump;
@@ -80,7 +76,8 @@
mWMShell = new WMShell(mContext, mCommandQueue, mConfigurationController,
mKeyguardUpdateMonitor, mNavigationModeController,
mScreenLifecycle, mSysUiState, Optional.of(mPip), Optional.of(mSplitScreen),
- Optional.of(mOneHanded), mProtoTracer, Optional.of(mShellDump));
+ Optional.of(mOneHanded), Optional.of(mHideDisplayCutout), mProtoTracer,
+ Optional.of(mShellDump));
when(mPip.getPipTouchHandler()).thenReturn(mPipTouchHandler);
}
@@ -113,4 +110,12 @@
OneHandedGestureHandler.OneHandedGestureEventCallback.class));
verify(mOneHanded).registerTransitionCallback(any(OneHandedTransitionCallback.class));
}
+
+ @Test
+ public void initHideDisplayCutout_registersCallbacks() {
+ mWMShell.initHideDisplayCutout(mHideDisplayCutout);
+
+ verify(mConfigurationController).addCallback(
+ any(ConfigurationController.ConfigurationListener.class));
+ }
}
diff --git a/services/core/Android.bp b/services/core/Android.bp
index fb3c61b..e9edebd 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -211,6 +211,7 @@
":connectivity-service-srcs",
],
installable: true,
+ jarjar_rules: "jarjar-rules.txt",
libs: [
"android.net.ipsec.ike",
"services.core",
diff --git a/services/core/jarjar-rules.txt b/services/core/jarjar-rules.txt
new file mode 100644
index 0000000..58f7bcb
--- /dev/null
+++ b/services/core/jarjar-rules.txt
@@ -0,0 +1,2 @@
+# For ConnectivityService module
+rule com.android.modules.utils.** com.android.connectivity.utils.@1
\ No newline at end of file
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 8b6007c..1eba37d 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -137,7 +137,6 @@
import android.net.shared.PrivateDnsConfig;
import android.net.util.MultinetworkPolicyTracker;
import android.net.util.NetdService;
-import android.os.BasicShellCommandHandler;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -190,6 +189,7 @@
import com.android.internal.util.LocationPermissionChecker;
import com.android.internal.util.MessageUtils;
import com.android.internal.util.XmlUtils;
+import com.android.modules.utils.BasicShellCommandHandler;
import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult;
import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
import com.android.server.am.BatteryStatsService;
@@ -1917,10 +1917,13 @@
}
if (DBG) log("Adding legacy route " + bestRoute +
" for UID/PID " + uid + "/" + Binder.getCallingPid());
+
+ final String dst = bestRoute.getDestinationLinkAddress().toString();
+ final String nextHop = bestRoute.hasGateway()
+ ? bestRoute.getGateway().getHostAddress() : "";
try {
- mNMS.addLegacyRouteForNetId(netId, bestRoute, uid);
- } catch (Exception e) {
- // never crash - catch them all
+ mNetd.networkAddLegacyRoute(netId, bestRoute.getInterface(), dst, nextHop , uid);
+ } catch (RemoteException | ServiceSpecificException e) {
if (DBG) loge("Exception trying to add a route: " + e);
return false;
}
diff --git a/services/core/java/com/android/server/RescueParty.java b/services/core/java/com/android/server/RescueParty.java
index 6206f7a..d04949a 100644
--- a/services/core/java/com/android/server/RescueParty.java
+++ b/services/core/java/com/android/server/RescueParty.java
@@ -78,6 +78,7 @@
@VisibleForTesting
static final String PROP_RESCUE_LEVEL = "sys.rescue_level";
static final String PROP_ATTEMPTING_FACTORY_RESET = "sys.attempting_factory_reset";
+ static final String PROP_MAX_RESCUE_LEVEL_ATTEMPTED = "sys.max_rescue_level_attempted";
@VisibleForTesting
static final int LEVEL_NONE = 0;
@VisibleForTesting
@@ -94,6 +95,8 @@
static final String TAG = "RescueParty";
@VisibleForTesting
static final long DEFAULT_OBSERVING_DURATION_MS = TimeUnit.DAYS.toMillis(2);
+ @VisibleForTesting
+ static final int DEVICE_CONFIG_RESET_MODE = Settings.RESET_MODE_TRUSTED_DEFAULTS;
private static final String NAME = "rescue-party-observer";
@@ -225,7 +228,7 @@
if (NAMESPACE_CONFIGURATION.equals(resetNativeCategories[i])) {
continue;
}
- DeviceConfig.resetToDefaults(Settings.RESET_MODE_TRUSTED_DEFAULTS,
+ DeviceConfig.resetToDefaults(DEVICE_CONFIG_RESET_MODE,
resetNativeCategories[i]);
}
}
@@ -300,15 +303,48 @@
private static void executeRescueLevelInternal(Context context, int level, @Nullable
String failedPackage) throws Exception {
FrameworkStatsLog.write(FrameworkStatsLog.RESCUE_PARTY_RESET_REPORTED, level);
+ // Try our best to reset all settings possible, and once finished
+ // rethrow any exception that we encountered
+ Exception res = null;
switch (level) {
case LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS:
- resetAllSettings(context, Settings.RESET_MODE_UNTRUSTED_DEFAULTS, failedPackage);
+ try {
+ resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_DEFAULTS,
+ level);
+ } catch (Exception e) {
+ res = e;
+ }
+ try {
+ resetDeviceConfig(context, /*isScoped=*/true, failedPackage);
+ } catch (Exception e) {
+ res = e;
+ }
break;
case LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES:
- resetAllSettings(context, Settings.RESET_MODE_UNTRUSTED_CHANGES, failedPackage);
+ try {
+ resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_CHANGES,
+ level);
+ } catch (Exception e) {
+ res = e;
+ }
+ try {
+ resetDeviceConfig(context, /*isScoped=*/true, failedPackage);
+ } catch (Exception e) {
+ res = e;
+ }
break;
case LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS:
- resetAllSettings(context, Settings.RESET_MODE_TRUSTED_DEFAULTS, failedPackage);
+ try {
+ resetAllSettingsIfNecessary(context, Settings.RESET_MODE_TRUSTED_DEFAULTS,
+ level);
+ } catch (Exception e) {
+ res = e;
+ }
+ try {
+ resetDeviceConfig(context, /*isScoped=*/false, failedPackage);
+ } catch (Exception e) {
+ res = e;
+ }
break;
case LEVEL_FACTORY_RESET:
// Request the reboot from a separate thread to avoid deadlock on PackageWatchdog
@@ -328,6 +364,10 @@
thread.start();
break;
}
+
+ if (res != null) {
+ throw res;
+ }
}
private static void logRescueException(int level, Throwable t) {
@@ -350,18 +390,18 @@
}
}
- private static void resetAllSettings(Context context, int mode, @Nullable String failedPackage)
- throws Exception {
+ private static void resetAllSettingsIfNecessary(Context context, int mode,
+ int level) throws Exception {
+ // No need to reset Settings again if they are already reset in the current level once.
+ if (SystemProperties.getInt(PROP_MAX_RESCUE_LEVEL_ATTEMPTED, LEVEL_NONE) >= level) {
+ return;
+ }
+ SystemProperties.set(PROP_MAX_RESCUE_LEVEL_ATTEMPTED, Integer.toString(level));
// Try our best to reset all settings possible, and once finished
// rethrow any exception that we encountered
Exception res = null;
final ContentResolver resolver = context.getContentResolver();
try {
- resetDeviceConfig(context, mode, failedPackage);
- } catch (Exception e) {
- res = new RuntimeException("Failed to reset config settings", e);
- }
- try {
Settings.Global.resetToDefaultsAsUser(resolver, null, mode, UserHandle.USER_SYSTEM);
} catch (Exception e) {
res = new RuntimeException("Failed to reset global settings", e);
@@ -378,16 +418,21 @@
}
}
- private static void resetDeviceConfig(Context context, int resetMode,
- @Nullable String failedPackage) {
- if (!shouldPerformScopedResets(resetMode) || failedPackage == null) {
- resetAllAffectedNamespaces(context, resetMode);
- } else {
- performScopedReset(context, resetMode, failedPackage);
+ private static void resetDeviceConfig(Context context, boolean isScoped,
+ @Nullable String failedPackage) throws Exception {
+ final ContentResolver resolver = context.getContentResolver();
+ try {
+ if (!isScoped || failedPackage == null) {
+ resetAllAffectedNamespaces(context);
+ } else {
+ performScopedReset(context, failedPackage);
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to reset config settings", e);
}
}
- private static void resetAllAffectedNamespaces(Context context, int resetMode) {
+ private static void resetAllAffectedNamespaces(Context context) {
RescuePartyObserver rescuePartyObserver = RescuePartyObserver.getInstance(context);
Set<String> allAffectedNamespaces = rescuePartyObserver.getAllAffectedNamespaceSet();
@@ -401,16 +446,11 @@
if (NAMESPACE_CONFIGURATION.equals(namespace)) {
continue;
}
- DeviceConfig.resetToDefaults(resetMode, namespace);
+ DeviceConfig.resetToDefaults(DEVICE_CONFIG_RESET_MODE, namespace);
}
}
- private static boolean shouldPerformScopedResets(int resetMode) {
- return resetMode <= Settings.RESET_MODE_UNTRUSTED_CHANGES;
- }
-
- private static void performScopedReset(Context context, int resetMode,
- @NonNull String failedPackage) {
+ private static void performScopedReset(Context context, @NonNull String failedPackage) {
RescuePartyObserver rescuePartyObserver = RescuePartyObserver.getInstance(context);
Set<String> affectedNamespaces = rescuePartyObserver.getAffectedNamespaceSet(
failedPackage);
@@ -428,7 +468,7 @@
if (NAMESPACE_CONFIGURATION.equals(namespace)) {
continue;
}
- DeviceConfig.resetToDefaults(resetMode, namespace);
+ DeviceConfig.resetToDefaults(DEVICE_CONFIG_RESET_MODE, namespace);
}
}
}
diff --git a/services/core/java/com/android/server/ServiceWatcher.java b/services/core/java/com/android/server/ServiceWatcher.java
index b78b5d9..3ccb6e5 100644
--- a/services/core/java/com/android/server/ServiceWatcher.java
+++ b/services/core/java/com/android/server/ServiceWatcher.java
@@ -185,9 +185,49 @@
private final Handler mHandler;
private final Intent mIntent;
+ private final PackageMonitor mPackageMonitor = new PackageMonitor() {
+ @Override
+ public boolean onPackageChanged(String packageName, int uid, String[] components) {
+ return true;
+ }
+
+ @Override
+ public void onSomePackagesChanged() {
+ onBestServiceChanged(false);
+ }
+ };
+ private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (action == null) {
+ return;
+ }
+ int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+ if (userId == UserHandle.USER_NULL) {
+ return;
+ }
+
+ switch (action) {
+ case Intent.ACTION_USER_SWITCHED:
+ onUserSwitched(userId);
+ break;
+ case Intent.ACTION_USER_UNLOCKED:
+ onUserUnlocked(userId);
+ break;
+ default:
+ break;
+ }
+
+ }
+ };
+
@Nullable private final OnBindRunner mOnBind;
@Nullable private final Runnable mOnUnbind;
+ // write from caller thread only, read anywhere
+ private volatile boolean mRegistered;
+
// read/write from handler thread only
private int mCurrentUserId;
@@ -225,77 +265,65 @@
}
/**
- * Register this class, which will start the process of determining the best matching service
- * and maintaining a binding to it. Will return false and fail if there are no possible matching
- * services at the time this functions is called.
+ * Returns true if there is at least one component that could satisfy the ServiceWatcher's
+ * constraints.
*/
- public boolean register() {
- if (mContext.getPackageManager().queryIntentServicesAsUser(mIntent,
+ public boolean checkServiceResolves() {
+ return !mContext.getPackageManager().queryIntentServicesAsUser(mIntent,
MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE | MATCH_SYSTEM_ONLY,
- UserHandle.USER_SYSTEM).isEmpty()) {
- return false;
- }
+ UserHandle.USER_SYSTEM).isEmpty();
+ }
- new PackageMonitor() {
- @Override
- public boolean onPackageChanged(String packageName, int uid, String[] components) {
- return true;
- }
+ /**
+ * Starts the process of determining the best matching service and maintaining a binding to it.
+ */
+ public void register() {
+ Preconditions.checkState(!mRegistered);
- @Override
- public void onSomePackagesChanged() {
- onBestServiceChanged(false);
- }
- }.register(mContext, UserHandle.ALL, true, mHandler);
+ mPackageMonitor.register(mContext, UserHandle.ALL, true, mHandler);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
- mContext.registerReceiverAsUser(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action == null) {
- return;
- }
- int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
- if (userId == UserHandle.USER_NULL) {
- return;
- }
-
- switch (action) {
- case Intent.ACTION_USER_SWITCHED:
- onUserSwitched(userId);
- break;
- case Intent.ACTION_USER_UNLOCKED:
- onUserUnlocked(userId);
- break;
- default:
- break;
- }
-
- }
- }, UserHandle.ALL, intentFilter, null, mHandler);
+ mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, intentFilter, null,
+ mHandler);
mCurrentUserId = ActivityManager.getCurrentUser();
+ mRegistered = true;
+
mHandler.post(() -> onBestServiceChanged(false));
- return true;
+ }
+
+ /**
+ * Stops the process of determining the best matching service and releases any binding.
+ */
+ public void unregister() {
+ Preconditions.checkState(mRegistered);
+
+ mRegistered = false;
+
+ mPackageMonitor.unregister();
+ mContext.unregisterReceiver(mBroadcastReceiver);
+
+ mHandler.post(() -> onBestServiceChanged(false));
}
private void onBestServiceChanged(boolean forceRebind) {
Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
- List<ResolveInfo> resolveInfos = mContext.getPackageManager().queryIntentServicesAsUser(
- mIntent,
- GET_META_DATA | MATCH_DIRECT_BOOT_AUTO | MATCH_SYSTEM_ONLY,
- mCurrentUserId);
-
ServiceInfo bestServiceInfo = ServiceInfo.NONE;
- for (ResolveInfo resolveInfo : resolveInfos) {
- ServiceInfo serviceInfo = new ServiceInfo(resolveInfo, mCurrentUserId);
- if (serviceInfo.compareTo(bestServiceInfo) > 0) {
- bestServiceInfo = serviceInfo;
+
+ if (mRegistered) {
+ List<ResolveInfo> resolveInfos = mContext.getPackageManager().queryIntentServicesAsUser(
+ mIntent,
+ GET_META_DATA | MATCH_DIRECT_BOOT_AUTO | MATCH_SYSTEM_ONLY,
+ mCurrentUserId);
+ for (ResolveInfo resolveInfo : resolveInfos) {
+ ServiceInfo serviceInfo = new ServiceInfo(resolveInfo, mCurrentUserId);
+ if (serviceInfo.compareTo(bestServiceInfo) > 0) {
+ bestServiceInfo = serviceInfo;
+ }
}
}
diff --git a/services/core/java/com/android/server/adb/AdbShellCommand.java b/services/core/java/com/android/server/adb/AdbShellCommand.java
index 7691852..d7e95df 100644
--- a/services/core/java/com/android/server/adb/AdbShellCommand.java
+++ b/services/core/java/com/android/server/adb/AdbShellCommand.java
@@ -16,7 +16,7 @@
package com.android.server.adb;
-import android.os.BasicShellCommandHandler;
+import com.android.modules.utils.BasicShellCommandHandler;
import java.io.PrintWriter;
import java.util.Objects;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 9f2216d..796ea0e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -194,6 +194,7 @@
import android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageManager;
+import android.content.pm.IncrementalStatesInfo;
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -7574,6 +7575,20 @@
*/
void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
ApplicationErrorReport.CrashInfo crashInfo) {
+ boolean isPackageLoading = false;
+ // Notify package manager service to possibly update package state
+ if (r != null && r.info != null && r.info.packageName != null) {
+ mPackageManagerInt.notifyPackageCrashOrAnr(r.info.packageName);
+ IncrementalStatesInfo incrementalStatesInfo =
+ mPackageManagerInt.getIncrementalStatesInfo(r.info.packageName, r.uid,
+ r.userId);
+ isPackageLoading = incrementalStatesInfo.isLoading();
+ if (isPackageLoading) {
+ // Report in the main log that the package is still loading
+ Slog.e(TAG, "App crashed when package " + r.info.packageName + " is "
+ + ((int) (incrementalStatesInfo.getProgress() * 100)) + "% loaded.");
+ }
+ }
EventLogTags.writeAmCrash(Binder.getCallingPid(),
UserHandle.getUserId(Binder.getCallingUid()), processName,
@@ -7599,7 +7614,8 @@
: FrameworkStatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__UNKNOWN,
processName.equals("system_server") ? ServerProtoEnums.SYSTEM_SERVER
: (r != null) ? r.getProcessClassEnum()
- : ServerProtoEnums.ERROR_SOURCE_UNKNOWN
+ : ServerProtoEnums.ERROR_SOURCE_UNKNOWN,
+ isPackageLoading
);
final int relaunchReason = r == null ? RELAUNCH_REASON_NONE
@@ -7615,10 +7631,6 @@
eventType, r, processName, null, null, null, null, null, null, crashInfo);
mAppErrors.crashApplication(r, crashInfo);
- // Notify package manager service to possibly update package state
- if (r != null && r.info != null && r.info.packageName != null) {
- mPackageManagerInt.notifyPackageCrashOrAnr(r.info.packageName);
- }
}
public void handleApplicationStrictModeViolation(
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 85c5bdc..1b06dd9 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -36,6 +36,8 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
+import android.content.pm.IncrementalStatesInfo;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.ProcessInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.VersionedPackage;
@@ -1652,6 +1654,19 @@
}
}
+ // Check if package is still being loaded
+ boolean isPackageLoading = false;
+ final PackageManagerInternal packageManagerInternal =
+ mService.getPackageManagerInternalLocked();
+ if (aInfo != null && aInfo.packageName != null) {
+ IncrementalStatesInfo incrementalStatesInfo =
+ packageManagerInternal.getIncrementalStatesInfo(
+ aInfo.packageName, uid, userId);
+ if (incrementalStatesInfo != null) {
+ isPackageLoading = incrementalStatesInfo.isLoading();
+ }
+ }
+
// Log the ANR to the main log.
StringBuilder info = new StringBuilder();
info.setLength(0);
@@ -1669,6 +1684,13 @@
info.append("Parent: ").append(parentShortComponentName).append("\n");
}
+ if (isPackageLoading) {
+ // Report in the main log that the package is still loading
+ final float loadingProgress = packageManagerInternal.getIncrementalStatesInfo(
+ aInfo.packageName, uid, userId).getProgress();
+ info.append("Package is ").append((int) (loadingProgress * 100)).append("% loaded.\n");
+ }
+
StringBuilder report = new StringBuilder();
report.append(MemoryPressureUtil.currentPsiState());
ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
@@ -1736,7 +1758,7 @@
? FrameworkStatsLog.ANROCCURRED__FOREGROUND_STATE__FOREGROUND
: FrameworkStatsLog.ANROCCURRED__FOREGROUND_STATE__BACKGROUND,
getProcessClassEnum(),
- (this.info != null) ? this.info.packageName : "");
+ (this.info != null) ? this.info.packageName : "", isPackageLoading);
final ProcessRecord parentPr = parentProcess != null
? (ProcessRecord) parentProcess.mOwner : null;
mService.addErrorToDropBox("anr", this, processName, activityShortComponentName,
@@ -1771,8 +1793,7 @@
// Notify package manager service to possibly update package state
if (aInfo != null && aInfo.packageName != null) {
- mService.getPackageManagerInternalLocked().notifyPackageCrashOrAnr(
- aInfo.packageName);
+ packageManagerInternal.notifyPackageCrashOrAnr(aInfo.packageName);
}
// mUiHandler can be null if the AMS is constructed with injector only. This will only
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index d52cf02..eeec1bb 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -333,7 +333,7 @@
// initialization from here. AIDL HALs are initialized by FingerprintService since
// the HAL interface provides ID, strength, and other configuration information.
fingerprintService.initializeConfiguration(config.id, config.strength);
- authenticator = new FingerprintAuthenticator(fingerprintService, config);
+ authenticator = new FingerprintAuthenticator(fingerprintService, config.id);
break;
case TYPE_FACE:
@@ -348,7 +348,7 @@
// initialization from here. AIDL HALs are initialized by FaceService since
// the HAL interface provides ID, strength, and other configuration information.
faceService.initializeConfiguration(config.id, config.strength);
- authenticator = new FaceAuthenticator(faceService, config);
+ authenticator = new FaceAuthenticator(faceService, config.id);
break;
case TYPE_IRIS:
@@ -359,7 +359,8 @@
return;
}
- authenticator = new IrisAuthenticator(irisService, config);
+ irisService.initializeConfiguration(config.id, config.strength);
+ authenticator = new IrisAuthenticator(irisService, config.id);
break;
default:
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 3e0a40f..29424b4 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -594,20 +594,6 @@
}
}
- // This happens infrequently enough, not worth caching.
- final String[] configs = mInjector.getConfiguration(getContext());
- boolean idFound = false;
- for (int i = 0; i < configs.length; i++) {
- SensorConfig config = new SensorConfig(configs[i]);
- if (config.id == id) {
- idFound = true;
- break;
- }
- }
- if (!idFound) {
- throw new IllegalStateException("Cannot register unknown id");
- }
-
mSensors.add(new BiometricSensor(id, modality, strength, authenticator) {
@Override
boolean confirmationAlwaysRequired(int userId) {
diff --git a/services/core/java/com/android/server/biometrics/Utils.java b/services/core/java/com/android/server/biometrics/Utils.java
index 88804e2..6741942 100644
--- a/services/core/java/com/android/server/biometrics/Utils.java
+++ b/services/core/java/com/android/server/biometrics/Utils.java
@@ -453,7 +453,7 @@
* {@link SensorPropertiesInternal} strength.
*/
public static @SensorProperties.Strength int authenticatorStrengthToPropertyStrength(
- @BiometricManager.Authenticators.Types int strength) {
+ @Authenticators.Types int strength) {
switch (strength) {
case BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE:
return SensorProperties.STRENGTH_CONVENIENCE;
@@ -465,4 +465,18 @@
throw new IllegalArgumentException("Unknown strength: " + strength);
}
}
+
+ public static @Authenticators.Types int propertyStrengthToAuthenticatorStrength(
+ @SensorProperties.Strength int strength) {
+ switch (strength) {
+ case SensorProperties.STRENGTH_CONVENIENCE:
+ return Authenticators.BIOMETRIC_CONVENIENCE;
+ case SensorProperties.STRENGTH_WEAK:
+ return Authenticators.BIOMETRIC_WEAK;
+ case SensorProperties.STRENGTH_STRONG:
+ return Authenticators.BIOMETRIC_STRONG;
+ default:
+ throw new IllegalArgumentException("Unknown strength: " + strength);
+ }
+ }
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSysUIComponentModule.java b/services/core/java/com/android/server/biometrics/sensors/BiometricServiceCallback.java
similarity index 64%
rename from packages/CarSystemUI/src/com/android/systemui/CarSysUIComponentModule.java
rename to services/core/java/com/android/server/biometrics/sensors/BiometricServiceCallback.java
index 4de3166..2ae6ccd 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSysUIComponentModule.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricServiceCallback.java
@@ -14,15 +14,15 @@
* limitations under the License.
*/
-package com.android.systemui;
-
-import dagger.Module;
+package com.android.server.biometrics.sensors;
/**
- * Dagger module for including the CarSysUIComponent.
- *
- * TODO(b/162923491): Remove or otherwise refactor this module. This is a stop gap.
+ * System_server services that require BiometricService to load before finishing initialization
+ * should implement this interface.
*/
-@Module(subcomponents = {CarSysUIComponent.class})
-public abstract class CarSysUIComponentModule {
+public interface BiometricServiceCallback {
+ /**
+ * Notifies the service that BiometricService is initialized.
+ */
+ void onBiometricServiceReady();
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
index e742d10..b3e6cad 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
@@ -32,10 +32,10 @@
private final IFaceService mFaceService;
private final int mSensorId;
- public FaceAuthenticator(IFaceService faceService, SensorConfig config)
+ public FaceAuthenticator(IFaceService faceService, int sensorId)
throws RemoteException {
mFaceService = faceService;
- mSensorId = config.id;
+ mSensorId = sensorId;
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index 65e57f1..1e0764a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -19,6 +19,7 @@
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.Manifest.permission.MANAGE_BIOMETRIC;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
+import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -26,6 +27,7 @@
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.IBiometricSensorReceiver;
+import android.hardware.biometrics.IBiometricService;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.biometrics.face.IFace;
import android.hardware.biometrics.face.SensorProps;
@@ -54,7 +56,9 @@
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
import com.android.server.biometrics.sensors.LockoutTracker;
+import com.android.server.biometrics.sensors.BiometricServiceCallback;
import com.android.server.biometrics.sensors.face.aidl.FaceProvider;
+import com.android.server.biometrics.sensors.face.hidl.Face10;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -67,10 +71,11 @@
* The service is responsible for maintaining a list of clients and dispatching all
* face-related events.
*/
-public class FaceService extends SystemService {
+public class FaceService extends SystemService implements BiometricServiceCallback {
protected static final String TAG = "FaceService";
+ private final FaceServiceWrapper mServiceWrapper;
private final LockoutResetDispatcher mLockoutResetDispatcher;
private final LockPatternUtils mLockPatternUtils;
@NonNull
@@ -506,21 +511,23 @@
@BiometricManager.Authenticators.Types int strength) {
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
mServiceProviders.add(
- new com.android.server.biometrics.sensors.face.hidl.Face10(getContext(),
- sensorId, strength, mLockoutResetDispatcher));
+ new Face10(getContext(), sensorId, strength, mLockoutResetDispatcher));
}
}
public FaceService(Context context) {
super(context);
+ mServiceWrapper = new FaceServiceWrapper();
mLockoutResetDispatcher = new LockoutResetDispatcher(context);
mLockPatternUtils = new LockPatternUtils(context);
mServiceProviders = new ArrayList<>();
-
- initializeAidlHals();
}
- private void initializeAidlHals() {
+ @Override
+ public void onBiometricServiceReady() {
+ final IBiometricService biometricService = IBiometricService.Stub.asInterface(
+ ServiceManager.getService(Context.BIOMETRIC_SERVICE));
+
final String[] instances = ServiceManager.getDeclaredInstances(IFace.DESCRIPTOR);
if (instances == null || instances.length == 0) {
return;
@@ -543,6 +550,23 @@
final FaceProvider provider = new FaceProvider(getContext(), props, instance,
mLockoutResetDispatcher);
mServiceProviders.add(provider);
+
+ // Register each sensor individually with BiometricService
+ for (SensorProps prop : props) {
+ final int sensorId = prop.commonProps.sensorId;
+ @BiometricManager.Authenticators.Types int strength =
+ Utils.propertyStrengthToAuthenticatorStrength(
+ prop.commonProps.sensorStrength);
+ final FaceAuthenticator authenticator =
+ new FaceAuthenticator(mServiceWrapper, sensorId);
+ try {
+ biometricService.registerAuthenticator(sensorId, TYPE_FACE, strength,
+ authenticator);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception when registering sensorId: "
+ + sensorId);
+ }
+ }
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when initializing instance: " + fqName);
}
@@ -552,7 +576,7 @@
@Override
public void onStart() {
- publishBinderService(Context.FACE_SERVICE, new FaceServiceWrapper());
+ publishBinderService(Context.FACE_SERVICE, mServiceWrapper);
}
private native NativeHandle convertSurfaceToNativeHandle(Surface surface);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
index f77bc79..9f9d9cc 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
@@ -32,10 +32,10 @@
private final IFingerprintService mFingerprintService;
private final int mSensorId;
- public FingerprintAuthenticator(IFingerprintService fingerprintService, SensorConfig config)
+ public FingerprintAuthenticator(IFingerprintService fingerprintService, int sensorId)
throws RemoteException {
mFingerprintService = fingerprintService;
- mSensorId = config.id;
+ mSensorId = sensorId;
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 99569b1..b84d095 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -24,14 +24,17 @@
import static android.Manifest.permission.USE_BIOMETRIC;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
import static android.Manifest.permission.USE_FINGERPRINT;
+import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.IBiometricSensorReceiver;
+import android.hardware.biometrics.IBiometricService;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.biometrics.ITestSession;
import android.hardware.biometrics.fingerprint.IFingerprint;
@@ -65,6 +68,7 @@
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
import com.android.server.biometrics.sensors.LockoutTracker;
+import com.android.server.biometrics.sensors.BiometricServiceCallback;
import com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintProvider;
import com.android.server.biometrics.sensors.fingerprint.hidl.Fingerprint21;
import com.android.server.biometrics.sensors.fingerprint.hidl.Fingerprint21UdfpsMock;
@@ -80,7 +84,7 @@
* The service is responsible for maintaining a list of clients and dispatching all
* fingerprint-related events.
*/
-public class FingerprintService extends SystemService {
+public class FingerprintService extends SystemService implements BiometricServiceCallback {
protected static final String TAG = "FingerprintService";
@@ -88,6 +92,7 @@
private final LockoutResetDispatcher mLockoutResetDispatcher;
private final GestureAvailabilityDispatcher mGestureAvailabilityDispatcher;
private final LockPatternUtils mLockPatternUtils;
+ private final FingerprintServiceWrapper mServiceWrapper;
@NonNull private List<ServiceProvider> mServiceProviders;
/**
@@ -572,7 +577,8 @@
}
@Override // Binder call
- public void initializeConfiguration(int sensorId, int strength) {
+ public void initializeConfiguration(int sensorId,
+ @BiometricManager.Authenticators.Types int strength) {
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final Fingerprint21 fingerprint21;
@@ -626,16 +632,19 @@
public FingerprintService(Context context) {
super(context);
+ mServiceWrapper = new FingerprintServiceWrapper();
mAppOps = context.getSystemService(AppOpsManager.class);
mGestureAvailabilityDispatcher = new GestureAvailabilityDispatcher();
mLockoutResetDispatcher = new LockoutResetDispatcher(context);
mLockPatternUtils = new LockPatternUtils(context);
mServiceProviders = new ArrayList<>();
-
- initializeAidlHals();
}
- private void initializeAidlHals() {
+ @Override
+ public void onBiometricServiceReady() {
+ final IBiometricService biometricService = IBiometricService.Stub.asInterface(
+ ServiceManager.getService(Context.BIOMETRIC_SERVICE));
+
final String[] instances = ServiceManager.getDeclaredInstances(IFingerprint.DESCRIPTOR);
if (instances == null || instances.length == 0) {
return;
@@ -659,6 +668,23 @@
new FingerprintProvider(getContext(), props, instance,
mLockoutResetDispatcher, mGestureAvailabilityDispatcher);
mServiceProviders.add(provider);
+
+ // Register each sensor individually with BiometricService
+ for (SensorProps prop : props) {
+ final int sensorId = prop.commonProps.sensorId;
+ @BiometricManager.Authenticators.Types int strength =
+ Utils.propertyStrengthToAuthenticatorStrength(
+ prop.commonProps.sensorStrength);
+ final FingerprintAuthenticator authenticator =
+ new FingerprintAuthenticator(mServiceWrapper, sensorId);
+ try {
+ biometricService.registerAuthenticator(sensorId,
+ TYPE_FINGERPRINT, strength, authenticator);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception when registering sensorId: "
+ + sensorId);
+ }
+ }
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when initializing instance: " + fqName);
}
@@ -668,7 +694,7 @@
@Override
public void onStart() {
- publishBinderService(Context.FINGERPRINT_SERVICE, new FingerprintServiceWrapper());
+ publishBinderService(Context.FINGERPRINT_SERVICE, mServiceWrapper);
}
@Nullable
diff --git a/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java
index 0400ef5..b756d8e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java
@@ -31,10 +31,8 @@
public final class IrisAuthenticator extends IBiometricAuthenticator.Stub {
private final IIrisService mIrisService;
- public IrisAuthenticator(IIrisService irisService, SensorConfig config) throws
- RemoteException {
+ public IrisAuthenticator(IIrisService irisService, int sensorId) throws RemoteException {
mIrisService = irisService;
- mIrisService.initializeConfiguration(config.id);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java b/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java
index bcf63dc..08b2489 100644
--- a/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java
@@ -42,7 +42,7 @@
*/
private final class IrisServiceWrapper extends IIrisService.Stub {
@Override // Binder call
- public void initializeConfiguration(int sensorId) {
+ public void initializeConfiguration(int sensorId, int strength) {
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
}
}
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index ff017f89..ba7ba78 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -33,7 +33,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
-import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationManager;
@@ -1333,16 +1332,17 @@
// Restricted users are not allowed to create VPNs, they are tied to Owner
enforceNotRestrictedUser();
- ResolveInfo info = AppGlobals.getPackageManager().resolveService(intent,
- null, 0, mUserId);
+ final PackageManager packageManager = mUserIdContext.getPackageManager();
+ if (packageManager == null) {
+ throw new UnsupportedOperationException("Cannot get PackageManager.");
+ }
+ final ResolveInfo info = packageManager.resolveService(intent, 0 /* flags */);
if (info == null) {
throw new SecurityException("Cannot find " + config.user);
}
if (!BIND_VPN_SERVICE.equals(info.serviceInfo.permission)) {
throw new SecurityException(config.user + " does not require " + BIND_VPN_SERVICE);
}
- } catch (RemoteException e) {
- throw new SecurityException("Cannot find " + config.user);
} finally {
Binder.restoreCallingIdentity(token);
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecConfig.java b/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
index ca78f35..3794da3 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
@@ -229,6 +229,8 @@
switch (setting.getName()) {
case HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED:
return STORAGE_GLOBAL_SETTINGS;
+ case HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION:
+ return STORAGE_GLOBAL_SETTINGS;
case HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP:
return STORAGE_GLOBAL_SETTINGS;
case HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST:
@@ -237,7 +239,7 @@
return STORAGE_SYSPROPS;
default:
throw new RuntimeException("Invalid CEC setting '" + setting.getName()
- + "' storage.");
+ + "' storage.");
}
}
@@ -245,6 +247,8 @@
switch (setting.getName()) {
case HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED:
return Global.HDMI_CONTROL_ENABLED;
+ case HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION:
+ return Global.HDMI_CEC_VERSION;
case HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP:
return Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP;
case HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST:
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
index cdd9216..baed9cc 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
@@ -148,9 +148,25 @@
addValidationInfo(Constants.MESSAGE_SET_MENU_LANGUAGE,
new AsciiValidator(3), DEST_BROADCAST);
- // TODO: Handle messages for the Deck Control.
+ ParameterValidator statusRequestValidator = new OneByteRangeValidator(0x01, 0x03);
+ addValidationInfo(
+ Constants.MESSAGE_DECK_CONTROL, new OneByteRangeValidator(0x01, 0x04), DEST_DIRECT);
+ addValidationInfo(
+ Constants.MESSAGE_DECK_STATUS, new OneByteRangeValidator(0x11, 0x1F), DEST_DIRECT);
+ addValidationInfo(Constants.MESSAGE_GIVE_DECK_STATUS, statusRequestValidator, DEST_DIRECT);
+ addValidationInfo(Constants.MESSAGE_PLAY, new PlayModeValidator(), DEST_DIRECT);
// TODO: Handle messages for the Tuner Control.
+ addValidationInfo(
+ Constants.MESSAGE_GIVE_TUNER_DEVICE_STATUS, statusRequestValidator, DEST_DIRECT);
+ addValidationInfo(
+ Constants.MESSAGE_SELECT_ANALOG_SERVICE,
+ new SelectAnalogueServiceValidator(),
+ DEST_DIRECT);
+ addValidationInfo(
+ Constants.MESSAGE_SELECT_DIGITAL_SERVICE,
+ new SelectDigitalServiceValidator(),
+ DEST_DIRECT);
// Messages for the Vendor Specific Commands.
VariableLengthValidator maxLengthValidator = new VariableLengthValidator(0, 14);
@@ -176,9 +192,10 @@
Constants.MESSAGE_MENU_STATUS, new OneByteRangeValidator(0x00, 0x01), DEST_DIRECT);
// Messages for the Remote Control Passthrough.
- // TODO: Parse the first parameter and determine if it can have the next parameter.
- addValidationInfo(Constants.MESSAGE_USER_CONTROL_PRESSED,
- new VariableLengthValidator(1, 2), DEST_DIRECT);
+ addValidationInfo(
+ Constants.MESSAGE_USER_CONTROL_PRESSED,
+ new UserControlPressedValidator(),
+ DEST_DIRECT);
// Messages for the Power Status.
addValidationInfo(
@@ -526,6 +543,28 @@
}
/**
+ * Check if the given value is a valid Channel Identifier. A valid value is one which falls
+ * within the range description defined in CEC 1.4 Specification : Operand Descriptions (Section
+ * 17)
+ *
+ * @param params Channel Identifier parameters
+ * @param offset start offset of Channel Identifier
+ * @return true if the Channel Identifier is valid
+ */
+ private boolean isValidChannelIdentifier(byte[] params, int offset) {
+ // First 6 bits contain Channel Number Format
+ int channelNumberFormat = params[offset] & 0xFC;
+ if (channelNumberFormat == 0x04) {
+ // Validate it contains 1-part Channel Number data (16 bits)
+ return params.length - offset >= 3;
+ } else if (channelNumberFormat == 0x08) {
+ // Validate it contains Major Channel Number and Minor Channel Number (26 bits)
+ return params.length - offset >= 4;
+ }
+ return false;
+ }
+
+ /**
* Check if the given value is a valid Digital Service Identification. A valid value is one
* which falls within the range description defined in CEC 1.4 Specification : Operand
* Descriptions (Section 17)
@@ -555,15 +594,7 @@
} else if (serviceIdentificationMethod == 0x80) {
// Services identified by Channel
if (isValidDigitalBroadcastSystem(digitalBroadcastSystem)) {
- // First 6 bits contain Channel Number Format
- int channelNumberFormat = params[offset] & 0xFC;
- if (channelNumberFormat == 0x04) {
- // Validate it contains 1-part Channel Number data (16 bits)
- return params.length - offset >= 3;
- } else if (channelNumberFormat == 0x08) {
- // Validate it contains Major Channel Number and Minor Channel Number (26 bits)
- return params.length - offset >= 4;
- }
+ return isValidChannelIdentifier(params, offset);
}
}
return false;
@@ -643,6 +674,65 @@
return false;
}
+ /**
+ * Check if the given value is a valid Play mode. A valid value is one which falls within the
+ * range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+ *
+ * @param value Play mode
+ * @return true if the Play mode is valid
+ */
+ private boolean isValidPlayMode(int value) {
+ return (isWithinRange(value, 0x05, 0x07)
+ || isWithinRange(value, 0x09, 0x0B)
+ || isWithinRange(value, 0x15, 0x17)
+ || isWithinRange(value, 0x19, 0x1B)
+ || isWithinRange(value, 0x24, 0x25)
+ || (value == 0x20));
+ }
+
+ /**
+ * Check if the given value is a valid UI Broadcast type. A valid value is one which falls
+ * within the range description defined in CEC 1.4 Specification : Operand Descriptions (Section
+ * 17)
+ *
+ * @param value UI Broadcast type
+ * @return true if the UI Broadcast type is valid
+ */
+ private boolean isValidUiBroadcastType(int value) {
+ return ((value == 0x00)
+ || (value == 0x01)
+ || (value == 0x10)
+ || (value == 0x20)
+ || (value == 0x30)
+ || (value == 0x40)
+ || (value == 0x50)
+ || (value == 0x60)
+ || (value == 0x70)
+ || (value == 0x80)
+ || (value == 0x90)
+ || (value == 0x91)
+ || (value == 0xA0));
+ }
+
+ /**
+ * Check if the given value is a valid UI Sound Presenation Control. A valid value is one which
+ * falls within the range description defined in CEC 1.4 Specification : Operand Descriptions
+ * (Section 17)
+ *
+ * @param value UI Sound Presenation Control
+ * @return true if the UI Sound Presenation Control is valid
+ */
+ private boolean isValidUiSoundPresenationControl(int value) {
+ value = value & 0xFF;
+ return ((value == 0x20)
+ || (value == 0x30)
+ || (value == 0x80)
+ || (value == 0x90)
+ || (value == 0xA0)
+ || (isWithinRange(value, 0xB1, 0xB3))
+ || (isWithinRange(value, 0xC1, 0xC3)));
+ }
+
private class PhysicalAddressValidator implements ParameterValidator {
@Override
public int isValid(byte[] params) {
@@ -874,4 +964,78 @@
return toErrorCode(isValidTimerStatusData(params, 0));
}
}
+
+ /**
+ * Check if the given play mode parameter is valid. A valid parameter should lie within the
+ * range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+ */
+ private class PlayModeValidator implements ParameterValidator {
+ @Override
+ public int isValid(byte[] params) {
+ if (params.length < 1) {
+ return ERROR_PARAMETER_SHORT;
+ }
+ return toErrorCode(isValidPlayMode(params[0]));
+ }
+ }
+
+ /**
+ * Check if the given select analogue service parameter is valid. A valid parameter should lie
+ * within the range description defined in CEC 1.4 Specification : Operand Descriptions
+ * (Section 17)
+ */
+ private class SelectAnalogueServiceValidator implements ParameterValidator {
+ @Override
+ public int isValid(byte[] params) {
+ if (params.length < 4) {
+ return ERROR_PARAMETER_SHORT;
+ }
+ return toErrorCode(isValidAnalogueBroadcastType(params[0])
+ && isValidAnalogueFrequency(HdmiUtils.twoBytesToInt(params, 1))
+ && isValidBroadcastSystem(params[3]));
+ }
+ }
+
+ /**
+ * Check if the given select digital service parameter is valid. A valid parameter should lie
+ * within the range description defined in CEC 1.4 Specification : Operand Descriptions
+ * (Section 17)
+ */
+ private class SelectDigitalServiceValidator implements ParameterValidator {
+ @Override
+ public int isValid(byte[] params) {
+ if (params.length < 4) {
+ return ERROR_PARAMETER_SHORT;
+ }
+ return toErrorCode(isValidDigitalServiceIdentification(params, 0));
+ }
+ }
+
+ /** Check if the given user control press parameter is valid. */
+ private class UserControlPressedValidator implements ParameterValidator {
+ @Override
+ public int isValid(byte[] params) {
+ if (params.length < 1) {
+ return ERROR_PARAMETER_SHORT;
+ }
+ if (params.length == 1) {
+ return OK;
+ }
+ int uiCommand = params[0];
+ switch (uiCommand) {
+ case HdmiCecKeycode.CEC_KEYCODE_PLAY_FUNCTION:
+ return toErrorCode(isValidPlayMode(params[1]));
+ case HdmiCecKeycode.CEC_KEYCODE_TUNE_FUNCTION:
+ return (params.length >= 4
+ ? toErrorCode(isValidChannelIdentifier(params, 1))
+ : ERROR_PARAMETER_SHORT);
+ case HdmiCecKeycode.CEC_KEYCODE_SELECT_BROADCAST_TYPE:
+ return toErrorCode(isValidUiBroadcastType(params[1]));
+ case HdmiCecKeycode.CEC_KEYCODE_SELECT_SOUND_PRESENTATION:
+ return toErrorCode(isValidUiSoundPresenationControl(params[1]));
+ default:
+ return OK;
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 2fc9acb..dcd6c02 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -26,7 +26,6 @@
import static com.android.server.hdmi.Constants.OPTION_MHL_INPUT_SWITCHING;
import static com.android.server.hdmi.Constants.OPTION_MHL_POWER_CHARGE;
import static com.android.server.hdmi.Constants.OPTION_MHL_SERVICE_CONTROL;
-import static com.android.server.hdmi.Constants.VERSION_1_4;
import static com.android.server.power.ShutdownThread.SHUTDOWN_ACTION_PROPERTY;
import android.annotation.IntDef;
@@ -81,7 +80,6 @@
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.SystemService;
-import com.android.server.hdmi.Constants.CecVersion;
import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;
import com.android.server.hdmi.HdmiCecController.AllocateAddressCallback;
import com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource;
@@ -391,8 +389,8 @@
@Nullable
private Looper mIoLooper;
- @CecVersion
- private int mCecVersion = Constants.VERSION_1_4;
+ @HdmiControlManager.HdmiCecVersion
+ private int mCecVersion;
// Last input port before switching to the MHL port. Should switch back to this port
// when the mobile device sends the request one touch play with off.
@@ -820,7 +818,8 @@
private void initializeCec(int initiatedBy) {
mAddressAllocated = false;
- mCecVersion = readIntSetting(Global.HDMI_CEC_VERSION, VERSION_1_4);
+ mCecVersion = getHdmiCecConfig().getIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION);
mCecController.setOption(OptionKey.SYSTEM_CEC_CONTROL, true);
mCecController.setLanguage(mMenuLanguage);
@@ -1028,7 +1027,7 @@
/**
* Returns version of CEC.
*/
- @CecVersion
+ @HdmiControlManager.HdmiCecVersion
int getCecVersion() {
return mCecVersion;
}
@@ -2191,7 +2190,6 @@
if (!DumpUtils.checkDumpPermission(getContext(), TAG, writer)) return;
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
- pw.println("mCecVersion: " + mCecVersion);
pw.println("mProhibitMode: " + mProhibitMode);
pw.println("mPowerStatus: " + mPowerStatus);
diff --git a/services/core/java/com/android/server/hdmi/HdmiUtils.java b/services/core/java/com/android/server/hdmi/HdmiUtils.java
index 45aaa73..cdc28e6 100644
--- a/services/core/java/com/android/server/hdmi/HdmiUtils.java
+++ b/services/core/java/com/android/server/hdmi/HdmiUtils.java
@@ -21,6 +21,7 @@
import static com.android.server.hdmi.Constants.ADDR_TV;
import android.annotation.Nullable;
+import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.util.Slog;
import android.util.SparseArray;
@@ -134,7 +135,7 @@
static boolean isEligibleAddressForCecVersion(int cecVersion, int logicalAddress) {
if (isValidAddress(logicalAddress)) {
if (logicalAddress == ADDR_BACKUP_1 || logicalAddress == ADDR_BACKUP_2) {
- return cecVersion == Constants.VERSION_2_0;
+ return cecVersion >= HdmiControlManager.HDMI_CEC_VERSION_2_0;
}
return true;
}
diff --git a/services/core/java/com/android/server/location/AbstractLocationProvider.java b/services/core/java/com/android/server/location/AbstractLocationProvider.java
index 26bf6c1..fac7952 100644
--- a/services/core/java/com/android/server/location/AbstractLocationProvider.java
+++ b/services/core/java/com/android/server/location/AbstractLocationProvider.java
@@ -310,6 +310,7 @@
* Sets a new request and worksource for the provider.
*/
public final void setRequest(ProviderRequest request) {
+ // TODO: do we want to hold a wakelock until onSetRequest is run?
// all calls into the provider must be moved onto the provider thread to prevent deadlock
mExecutor.execute(() -> onSetRequest(request));
}
diff --git a/services/core/java/com/android/server/location/GeocoderProxy.java b/services/core/java/com/android/server/location/GeocoderProxy.java
index 3b74d5a..3ac148d 100644
--- a/services/core/java/com/android/server/location/GeocoderProxy.java
+++ b/services/core/java/com/android/server/location/GeocoderProxy.java
@@ -60,7 +60,11 @@
}
private boolean register() {
- return mServiceWatcher.register();
+ boolean resolves = mServiceWatcher.checkServiceResolves();
+ if (resolves) {
+ mServiceWatcher.register();
+ }
+ return resolves;
}
/**
diff --git a/services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java b/services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java
index eed1aac..7b400b6 100644
--- a/services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java
+++ b/services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java
@@ -75,7 +75,11 @@
}
private boolean register() {
- return mServiceWatcher.register();
+ boolean resolves = mServiceWatcher.checkServiceResolves();
+ if (resolves) {
+ mServiceWatcher.register();
+ }
+ return resolves;
}
private void onBind(IBinder binder, ComponentName service) throws RemoteException {
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index d225f968..086757f 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -324,6 +324,8 @@
}
void onSystemThirdPartyAppsCanStart() {
+ // network provider should always be initialized before the gps provider since the gps
+ // provider has unfortunate hard dependencies on the network provider
ProxyLocationProvider networkProvider = ProxyLocationProvider.createAndRegister(
mContext,
NETWORK_LOCATION_SERVICE_ACTION,
diff --git a/services/core/java/com/android/server/location/LocationShellCommand.java b/services/core/java/com/android/server/location/LocationShellCommand.java
index 909873f..3464704 100644
--- a/services/core/java/com/android/server/location/LocationShellCommand.java
+++ b/services/core/java/com/android/server/location/LocationShellCommand.java
@@ -16,9 +16,10 @@
package com.android.server.location;
-import android.os.BasicShellCommandHandler;
import android.os.UserHandle;
+import com.android.modules.utils.BasicShellCommandHandler;
+
import java.io.PrintWriter;
import java.util.Objects;
diff --git a/services/core/java/com/android/server/location/ProxyLocationProvider.java b/services/core/java/com/android/server/location/ProxyLocationProvider.java
index ce9b10d..555b2d2 100644
--- a/services/core/java/com/android/server/location/ProxyLocationProvider.java
+++ b/services/core/java/com/android/server/location/ProxyLocationProvider.java
@@ -92,7 +92,11 @@
}
private boolean register() {
- return mServiceWatcher.register();
+ boolean resolves = mServiceWatcher.checkServiceResolves();
+ if (resolves) {
+ mServiceWatcher.register();
+ }
+ return resolves;
}
private void onBind(IBinder binder, ComponentName service) throws RemoteException {
diff --git a/services/core/java/com/android/server/location/geofence/GeofenceProxy.java b/services/core/java/com/android/server/location/geofence/GeofenceProxy.java
index 686a66b..bdfa6d7 100644
--- a/services/core/java/com/android/server/location/geofence/GeofenceProxy.java
+++ b/services/core/java/com/android/server/location/geofence/GeofenceProxy.java
@@ -75,16 +75,16 @@
}
private boolean register(Context context) {
- if (mServiceWatcher.register()) {
+ boolean resolves = mServiceWatcher.checkServiceResolves();
+ if (resolves) {
+ mServiceWatcher.register();
context.bindServiceAsUser(
new Intent(context, GeofenceHardwareService.class),
new GeofenceProxyServiceConnection(),
Context.BIND_AUTO_CREATE,
UserHandle.SYSTEM);
- return true;
}
-
- return false;
+ return resolves;
}
private class GeofenceProxyServiceConnection implements ServiceConnection {
diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
index 55073c0..593312e 100644
--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
@@ -16,11 +16,12 @@
package com.android.server.location.gnss;
+import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
+
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import android.app.AlarmManager;
import android.app.AppOpsManager;
-import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -45,10 +46,8 @@
import android.location.util.identity.CallerIdentity;
import android.os.AsyncTask;
import android.os.BatteryStats;
-import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
-import android.os.HandlerExecutor;
import android.os.Looper;
import android.os.Message;
import android.os.PersistableBundle;
@@ -77,9 +76,7 @@
import com.android.internal.location.ProviderRequest;
import com.android.internal.location.gnssmetrics.GnssMetrics;
import com.android.internal.util.FrameworkStatsLog;
-import com.android.server.DeviceIdleInternal;
import com.android.server.FgThread;
-import com.android.server.LocalServices;
import com.android.server.location.AbstractLocationProvider;
import com.android.server.location.gnss.GnssSatelliteBlocklistHelper.GnssSatelliteBlocklistCallback;
import com.android.server.location.gnss.NtpTimeHelper.InjectNtpTimeCallback;
@@ -91,6 +88,7 @@
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
+import java.util.Objects;
import java.util.Set;
/**
@@ -182,12 +180,9 @@
private static final int AGPS_SUPL_MODE_MSA = 0x02;
private static final int AGPS_SUPL_MODE_MSB = 0x01;
- private static final int UPDATE_LOW_POWER_MODE = 1;
- private static final int SET_REQUEST = 3;
private static final int INJECT_NTP_TIME = 5;
// PSDS stands for Predicted Satellite Data Service
private static final int DOWNLOAD_PSDS_DATA = 6;
- private static final int INITIALIZE_HANDLER = 13;
private static final int REQUEST_LOCATION = 16;
private static final int REPORT_LOCATION = 17; // HAL reports location
private static final int REPORT_SV_STATUS = 18; // HAL reports SV status
@@ -270,8 +265,6 @@
}
}
- private final Object mLock = new Object();
-
// stop trying if we do not receive a fix within 60 seconds
private static final int NO_FIX_TIMEOUT = 60 * 1000;
@@ -293,6 +286,23 @@
private static final long DOWNLOAD_PSDS_DATA_TIMEOUT_MS = 60 * 1000;
private static final long WAKELOCK_TIMEOUT_MILLIS = 30 * 1000;
+ // threshold for delay in GNSS engine turning off before warning & error
+ private static final long LOCATION_OFF_DELAY_THRESHOLD_WARN_MILLIS = 2 * 1000;
+ private static final long LOCATION_OFF_DELAY_THRESHOLD_ERROR_MILLIS = 15 * 1000;
+
+ private static final String DOWNLOAD_EXTRA_WAKELOCK_KEY = "GnssLocationProviderPsdsDownload";
+
+ // Set lower than the current ITAR limit of 600m/s to allow this to trigger even if GPS HAL
+ // stops output right at 600m/s, depriving this of the information of a device that reaches
+ // greater than 600m/s, and higher than the speed of sound to avoid impacting most use cases.
+ private static final float ITAR_SPEED_LIMIT_METERS_PER_SECOND = 400.0F;
+
+
+ private final Object mLock = new Object();
+
+ private final Context mContext;
+ private final Handler mHandler;
+
@GuardedBy("mLock")
private final ExponentialBackOff mPsdsBackOff = new ExponentialBackOff(RETRY_INTERVAL,
MAX_RETRY_INTERVAL);
@@ -305,37 +315,16 @@
private boolean mBatchingEnabled;
private boolean mShutdown;
-
- @GuardedBy("mLock")
- private Set<Integer> mPendingDownloadPsdsTypes = new HashSet<>();
-
- // true if GPS is navigating
private boolean mNavigating;
-
- // requested frequency of fixes, in milliseconds
+ private boolean mStarted;
+ private boolean mBatchingStarted;
+ private long mStartedChangedElapsedRealtime;
private int mFixInterval = 1000;
- // true if low power mode for the GNSS chipset is part of the latest request.
- private boolean mLowPowerMode = false;
+ private ProviderRequest mProviderRequest;
- // true if we started navigation in the HAL, only change value of this in setStarted
- private boolean mStarted;
-
- // true if batching is being used
- private boolean mBatchingStarted;
-
- // for logging of latest change, and warning of ongoing location after a stop
- private long mStartedChangedElapsedRealtime;
-
- // threshold for delay in GNSS engine turning off before warning & error
- private static final long LOCATION_OFF_DELAY_THRESHOLD_WARN_MILLIS = 2 * 1000;
- private static final long LOCATION_OFF_DELAY_THRESHOLD_ERROR_MILLIS = 15 * 1000;
-
- // capabilities reported through the top level IGnssCallback.hal
- private volatile int mTopHalCapabilities;
-
- // true if PSDS is supported
- private boolean mSupportsPsds;
+ private int mPositionMode;
+ private GnssPositionMode mLastPositionMode;
// for calculating time to first fix
private long mFixRequestTime = 0;
@@ -344,25 +333,23 @@
// time we received our last fix
private long mLastFixTime;
- private int mPositionMode;
- private GnssPositionMode mLastPositionMode;
+ private final WorkSource mClientSource = new WorkSource();
- // Current request from underlying location clients.
- private ProviderRequest mProviderRequest;
- // True if gps should be disabled because of PowerManager controls
- private boolean mDisableGpsForPowerManager = false;
+ // capabilities reported through the top level IGnssCallback.hal
+ private volatile int mTopHalCapabilities;
- /**
- * True if the device idle controller has determined that the device is stationary. This is only
- * updated when the device enters idle mode.
- */
- private volatile boolean mIsDeviceStationary = false;
+ // true if PSDS is supported
+ private boolean mSupportsPsds;
+ @GuardedBy("mLock")
+ private final PowerManager.WakeLock mDownloadPsdsWakeLock;
+ @GuardedBy("mLock")
+ private final Set<Integer> mPendingDownloadPsdsTypes = new HashSet<>();
/**
* Properties loaded from PROPERTIES_FILE.
* It must be accessed only inside {@link #mHandler}.
*/
- private GnssConfiguration mGnssConfiguration;
+ private final GnssConfiguration mGnssConfiguration;
private String mSuplServerHost;
private int mSuplServerPort = TCP_MIN_PORT;
@@ -370,15 +357,12 @@
private int mC2KServerPort;
private boolean mSuplEsEnabled = false;
- private final Looper mLooper;
private final LocationExtras mLocationExtras = new LocationExtras();
private final GnssStatusProvider mGnssStatusListenerHelper;
private final GnssMeasurementsProvider mGnssMeasurementsProvider;
private final GnssMeasurementCorrectionsProvider mGnssMeasurementCorrectionsProvider;
private final GnssAntennaInfoProvider mGnssAntennaInfoProvider;
private final GnssNavigationMessageProvider mGnssNavigationMessageProvider;
- private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener();
- private final LocationChangeListener mFusedLocationListener = new FusedLocationListener();
private final NtpTimeHelper mNtpTimeHelper;
private final GnssGeofenceProvider mGnssGeofenceProvider;
private final GnssCapabilitiesProvider mGnssCapabilitiesProvider;
@@ -387,53 +371,32 @@
// Available only on GNSS HAL 2.0 implementations and later.
private GnssVisibilityControl mGnssVisibilityControl;
- private final Context mContext;
- private Handler mHandler;
-
private final GnssNetworkConnectivityHandler mNetworkConnectivityHandler;
private final GpsNetInitiatedHandler mNIHandler;
// Wakelocks
- private static final String WAKELOCK_KEY = "GnssLocationProvider";
private final PowerManager.WakeLock mWakeLock;
- private static final String DOWNLOAD_EXTRA_WAKELOCK_KEY = "GnssLocationProviderPsdsDownload";
- @GuardedBy("mLock")
- private final PowerManager.WakeLock mDownloadPsdsWakeLock;
- // Alarms
- private static final String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP";
- private static final String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT";
-
- private final PowerManager mPowerManager;
private final AlarmManager mAlarmManager;
- private final PendingIntent mWakeupIntent;
- private final PendingIntent mTimeoutIntent;
+ private final AlarmManager.OnAlarmListener mWakeupListener = this::startNavigating;
+ private final AlarmManager.OnAlarmListener mTimeoutListener = this::hibernate;
private final AppOpsManager mAppOps;
private final IBatteryStats mBatteryStats;
- // Current list of underlying location clients.
- // only modified on handler thread
- private WorkSource mClientSource = new WorkSource();
-
private GeofenceHardwareImpl mGeofenceHardwareImpl;
// Volatile for simple inter-thread sync on these values.
private volatile int mHardwareYear = 0;
private volatile String mHardwareModelName;
- // Set lower than the current ITAR limit of 600m/s to allow this to trigger even if GPS HAL
- // stops output right at 600m/s, depriving this of the information of a device that reaches
- // greater than 600m/s, and higher than the speed of sound to avoid impacting most use cases.
- private static final float ITAR_SPEED_LIMIT_METERS_PER_SECOND = 400.0F;
-
private volatile boolean mItarSpeedLimitExceeded = false;
@GuardedBy("mLock")
private final ArrayList<Runnable> mFlushListeners = new ArrayList<>(0);
// GNSS Metrics
- private GnssMetrics mGnssMetrics;
+ private final GnssMetrics mGnssMetrics;
public GnssStatusProvider getGnssStatusProvider() {
return mGnssStatusListenerHelper;
@@ -459,51 +422,6 @@
return mGnssNavigationMessageProvider;
}
- private final DeviceIdleInternal.StationaryListener mDeviceIdleStationaryListener =
- isStationary -> {
- mIsDeviceStationary = isStationary;
- // Call updateLowPowerMode on handler thread so it's always called from the same
- // thread.
- mHandler.sendEmptyMessage(UPDATE_LOW_POWER_MODE);
- };
-
- private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (DEBUG) Log.d(TAG, "receive broadcast intent, action: " + action);
- if (action == null) {
- return;
- }
-
- switch (action) {
- case ALARM_WAKEUP:
- startNavigating();
- break;
- case ALARM_TIMEOUT:
- hibernate();
- break;
- case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED:
- DeviceIdleInternal deviceIdleService = LocalServices.getService(
- DeviceIdleInternal.class);
- if (mPowerManager.isDeviceIdleMode()) {
- deviceIdleService.registerStationaryListener(mDeviceIdleStationaryListener);
- } else {
- deviceIdleService.unregisterStationaryListener(
- mDeviceIdleStationaryListener);
- }
- // Call updateLowPowerMode on handler thread so it's always called from the
- // same thread.
- mHandler.sendEmptyMessage(UPDATE_LOW_POWER_MODE);
- break;
- case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED:
- case TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED:
- subscriptionOrCarrierConfigChanged();
- break;
- }
- }
- };
-
/**
* Implements {@link GnssSatelliteBlocklistCallback#onUpdateSatelliteBlocklist}.
*/
@@ -553,16 +471,6 @@
}
}
- private void updateLowPowerMode() {
- // Disable GPS if we are in device idle mode and the device is stationary.
- boolean disableGpsForPowerManager = mPowerManager.isDeviceIdleMode() && mIsDeviceStationary;
- if (disableGpsForPowerManager != mDisableGpsForPowerManager) {
- mDisableGpsForPowerManager = disableGpsForPowerManager;
- updateEnabled();
- updateRequirements();
- }
- }
-
private void reloadGpsProperties() {
mGnssConfiguration.reloadGpsProperties();
setSuplHostPort();
@@ -581,23 +489,19 @@
super(FgThread.getExecutor(), CallerIdentity.fromContext(context));
mContext = context;
- mLooper = FgThread.getHandler().getLooper();
// Create a wake lock
- mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
+ PowerManager powerManager = Objects.requireNonNull(
+ mContext.getSystemService(PowerManager.class));
+ mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mWakeLock.setReferenceCounted(true);
// Create a separate wake lock for psds downloader as it may be released due to timeout.
- mDownloadPsdsWakeLock = mPowerManager.newWakeLock(
+ mDownloadPsdsWakeLock = powerManager.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, DOWNLOAD_EXTRA_WAKELOCK_KEY);
mDownloadPsdsWakeLock.setReferenceCounted(true);
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
- mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP),
- PendingIntent.FLAG_IMMUTABLE);
- mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT),
- PendingIntent.FLAG_IMMUTABLE);
// App ops service to keep track of who is accessing the GPS
mAppOps = mContext.getSystemService(AppOpsManager.class);
@@ -607,7 +511,7 @@
BatteryStats.SERVICE_NAME));
// Construct internal handler
- mHandler = new ProviderHandler(mLooper);
+ mHandler = new ProviderHandler(FgThread.getHandler().getLooper());
// Load GPS configuration and register listeners in the background:
// some operations, such as opening files and registering broadcast receivers, can take a
@@ -623,7 +527,7 @@
// Trigger PSDS data download when the network comes up after booting.
mPendingDownloadPsdsTypes.add(GnssPsdsDownloader.LONG_TERM_PSDS_SERVER_INDEX);
mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(context,
- GnssLocationProvider.this::onNetworkAvailable, mLooper, mNIHandler);
+ GnssLocationProvider.this::onNetworkAvailable, mHandler.getLooper(), mNIHandler);
mGnssStatusListenerHelper = new GnssStatusProvider(injector);
mGnssMeasurementsProvider = new GnssMeasurementsProvider(injector);
@@ -632,10 +536,10 @@
mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(injector);
mGnssMetrics = new GnssMetrics(mContext, mBatteryStats);
- mNtpTimeHelper = new NtpTimeHelper(mContext, mLooper, this);
+ mNtpTimeHelper = new NtpTimeHelper(mContext, mHandler.getLooper(), this);
mGnssSatelliteBlocklistHelper =
new GnssSatelliteBlocklistHelper(mContext,
- mLooper, this);
+ mHandler.getLooper(), this);
mGnssGeofenceProvider = new GnssGeofenceProvider();
setProperties(PROPERTIES);
@@ -664,10 +568,66 @@
}
}, UserHandle.USER_ALL);
- sendMessage(INITIALIZE_HANDLER, 0, null);
+ mHandler.post(this::handleInitialize);
mHandler.post(mGnssSatelliteBlocklistHelper::updateSatelliteBlocklist);
}
+ private void handleInitialize() {
+ // it *appears* that native_init() needs to be called at least once before invoking any
+ // other gnss methods, so we cycle once on initialization.
+ native_init();
+ native_cleanup();
+
+ if (native_is_gnss_visibility_control_supported()) {
+ mGnssVisibilityControl = new GnssVisibilityControl(mContext, mHandler.getLooper(),
+ mNIHandler);
+ }
+
+ // load default GPS configuration
+ // (this configuration might change in the future based on SIM changes)
+ reloadGpsProperties();
+
+ // listen for events
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+ intentFilter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (DEBUG) Log.d(TAG, "receive broadcast intent, action: " + action);
+ if (action == null) {
+ return;
+ }
+
+ switch (action) {
+ case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED:
+ case TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED:
+ subscriptionOrCarrierConfigChanged();
+ break;
+ }
+ }
+ }, intentFilter, null, mHandler);
+
+ mNetworkConnectivityHandler.registerNetworkCallbacks();
+
+ // permanently passively listen to all network locations
+ LocationManager locationManager = Objects.requireNonNull(
+ mContext.getSystemService(LocationManager.class));
+ if (locationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
+ locationManager.requestLocationUpdates(
+ LocationManager.NETWORK_PROVIDER,
+ new LocationRequest.Builder(LocationRequest.PASSIVE_INTERVAL)
+ .setMinUpdateIntervalMillis(0)
+ .setHiddenFromAppOps(true)
+ .build(),
+ DIRECT_EXECUTOR,
+ this::injectLocation);
+ }
+
+ updateEnabled();
+ }
+
/**
* Implements {@link InjectNtpTimeCallback#injectTime}
*/
@@ -712,19 +672,20 @@
LocationManager locationManager = (LocationManager) mContext.getSystemService(
Context.LOCATION_SERVICE);
String provider;
- LocationChangeListener locationListener;
+ LocationListener locationListener;
LocationRequest.Builder locationRequest = new LocationRequest.Builder(
- LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS);
+ LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS).setMaxUpdates(1);
if (independentFromGnss) {
- // For fast GNSS TTFF
+ // For fast GNSS TTFF - we use an empty listener because we will rely on the passive
+ // network listener to actually inject the location. this prevents double injection
provider = LocationManager.NETWORK_PROVIDER;
- locationListener = mNetworkLocationListener;
+ locationListener = location -> { };
locationRequest.setQuality(LocationRequest.QUALITY_LOW_POWER);
} else {
// For Device-Based Hybrid (E911)
provider = LocationManager.FUSED_PROVIDER;
- locationListener = mFusedLocationListener;
+ locationListener = this::injectBestLocation;
locationRequest.setQuality(LocationRequest.QUALITY_HIGH_ACCURACY);
}
@@ -739,31 +700,26 @@
}
}
+ locationRequest.setDurationMillis(durationMillis);
+
Log.i(TAG,
String.format(
"GNSS HAL Requesting location updates from %s provider for %d millis.",
provider, durationMillis));
- try {
- locationManager.requestLocationUpdates(provider, locationRequest.build(),
- new HandlerExecutor(mHandler), locationListener);
- locationListener.mNumLocationUpdateRequest++;
- mHandler.postDelayed(() -> {
- if (--locationListener.mNumLocationUpdateRequest == 0) {
- Log.i(TAG,
- String.format("Removing location updates from %s provider.", provider));
- locationManager.removeUpdates(locationListener);
- }
- }, durationMillis);
- } catch (IllegalArgumentException e) {
- Log.w(TAG, "Unable to request location.", e);
- }
+ locationManager.requestLocationUpdates(provider, locationRequest.build(),
+ DIRECT_EXECUTOR, locationListener);
}
private void injectBestLocation(Location location) {
if (DEBUG) {
Log.d(TAG, "injectBestLocation: " + location);
}
+
+ if (location.isFromMockProvider()) {
+ return;
+ }
+
int gnssLocationFlags = LOCATION_HAS_LAT_LONG
| (location.hasAltitude() ? LOCATION_HAS_ALTITUDE : 0)
| (location.hasSpeed() ? LOCATION_HAS_SPEED : 0)
@@ -864,10 +820,7 @@
}
private void injectLocation(Location location) {
- if (location.hasAccuracy()) {
- if (DEBUG) {
- Log.d(TAG, "injectLocation: " + location);
- }
+ if (location.hasAccuracy() && !location.isFromMockProvider()) {
native_inject_location(location.getLatitude(), location.getLongitude(),
location.getAccuracy());
}
@@ -954,6 +907,7 @@
mGnssVisibilityControl.onGpsEnabledChanged(/* isEnabled= */ false);
}
// do this before releasing wakelock
+ native_cleanup_batching();
native_cleanup();
}
@@ -962,10 +916,7 @@
boolean enabled = mContext.getSystemService(LocationManager.class)
.isLocationEnabledForUser(UserHandle.CURRENT);
- // ... but disable if PowerManager overrides
- enabled &= !mDisableGpsForPowerManager;
-
- // .. but enable anyway, if there's an active settings-ignored request
+ // .. but enable anyway, if there's an active settings-ignored request (e.g. ELS)
enabled |= (mProviderRequest != null
&& mProviderRequest.isActive()
&& mProviderRequest.isLocationSettingsIgnored());
@@ -1016,10 +967,6 @@
@Override
public void onSetRequest(ProviderRequest request) {
- sendMessage(SET_REQUEST, 0, request);
- }
-
- private void handleSetRequest(ProviderRequest request) {
mProviderRequest = request;
updateEnabled();
updateRequirements();
@@ -1037,7 +984,6 @@
updateClientUids(mProviderRequest.getWorkSource());
mFixInterval = (int) mProviderRequest.getIntervalMillis();
- mLowPowerMode = mProviderRequest.isLowPower();
// check for overflow
if (mFixInterval != mProviderRequest.getIntervalMillis()) {
Log.w(TAG, "interval overflow: " + mProviderRequest.getIntervalMillis());
@@ -1066,7 +1012,7 @@
if (mStarted && hasCapability(GPS_CAPABILITY_SCHEDULING)) {
// change period and/or lowPowerMode
if (!setPositionMode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
- mFixInterval, mLowPowerMode)) {
+ mFixInterval, mProviderRequest.isLowPower())) {
Log.e(TAG, "set_position_mode failed in updateRequirements");
}
} else if (!mStarted) {
@@ -1074,18 +1020,18 @@
startNavigating();
} else {
// GNSS Engine is already ON, but no GPS_CAPABILITY_SCHEDULING
- mAlarmManager.cancel(mTimeoutIntent);
+ mAlarmManager.cancel(mTimeoutListener);
if (mFixInterval >= NO_FIX_TIMEOUT) {
// set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
// and our fix interval is not short
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
+ SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, TAG,
+ mTimeoutListener, mHandler);
}
}
}
} else {
updateClientUids(new WorkSource());
-
stopNavigating();
stopBatching();
}
@@ -1123,6 +1069,7 @@
// (2) Inform AppOps service about the list of changes to UIDs.
+ // TODO: this doesn't seem correct, work chain attribution tag != package?
List<WorkChain>[] diffs = WorkSource.diffChains(mClientSource, source);
if (diffs != null) {
List<WorkChain> newChains = diffs[0];
@@ -1146,6 +1093,7 @@
}
// Update the flat UIDs and names list and inform app-ops of all changes.
+ // TODO: why is GnssLocationProvider the only component using these deprecated APIs?
WorkSource[] changes = mClientSource.setReturningDiffs(source);
if (changes != null) {
WorkSource newWork = changes[0];
@@ -1171,23 +1119,17 @@
@Override
public void onExtraCommand(int uid, int pid, String command, Bundle extras) {
-
- final long identity = Binder.clearCallingIdentity();
- try {
- if ("delete_aiding_data".equals(command)) {
- deleteAidingData(extras);
- } else if ("force_time_injection".equals(command)) {
- requestUtcTime();
- } else if ("force_psds_injection".equals(command)) {
- if (mSupportsPsds) {
- downloadPsdsData(/* psdsType= */
- GnssPsdsDownloader.LONG_TERM_PSDS_SERVER_INDEX);
- }
- } else {
- Log.w(TAG, "sendExtraCommand: unknown command " + command);
+ if ("delete_aiding_data".equals(command)) {
+ deleteAidingData(extras);
+ } else if ("force_time_injection".equals(command)) {
+ requestUtcTime();
+ } else if ("force_psds_injection".equals(command)) {
+ if (mSupportsPsds) {
+ downloadPsdsData(/* psdsType= */
+ GnssPsdsDownloader.LONG_TERM_PSDS_SERVER_INDEX);
}
- } finally {
- Binder.restoreCallingIdentity(identity);
+ } else {
+ Log.w(TAG, "sendExtraCommand: unknown command " + command);
}
}
@@ -1258,9 +1200,8 @@
}
int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000);
- mLowPowerMode = mProviderRequest.isLowPower();
if (!setPositionMode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
- interval, mLowPowerMode)) {
+ interval, mProviderRequest.isLowPower())) {
setStarted(false);
Log.e(TAG, "set_position_mode failed in startNavigating()");
return;
@@ -1279,7 +1220,8 @@
// and our fix interval is not short
if (mFixInterval >= NO_FIX_TIMEOUT) {
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
+ SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, TAG, mTimeoutListener,
+ mHandler);
}
}
}
@@ -1297,8 +1239,8 @@
// reset SV count to zero
mLocationExtras.reset();
}
- mAlarmManager.cancel(mTimeoutIntent);
- mAlarmManager.cancel(mWakeupIntent);
+ mAlarmManager.cancel(mTimeoutListener);
+ mAlarmManager.cancel(mWakeupListener);
}
private void startBatching() {
@@ -1331,7 +1273,8 @@
// stop GPS until our next fix interval arrives
stopNavigating();
long now = SystemClock.elapsedRealtime();
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, mWakeupIntent);
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, TAG,
+ mWakeupListener, mHandler);
}
private boolean hasCapability(int capability) {
@@ -1409,7 +1352,7 @@
// slow.
// As we just recievied a location, we'll cancel that timer.
if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) {
- mAlarmManager.cancel(mTimeoutIntent);
+ mAlarmManager.cancel(mTimeoutListener);
}
}
@@ -1428,11 +1371,10 @@
case GPS_STATUS_SESSION_BEGIN:
mNavigating = true;
break;
- case GPS_STATUS_SESSION_END:
- mNavigating = false;
- break;
case GPS_STATUS_ENGINE_ON:
break;
+ case GPS_STATUS_SESSION_END:
+ // fall through
case GPS_STATUS_ENGINE_OFF:
mNavigating = false;
break;
@@ -1626,7 +1568,7 @@
* @hide
*/
public GnssMetricsProvider getGnssMetricsProvider() {
- return () -> mGnssMetrics.dumpGnssMetricsAsProtoString();
+ return mGnssMetrics::dumpGnssMetricsAsProtoString;
}
/**
@@ -1959,9 +1901,6 @@
public void handleMessage(Message msg) {
int message = msg.what;
switch (message) {
- case SET_REQUEST:
- handleSetRequest((ProviderRequest) msg.obj);
- break;
case INJECT_NTP_TIME:
mNtpTimeHelper.retrieveAndInjectNtpTime();
break;
@@ -1971,18 +1910,12 @@
case DOWNLOAD_PSDS_DATA:
handleDownloadPsdsData(msg.arg1);
break;
- case INITIALIZE_HANDLER:
- handleInitialize();
- break;
case REPORT_LOCATION:
handleReportLocation(msg.arg1 == 1, (Location) msg.obj);
break;
case REPORT_SV_STATUS:
handleReportSvStatus((GnssStatus) msg.obj);
break;
- case UPDATE_LOW_POWER_MODE:
- updateLowPowerMode();
- break;
}
if (msg.arg2 == 1) {
// wakelock was taken for this message, release it
@@ -1993,70 +1926,6 @@
}
}
}
-
- /**
- * This method is bound to the constructor. It is in charge of loading properties and
- * registering for events that will be posted to this handler.
- */
- private void handleInitialize() {
- // it *appears* that native_init() needs to be called at least once before invoking any
- // other gnss methods, so we cycle once on initialization.
- native_init();
- native_cleanup();
-
- if (native_is_gnss_visibility_control_supported()) {
- mGnssVisibilityControl = new GnssVisibilityControl(mContext, mLooper, mNIHandler);
- }
-
- // load default GPS configuration
- // (this configuration might change in the future based on SIM changes)
- reloadGpsProperties();
-
- // listen for events
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(ALARM_WAKEUP);
- intentFilter.addAction(ALARM_TIMEOUT);
- intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
- intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
- intentFilter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
- mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
-
- mNetworkConnectivityHandler.registerNetworkCallbacks();
-
- // listen for PASSIVE_PROVIDER updates
- LocationManager locManager =
- (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
- locManager.requestLocationUpdates(
- LocationManager.PASSIVE_PROVIDER,
- new LocationRequest.Builder(0)
- .setHiddenFromAppOps(true)
- .build(),
- new HandlerExecutor(this),
- new NetworkLocationListener());
-
- updateEnabled();
- }
- }
-
- private abstract static class LocationChangeListener implements LocationListener {
- private int mNumLocationUpdateRequest;
- }
-
- private final class NetworkLocationListener extends LocationChangeListener {
- @Override
- public void onLocationChanged(Location location) {
- // this callback happens on mHandler looper
- if (LocationManager.NETWORK_PROVIDER.equals(location.getProvider())) {
- injectLocation(location);
- }
- }
- }
-
- private final class FusedLocationListener extends LocationChangeListener {
- @Override
- public void onLocationChanged(Location location) {
- injectBestLocation(location);
- }
}
/**
@@ -2064,16 +1933,12 @@
*/
private String messageIdAsString(int message) {
switch (message) {
- case SET_REQUEST:
- return "SET_REQUEST";
case INJECT_NTP_TIME:
return "INJECT_NTP_TIME";
case REQUEST_LOCATION:
return "REQUEST_LOCATION";
case DOWNLOAD_PSDS_DATA:
return "DOWNLOAD_PSDS_DATA";
- case INITIALIZE_HANDLER:
- return "INITIALIZE_HANDLER";
case REPORT_LOCATION:
return "REPORT_LOCATION";
case REPORT_SV_STATUS:
@@ -2109,8 +1974,6 @@
s.append("mBatchingStarted=").append(mBatchingStarted).append('\n');
s.append("mBatchSize=").append(getBatchSize()).append('\n');
s.append("mFixInterval=").append(mFixInterval).append('\n');
- s.append("mLowPowerMode=").append(mLowPowerMode).append('\n');
- s.append("mDisableGpsForPowerManager=").append(mDisableGpsForPowerManager).append('\n');
s.append("mTopHalCapabilities=0x").append(Integer.toHexString(mTopHalCapabilities));
s.append(" ( ");
if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHEDULING ");
diff --git a/services/core/java/com/android/server/location/timezone/RealLocationTimeZoneProviderProxy.java b/services/core/java/com/android/server/location/timezone/RealLocationTimeZoneProviderProxy.java
index 3801877..94062fa 100644
--- a/services/core/java/com/android/server/location/timezone/RealLocationTimeZoneProviderProxy.java
+++ b/services/core/java/com/android/server/location/timezone/RealLocationTimeZoneProviderProxy.java
@@ -78,10 +78,14 @@
}
private boolean register() {
- return mServiceWatcher.register();
+ boolean resolves = mServiceWatcher.checkServiceResolves();
+ if (resolves) {
+ mServiceWatcher.register();
+ }
+ return resolves;
}
- private void onBind(IBinder binder, ComponentName componentName) throws RemoteException {
+ private void onBind(IBinder binder, ComponentName componentName) {
processServiceWatcherCallbackOnThreadingDomainThread(() -> onBindOnHandlerThread(binder));
}
diff --git a/services/core/java/com/android/server/location/util/LocationEventLog.java b/services/core/java/com/android/server/location/util/LocationEventLog.java
index ff4503e..134b142 100644
--- a/services/core/java/com/android/server/location/util/LocationEventLog.java
+++ b/services/core/java/com/android/server/location/util/LocationEventLog.java
@@ -22,6 +22,8 @@
import static android.os.PowerManager.LOCATION_MODE_NO_CHANGE;
import static android.os.PowerManager.LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF;
+import static com.android.server.location.LocationManagerService.D;
+
import android.annotation.Nullable;
import android.location.LocationRequest;
import android.location.util.identity.CallerIdentity;
@@ -29,14 +31,13 @@
import android.os.PowerManager.LocationPowerSaveMode;
import com.android.internal.location.ProviderRequest;
-import com.android.server.location.LocationManagerService;
import com.android.server.utils.eventlog.LocalEventLog;
/** In memory event log for location events. */
public class LocationEventLog extends LocalEventLog {
private static int getLogSize() {
- if (Build.IS_DEBUGGABLE || LocationManagerService.D) {
+ if (Build.IS_DEBUGGABLE || D) {
return 500;
} else {
return 200;
@@ -91,13 +92,17 @@
/** Logs a new incoming location for a location provider. */
public synchronized void logProviderReceivedLocations(String provider, int numLocations) {
- addLogEvent(EVENT_PROVIDER_RECEIVE_LOCATION, provider, numLocations);
+ if (Build.IS_DEBUGGABLE || D) {
+ addLogEvent(EVENT_PROVIDER_RECEIVE_LOCATION, provider, numLocations);
+ }
}
/** Logs a location deliver for a client of a location provider. */
public synchronized void logProviderDeliveredLocations(String provider, int numLocations,
CallerIdentity identity) {
- addLogEvent(EVENT_PROVIDER_DELIVER_LOCATION, provider, numLocations, identity);
+ if (Build.IS_DEBUGGABLE || D) {
+ addLogEvent(EVENT_PROVIDER_DELIVER_LOCATION, provider, numLocations, identity);
+ }
}
/** Logs that the location power save mode has changed. */
diff --git a/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java b/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java
index f058ad9..252ba60 100644
--- a/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java
+++ b/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java
@@ -418,6 +418,8 @@
@VisibleForTesting
static boolean hasAutoGeneratedRROSuffix(String name) {
return name.endsWith(".auto_generated_rro_product__")
+ // TODO(b/172956245): temporary workaround until OEMs can customize name
+ || name.endsWith("carui.rro") || name.endsWith("carui.overlayable.rro")
|| name.endsWith(".auto_generated_rro_vendor__");
}
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 bf5a50e..7a37bdd 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -820,7 +820,7 @@
CONTACTS_PERMISSIONS, STORAGE_PERMISSIONS);
}
- // Atthention Service
+ // Attention Service
String attentionServicePackageName =
mContext.getPackageManager().getAttentionServicePackageName();
if (!TextUtils.isEmpty(attentionServicePackageName)) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 098be92..f7e6822 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -20,7 +20,6 @@
import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
import static android.app.AppOpsManager.OP_TOAST_WINDOW;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.content.Context.CONTEXT_RESTRICTED;
import static android.content.Context.WINDOW_SERVICE;
import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE;
@@ -45,10 +44,8 @@
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.LAST_SYSTEM_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
@@ -178,7 +175,6 @@
import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManager;
-import android.view.WindowManager.LayoutParams;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicyConstants;
import android.view.accessibility.AccessibilityEvent;
@@ -603,8 +599,6 @@
private final MutableBoolean mTmpBoolean = new MutableBoolean(false);
- private boolean mAodShowing;
-
private boolean mPerDisplayFocusEnabled = false;
private volatile int mTopFocusedDisplayId = INVALID_DISPLAY;
@@ -2267,44 +2261,6 @@
}
}
- private boolean shouldBeHiddenByKeyguard(WindowState win, WindowState imeTarget) {
- final LayoutParams attrs = win.getAttrs();
-
- boolean hideDockDivider = attrs.type == TYPE_DOCK_DIVIDER
- && !mWindowManagerInternal.isStackVisibleLw(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
- if (hideDockDivider) {
- return true;
- }
-
- // If AOD is showing, the IME should be hidden. However, sometimes the AOD is considered
- // hidden because it's in the process of hiding, but it's still being shown on screen.
- // In that case, we want to continue hiding the IME until the windows have completed
- // drawing. This way, we know that the IME can be safely shown since the other windows are
- // now shown.
- final boolean hideIme = win.isInputMethodWindow()
- && (mAodShowing || !mDefaultDisplayPolicy.isWindowManagerDrawComplete());
- if (hideIme) {
- return true;
- }
-
- final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisibleLw()
- && (imeTarget.canShowWhenLocked() || !canBeHiddenByKeyguardLw(imeTarget));
-
- // Show IME over the keyguard if the target allows it
- boolean allowWhenLocked = win.isInputMethodWindow() && showImeOverKeyguard;
-
- final boolean isKeyguardShowing = mKeyguardDelegate.isShowing();
-
- if (isKeyguardShowing && isKeyguardOccluded()) {
- // Show SHOW_WHEN_LOCKED windows if Keyguard is occluded.
- allowWhenLocked |= win.canShowWhenLocked()
- // Show error dialogs over apps that are shown on lockscreen
- || (attrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0;
- }
-
- return isKeyguardShowing && !allowWhenLocked && win.getDisplayId() == DEFAULT_DISPLAY;
- }
-
/** {@inheritDoc} */
@Override
public StartingSurface addSplashScreen(IBinder appToken, String packageName, int theme,
@@ -3442,18 +3398,6 @@
/** {@inheritDoc} */
@Override
- public void applyKeyguardPolicyLw(WindowState win, WindowState imeTarget) {
- if (canBeHiddenByKeyguardLw(win)) {
- if (shouldBeHiddenByKeyguard(win, imeTarget)) {
- win.hideLw(false /* doAnimation */);
- } else {
- win.showLw(false /* doAnimation */);
- }
- }
- }
-
- /** {@inheritDoc} */
- @Override
public void setKeyguardCandidateLw(WindowState win) {
mKeyguardCandidate = win;
setKeyguardOccludedLw(mKeyguardOccluded, true /* force */);
@@ -5636,15 +5580,6 @@
}
}
- @Override
- public boolean setAodShowing(boolean aodShowing) {
- if (mAodShowing != aodShowing) {
- mAodShowing = aodShowing;
- return true;
- }
- return false;
- }
-
private class HdmiVideoExtconUEventObserver extends ExtconStateObserver<Boolean> {
private static final String HDMI_EXIST = "HDMI=1";
private static final String NAME = "hdmi";
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 0d8d347..6934e5c 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -207,45 +207,12 @@
public IApplicationToken getAppToken();
/**
- * Is this window visible? It is not visible if there is no
- * surface, or we are in the process of running an exit animation
- * that will remove the surface.
- */
- boolean isVisibleLw();
-
- /**
* Return true if this window (or a window it is attached to, but not
* considering its app token) is currently animating.
*/
boolean isAnimatingLw();
/**
- * Can be called by the policy to force a window to be hidden,
- * regardless of whether the client or window manager would like
- * it shown. Must be called with the window manager lock held.
- * Returns true if {@link #showLw} was last called for the window.
- */
- public boolean hideLw(boolean doAnimation);
-
- /**
- * Can be called to undo the effect of {@link #hideLw}, allowing a
- * window to be shown as long as the window manager and client would
- * also like it to be shown. Must be called with the window manager
- * lock held.
- * Returns true if {@link #hideLw} was last called for the window.
- */
- public boolean showLw(boolean doAnimation);
-
- /**
- * Check whether the window is currently dimming.
- */
- public boolean isDimming();
-
- public boolean isInputMethodWindow();
-
- public int getDisplayId();
-
- /**
* Returns true if the window owner can add internal system windows.
* That is, they have {@link Manifest.permission#INTERNAL_SYSTEM_WINDOW}.
*/
@@ -788,14 +755,6 @@
void setTopFocusedDisplay(int displayId);
/**
- * Apply the keyguard policy to a specific window.
- *
- * @param win The window to apply the keyguard policy.
- * @param imeTarget The current IME target window.
- */
- void applyKeyguardPolicyLw(WindowState win, WindowState imeTarget);
-
- /**
* Called when the state of allow-lockscreen-when-on of the display is changed. See
* {@link WindowManager.LayoutParams#FLAG_ALLOW_LOCK_WHILE_SCREEN_ON}
*
@@ -1210,11 +1169,4 @@
* A new window on default display has been focused.
*/
default void onDefaultDisplayFocusChangedLw(WindowState newFocus) {}
-
- /**
- * Updates the flag about whether AOD is showing.
- *
- * @return whether the value was changed.
- */
- boolean setAodShowing(boolean aodShowing);
}
diff --git a/services/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java
index ae0db44..db408488 100644
--- a/services/core/java/com/android/server/power/ThermalManagerService.java
+++ b/services/core/java/com/android/server/power/ThermalManagerService.java
@@ -514,6 +514,9 @@
pw.println("Current cooling devices from HAL:");
dumpItemsLocked(pw, "\t",
mHalWrapper.getCurrentCoolingDevices(false, 0));
+ pw.println("Temperature static thresholds from HAL:");
+ dumpItemsLocked(pw, "\t",
+ mHalWrapper.getTemperatureThresholds(false, 0));
}
}
} finally {
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 9e21167..f4e0fb1 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -857,7 +857,7 @@
private void populateWindowsOnScreenLocked(SparseArray<WindowState> outWindows) {
mTempLayer = 0;
mDisplayContent.forAllWindows((w) -> {
- if (w.isOnScreen() && w.isVisibleLw()
+ if (w.isOnScreen() && w.isVisible()
&& (w.mAttrs.alpha != 0)) {
mTempLayer++;
outWindows.put(mTempLayer, w);
@@ -1517,7 +1517,7 @@
}
dc.forAllWindows(w -> {
- if (w.isVisibleLw()) {
+ if (w.isVisible()) {
tempWindowStatesList.add(w);
}
}, false /* traverseTopToBottom */);
@@ -1529,7 +1529,7 @@
return;
}
- if (w.isVisibleLw() && tempWindowStatesList.contains(parentWindow)) {
+ if (w.isVisible() && tempWindowStatesList.contains(parentWindow)) {
tempWindowStatesList.add(tempWindowStatesList.lastIndexOf(parentWindow), w);
}
}, false /* traverseTopToBottom */);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 33df8b8..1076906 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -651,8 +651,8 @@
// Information about an application starting window if displayed.
// Note: these are de-referenced before the starting window animates away.
StartingData mStartingData;
- WindowState startingWindow;
- WindowManagerPolicy.StartingSurface startingSurface;
+ WindowState mStartingWindow;
+ WindowManagerPolicy.StartingSurface mStartingSurface;
boolean startingDisplayed;
boolean startingMoved;
@@ -950,10 +950,10 @@
pw.print(" firstWindowDrawn="); pw.print(firstWindowDrawn);
pw.print(" mIsExiting="); pw.println(mIsExiting);
}
- if (startingWindow != null || startingSurface != null
+ if (mStartingWindow != null || mStartingSurface != null
|| startingDisplayed || startingMoved || mVisibleSetFromTransferredStartingWindow) {
- pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
- pw.print(" startingSurface="); pw.print(startingSurface);
+ pw.print(prefix); pw.print("startingWindow="); pw.print(mStartingWindow);
+ pw.print(" startingSurface="); pw.print(mStartingSurface);
pw.print(" startingDisplayed="); pw.print(startingDisplayed);
pw.print(" startingMoved="); pw.print(startingMoved);
pw.println(" mVisibleSetFromTransferredStartingWindow="
@@ -1896,16 +1896,16 @@
ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Aborted starting %s: startingData=%s",
ActivityRecord.this, mStartingData);
- startingWindow = null;
+ mStartingWindow = null;
mStartingData = null;
abort = true;
} else {
- startingSurface = surface;
+ mStartingSurface = surface;
}
if (!abort) {
ProtoLog.v(WM_DEBUG_STARTING_WINDOW,
"Added starting %s: startingWindow=%s startingView=%s",
- ActivityRecord.this, startingWindow, startingSurface);
+ ActivityRecord.this, mStartingWindow, mStartingSurface);
}
}
if (abort) {
@@ -1957,7 +1957,7 @@
}
void removeStartingWindow() {
- if (startingWindow == null) {
+ if (mStartingWindow == null) {
if (mStartingData != null) {
// Starting window has not been added yet, but it is scheduled to be added.
// Go ahead and cancel the request.
@@ -1969,10 +1969,10 @@
final WindowManagerPolicy.StartingSurface surface;
if (mStartingData != null) {
- surface = startingSurface;
+ surface = mStartingSurface;
mStartingData = null;
- startingSurface = null;
- startingWindow = null;
+ mStartingSurface = null;
+ mStartingWindow = null;
startingDisplayed = false;
if (surface == null) {
ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "startingWindow was set but "
@@ -1988,7 +1988,7 @@
ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Schedule remove starting %s startingWindow=%s"
- + " startingView=%s Callers=%s", this, startingWindow, startingSurface,
+ + " startingView=%s Callers=%s", this, mStartingWindow, mStartingSurface,
Debug.getCallers(5));
@@ -2738,7 +2738,8 @@
if (ensureVisibility) {
mDisplayContent.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
- false /* preserveWindows */, true /* notifyClients */);
+ false /* preserveWindows */, true /* notifyClients */,
+ mStackSupervisor.mUserLeaving);
}
}
@@ -3443,8 +3444,8 @@
return false;
}
- final WindowState tStartingWindow = fromActivity.startingWindow;
- if (tStartingWindow != null && fromActivity.startingSurface != null) {
+ final WindowState tStartingWindow = fromActivity.mStartingWindow;
+ if (tStartingWindow != null && fromActivity.mStartingSurface != null) {
// In this case, the starting icon has already been displayed, so start
// letting windows get shown immediately without any more transitions.
getDisplayContent().mSkipAppTransitionAnimation = true;
@@ -3463,14 +3464,14 @@
// Transfer the starting window over to the new token.
mStartingData = fromActivity.mStartingData;
- startingSurface = fromActivity.startingSurface;
+ mStartingSurface = fromActivity.mStartingSurface;
startingDisplayed = fromActivity.startingDisplayed;
fromActivity.startingDisplayed = false;
- startingWindow = tStartingWindow;
+ mStartingWindow = tStartingWindow;
reportedVisible = fromActivity.reportedVisible;
fromActivity.mStartingData = null;
- fromActivity.startingSurface = null;
- fromActivity.startingWindow = null;
+ fromActivity.mStartingSurface = null;
+ fromActivity.mStartingWindow = null;
fromActivity.startingMoved = true;
tStartingWindow.mToken = this;
tStartingWindow.mActivityRecord = this;
@@ -4320,9 +4321,9 @@
} else {
// If we are being set visible, and the starting window is not yet displayed,
// then make sure it doesn't get displayed.
- if (startingWindow != null && !startingWindow.isDrawn()) {
- startingWindow.clearPolicyVisibilityFlag(LEGACY_POLICY_VISIBILITY);
- startingWindow.mLegacyPolicyVisibilityAfterAnim = false;
+ if (mStartingWindow != null && !mStartingWindow.isDrawn()) {
+ mStartingWindow.clearPolicyVisibilityFlag(LEGACY_POLICY_VISIBILITY);
+ mStartingWindow.mLegacyPolicyVisibilityAfterAnim = false;
}
// We are becoming visible, so better freeze the screen with the windows that are
// getting visible so we also wait for them.
@@ -4752,7 +4753,7 @@
handleAlreadyVisible();
}
- void makeInvisible() {
+ void makeInvisible(boolean userLeaving) {
if (!mVisibleRequested) {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + this);
return;
@@ -4793,9 +4794,8 @@
// If the app is capable of entering PIP, we should try pausing it now
// so it can PIP correctly.
if (deferHidingClient) {
- getRootTask().startPausingLocked(
- mStackSupervisor.mUserLeaving /* userLeaving */,
- false /* uiSleeping */, null /* resuming */, "makeInvisible");
+ getRootTask().startPausingLocked(userLeaving, false /* uiSleeping */,
+ null /* resuming */, "makeInvisible");
break;
}
case INITIALIZING:
@@ -5395,7 +5395,7 @@
// We now have a good window to show, remove dead placeholders
removeDeadWindows();
- if (startingWindow != null) {
+ if (mStartingWindow != null) {
ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Finish starting %s"
+ ": first real window is shown, no animation", win.mToken);
// If this initial window is animating, stop it -- we will do an animation to reveal
@@ -5570,7 +5570,7 @@
boolean updateDrawnWindowStates(WindowState w) {
w.setDrawnStateEvaluated(true /*evaluated*/);
- if (DEBUG_STARTING_WINDOW_VERBOSE && w == startingWindow) {
+ if (DEBUG_STARTING_WINDOW_VERBOSE && w == mStartingWindow) {
Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" + w.isOnScreen()
+ " allDrawn=" + allDrawn + " freezingScreen=" + mFreezingScreen);
}
@@ -5607,7 +5607,7 @@
}
}
- if (w != startingWindow) {
+ if (w != mStartingWindow) {
if (w.isInteresting()) {
// Add non-main window as interesting since the main app has already been added
if (findMainWindow(false /* includeStartingApp */) != w) {
@@ -5847,7 +5847,7 @@
void postWindowRemoveStartingWindowCleanup(WindowState win) {
// TODO: Something smells about the code below...Is there a better way?
- if (startingWindow == win) {
+ if (mStartingWindow == win) {
ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Notify removed startingWindow %s", win);
removeStartingWindow();
} else if (mChildren.size() == 0) {
@@ -5861,7 +5861,7 @@
// window in the token.
setVisible(false);
}
- } else if (mChildren.size() == 1 && startingSurface != null && !isRelaunching()) {
+ } else if (mChildren.size() == 1 && mStartingSurface != null && !isRelaunching()) {
// If this is the last window except for a starting transition window,
// we need to get rid of the starting transition.
ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Last window, removing starting window %s", win);
@@ -7693,8 +7693,8 @@
proto.write(NUM_DRAWN_WINDOWS, mNumDrawnWindows);
proto.write(ALL_DRAWN, allDrawn);
proto.write(LAST_ALL_DRAWN, mLastAllDrawn);
- if (startingWindow != null) {
- startingWindow.writeIdentifierToProto(proto, STARTING_WINDOW);
+ if (mStartingWindow != null) {
+ mStartingWindow.writeIdentifierToProto(proto, STARTING_WINDOW);
}
proto.write(STARTING_DISPLAYED, startingDisplayed);
proto.write(STARTING_MOVED, startingMoved);
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 17209eb..e2a7afb 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -2189,7 +2189,7 @@
.notifyActivityDismissingDockedStack();
taskDisplayArea.onSplitScreenModeDismissed(task);
taskDisplayArea.mDisplayContent.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS,
- true /* notifyClients */);
+ true /* notifyClients */, mUserLeaving);
}
return;
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 84255c7..2cbc514 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -2460,7 +2460,7 @@
} else {
stack.setWindowingMode(windowingMode);
stack.mDisplayContent.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS,
- true /* notifyClients */);
+ true /* notifyClients */, mStackSupervisor.mUserLeaving);
}
return true;
} finally {
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 97912c1..c87f3da 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -575,7 +575,7 @@
app.allDrawn = true;
// Ensure that apps that are mid-starting are also scheduled to have their
// starting windows removed after the animation is complete
- if (app.startingWindow != null && !app.startingWindow.mAnimatingExit) {
+ if (app.mStartingWindow != null && !app.mStartingWindow.mAnimatingExit) {
app.removeStartingWindow();
}
@@ -651,7 +651,7 @@
+ "startingMoved=%b isRelaunching()=%b startingWindow=%s",
activity, activity.allDrawn, activity.startingDisplayed,
activity.startingMoved, activity.isRelaunching(),
- activity.startingWindow);
+ activity.mStartingWindow);
final boolean allDrawn = activity.allDrawn && !activity.isRelaunching();
@@ -760,7 +760,7 @@
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
"New transit away from wallpaper: %s",
AppTransition.appTransitionOldToString(transit));
- } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw()
+ } else if (wallpaperTarget != null && wallpaperTarget.isVisible()
&& openingApps.contains(wallpaperTarget.mActivityRecord)
&& topOpeningApp == wallpaperTarget.mActivityRecord
&& transit != TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE) {
diff --git a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
index be18d0a..76a5cda 100644
--- a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
@@ -22,8 +22,11 @@
import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
import static android.window.DisplayAreaOrganizer.FEATURE_FULLSCREEN_MAGNIFICATION;
+import static android.window.DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT;
import static android.window.DisplayAreaOrganizer.FEATURE_ONE_HANDED;
import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION;
@@ -99,6 +102,12 @@
// layer
.setNewDisplayAreaSupplier(DisplayArea.Dimmable::new)
.build())
+ .addFeature(new Feature.Builder(wmService.mPolicy, "HideDisplayCutout",
+ FEATURE_HIDE_DISPLAY_CUTOUT)
+ .all()
+ .except(TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL, TYPE_STATUS_BAR,
+ TYPE_NOTIFICATION_SHADE)
+ .build())
.addFeature(new Feature.Builder(wmService.mPolicy, "OneHanded",
FEATURE_ONE_HANDED)
.all()
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 90c0c6f..07c61d3 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -862,7 +862,7 @@
}
}
- if (obscuredChanged && w.isVisibleLw() && mWallpaperController.isWallpaperTarget(w)) {
+ if (obscuredChanged && w.isVisible() && mWallpaperController.isWallpaperTarget(w)) {
// This is the wallpaper target and its obscured state changed... make sure the
// current wallpaper's visibility has been updated accordingly.
mWallpaperController.updateWallpaperVisibility();
@@ -2584,7 +2584,7 @@
return;
}
- if (w.isOnScreen() && w.isVisibleLw() && w.getFrame().contains(x, y)) {
+ if (w.isOnScreen() && w.isVisible() && w.getFrame().contains(x, y)) {
targetWindowType[0] = w.mAttrs.type;
return;
}
@@ -2629,7 +2629,7 @@
mTouchExcludeRegion.op(mTmpRect2, Region.Op.UNION);
}
}
- if (mInputMethodWindow != null && mInputMethodWindow.isVisibleLw()) {
+ if (mInputMethodWindow != null && mInputMethodWindow.isVisible()) {
// If the input method is visible and the user is typing, we don't want these touch
// events to be intercepted and used to change focus. This would likely cause a
// disappearance of the input method.
@@ -2638,7 +2638,7 @@
}
for (int i = mTapExcludedWindows.size() - 1; i >= 0; i--) {
final WindowState win = mTapExcludedWindows.get(i);
- if (!win.isVisibleLw()) {
+ if (!win.isVisible()) {
continue;
}
win.getTouchableRegion(mTmpRegion);
@@ -2781,7 +2781,7 @@
void adjustForImeIfNeeded() {
final WindowState imeWin = mInputMethodWindow;
- final boolean imeVisible = imeWin != null && imeWin.isVisibleLw()
+ final boolean imeVisible = imeWin != null && imeWin.isVisible()
&& imeWin.isDisplayed();
final int imeHeight = mDisplayFrames.getInputMethodWindowVisibleHeight();
mPinnedStackControllerLocked.setAdjustedForIme(imeVisible, imeHeight);
@@ -3068,7 +3068,7 @@
final int y = (int) yf;
final WindowState touchedWin = getWindow(w -> {
final int flags = w.mAttrs.flags;
- if (!w.isVisibleLw()) {
+ if (!w.isVisible()) {
return false;
}
if ((flags & FLAG_NOT_TOUCHABLE) != 0) {
@@ -5308,7 +5308,7 @@
void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
- boolean preserveWindows, boolean notifyClients) {
+ boolean preserveWindows, boolean notifyClients, boolean userLeaving) {
if (mInEnsureActivitiesVisible) {
// Don't do recursive work.
return;
@@ -5317,7 +5317,7 @@
try {
forAllTaskDisplayAreas(taskDisplayArea -> {
taskDisplayArea.ensureActivitiesVisible(starting, configChanges,
- preserveWindows, notifyClients);
+ preserveWindows, notifyClients, userLeaving);
});
} finally {
mInEnsureActivitiesVisible = false;
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 7a42b0d..61cc430 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -1153,15 +1153,19 @@
});
mDisplayContent.setInsetProvider(ITYPE_LEFT_GESTURES, win,
(displayFrames, windowState, inOutFrame) -> {
+ final int leftSafeInset =
+ Math.max(displayFrames.mDisplayCutoutSafe.left, 0);
inOutFrame.left = 0;
inOutFrame.top = 0;
inOutFrame.bottom = displayFrames.mDisplayHeight;
- inOutFrame.right = displayFrames.mUnrestricted.left + mLeftGestureInset;
+ inOutFrame.right = leftSafeInset + mLeftGestureInset;
});
mDisplayContent.setInsetProvider(ITYPE_RIGHT_GESTURES, win,
(displayFrames, windowState, inOutFrame) -> {
- inOutFrame.left = displayFrames.mUnrestricted.right
- - mRightGestureInset;
+ final int rightSafeInset =
+ Math.min(displayFrames.mDisplayCutoutSafe.right,
+ displayFrames.mUnrestricted.right);
+ inOutFrame.left = rightSafeInset - mRightGestureInset;
inOutFrame.top = 0;
inOutFrame.bottom = displayFrames.mDisplayHeight;
inOutFrame.right = displayFrames.mDisplayWidth;
@@ -1718,7 +1722,7 @@
for (int i = mScreenDecorWindows.size() - 1; i >= 0; --i) {
final WindowState w = mScreenDecorWindows.valueAt(i);
- if (w.getDisplayId() != displayId || !w.isVisibleLw()) {
+ if (w.getDisplayId() != displayId || !w.isVisible()) {
// Skip if not on the same display or not visible.
continue;
}
@@ -1824,7 +1828,7 @@
boolean statusBarTranslucent = (appearance & APPEARANCE_OPAQUE_STATUS_BARS) == 0;
// If the status bar is hidden, we don't want to cause windows behind it to scroll.
- if (mStatusBar.isVisibleLw() && !statusBarTransient) {
+ if (mStatusBar.isVisible() && !statusBarTransient) {
// Status bar may go away, so the screen area it occupies is available to apps but just
// covering them when the status bar is visible.
final Rect dockFrame = displayFrames.mDock;
@@ -2143,10 +2147,10 @@
win.computeFrame(displayFrames);
// Dock windows carve out the bottom of the screen, so normal windows
// can't appear underneath them.
- if (type == TYPE_INPUT_METHOD && win.isVisibleLw() && !win.mGivenInsetsPending) {
+ if (type == TYPE_INPUT_METHOD && win.isVisible() && !win.mGivenInsetsPending) {
offsetInputMethodWindowLw(win, displayFrames);
}
- if (type == TYPE_VOICE_INTERACTION && win.isVisibleLw() && !win.mGivenInsetsPending) {
+ if (type == TYPE_VOICE_INTERACTION && win.isVisible() && !win.mGivenInsetsPending) {
offsetVoiceInputWindowLw(win, displayFrames);
}
}
@@ -2219,7 +2223,7 @@
WindowState attached, WindowState imeTarget) {
final boolean affectsSystemUi = win.canAffectSystemUiFlags();
if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": affectsSystemUi=" + affectsSystemUi);
- mService.mPolicy.applyKeyguardPolicyLw(win, imeTarget);
+ applyKeyguardPolicy(win, imeTarget);
final int fl = attrs.flags;
if (mTopFullscreenOpaqueWindowState == null && affectsSystemUi
&& attrs.type == TYPE_INPUT_METHOD) {
@@ -2240,7 +2244,7 @@
if (win.isDreamWindow()) {
// If the lockscreen was showing when the dream started then wait
// for the dream to draw before hiding the lockscreen.
- if (!mDreamingLockscreen || (win.isVisibleLw() && win.hasDrawn())) {
+ if (!mDreamingLockscreen || (win.isVisible() && win.hasDrawn())) {
mShowingDream = true;
appWindow = true;
}
@@ -2387,6 +2391,55 @@
}
/**
+ * Applies the keyguard policy to a specific window.
+ *
+ * @param win The window to apply the keyguard policy.
+ * @param imeTarget The current IME target window.
+ */
+ private void applyKeyguardPolicy(WindowState win, WindowState imeTarget) {
+ if (mService.mPolicy.canBeHiddenByKeyguardLw(win)) {
+ if (shouldBeHiddenByKeyguard(win, imeTarget)) {
+ win.hide(false /* doAnimation */, true /* requestAnim */);
+ } else {
+ win.show(false /* doAnimation */, true /* requestAnim */);
+ }
+ }
+ }
+
+ private boolean shouldBeHiddenByKeyguard(WindowState win, WindowState imeTarget) {
+ // If AOD is showing, the IME should be hidden. However, sometimes the AOD is considered
+ // hidden because it's in the process of hiding, but it's still being shown on screen.
+ // In that case, we want to continue hiding the IME until the windows have completed
+ // drawing. This way, we know that the IME can be safely shown since the other windows are
+ // now shown.
+ final boolean hideIme = win.mIsImWindow
+ && (mService.mAtmService.mKeyguardController.isAodShowing()
+ || (mDisplayContent.isDefaultDisplay && !mWindowManagerDrawComplete));
+ if (hideIme) {
+ return true;
+ }
+
+ if (!mDisplayContent.isDefaultDisplay || !isKeyguardShowing()) {
+ return false;
+ }
+
+ // Show IME over the keyguard if the target allows it.
+ final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisible()
+ && win.mIsImWindow && (imeTarget.canShowWhenLocked()
+ || !mService.mPolicy.canBeHiddenByKeyguardLw(imeTarget));
+ if (showImeOverKeyguard) {
+ return false;
+ }
+
+ // Show SHOW_WHEN_LOCKED windows if keyguard is occluded.
+ final boolean allowShowWhenLocked = isKeyguardOccluded()
+ // Show error dialogs over apps that are shown on keyguard.
+ && (win.canShowWhenLocked()
+ || (win.mAttrs.privateFlags & LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR) != 0);
+ return !allowShowWhenLocked;
+ }
+
+ /**
* @return Whether the top app should hide the statusbar based on the top fullscreen opaque
* window.
*/
@@ -2916,10 +2969,6 @@
mDisplayContent.getInsetsPolicy().updateBarControlTarget(win);
- final int fullscreenAppearance = updateLightStatusBarLw(0 /* appearance */,
- mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState);
- final int dockedAppearance = updateLightStatusBarLw(0 /* appearance */,
- mTopDockedOpaqueWindowState, mTopDockedOpaqueOrDimmingWindowState);
final boolean inSplitScreen =
mService.mRoot.getDefaultTaskDisplayArea().isSplitScreenModeActivated();
if (inSplitScreen) {
@@ -2931,6 +2980,12 @@
mService.getStackBounds(inSplitScreen ? WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
: WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_UNDEFINED, mNonDockedStackBounds);
+ final int fullscreenAppearance = updateLightStatusBarLw(0 /* appearance */,
+ mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState,
+ mNonDockedStackBounds);
+ final int dockedAppearance = updateLightStatusBarLw(0 /* appearance */,
+ mTopDockedOpaqueWindowState, mTopDockedOpaqueOrDimmingWindowState,
+ mDockedStackBounds);
final int disableFlags = win.getSystemUiVisibility() & StatusBarManager.DISABLE_MASK;
final int opaqueAppearance = updateSystemBarsLw(win, disableFlags);
final WindowState navColorWin = chooseNavigationColorWindowLw(
@@ -2996,10 +3051,14 @@
}
private int updateLightStatusBarLw(@Appearance int appearance, WindowState opaque,
- WindowState opaqueOrDimming) {
+ WindowState opaqueOrDimming, Rect stackBounds) {
+ final DisplayRotation displayRotation = mDisplayContent.getDisplayRotation();
+ final int statusBarHeight = mStatusBarHeightForRotation[displayRotation.getRotation()];
+ final boolean stackBoundsContainStatusBar =
+ stackBounds.isEmpty() ? false : stackBounds.top < statusBarHeight;
final boolean onKeyguard = isKeyguardShowing() && !isKeyguardOccluded();
final WindowState statusColorWin = onKeyguard ? mNotificationShade : opaqueOrDimming;
- if (statusColorWin != null) {
+ if (stackBoundsContainStatusBar && statusColorWin != null) {
if (statusColorWin == opaque || onKeyguard) {
// If the top fullscreen-or-dimming window is also the top fullscreen, respect
// its light flag.
@@ -3025,7 +3084,7 @@
// If the IME window is visible and FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS is set, then IME
// window can be navigation color window.
final boolean imeWindowCanNavColorWindow = imeWindow != null
- && imeWindow.isVisibleLw()
+ && imeWindow.isVisible()
&& navBarPosition == NAV_BAR_BOTTOM
&& (imeWindow.mAttrs.flags
& WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
@@ -3294,8 +3353,8 @@
public void takeScreenshot(int screenshotType, int source) {
if (mScreenshotHelper != null) {
mScreenshotHelper.takeScreenshot(screenshotType,
- getStatusBar() != null && getStatusBar().isVisibleLw(),
- getNavigationBar() != null && getNavigationBar().isVisibleLw(),
+ getStatusBar() != null && getStatusBar().isVisible(),
+ getNavigationBar() != null && getNavigationBar().isVisible(),
source, mHandler, null /* completionConsumer */);
}
}
@@ -3464,8 +3523,8 @@
@VisibleForTesting
static boolean isOverlappingWithNavBar(WindowState targetWindow, WindowState navBarWindow) {
- if (navBarWindow == null || !navBarWindow.isVisibleLw()
- || targetWindow.mActivityRecord == null || !targetWindow.isVisibleLw()) {
+ if (navBarWindow == null || !navBarWindow.isVisible()
+ || targetWindow.mActivityRecord == null || !targetWindow.isVisible()) {
return false;
}
diff --git a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
index 231cc97..e1d5b1d 100644
--- a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
+++ b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
@@ -33,6 +33,7 @@
private int mConfigChanges;
private boolean mPreserveWindows;
private boolean mNotifyClients;
+ private boolean mUserLeaving;
EnsureActivitiesVisibleHelper(Task container) {
mTask = container;
@@ -49,7 +50,7 @@
* be sent to the clients.
*/
void reset(ActivityRecord starting, int configChanges, boolean preserveWindows,
- boolean notifyClients) {
+ boolean notifyClients, boolean userLeaving) {
mStarting = starting;
mTop = mTask.topRunningActivity();
// If the top activity is not fullscreen, then we need to make sure any activities under it
@@ -60,6 +61,7 @@
mConfigChanges = configChanges;
mPreserveWindows = preserveWindows;
mNotifyClients = notifyClients;
+ mUserLeaving = userLeaving;
}
/**
@@ -76,10 +78,12 @@
* @param preserveWindows Flag indicating whether windows should be preserved when updating.
* @param notifyClients Flag indicating whether the configuration and visibility changes shoulc
* be sent to the clients.
+ * @param userLeaving Flag indicating whether a userLeaving callback should be issued in the
+ * case the activity is being set to invisible.
*/
void process(@Nullable ActivityRecord starting, int configChanges, boolean preserveWindows,
- boolean notifyClients) {
- reset(starting, configChanges, preserveWindows, notifyClients);
+ boolean notifyClients, boolean userLeaving) {
+ reset(starting, configChanges, preserveWindows, notifyClients, userLeaving);
if (DEBUG_VISIBILITY) {
Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + mTop
@@ -173,7 +177,7 @@
+ " behindFullscreenActivity=" + mBehindFullscreenActivity
+ " mLaunchTaskBehind=" + r.mLaunchTaskBehind);
}
- r.makeInvisible();
+ r.makeInvisible(mUserLeaving);
}
if (!mBehindFullscreenActivity && mTask.isActivityTypeHome() && r.isRootOfTask()) {
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 086513b..457df4e 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -556,7 +556,7 @@
}
if (mAddWallpaperInputConsumerHandle) {
- if (w.mAttrs.type == TYPE_WALLPAPER && w.isVisibleLw()) {
+ if (w.mAttrs.type == TYPE_WALLPAPER && w.isVisible()) {
// Add the wallpaper input consumer above the first visible wallpaper.
mWallpaperInputConsumer.show(mInputTransaction, w);
mAddWallpaperInputConsumerHandle = false;
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index de2164d..9068bb7 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -92,6 +92,10 @@
mRootWindowContainer = mService.mRootWindowContainer;
}
+ boolean isAodShowing() {
+ return mAodShowing;
+ }
+
/**
* @return true if either Keyguard or AOD are showing, not going away, and not being occluded
* on the given display, false otherwise.
@@ -163,7 +167,10 @@
"setKeyguardShown");
mKeyguardShowing = keyguardShowing;
mAodShowing = aodShowing;
- mWindowManager.setAodShowing(aodShowing);
+ if (aodChanged) {
+ // Ensure the new state takes effect.
+ mWindowManager.mWindowPlacerLocked.performSurfacePlacement();
+ }
if (keyguardChanged) {
// Irrelevant to AOD.
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 2749cc9..3200bbc 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -706,7 +706,7 @@
}
boolean canShowStrictModeViolation(int pid) {
- final WindowState win = getWindow((w) -> w.mSession.mPid == pid && w.isVisibleLw());
+ final WindowState win = getWindow((w) -> w.mSession.mPid == pid && w.isVisible());
return win != null;
}
@@ -1812,7 +1812,8 @@
// Passing null here for 'starting' param value, so that visibility of actual starting
// activity will be properly updated.
ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
- false /* preserveWindows */, false /* notifyClients */);
+ false /* preserveWindows */, false /* notifyClients */,
+ mStackSupervisor.mUserLeaving);
if (displayId == INVALID_DISPLAY) {
// The caller didn't provide a valid display id, skip updating config.
@@ -2005,14 +2006,15 @@
*/
void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
boolean preserveWindows) {
- ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */);
+ ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */,
+ mStackSupervisor.mUserLeaving);
}
/**
* @see #ensureActivitiesVisible(ActivityRecord, int, boolean)
*/
void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
- boolean preserveWindows, boolean notifyClients) {
+ boolean preserveWindows, boolean notifyClients, boolean userLeaving) {
if (mStackSupervisor.inActivityVisibilityUpdate()) {
// Don't do recursive work.
return;
@@ -2024,7 +2026,7 @@
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
final DisplayContent display = getChildAt(displayNdx);
display.ensureActivitiesVisible(starting, configChanges, preserveWindows,
- notifyClients);
+ notifyClients, userLeaving);
}
} finally {
mStackSupervisor.endActivityVisibilityUpdate();
diff --git a/services/core/java/com/android/server/wm/SplashScreenStartingData.java b/services/core/java/com/android/server/wm/SplashScreenStartingData.java
index 726b7da..50a101d 100644
--- a/services/core/java/com/android/server/wm/SplashScreenStartingData.java
+++ b/services/core/java/com/android/server/wm/SplashScreenStartingData.java
@@ -53,8 +53,9 @@
@Override
StartingSurface createStartingSurface(ActivityRecord activity) {
- return mService.mPolicy.addSplashScreen(activity.token, mPkg, mTheme, mCompatInfo,
- mNonLocalizedLabel, mLabelRes, mIcon, mLogo, mWindowFlags,
- mMergedOverrideConfiguration, activity.getDisplayContent().getDisplayId());
+ return mService.mStartingSurfaceController.createSplashScreenStartingSurface(
+ activity, mPkg, mTheme, mCompatInfo, mNonLocalizedLabel, mLabelRes, mIcon,
+ mLogo, mWindowFlags, mMergedOverrideConfiguration,
+ activity.getDisplayContent().getDisplayId());
}
}
diff --git a/services/core/java/com/android/server/wm/StartingSurfaceController.java b/services/core/java/com/android/server/wm/StartingSurfaceController.java
new file mode 100644
index 0000000..6d7ddf6
--- /dev/null
+++ b/services/core/java/com/android/server/wm/StartingSurfaceController.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.content.res.CompatibilityInfo;
+import android.content.res.Configuration;
+import android.os.SystemProperties;
+
+import com.android.server.policy.WindowManagerPolicy.StartingSurface;
+
+/**
+ * Managing to create and release a starting window surface.
+ */
+public class StartingSurfaceController {
+
+ /** Set to {@code true} to enable shell starting surface drawer. */
+ private static final boolean DEBUG_ENABLE_SHELL_DRAWER =
+ SystemProperties.getBoolean("persist.debug.shell_starting_surface", false);
+
+ private final WindowManagerService mService;
+
+ public StartingSurfaceController(WindowManagerService wm) {
+ mService = wm;
+ }
+
+ StartingSurface createSplashScreenStartingSurface(ActivityRecord activity, String packageName,
+ int theme, CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
+ int icon, int logo, int windowFlags, Configuration overrideConfig, int displayId) {
+ if (!DEBUG_ENABLE_SHELL_DRAWER) {
+ return mService.mPolicy.addSplashScreen(activity.token, packageName, theme,
+ compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
+ overrideConfig, displayId);
+ }
+
+ final Task task = activity.getTask();
+ if (task != null && mService.mAtmService.mTaskOrganizerController.addStartingWindow(task,
+ activity.token)) {
+ return new SplashScreenContainerSurface(task);
+ }
+ return null;
+ }
+
+ private final class SplashScreenContainerSurface implements StartingSurface {
+ private final Task mTask;
+
+ SplashScreenContainerSurface(Task task) {
+ mTask = task;
+ }
+
+ @Override
+ public void remove() {
+ mService.mAtmService.mTaskOrganizerController.removeStartingWindow(mTask);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 86f1cf7..ac9c289 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -5734,7 +5734,8 @@
*/
void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges,
boolean preserveWindows) {
- ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */);
+ ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */,
+ mStackSupervisor.mUserLeaving);
}
/**
@@ -5751,14 +5752,16 @@
* @param configChanges Parts of the configuration that changed for this activity for evaluating
* if the screen should be frozen as part of
* {@link mEnsureActivitiesVisibleHelper}.
+ * @param userLeaving Flag indicating whether a userLeaving callback should be issued in the
+ * case an activity is being set to invisible.
*/
// TODO: Should be re-worked based on the fact that each task as a stack in most cases.
void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges,
- boolean preserveWindows, boolean notifyClients) {
+ boolean preserveWindows, boolean notifyClients, boolean userLeaving) {
mStackSupervisor.beginActivityVisibilityUpdate();
try {
forAllLeafTasks(task -> task.mEnsureActivitiesVisibleHelper.process(
- starting, configChanges, preserveWindows, notifyClients),
+ starting, configChanges, preserveWindows, notifyClients, userLeaving),
true /* traverseTopToBottom */);
if (mTranslucentActivityWaiting != null &&
@@ -5940,17 +5943,20 @@
final TaskDisplayArea taskDisplayArea = getDisplayArea();
// If the top activity is the resumed one, nothing to do.
- // For devices that are not in fullscreen mode (e.g. freeform windows), it's possible
- // we still want to proceed if the visibility of other windows have changed (e.g. bringing
- // a fullscreen window forward to cover another freeform activity.)
if (mResumedActivity == next && next.isState(RESUMED)
- && taskDisplayArea.getWindowingMode() != WINDOWING_MODE_FREEFORM
&& taskDisplayArea.allResumedActivitiesComplete()) {
// The activity may be waiting for stop, but that is no longer appropriate for it.
mStackSupervisor.mStoppingActivities.remove(next);
// Make sure we have executed any pending transitions, since there
// should be nothing left to do at this point.
executeAppTransition(options);
+ // For devices that are not in fullscreen mode (e.g. freeform windows), it's possible
+ // we still want to check if the visibility of other windows have changed (e.g. bringing
+ // a fullscreen window forward to cover another freeform activity.)
+ if (taskDisplayArea.inMultiWindowMode()) {
+ taskDisplayArea.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
+ false /* preserveWindows */, true /* notifyClients */, userLeaving);
+ }
ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Top activity "
+ "resumed %s", next);
return false;
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 9d14e0d..802c8f9 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -1806,13 +1806,13 @@
}
void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
- boolean preserveWindows, boolean notifyClients) {
+ boolean preserveWindows, boolean notifyClients, boolean userLeaving) {
mAtmService.mStackSupervisor.beginActivityVisibilityUpdate();
try {
for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) {
final Task stack = getStackAt(stackNdx);
stack.ensureActivitiesVisible(starting, configChanges, preserveWindows,
- notifyClients);
+ notifyClients, userLeaving);
}
} finally {
mAtmService.mStackSupervisor.endActivityVisibilityUpdate();
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 7423763..bb8b4a5 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -116,6 +116,28 @@
return mTaskOrganizer.asBinder();
}
+ void addStartingWindow(Task task, IBinder appToken) {
+ final RunningTaskInfo taskInfo = task.getTaskInfo();
+ mDeferTaskOrgCallbacksConsumer.accept(() -> {
+ try {
+ mTaskOrganizer.addStartingWindow(taskInfo, appToken);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Exception sending onTaskStart callback", e);
+ }
+ });
+ }
+
+ void removeStartingWindow(Task task) {
+ final RunningTaskInfo taskInfo = task.getTaskInfo();
+ mDeferTaskOrgCallbacksConsumer.accept(() -> {
+ try {
+ mTaskOrganizer.removeStartingWindow(taskInfo);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Exception sending onStartTaskFinished callback", e);
+ }
+ });
+ }
+
SurfaceControl prepareLeash(Task task, boolean visible, String reason) {
SurfaceControl outSurfaceControl = new SurfaceControl(task.getSurfaceControl(), reason);
if (!task.mCreatedByOrganizer && !visible) {
@@ -218,6 +240,14 @@
mUid = uid;
}
+ void addStartingWindow(Task t, IBinder appToken) {
+ mOrganizer.addStartingWindow(t, appToken);
+ }
+
+ void removeStartingWindow(Task t) {
+ mOrganizer.removeStartingWindow(t);
+ }
+
/**
* Register this task with this state, but doesn't trigger the task appeared callback to
* the organizer.
@@ -390,6 +420,27 @@
return !ArrayUtils.contains(UNSUPPORTED_WINDOWING_MODES, winMode);
}
+ boolean addStartingWindow(Task task, IBinder appToken) {
+ final Task rootTask = task.getRootTask();
+ if (rootTask == null || rootTask.mTaskOrganizer == null) {
+ return false;
+ }
+ final TaskOrganizerState state =
+ mTaskOrganizerStates.get(rootTask.mTaskOrganizer.asBinder());
+ state.addStartingWindow(task, appToken);
+ return true;
+ }
+
+ void removeStartingWindow(Task task) {
+ final Task rootTask = task.getRootTask();
+ if (rootTask == null || rootTask.mTaskOrganizer == null) {
+ return;
+ }
+ final TaskOrganizerState state =
+ mTaskOrganizerStates.get(rootTask.mTaskOrganizer.asBinder());
+ state.removeStartingWindow(task);
+ }
+
void onTaskAppeared(ITaskOrganizer organizer, Task task) {
final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
state.addTask(task);
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 66cb674..8729801 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -430,9 +430,6 @@
public abstract void setOnHardKeyboardStatusChangeListener(
OnHardKeyboardStatusChangeListener listener);
- /** Returns true if a stack in the windowing mode is currently visible. */
- public abstract boolean isStackVisibleLw(int windowingMode);
-
/**
* Requests the window manager to resend the windows for accessibility on specified display.
*
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 01abbe2..8a09bd4 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -490,6 +490,7 @@
final Map<IBinder, KeyInterceptionInfo> mKeyInterceptionInfoForToken =
Collections.synchronizedMap(new ArrayMap<>());
+ final StartingSurfaceController mStartingSurfaceController;
private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() {
@Override
@@ -1375,6 +1376,8 @@
mContext.getResources());
setGlobalShadowSettings();
+
+ mStartingSurfaceController = new StartingSurfaceController(this);
}
private void setGlobalShadowSettings() {
@@ -1559,7 +1562,7 @@
ProtoLog.w(WM_ERROR, "Attempted to add window with exiting application token "
+ ".%s Aborting.", token);
return WindowManagerGlobal.ADD_APP_EXITING;
- } else if (type == TYPE_APPLICATION_STARTING && activity.startingWindow != null) {
+ } else if (type == TYPE_APPLICATION_STARTING && activity.mStartingWindow != null) {
ProtoLog.w(WM_ERROR,
"Attempted to add starting window to token with already existing"
+ " starting window");
@@ -1708,7 +1711,7 @@
final ActivityRecord tokenActivity = token.asActivityRecord();
if (type == TYPE_APPLICATION_STARTING && tokenActivity != null) {
- tokenActivity.startingWindow = win;
+ tokenActivity.mStartingWindow = win;
ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "addWindow: %s startingWindow=%s",
activity, win);
}
@@ -5615,7 +5618,7 @@
final WindowState win = (WindowState) container.mWaitingForDrawn.get(j);
ProtoLog.i(WM_DEBUG_SCREEN_ON,
"Waiting for drawn %s: removed=%b visible=%b mHasSurface=%b drawState=%d",
- win, win.mRemoved, win.isVisibleLw(), win.mHasSurface,
+ win, win.mRemoved, win.isVisible(), win.mHasSurface,
win.mWinAnimator.mDrawState);
if (win.mRemoved || !win.mHasSurface || !win.isVisibleByPolicy()) {
// Window has been removed or hidden; no draw will now happen, so stop waiting.
@@ -7601,13 +7604,6 @@
}
@Override
- public boolean isStackVisibleLw(int windowingMode) {
- // TODO(b/153090332): Support multiple task display areas & displays
- final TaskDisplayArea tc = mRoot.getDefaultTaskDisplayArea();
- return tc.isStackVisible(windowingMode);
- }
-
- @Override
public void computeWindowsForAccessibility(int displayId) {
final AccessibilityController accessibilityController;
synchronized (mGlobalLock) {
@@ -8000,19 +7996,6 @@
}
}
- /**
- * Updates {@link WindowManagerPolicy} with new value about whether AOD is showing. If AOD
- * has changed, this will trigger a {@link WindowSurfacePlacer#performSurfacePlacement} to
- * ensure the new value takes effect.
- */
- public void setAodShowing(boolean aodShowing) {
- synchronized (mGlobalLock) {
- if (mPolicy.setAodShowing(aodShowing)) {
- mWindowPlacerLocked.performSurfacePlacement();
- }
- }
- }
-
@Override
public boolean injectInputAfterTransactionsApplied(InputEvent ev, int mode) {
boolean isDown;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 64d24fb..04d7772 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -309,7 +309,7 @@
/**
* The visibility flag of the window based on policy like {@link WindowManagerPolicy}.
- * Normally set by calling {@link #showLw} and {@link #hideLw}.
+ * Normally set by calling {@link #show} and {@link #hide}.
*
* TODO: b/131253938 This will eventually be split into individual visibility policy flags.
*/
@@ -1546,8 +1546,7 @@
return state;
}
- @Override
- public int getDisplayId() {
+ int getDisplayId() {
final DisplayContent displayContent = getDisplayContent();
if (displayContent == null) {
return Display.INVALID_DISPLAY;
@@ -1731,11 +1730,6 @@
&& !mAnimatingExit && !mDestroying && (!mIsWallpaper || mWallpaperVisible);
}
- @Override
- public boolean isVisibleLw() {
- return isVisible();
- }
-
/**
* Is this window visible, ignoring its app token? It is not visible if there is no surface,
* or we are in the process of running an exit animation that will remove the surface.
@@ -1951,7 +1945,7 @@
// Unnecessary to redraw a drawn starting window.
return;
}
- } else if (mActivityRecord.startingWindow != null) {
+ } else if (mActivityRecord.mStartingWindow != null) {
// If the activity has an active starting window, there is no need to wait for the
// main window.
return;
@@ -2797,13 +2791,13 @@
void adjustStartingWindowFlags() {
if (mAttrs.type == TYPE_BASE_APPLICATION && mActivityRecord != null
- && mActivityRecord.startingWindow != null) {
+ && mActivityRecord.mStartingWindow != null) {
// Special handling of starting window over the base
// window of the app: propagate lock screen flags to it,
// to provide the correct semantics while starting.
final int mask = FLAG_SHOW_WHEN_LOCKED | FLAG_DISMISS_KEYGUARD
| FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
- WindowManager.LayoutParams sa = mActivityRecord.startingWindow.mAttrs;
+ WindowManager.LayoutParams sa = mActivityRecord.mStartingWindow.mAttrs;
sa.flags = (sa.flags & ~mask) | (mAttrs.flags & mask);
}
}
@@ -2962,12 +2956,11 @@
return mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN;
}
- @Override
- public boolean showLw(boolean doAnimation) {
- return showLw(doAnimation, true);
- }
-
- boolean showLw(boolean doAnimation, boolean requestAnim) {
+ /**
+ * Can be called to undo the effect of {@link #hide}, allowing a window to be shown as long
+ * as the client would also like it to be shown.
+ */
+ boolean show(boolean doAnimation, boolean requestAnim) {
if (isLegacyPolicyVisibility() && mLegacyPolicyVisibilityAfterAnim) {
// Already showing.
return false;
@@ -3020,12 +3013,8 @@
return true;
}
- @Override
- public boolean hideLw(boolean doAnimation) {
- return hideLw(doAnimation, true);
- }
-
- boolean hideLw(boolean doAnimation, boolean requestAnim) {
+ /** Forces the window to be hidden, regardless of whether the client like it shown. */
+ boolean hide(boolean doAnimation, boolean requestAnim) {
if (doAnimation) {
if (!mToken.okToAnimate()) {
doAnimation = false;
@@ -3077,9 +3066,9 @@
}
mForceHideNonSystemOverlayWindow = forceHide;
if (forceHide) {
- hideLw(true /* doAnimation */, true /* requestAnim */);
+ hide(true /* doAnimation */, true /* requestAnim */);
} else {
- showLw(true /* doAnimation */, true /* requestAnim */);
+ show(true /* doAnimation */, true /* requestAnim */);
}
}
@@ -3093,9 +3082,9 @@
}
mHiddenWhileSuspended = hide;
if (hide) {
- hideLw(true, true);
+ hide(true /* doAnimation */, true /* requestAnim */);
} else {
- showLw(true, true);
+ show(true /* doAnimation */, true /* requestAnim */);
}
}
@@ -3109,9 +3098,9 @@
// ops modifies they should only be hidden by policy due to the
// lock screen, and the user won't be changing this if locked.
// Plus it will quickly be fixed the next time we do a layout.
- showLw(true, true);
+ show(true /* doAnimation */, true /* requestAnim */);
} else {
- hideLw(true, true);
+ hide(true /* doAnimation */, true /* requestAnim */);
}
}
}
@@ -3165,7 +3154,7 @@
public void hidePermanentlyLw() {
if (!mPermanentlyHidden) {
mPermanentlyHidden = true;
- hideLw(true, true);
+ hide(true /* doAnimation */, true /* requestAnim */);
}
}
@@ -4437,11 +4426,6 @@
}
}
- @Override
- public boolean isInputMethodWindow() {
- return mIsImWindow;
- }
-
// This must be called while inside a transaction.
boolean performShowLocked() {
if (!showToCurrentUser()) {
@@ -4969,7 +4953,7 @@
}
int relayoutVisibleWindow(int result, int attrChanges) {
- final boolean wasVisible = isVisibleLw();
+ final boolean wasVisible = isVisible();
result |= (!wasVisible || !isDrawn()) ? RELAYOUT_RES_FIRST_TIME : 0;
@@ -5464,8 +5448,7 @@
super.assignLayer(t, layer);
}
- @Override
- public boolean isDimming() {
+ boolean isDimming() {
return mIsDimming;
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 72aa766..0fd8146 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -532,7 +532,7 @@
void destroySurfaceLocked() {
final ActivityRecord activity = mWin.mActivityRecord;
if (activity != null) {
- if (mWin == activity.startingWindow) {
+ if (mWin == activity.mStartingWindow) {
activity.startingDisplayed = false;
}
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
index eff222a..ce61d50 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
@@ -15,8 +15,10 @@
*/
package com.android.server.devicepolicy;
+import android.app.admin.DevicePolicySafetyChecker;
import android.app.admin.IDevicePolicyManager;
import android.content.ComponentName;
+import android.util.Slog;
import com.android.server.SystemService;
@@ -30,6 +32,9 @@
* should be added here to avoid build breakage in downstream branches.
*/
abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub {
+
+ private static final String TAG = BaseIDevicePolicyManager.class.getSimpleName();
+
/**
* To be called by {@link DevicePolicyManagerService#Lifecycle} during the various boot phases.
*
@@ -55,6 +60,16 @@
*/
abstract void handleStopUser(int userId);
+ /**
+ * Sets the {@link DevicePolicySafetyChecker}.
+ *
+ * <p>Currently, it's called only by {@code SystemServer} on
+ * {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE automotive builds}
+ */
+ public void setDevicePolicySafetyChecker(DevicePolicySafetyChecker safetyChecker) {
+ Slog.w(TAG, "setDevicePolicySafetyChecker() not implemented by " + getClass());
+ }
+
public void clearSystemUpdatePolicyFreezePeriodRecord() {
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 2190392..f2c9718 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -135,9 +135,11 @@
import android.app.admin.DevicePolicyCache;
import android.app.admin.DevicePolicyEventLogger;
import android.app.admin.DevicePolicyManager;
+import android.app.admin.DevicePolicyManager.DevicePolicyOperation;
import android.app.admin.DevicePolicyManager.PasswordComplexity;
import android.app.admin.DevicePolicyManager.PersonalAppsSuspensionReason;
import android.app.admin.DevicePolicyManagerInternal;
+import android.app.admin.DevicePolicySafetyChecker;
import android.app.admin.DeviceStateCache;
import android.app.admin.FactoryResetProtectionPolicy;
import android.app.admin.NetworkEvent;
@@ -148,6 +150,7 @@
import android.app.admin.StartInstallingUpdateCallback;
import android.app.admin.SystemUpdateInfo;
import android.app.admin.SystemUpdatePolicy;
+import android.app.admin.UnsafeStateException;
import android.app.backup.IBackupManager;
import android.app.trust.TrustManager;
import android.app.usage.UsageStatsManagerInternal;
@@ -634,6 +637,9 @@
@VisibleForTesting
final TransferOwnershipMetadataManager mTransferOwnershipMetadataManager;
+ @Nullable
+ private DevicePolicySafetyChecker mSafetyChecker;
+
public static final class Lifecycle extends SystemService {
private BaseIDevicePolicyManager mService;
@@ -645,8 +651,8 @@
dpmsClassName = DevicePolicyManagerService.class.getName();
}
try {
- Class serviceClass = Class.forName(dpmsClassName);
- Constructor constructor = serviceClass.getConstructor(Context.class);
+ Class<?> serviceClass = Class.forName(dpmsClassName);
+ Constructor<?> constructor = serviceClass.getConstructor(Context.class);
mService = (BaseIDevicePolicyManager) constructor.newInstance(context);
} catch (Exception e) {
throw new IllegalStateException(
@@ -655,6 +661,11 @@
}
}
+ /** Sets the {@link DevicePolicySafetyChecker}. */
+ public void setDevicePolicySafetyChecker(DevicePolicySafetyChecker safetyChecker) {
+ mService.setDevicePolicySafetyChecker(safetyChecker);
+ }
+
@Override
public void onStart() {
publishBinderService(Context.DEVICE_POLICY_SERVICE, mService);
@@ -953,6 +964,38 @@
}
}
+ @Override
+ public void setDevicePolicySafetyChecker(DevicePolicySafetyChecker safetyChecker) {
+ Slog.i(LOG_TAG, "Setting DevicePolicySafetyChecker as " + safetyChecker.getClass());
+ mSafetyChecker = safetyChecker;
+ }
+
+ /**
+ * Checks if the feature is supported and it's safe to execute the given {@code operation}.
+ *
+ * <p>Typically called at the beginning of each API method as:
+ *
+ * <pre><code>
+ *
+ * if (!canExecute(operation, permission)) return;
+ *
+ * </code></pre>
+ *
+ * @return {@code true} when it's safe to execute, {@code false} when the feature is not
+ * supported or the caller does not have the given {@code requiredPermission}.
+ *
+ * @throws UnsafeStateException if it's not safe to execute the operation.
+ */
+ boolean canExecute(@DevicePolicyOperation int operation, @NonNull String requiredPermission) {
+ if (!mHasFeature && !hasCallingPermission(requiredPermission)) {
+ return false;
+ }
+ if (mSafetyChecker == null || mSafetyChecker.isDevicePolicyOperationSafe(operation)) {
+ return true;
+ }
+ throw mSafetyChecker.newUnsafeStateException(operation);
+ }
+
/**
* Unit test will subclass it to inject mocks.
*/
@@ -1228,10 +1271,15 @@
SystemProperties.set(key, value);
}
+ // TODO (b/137101239): clean up split system user codes
boolean userManagerIsSplitSystemUser() {
return UserManager.isSplitSystemUser();
}
+ boolean userManagerIsHeadlessSystemUserMode() {
+ return UserManager.isHeadlessSystemUserMode();
+ }
+
String getDevicePolicyFilePathForSystemUser() {
return "/data/system/";
}
@@ -2932,8 +2980,7 @@
synchronized (getLockObject()) {
final long now = System.currentTimeMillis();
- List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(
- userHandle, /* parent */ false);
+ List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(userHandle);
final int N = admins.size();
for (int i = 0; i < N; i++) {
ActiveAdmin admin = admins.get(i);
@@ -3503,8 +3550,8 @@
}
// Return the strictest policy across all participating admins.
- List<ActiveAdmin> admins =
- getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+ List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(
+ getProfileParentUserIfRequested(userHandle, parent));
final int N = admins.size();
for (int i = 0; i < N; i++) {
ActiveAdmin admin = admins.get(i);
@@ -3516,16 +3563,13 @@
}
}
- private List<ActiveAdmin> getActiveAdminsForLockscreenPoliciesLocked(
- int userHandle, boolean parent) {
- if (!parent && isSeparateProfileChallengeEnabled(userHandle)) {
+ private List<ActiveAdmin> getActiveAdminsForLockscreenPoliciesLocked(int userHandle) {
+ if (isSeparateProfileChallengeEnabled(userHandle)) {
// If this user has a separate challenge, only return its restrictions.
return getUserDataUnchecked(userHandle).mAdminList;
}
- // Either parent == true, or isSeparateProfileChallengeEnabled == false
- // If parent is true, query the parent user of userHandle by definition,
- // If isSeparateProfileChallengeEnabled is false, userHandle points to a managed profile
- // with unified challenge so also need to query the parent user who owns the credential.
+ // If isSeparateProfileChallengeEnabled is false and userHandle points to a managed profile
+ // we need to query the parent user who owns the credential.
return getActiveAdminsForUserAndItsManagedProfilesLocked(getProfileParentId(userHandle),
(user) -> !mLockPatternUtils.isSeparateProfileChallengeEnabled(user.id));
}
@@ -3719,8 +3763,8 @@
}
// Return the strictest policy across all participating admins.
- List<ActiveAdmin> admins =
- getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+ List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(
+ getProfileParentUserIfRequested(userHandle, parent));
final int N = admins.size();
for (int i = 0; i < N; i++) {
ActiveAdmin admin = admins.get(i);
@@ -3837,7 +3881,8 @@
}
// Return the strictest policy across all participating admins.
- List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+ List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(
+ getProfileParentUserIfRequested(userHandle, parent));
final int N = admins.size();
for (int i = 0; i < N; i++) {
ActiveAdmin admin = admins.get(i);
@@ -4076,8 +4121,8 @@
}
int maxValue = 0;
- final List<ActiveAdmin> admins =
- getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+ final List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(
+ getProfileParentUserIfRequested(userHandle, parent));
final int N = admins.size();
for (int i = 0; i < N; i++) {
final ActiveAdmin admin = admins.get(i);
@@ -4098,6 +4143,8 @@
*/
@Override
public PasswordMetrics getPasswordMinimumMetrics(@UserIdInt int userHandle) {
+ final CallerIdentity caller = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle));
return getPasswordMinimumMetrics(userHandle, false /* parent */);
}
@@ -4110,13 +4157,10 @@
}
Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
- final CallerIdentity caller = getCallerIdentity();
- Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle));
-
ArrayList<PasswordMetrics> adminMetrics = new ArrayList<>();
synchronized (getLockObject()) {
- List<ActiveAdmin> admins =
- getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+ List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(
+ getProfileParentUserIfRequested(userHandle, parent));
for (ActiveAdmin admin : admins) {
adminMetrics.add(admin.mPasswordPolicy.getMinMetrics());
}
@@ -4142,8 +4186,9 @@
int credentialOwner = getCredentialOwner(userHandle, parent);
DevicePolicyData policy = getUserDataUnchecked(credentialOwner);
PasswordMetrics metrics = mLockSettingsInternal.getUserPasswordMetrics(credentialOwner);
+ final int userToCheck = getProfileParentUserIfRequested(userHandle, parent);
boolean activePasswordSufficientForUserLocked = isActivePasswordSufficientForUserLocked(
- policy.mPasswordValidAtLastCheckpoint, metrics, userHandle, parent);
+ policy.mPasswordValidAtLastCheckpoint, metrics, userToCheck);
return activePasswordSufficientForUserLocked;
}
}
@@ -4182,7 +4227,7 @@
DevicePolicyData policy = getUserDataUnchecked(credentialOwner);
PasswordMetrics metrics = mLockSettingsInternal.getUserPasswordMetrics(credentialOwner);
return isActivePasswordSufficientForUserLocked(
- policy.mPasswordValidAtLastCheckpoint, metrics, targetUser, false);
+ policy.mPasswordValidAtLastCheckpoint, metrics, targetUser);
}
}
@@ -4219,7 +4264,7 @@
private boolean isActivePasswordSufficientForUserLocked(
boolean passwordValidAtLastCheckpoint, @Nullable PasswordMetrics metrics,
- int userHandle, boolean parent) {
+ int userHandle) {
if (!mInjector.storageManagerIsFileBasedEncryptionEnabled() && (metrics == null)) {
// Before user enters their password for the first time after a reboot, return the
// value of this flag, which tells us whether the password was valid the last time
@@ -4236,7 +4281,7 @@
throw new IllegalStateException("isActivePasswordSufficient called on FBE-locked user");
}
- return isPasswordSufficientForUserWithoutCheckpointLocked(metrics, userHandle, parent);
+ return isPasswordSufficientForUserWithoutCheckpointLocked(metrics, userHandle, false);
}
/**
@@ -4382,7 +4427,8 @@
ActiveAdmin strictestAdmin = null;
// Return the strictest policy across all participating admins.
- List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+ List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(
+ getProfileParentUserIfRequested(userHandle, parent));
final int N = admins.size();
for (int i = 0; i < N; i++) {
ActiveAdmin admin = admins.get(i);
@@ -4591,7 +4637,7 @@
// Update the device timeout
final int parentId = getProfileParentId(userId);
final long timeMs = getMaximumTimeToLockPolicyFromAdmins(
- getActiveAdminsForLockscreenPoliciesLocked(parentId, false));
+ getActiveAdminsForLockscreenPoliciesLocked(parentId));
final DevicePolicyData policy = getUserDataUnchecked(parentId);
if (policy.mLastMaximumTimeToLock == timeMs) {
@@ -4613,7 +4659,7 @@
final long timeMs;
if (isSeparateProfileChallengeEnabled(userId)) {
timeMs = getMaximumTimeToLockPolicyFromAdmins(
- getActiveAdminsForLockscreenPoliciesLocked(userId, false /* parent */));
+ getActiveAdminsForLockscreenPoliciesLocked(userId));
} else {
timeMs = Long.MAX_VALUE;
}
@@ -4646,7 +4692,7 @@
}
// Return the strictest policy across all participating admins.
final List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(
- userHandle, parent);
+ getProfileParentUserIfRequested(userHandle, parent));
final long timeMs = getMaximumTimeToLockPolicyFromAdmins(admins);
return timeMs == Long.MAX_VALUE ? 0 : timeMs;
}
@@ -4730,7 +4776,8 @@
}
// Return the strictest policy across all participating admins.
- List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(userId, parent);
+ List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(
+ getProfileParentUserIfRequested(userId, parent));
long strongAuthUnlockTimeout = DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS;
for (int i = 0; i < admins.size(); i++) {
@@ -4756,9 +4803,10 @@
@Override
public void lockNow(int flags, boolean parent) {
- if (!mHasFeature && !hasCallingPermission(permission.LOCK_DEVICE)) {
+ if (!canExecute(DevicePolicyManager.OPERATION_LOCK_NOW, permission.LOCK_DEVICE)) {
return;
}
+
final CallerIdentity caller = getCallerIdentity();
final int callingUserId = caller.getUserId();
@@ -6157,8 +6205,7 @@
*/
private Set<Integer> updatePasswordExpirationsLocked(int userHandle) {
final ArraySet<Integer> affectedUserIds = new ArraySet<>();
- List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(
- userHandle, /* parent */ false);
+ List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(userHandle);
for (int i = 0; i < admins.size(); i++) {
ActiveAdmin admin = admins.get(i);
if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)) {
@@ -7162,7 +7209,8 @@
admins = getUserDataUnchecked(userHandle).mAdminList;
} else {
// Otherwise return those set by admins in the user and its profiles.
- admins = getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+ admins = getActiveAdminsForLockscreenPoliciesLocked(
+ getProfileParentUserIfRequested(userHandle, parent));
}
int which = DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
@@ -7229,7 +7277,6 @@
|| (caller.hasPackage()
&& isCallerDelegate(caller, DELEGATION_KEEP_UNINSTALLED_PACKAGES)));
- // TODO In split system user mode, allow apps on user 0 to query the list
synchronized (getLockObject()) {
return getKeepUninstalledPackagesLocked();
}
@@ -8437,6 +8484,14 @@
});
}
+ private int getProfileParentUserIfRequested(int userHandle, boolean parent) {
+ if (parent) {
+ return getProfileParentId(userHandle);
+ }
+
+ return userHandle;
+ }
+
private int getCredentialOwner(final int userHandle, final boolean parent) {
return mInjector.binderWithCleanCallingIdentity(() -> {
int effectiveUserHandle = userHandle;
@@ -8543,6 +8598,8 @@
pw.printf("mIsWatch=%b\n", mIsWatch);
pw.printf("mIsAutomotive=%b\n", mIsAutomotive);
pw.printf("mHasTelephonyFeature=%b\n", mHasTelephonyFeature);
+ String safetyChecker = mSafetyChecker == null ? "N/A" : mSafetyChecker.getClass().getName();
+ pw.printf("mSafetyChecker=%b\n", safetyChecker);
pw.decreaseIndent();
}
@@ -8719,8 +8776,8 @@
// Search through all admins that use KEYGUARD_DISABLE_TRUST_AGENTS and keep track
// of the options. If any admin doesn't have options, discard options for the rest
// and return null.
- List<ActiveAdmin> admins =
- getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+ List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(
+ getProfileParentUserIfRequested(userHandle, parent));
boolean allAdminsHaveOptions = true;
final int N = admins.size();
for (int i = 0; i < N; i++) {
@@ -11981,6 +12038,9 @@
case DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE:
case DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE:
return checkDeviceOwnerProvisioningPreCondition(callingUserId);
+ // TODO (b/137101239): clean up split system user codes
+ // ACTION_PROVISION_MANAGED_USER and ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE
+ // only supported on split-user systems.
case DevicePolicyManager.ACTION_PROVISION_MANAGED_USER:
return checkManagedUserProvisioningPreCondition(callingUserId);
case DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE:
@@ -12003,24 +12063,27 @@
if (mOwners.hasProfileOwner(deviceOwnerUserId)) {
return CODE_USER_HAS_PROFILE_OWNER;
}
- if (!mUserManager.isUserRunning(new UserHandle(deviceOwnerUserId))) {
+ // System user is always running in headless system user mode.
+ if (!mInjector.userManagerIsHeadlessSystemUserMode()
+ && !mUserManager.isUserRunning(new UserHandle(deviceOwnerUserId))) {
return CODE_USER_NOT_RUNNING;
}
if (mIsWatch && hasPaired(UserHandle.USER_SYSTEM)) {
return CODE_HAS_PAIRED;
}
+ // TODO (b/137101239): clean up split system user codes
if (isAdb) {
- // if shell command runs after user setup completed check device status. Otherwise, OK.
+ // If shell command runs after user setup completed check device status. Otherwise, OK.
if (mIsWatch || hasUserSetupCompleted(UserHandle.USER_SYSTEM)) {
- if (!mInjector.userManagerIsSplitSystemUser()) {
- if (mUserManager.getUserCount() > 1) {
- return CODE_NONSYSTEM_USER_EXISTS;
- }
- if (hasIncompatibleAccountsOrNonAdb) {
- return CODE_ACCOUNTS_NOT_EMPTY;
- }
- } else {
- // STOPSHIP Do proper check in split user mode
+ // In non-headless system user mode, DO can be setup only if
+ // there's no non-system user
+ if (!mInjector.userManagerIsHeadlessSystemUserMode()
+ && !mInjector.userManagerIsSplitSystemUser()
+ && mUserManager.getUserCount() > 1) {
+ return CODE_NONSYSTEM_USER_EXISTS;
+ }
+ if (hasIncompatibleAccountsOrNonAdb) {
+ return CODE_ACCOUNTS_NOT_EMPTY;
}
}
return CODE_OK;
@@ -12030,19 +12093,26 @@
if (deviceOwnerUserId != UserHandle.USER_SYSTEM) {
return CODE_NOT_SYSTEM_USER;
}
- // In non-split user mode, only provision DO before setup wizard completes
+ // Only provision DO before setup wizard completes
+ // TODO (b/171423186): implement deferred DO setup for headless system user mode
if (hasUserSetupCompleted(UserHandle.USER_SYSTEM)) {
return CODE_USER_SETUP_COMPLETED;
}
- } else {
+ } else {
// STOPSHIP Do proper check in split user mode
}
return CODE_OK;
}
}
- private int checkDeviceOwnerProvisioningPreCondition(@UserIdInt int deviceOwnerUserId) {
+ private int checkDeviceOwnerProvisioningPreCondition(@UserIdInt int callingUserId) {
synchronized (getLockObject()) {
+ final int deviceOwnerUserId = mInjector.userManagerIsHeadlessSystemUserMode()
+ ? UserHandle.USER_SYSTEM
+ : callingUserId;
+ Slog.i(LOG_TAG,
+ String.format("Calling user %d, device owner will be set on user %d",
+ callingUserId, deviceOwnerUserId));
// hasIncompatibleAccountsOrNonAdb doesn't matter since the caller is not adb.
return checkDeviceOwnerProvisioningPreConditionLocked(/* owner unknown */ null,
deviceOwnerUserId, /* isAdb= */ false,
@@ -12050,6 +12120,7 @@
}
}
+ // TODO (b/137101239): clean up split system user codes
private int checkManagedProfileProvisioningPreCondition(String packageName,
@UserIdInt int callingUserId) {
if (!hasFeatureManagedUsers()) {
@@ -12138,6 +12209,7 @@
return null;
}
+ // TODO (b/137101239): clean up split system user codes
private int checkManagedUserProvisioningPreCondition(int callingUserId) {
if (!hasFeatureManagedUsers()) {
return CODE_MANAGED_USERS_NOT_SUPPORTED;
@@ -12159,6 +12231,7 @@
return CODE_OK;
}
+ // TODO (b/137101239): clean up split system user codes
private int checkManagedShareableDeviceProvisioningPreCondition(int callingUserId) {
if (!mInjector.userManagerIsSplitSystemUser()) {
// ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE only supported on split-user systems.
@@ -12731,9 +12804,8 @@
return true;
}
if (userId == UserHandle.USER_SYSTEM) {
- // The system user is always affiliated in a DO device, even if the DO is set on a
- // different user. This could be the case if the DO is set in the primary user
- // of a split user device.
+ // The system user is always affiliated in a DO device,
+ // even if in headless system user mode.
return true;
}
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index 599ac93..91478a5 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -2341,17 +2341,16 @@
return result;
}
- std::vector<incfs::ReadInfo> pendingReads;
- if (mService.mIncFs->waitForPendingReads(control, 0ms, &pendingReads) !=
+ if (mService.mIncFs->waitForPendingReads(control, 0ms, &mLastPendingReads) !=
android::incfs::WaitResult::HaveData ||
- pendingReads.empty()) {
+ mLastPendingReads.empty()) {
return result;
}
LOG(DEBUG) << id() << ": pendingReads: " << control.pendingReads() << ", "
- << pendingReads.size() << ": " << pendingReads.front().bootClockTsUs;
+ << mLastPendingReads.size() << ": " << mLastPendingReads.front().bootClockTsUs;
- for (auto&& pendingRead : pendingReads) {
+ for (auto&& pendingRead : mLastPendingReads) {
result = std::min(result, pendingRead.bootClockTsUs);
}
return result;
@@ -2400,6 +2399,18 @@
}
}
+static std::string toHexString(const RawMetadata& metadata) {
+ int n = metadata.size();
+ std::string res(n * 2, '\0');
+ // Same as incfs::toString(fileId)
+ static constexpr char kHexChar[] = "0123456789abcdef";
+ for (int i = 0; i < n; ++i) {
+ res[i * 2] = kHexChar[(metadata[i] & 0xf0) >> 4];
+ res[i * 2 + 1] = kHexChar[(metadata[i] & 0x0f)];
+ }
+ return res;
+}
+
void IncrementalService::DataLoaderStub::onDump(int fd) {
dprintf(fd, " dataLoader: {\n");
dprintf(fd, " currentStatus: %d\n", mCurrentStatus);
@@ -2415,6 +2426,15 @@
dprintf(fd, " unhealthyTimeoutMs: %d\n", int(mHealthCheckParams.unhealthyTimeoutMs));
dprintf(fd, " unhealthyMonitoringMs: %d\n",
int(mHealthCheckParams.unhealthyMonitoringMs));
+ dprintf(fd, " lastPendingReads: \n");
+ const auto control = mService.mIncFs->openMount(mHealthPath);
+ for (auto&& pendingRead : mLastPendingReads) {
+ dprintf(fd, " fileId: %s\n", mService.mIncFs->toString(pendingRead.id).c_str());
+ const auto metadata = mService.mIncFs->getMetadata(control, pendingRead.id);
+ dprintf(fd, " metadataHex: %s\n", toHexString(metadata).c_str());
+ dprintf(fd, " blockIndex: %d\n", pendingRead.block);
+ dprintf(fd, " bootClockTsUs: %lld\n", (long long)pendingRead.bootClockTsUs);
+ }
dprintf(fd, " }\n");
const auto& params = mParams;
dprintf(fd, " dataLoaderParams: {\n");
diff --git a/services/incremental/IncrementalService.h b/services/incremental/IncrementalService.h
index 4c4b8bd..eb69470 100644
--- a/services/incremental/IncrementalService.h
+++ b/services/incremental/IncrementalService.h
@@ -257,6 +257,7 @@
} mHealthBase = {TimePoint::max(), kMaxBootClockTsUs};
StorageHealthCheckParams mHealthCheckParams;
int mStreamStatus = content::pm::IDataLoaderStatusListener::STREAM_HEALTHY;
+ std::vector<incfs::ReadInfo> mLastPendingReads;
};
using DataLoaderStubPtr = sp<DataLoaderStub>;
diff --git a/services/incremental/ServiceWrappers.cpp b/services/incremental/ServiceWrappers.cpp
index 144c466..dfe9684 100644
--- a/services/incremental/ServiceWrappers.cpp
+++ b/services/incremental/ServiceWrappers.cpp
@@ -166,6 +166,7 @@
FileId getFileId(const Control& control, std::string_view path) const final {
return incfs::getFileId(control, path);
}
+ std::string toString(FileId fileId) const final { return incfs::toString(fileId); }
std::pair<IncFsBlockIndex, IncFsBlockIndex> countFilledBlocks(
const Control& control, std::string_view path) const final {
const auto fileId = incfs::getFileId(control, path);
diff --git a/services/incremental/ServiceWrappers.h b/services/incremental/ServiceWrappers.h
index 4815caf..f2d0073 100644
--- a/services/incremental/ServiceWrappers.h
+++ b/services/incremental/ServiceWrappers.h
@@ -92,6 +92,7 @@
virtual incfs::RawMetadata getMetadata(const Control& control, FileId fileid) const = 0;
virtual incfs::RawMetadata getMetadata(const Control& control, std::string_view path) const = 0;
virtual FileId getFileId(const Control& control, std::string_view path) const = 0;
+ virtual std::string toString(FileId fileId) const = 0;
virtual std::pair<IncFsBlockIndex, IncFsBlockIndex> countFilledBlocks(
const Control& control, std::string_view path) const = 0;
virtual ErrorCode link(const Control& control, std::string_view from,
diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp
index 867312e..9b8cf40 100644
--- a/services/incremental/test/IncrementalServiceTest.cpp
+++ b/services/incremental/test/IncrementalServiceTest.cpp
@@ -294,6 +294,7 @@
MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, FileId fileid));
MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, std::string_view path));
MOCK_CONST_METHOD2(getFileId, FileId(const Control& control, std::string_view path));
+ MOCK_CONST_METHOD1(toString, std::string(FileId fileId));
MOCK_CONST_METHOD2(countFilledBlocks,
std::pair<IncFsBlockIndex, IncFsBlockIndex>(const Control& control,
std::string_view path));
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index dfa726f..10b3265 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -34,6 +34,7 @@
import android.app.ApplicationErrorReport;
import android.app.INotificationManager;
import android.app.SystemServiceRegistry;
+import android.app.admin.DevicePolicySafetyChecker;
import android.app.usage.UsageStatsManagerInternal;
import android.content.ContentResolver;
import android.content.Context;
@@ -101,6 +102,7 @@
import com.android.server.audio.AudioService;
import com.android.server.biometrics.AuthService;
import com.android.server.biometrics.BiometricService;
+import com.android.server.biometrics.sensors.BiometricServiceCallback;
import com.android.server.biometrics.sensors.face.FaceService;
import com.android.server.biometrics.sensors.fingerprint.FingerprintService;
import com.android.server.biometrics.sensors.iris.IrisService;
@@ -195,8 +197,10 @@
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
+import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.concurrent.CountDownLatch;
@@ -1468,7 +1472,10 @@
}
t.traceEnd();
- if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
+ final DevicePolicyManagerService.Lifecycle dpms;
+ if (mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
+ dpms = null;
+ } else {
t.traceBegin("StartLockSettingsService");
try {
mSystemServiceManager.startService(LOCK_SETTINGS_SERVICE_CLASS);
@@ -1505,7 +1512,7 @@
// Always start the Device Policy Manager, so that the API is compatible with
// API8.
t.traceBegin("StartDevicePolicyManager");
- mSystemServiceManager.startService(DevicePolicyManagerService.Lifecycle.class);
+ dpms = mSystemServiceManager.startService(DevicePolicyManagerService.Lifecycle.class);
t.traceEnd();
if (!isWatch) {
@@ -2089,9 +2096,12 @@
final boolean hasFeatureFingerprint
= mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT);
+ final List<BiometricServiceCallback> biometricServiceCallback = new ArrayList<>();
if (hasFeatureFace) {
t.traceBegin("StartFaceSensor");
- mSystemServiceManager.startService(FaceService.class);
+ final FaceService faceService =
+ mSystemServiceManager.startService(FaceService.class);
+ biometricServiceCallback.add(faceService);
t.traceEnd();
}
@@ -2103,13 +2113,20 @@
if (hasFeatureFingerprint) {
t.traceBegin("StartFingerprintSensor");
- mSystemServiceManager.startService(FingerprintService.class);
+ final FingerprintService fingerprintService =
+ mSystemServiceManager.startService(FingerprintService.class);
+ biometricServiceCallback.add(fingerprintService);
t.traceEnd();
}
- // Start this service after all biometric services.
+ // Start this service after all biometric sensor services are started.
t.traceBegin("StartBiometricService");
mSystemServiceManager.startService(BiometricService.class);
+ for (BiometricServiceCallback service : biometricServiceCallback) {
+ Slog.d(TAG, "Notifying onBiometricServiceReady for: "
+ + service.getClass().getSimpleName());
+ service.onBiometricServiceReady();
+ }
t.traceEnd();
t.traceBegin("StartAuthService");
@@ -2427,6 +2444,9 @@
if (cshs instanceof Dumpable) {
mDumper.addDumpable((Dumpable) cshs);
}
+ if (cshs instanceof DevicePolicySafetyChecker) {
+ dpms.setDevicePolicySafetyChecker((DevicePolicySafetyChecker) cshs);
+ }
t.traceEnd();
}
diff --git a/services/net/Android.bp b/services/net/Android.bp
index 1ccd512..a52fe12 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -22,13 +22,14 @@
// Version of services.net for usage by the wifi mainline module.
// Note: This is compiled against module_current.
-// TODO(b/145825329): This should be moved to networkstack-client,
+// TODO(b/172457099): This should be moved to networkstack-client,
// with dependencies moved to frameworks/libs/net right.
java_library {
name: "services.net-module-wifi",
srcs: [
":framework-services-net-module-wifi-shared-srcs",
":net-module-utils-srcs",
+ ":net-utils-services-common-srcs",
"java/android/net/ip/IpClientCallbacks.java",
"java/android/net/ip/IpClientManager.java",
"java/android/net/ip/IpClientUtil.java",
@@ -39,6 +40,7 @@
"java/android/net/TcpKeepalivePacketData.java",
],
sdk_version: "module_current",
+ min_sdk_version: "30",
libs: [
"unsupportedappusage",
"framework-wifi-util-lib",
@@ -49,7 +51,6 @@
"netd_aidl_interface-V3-java",
"netlink-client",
"networkstack-client",
- "net-utils-services-common",
],
apex_available: [
"com.android.wifi",
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index 1944965..0d878b4 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -28,7 +28,6 @@
import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.SystemProperties;
import android.os.UpdateEngine;
import android.os.UpdateEngineCallback;
import android.provider.DeviceConfig;
@@ -227,8 +226,8 @@
}
// Sample for a fraction of app launches.
- int traceFrequency =
- SystemProperties.getInt("persist.profcollectd.applaunch_trace_freq", 2);
+ int traceFrequency = DeviceConfig.getInt(DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT,
+ "applaunch_trace_freq", 2);
int randomNum = ThreadLocalRandom.current().nextInt(100);
if (randomNum < traceFrequency) {
try {
diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
index da4071b..ebd4a4c 100644
--- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
@@ -191,10 +191,12 @@
RescueParty.onSettingsProviderPublished(mMockContext);
verify(() -> Settings.Config.registerMonitorCallback(eq(mMockContentResolver),
mMonitorCallbackCaptor.capture()));
+ HashMap<String, Integer> verifiedTimesMap = new HashMap<String, Integer>();
noteBoot();
- verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, /*resetNamespaces=*/ null);
+ verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, /*resetNamespaces=*/ null,
+ verifiedTimesMap);
assertEquals(RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS,
SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE));
@@ -208,13 +210,15 @@
noteBoot();
- verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES, expectedAllResetNamespaces);
+ verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES, expectedAllResetNamespaces,
+ verifiedTimesMap);
assertEquals(RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES,
SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE));
noteBoot();
- verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, expectedAllResetNamespaces);
+ verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, expectedAllResetNamespaces,
+ verifiedTimesMap);
assertEquals(RescueParty.LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS,
SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE));
@@ -228,15 +232,18 @@
public void testPersistentAppCrashDetectionWithExecutionForAllRescueLevels() {
notePersistentAppCrash(1);
- verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, /*resetNamespaces=*/ null);
+ verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, /*resetNamespaces=*/ null,
+ /*configResetVerifiedTimesMap=*/ null);
notePersistentAppCrash(2);
- verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES, /*resetNamespaces=*/ null);
+ verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES, /*resetNamespaces=*/ null,
+ /*configResetVerifiedTimesMap=*/ null);
notePersistentAppCrash(3);
- verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, /*resetNamespaces=*/ null);
+ verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, /*resetNamespaces=*/ null,
+ /*configResetVerifiedTimesMap=*/ null);
notePersistentAppCrash(4);
assertTrue(RescueParty.isAttemptingFactoryReset());
@@ -272,17 +279,82 @@
final String[] expectedResetNamespaces = new String[]{NAMESPACE1, NAMESPACE2};
final String[] expectedAllResetNamespaces =
new String[]{NAMESPACE1, NAMESPACE2, NAMESPACE3};
+ HashMap<String, Integer> verifiedTimesMap = new HashMap<String, Integer>();
observer.execute(new VersionedPackage(
CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
- verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, expectedResetNamespaces);
+ verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, expectedResetNamespaces,
+ verifiedTimesMap);
observer.execute(new VersionedPackage(
CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 2);
- verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES, expectedResetNamespaces);
+ verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES, expectedResetNamespaces,
+ verifiedTimesMap);
observer.execute(new VersionedPackage(
CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 3);
- verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, expectedAllResetNamespaces);
+ verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, expectedAllResetNamespaces,
+ verifiedTimesMap);
+
+ observer.execute(new VersionedPackage(
+ CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 4);
+ assertTrue(RescueParty.isAttemptingFactoryReset());
+ }
+
+ @Test
+ public void testNonDeviceConfigSettingsOnlyResetOncePerLevel() {
+ RescueParty.onSettingsProviderPublished(mMockContext);
+ verify(() -> Settings.Config.registerMonitorCallback(eq(mMockContentResolver),
+ mMonitorCallbackCaptor.capture()));
+
+ // Record DeviceConfig accesses
+ RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
+ RemoteCallback monitorCallback = mMonitorCallbackCaptor.getValue();
+ monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE1));
+ monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE2));
+ monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE2));
+ monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE3));
+ // Fake DeviceConfig value changes
+ monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE1));
+ monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE2));
+ monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE3));
+ // Perform and verify scoped resets
+ final String[] expectedPackage1ResetNamespaces = new String[]{NAMESPACE1, NAMESPACE2};
+ final String[] expectedPackage2ResetNamespaces = new String[]{NAMESPACE2, NAMESPACE3};
+ final String[] expectedAllResetNamespaces =
+ new String[]{NAMESPACE1, NAMESPACE2, NAMESPACE3};
+ HashMap<String, Integer> verifiedTimesMap = new HashMap<String, Integer>();
+ observer.execute(new VersionedPackage(
+ CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+ verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS,
+ expectedPackage1ResetNamespaces, verifiedTimesMap);
+
+ // Settings.Global & Settings.Secure should still remain the same execution times.
+ observer.execute(new VersionedPackage(
+ CALLING_PACKAGE2, 1), PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+ verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS,
+ expectedPackage2ResetNamespaces, verifiedTimesMap);
+
+ observer.execute(new VersionedPackage(
+ CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 2);
+ verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES,
+ expectedPackage1ResetNamespaces, verifiedTimesMap);
+
+ // Settings.Global & Settings.Secure should still remain the same execution times.
+ observer.execute(new VersionedPackage(
+ CALLING_PACKAGE2, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 2);
+ verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES,
+ expectedPackage2ResetNamespaces, verifiedTimesMap);
+
+ observer.execute(new VersionedPackage(
+ CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 3);
+ verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, expectedAllResetNamespaces,
+ verifiedTimesMap);
+
+ // Settings.Global & Settings.Secure should still remain the same execution times.
+ observer.execute(new VersionedPackage(
+ CALLING_PACKAGE2, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 3);
+ verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, expectedAllResetNamespaces,
+ verifiedTimesMap);
observer.execute(new VersionedPackage(
CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 4);
@@ -303,7 +375,8 @@
RescueParty.onSettingsProviderPublished(mMockContext);
- verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, /*resetNamespaces=*/ null);
+ verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, /*resetNamespaces=*/ null,
+ /*configResetVerifiedTimesMap=*/ null);
assertEquals(RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS,
SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE));
}
@@ -415,7 +488,8 @@
assertEquals(observer.onBootLoop(), PackageHealthObserverImpact.USER_IMPACT_HIGH);
}
- private void verifySettingsResets(int resetMode, String[] resetNamespaces) {
+ private void verifySettingsResets(int resetMode, String[] resetNamespaces,
+ HashMap<String, Integer> configResetVerifiedTimesMap) {
verify(() -> Settings.Global.resetToDefaultsAsUser(mMockContentResolver, null,
resetMode, UserHandle.USER_SYSTEM));
verify(() -> Settings.Secure.resetToDefaultsAsUser(eq(mMockContentResolver), isNull(),
@@ -425,7 +499,16 @@
verify(() -> DeviceConfig.resetToDefaults(anyInt(), anyString()), never());
} else {
for (String namespace : resetNamespaces) {
- verify(() -> DeviceConfig.resetToDefaults(resetMode, namespace));
+ int verifiedTimes = 0;
+ if (configResetVerifiedTimesMap != null
+ && configResetVerifiedTimesMap.get(namespace) != null) {
+ verifiedTimes = configResetVerifiedTimesMap.get(namespace);
+ }
+ verify(() -> DeviceConfig.resetToDefaults(RescueParty.DEVICE_CONFIG_RESET_MODE,
+ namespace), times(verifiedTimes + 1));
+ if (configResetVerifiedTimesMap != null) {
+ configResetVerifiedTimesMap.put(namespace, verifiedTimes + 1);
+ }
}
}
}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index 3b60594..435c700 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -1456,16 +1456,6 @@
mFingerprintAuthenticator);
}
- @Test(expected = IllegalStateException.class)
- public void testRegistrationWithUnknownId_throwsIllegalStateException() throws Exception {
- mBiometricService = new BiometricService(mContext, mInjector);
- mBiometricService.onStart();
-
- mBiometricService.mImpl.registerAuthenticator(
- 100 /* id */, 2 /* modality */, 15 /* strength */,
- mFingerprintAuthenticator);
- }
-
@Test(expected = IllegalArgumentException.class)
public void testRegistrationWithNullAuthenticator_throwsIllegalArgumentException()
throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/Face10Test.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/Face10Test.java
index b0f7b0c..35fc7f0 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/Face10Test.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/Face10Test.java
@@ -16,22 +16,28 @@
package com.android.server.biometrics.sensors.face;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
import android.hardware.biometrics.BiometricManager;
import android.os.Binder;
import android.os.IBinder;
+import android.os.UserManager;
import android.platform.test.annotations.Presubmit;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
+import com.android.server.biometrics.sensors.face.hidl.Face10;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
+
@Presubmit
@SmallTest
public class Face10Test {
@@ -41,6 +47,8 @@
@Mock
private Context mContext;
+ @Mock
+ private UserManager mUserManager;
private LockoutResetDispatcher mLockoutResetDispatcher;
private com.android.server.biometrics.sensors.face.hidl.Face10 mFace10;
@@ -54,10 +62,13 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
+ when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ when(mUserManager.getAliveUsers()).thenReturn(new ArrayList<>());
+
mLockoutResetDispatcher = new LockoutResetDispatcher(mContext);
- mFace10 = new com.android.server.biometrics.sensors.face.hidl.Face10(mContext, SENSOR_ID,
- BiometricManager.Authenticators.BIOMETRIC_STRONG, mLockoutResetDispatcher,
- false /* supportsSelfIllumination */, 1 /* maxTemplatesAllowed */);
+ mFace10 = new Face10(mContext, SENSOR_ID, BiometricManager.Authenticators.BIOMETRIC_STRONG,
+ mLockoutResetDispatcher, false /* supportsSelfIllumination */,
+ 1 /* maxTemplatesAllowed */);
mBinder = new Binder();
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
index 8af7332..6debc89 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
@@ -74,6 +74,8 @@
when(mContextSpy.getSystemService(PowerManager.class)).thenReturn(powerManager);
when(mIPowerManagerMock.isInteractive()).thenReturn(true);
+ HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(mContextSpy);
+
mHdmiControlService = new HdmiControlService(mContextSpy) {
@Override
AudioManager getAudioManager() {
@@ -104,6 +106,11 @@
void writeStringSystemProperty(String key, String value) {
// do nothing
}
+
+ @Override
+ HdmiCecConfig getHdmiCecConfig() {
+ return hdmiCecConfig;
+ }
};
Looper looper = mTestLooper.getLooper();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
index 37a75e3..a19336e 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
@@ -76,6 +76,8 @@
when(mContextSpy.getSystemService(PowerManager.class)).thenReturn(powerManager);
when(mIPowerManagerMock.isInteractive()).thenReturn(true);
+ HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(mContextSpy);
+
HdmiControlService hdmiControlService =
new HdmiControlService(mContextSpy) {
@Override
@@ -106,6 +108,11 @@
Looper getServiceLooper() {
return mTestLooper.getLooper();
}
+
+ @Override
+ HdmiCecConfig getHdmiCecConfig() {
+ return hdmiCecConfig;
+ }
};
mHdmiCecLocalDeviceAudioSystem = new HdmiCecLocalDeviceAudioSystem(hdmiControlService) {
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
index 6027c3e..cd69775 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
@@ -77,6 +77,8 @@
when(mContextSpy.getSystemService(PowerManager.class)).thenReturn(powerManager);
when(mIPowerManagerMock.isInteractive()).thenReturn(true);
+ HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(mContextSpy);
+
HdmiControlService hdmiControlService =
new HdmiControlService(mContextSpy) {
@Override
@@ -107,6 +109,11 @@
Looper getServiceLooper() {
return mTestLooper.getLooper();
}
+
+ @Override
+ HdmiCecConfig getHdmiCecConfig() {
+ return hdmiCecConfig;
+ }
};
Looper looper = mTestLooper.getLooper();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java b/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java
index fb6266d..52899fa 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java
@@ -31,26 +31,35 @@
import javax.xml.datatype.DatatypeConfigurationException;
/**
- * Fake class which loads default system configuration with user-configurable
- * settings (useful for testing).
+ * Fake class which loads default system configuration with user-configurable
+ * settings (useful for testing).
*/
final class FakeHdmiCecConfig extends HdmiCecConfig {
private static final String TAG = "FakeHdmiCecConfig";
private static final String SYSTEM_CONFIG_XML =
"<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
- + "<cec-settings>"
- + " <setting name=\"send_standby_on_sleep\""
- + " value-type=\"string\""
- + " user-configurable=\"true\">"
- + " <allowed-values>"
- + " <value string-value=\"to_tv\" />"
- + " <value string-value=\"broadcast\" />"
- + " <value string-value=\"none\" />"
- + " </allowed-values>"
- + " <default-value string-value=\"to_tv\" />"
- + " </setting>"
- + "</cec-settings>";
+ + "<cec-settings>"
+ + " <setting name=\"send_standby_on_sleep\""
+ + " value-type=\"string\""
+ + " user-configurable=\"true\">"
+ + " <allowed-values>"
+ + " <value string-value=\"to_tv\" />"
+ + " <value string-value=\"broadcast\" />"
+ + " <value string-value=\"none\" />"
+ + " </allowed-values>"
+ + " <default-value string-value=\"to_tv\" />"
+ + " </setting>"
+ + " <setting name=\"hdmi_cec_version\""
+ + " value-type=\"int\""
+ + " user-configurable=\"true\">"
+ + " <allowed-values>"
+ + " <value int-value=\"0x05\" />"
+ + " <value int-value=\"0x06\" />"
+ + " </allowed-values>"
+ + " <default-value int-value=\"0x05\" />"
+ + " </setting>"
+ + "</cec-settings>";
FakeHdmiCecConfig(@NonNull Context context) {
super(context, new StorageAdapter(), parseFromString(SYSTEM_CONFIG_XML), null);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
index a27f733..dd74f22 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
@@ -1006,22 +1006,22 @@
HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
mContext, mStorageAdapter,
"<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
- + "<cec-settings>"
- + " <setting name=\"system_audio_mode_muting\""
- + " value-type=\"int\""
- + " user-configurable=\"true\">"
- + " <allowed-values>"
- + " <value int-value=\"0\" />"
- + " <value int-value=\"1\" />"
- + " </allowed-values>"
- + " <default-value int-value=\"1\" />"
- + " </setting>"
- + "</cec-settings>", null);
+ + "<cec-settings>"
+ + " <setting name=\"system_audio_mode_muting\""
+ + " value-type=\"int\""
+ + " user-configurable=\"true\">"
+ + " <allowed-values>"
+ + " <value int-value=\"0\" />"
+ + " <value int-value=\"1\" />"
+ + " </allowed-values>"
+ + " <default-value int-value=\"1\" />"
+ + " </setting>"
+ + "</cec-settings>", null);
hdmiCecConfig.setIntValue(
- HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
- HdmiControlManager.SYSTEM_AUDIO_MODE_MUTING_DISABLED);
+ HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
+ HdmiControlManager.SYSTEM_AUDIO_MODE_MUTING_DISABLED);
verify(mStorageAdapter).storeSystemProperty(
- HdmiCecConfig.SYSPROP_SYSTEM_AUDIO_MODE_MUTING,
- Integer.toString(HdmiControlManager.SYSTEM_AUDIO_MODE_MUTING_DISABLED));
+ HdmiCecConfig.SYSPROP_SYSTEM_AUDIO_MODE_MUTING,
+ Integer.toString(HdmiControlManager.SYSTEM_AUDIO_MODE_MUTING_DISABLED));
}
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java
index 81c3be5..0a3d545 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java
@@ -32,6 +32,7 @@
import static junit.framework.Assert.assertEquals;
import android.content.Context;
+import android.hardware.hdmi.HdmiControlManager;
import android.hardware.tv.cec.V1_0.SendMessageResult;
import android.os.Looper;
import android.os.test.TestLooper;
@@ -78,7 +79,7 @@
}
private HdmiCecController mHdmiCecController;
- private int mCecVersion = Constants.VERSION_1_4;
+ private int mCecVersion = HdmiControlManager.HDMI_CEC_VERSION_1_4_b;
private int mLogicalAddress = 16;
private AllocateAddressCallback mCallback =
new AllocateAddressCallback() {
@@ -202,7 +203,7 @@
@Test
public void testAllocateLogicalAddress_PlaybackNonPreferred_2_0_BackupOne() {
- mCecVersion = Constants.VERSION_2_0;
+ mCecVersion = HdmiControlManager.HDMI_CEC_VERSION_2_0;
mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS);
mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_2, SendMessageResult.SUCCESS);
@@ -214,7 +215,7 @@
@Test
public void testAllocateLogicalAddress_PlaybackNonPreferred_2_0_BackupTwo() {
- mCecVersion = Constants.VERSION_2_0;
+ mCecVersion = HdmiControlManager.HDMI_CEC_VERSION_2_0;
mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS);
mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_2, SendMessageResult.SUCCESS);
@@ -245,7 +246,7 @@
@Test
public void testAllocateLogicalAddress_PlaybackNonPreferred_2_0_AllOccupied() {
- mCecVersion = Constants.VERSION_2_0;
+ mCecVersion = HdmiControlManager.HDMI_CEC_VERSION_2_0;
mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS);
mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_2, SendMessageResult.SUCCESS);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
index 433f6e7..2553094 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
@@ -96,6 +96,9 @@
mMyLooper = mTestLooper.getLooper();
PowerManager powerManager = new PowerManager(context, mIPowerManagerMock,
mIThermalServiceMock, new Handler(mMyLooper));
+
+ HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(context);
+
mHdmiControlService =
new HdmiControlService(InstrumentationRegistry.getTargetContext()) {
@Override
@@ -184,6 +187,11 @@
PowerManager getPowerManager() {
return powerManager;
}
+
+ @Override
+ HdmiCecConfig getHdmiCecConfig() {
+ return hdmiCecConfig;
+ }
};
mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index 647da95..9646b5d 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -82,6 +82,8 @@
mMyLooper = mTestLooper.getLooper();
PowerManager powerManager = new PowerManager(context, mIPowerManagerMock,
mIThermalServiceMock, new Handler(mMyLooper));
+ HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(context);
+
mHdmiControlService =
new HdmiControlService(InstrumentationRegistry.getTargetContext()) {
@Override
@@ -114,11 +116,16 @@
return false;
}
- @Override
- PowerManager getPowerManager() {
- return powerManager;
- }
- };
+ @Override
+ PowerManager getPowerManager() {
+ return powerManager;
+ }
+
+ @Override
+ HdmiCecConfig getHdmiCecConfig() {
+ return hdmiCecConfig;
+ }
+ };
mHdmiCecLocalDevicePlayback = new HdmiCecLocalDevicePlayback(mHdmiControlService);
mHdmiCecLocalDevicePlayback.init();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
index aa72d07..12414d9 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -72,6 +72,9 @@
mMyLooper = mTestLooper.getLooper();
PowerManager powerManager = new PowerManager(context, mIPowerManagerMock,
mIThermalServiceMock, new Handler(mMyLooper));
+
+ HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(context);
+
mHdmiControlService =
new HdmiControlService(InstrumentationRegistry.getTargetContext()) {
@Override
@@ -93,6 +96,11 @@
PowerManager getPowerManager() {
return powerManager;
}
+
+ @Override
+ HdmiCecConfig getHdmiCecConfig() {
+ return hdmiCecConfig;
+ }
};
mHdmiCecLocalDeviceTv = new HdmiCecLocalDeviceTv(mHdmiControlService);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
index c1532f2..0e9f01a 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
@@ -371,6 +371,147 @@
assertMessageValidity("0F:A6").isEqualTo(ERROR_PARAMETER_SHORT);
}
+ @Test
+ public void isValid_deckControl() {
+ assertMessageValidity("40:42:01:6E").isEqualTo(OK);
+ assertMessageValidity("40:42:04").isEqualTo(OK);
+
+ assertMessageValidity("4F:42:01").isEqualTo(ERROR_DESTINATION);
+ assertMessageValidity("F0:42:04").isEqualTo(ERROR_SOURCE);
+ assertMessageValidity("40:42").isEqualTo(ERROR_PARAMETER_SHORT);
+ assertMessageValidity("40:42:05").isEqualTo(ERROR_PARAMETER);
+ }
+
+ @Test
+ public void isValid_deckStatus() {
+ assertMessageValidity("40:1B:11:58").isEqualTo(OK);
+ assertMessageValidity("40:1B:1F").isEqualTo(OK);
+
+ assertMessageValidity("4F:1B:11").isEqualTo(ERROR_DESTINATION);
+ assertMessageValidity("F0:1B:1F").isEqualTo(ERROR_SOURCE);
+ assertMessageValidity("40:1B").isEqualTo(ERROR_PARAMETER_SHORT);
+ assertMessageValidity("40:1B:10").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:1B:20").isEqualTo(ERROR_PARAMETER);
+ }
+
+ @Test
+ public void isValid_statusRequest() {
+ assertMessageValidity("40:08:01").isEqualTo(OK);
+ assertMessageValidity("40:08:02:5C").isEqualTo(OK);
+ assertMessageValidity("40:1A:01:F8").isEqualTo(OK);
+ assertMessageValidity("40:1A:03").isEqualTo(OK);
+
+ assertMessageValidity("4F:08:01").isEqualTo(ERROR_DESTINATION);
+ assertMessageValidity("F0:08:03").isEqualTo(ERROR_SOURCE);
+ assertMessageValidity("4F:1A:01").isEqualTo(ERROR_DESTINATION);
+ assertMessageValidity("F0:1A:03").isEqualTo(ERROR_SOURCE);
+ assertMessageValidity("40:08").isEqualTo(ERROR_PARAMETER_SHORT);
+ assertMessageValidity("40:1A").isEqualTo(ERROR_PARAMETER_SHORT);
+ assertMessageValidity("40:08:00").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:08:05").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:1A:00").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:1A:04").isEqualTo(ERROR_PARAMETER);
+ }
+
+ @Test
+ public void isValid_play() {
+ assertMessageValidity("40:41:16:E3").isEqualTo(OK);
+ assertMessageValidity("40:41:20").isEqualTo(OK);
+
+ assertMessageValidity("4F:41:16").isEqualTo(ERROR_DESTINATION);
+ assertMessageValidity("F0:41:20").isEqualTo(ERROR_SOURCE);
+ assertMessageValidity("40:41").isEqualTo(ERROR_PARAMETER_SHORT);
+ assertMessageValidity("40:41:04").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:41:18").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:41:23").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:41:26").isEqualTo(ERROR_PARAMETER);
+ }
+
+ @Test
+ public void isValid_selectAnalogueService() {
+ assertMessageValidity("40:92:00:13:0F:00:96").isEqualTo(OK);
+ assertMessageValidity("40:92:02:EA:60:1F").isEqualTo(OK);
+
+ assertMessageValidity("4F:92:00:13:0F:00").isEqualTo(ERROR_DESTINATION);
+ assertMessageValidity("F0:92:02:EA:60:1F").isEqualTo(ERROR_SOURCE);
+ assertMessageValidity("40:92:00:13:0F").isEqualTo(ERROR_PARAMETER_SHORT);
+ // Invalid Analogue Broadcast type
+ assertMessageValidity("40:92:03:EA:60:1F").isEqualTo(ERROR_PARAMETER);
+ // Invalid Analogue Frequency
+ assertMessageValidity("40:92:00:FF:FF:00").isEqualTo(ERROR_PARAMETER);
+ // Invalid Broadcast system
+ assertMessageValidity("40:92:02:EA:60:20").isEqualTo(ERROR_PARAMETER);
+ }
+
+ @Test
+ public void isValid_selectDigitalService() {
+ assertMessageValidity("40:93:00:11:CE:90:0F:00:78").isEqualTo(OK);
+ assertMessageValidity("40:93:10:13:0B:34:38").isEqualTo(OK);
+ assertMessageValidity("40:93:9A:06:F9:D3:E6").isEqualTo(OK);
+ assertMessageValidity("40:93:91:09:F4:40:C8").isEqualTo(OK);
+
+ assertMessageValidity("4F:93:00:11:CE:90:0F:00:78").isEqualTo(ERROR_DESTINATION);
+ assertMessageValidity("F0:93:10:13:0B:34:38").isEqualTo(ERROR_SOURCE);
+ assertMessageValidity("40:93:9A:06:F9").isEqualTo(ERROR_PARAMETER_SHORT);
+ // Invalid Digital Broadcast System
+ assertMessageValidity("40:93:14:11:CE:90:0F:00:78").isEqualTo(ERROR_PARAMETER);
+ // Invalid Digital Broadcast System
+ assertMessageValidity("40:93:A0:07:95:F1").isEqualTo(ERROR_PARAMETER);
+ // Insufficient data for ARIB Broadcast system
+ assertMessageValidity("40:93:00:11:CE:90:0F:00").isEqualTo(ERROR_PARAMETER);
+ // Insufficient data for ATSC Broadcast system
+ assertMessageValidity("40:93:10:13:0B:34").isEqualTo(ERROR_PARAMETER);
+ // Insufficient data for DVB Broadcast system
+ assertMessageValidity("40:93:18:BE:77:00:7D:01").isEqualTo(ERROR_PARAMETER);
+ // Invalid channel number format
+ assertMessageValidity("40:93:9A:10:F9:D3").isEqualTo(ERROR_PARAMETER);
+ // Insufficient data for 2 part channel number
+ assertMessageValidity("40:93:91:09:F4:40").isEqualTo(ERROR_PARAMETER);
+ }
+
+ @Test
+ public void isValid_UserControlPressed() {
+ assertMessageValidity("40:44:07").isEqualTo(OK);
+ assertMessageValidity("40:44:52:A7").isEqualTo(OK);
+
+ assertMessageValidity("40:44:60").isEqualTo(OK);
+ assertMessageValidity("40:44:60:1A").isEqualTo(OK);
+
+ assertMessageValidity("40:44:67").isEqualTo(OK);
+ assertMessageValidity("40:44:67:04:00:B1").isEqualTo(OK);
+ assertMessageValidity("40:44:67:09:C8:72:C8").isEqualTo(OK);
+
+ assertMessageValidity("40:44:68").isEqualTo(OK);
+ assertMessageValidity("40:44:68:93").isEqualTo(OK);
+ assertMessageValidity("40:44:69").isEqualTo(OK);
+ assertMessageValidity("40:44:69:7C").isEqualTo(OK);
+ assertMessageValidity("40:44:6A").isEqualTo(OK);
+ assertMessageValidity("40:44:6A:B4").isEqualTo(OK);
+
+ assertMessageValidity("40:44:56").isEqualTo(OK);
+ assertMessageValidity("40:44:56:60").isEqualTo(OK);
+
+ assertMessageValidity("40:44:57").isEqualTo(OK);
+ assertMessageValidity("40:44:57:A0").isEqualTo(OK);
+
+ assertMessageValidity("4F:44:07").isEqualTo(ERROR_DESTINATION);
+ assertMessageValidity("F0:44:52:A7").isEqualTo(ERROR_SOURCE);
+ assertMessageValidity("40:44").isEqualTo(ERROR_PARAMETER_SHORT);
+ assertMessageValidity("40:44:67:04:B1").isEqualTo(ERROR_PARAMETER_SHORT);
+ // Invalid Play mode
+ assertMessageValidity("40:44:60:04").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:44:60:08").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:44:60:26").isEqualTo(ERROR_PARAMETER);
+ // Invalid Channel Identifier - Channel number format
+ assertMessageValidity("40:44:67:11:8A:42").isEqualTo(ERROR_PARAMETER);
+ // Insufficient data for 2 - part channel number
+ assertMessageValidity("40:44:67:09:C8:72").isEqualTo(ERROR_PARAMETER);
+ // Invalid UI Broadcast type
+ assertMessageValidity("40:44:56:11").isEqualTo(ERROR_PARAMETER);
+ // Invalid UI Sound Presentation Control
+ assertMessageValidity("40:44:57:40").isEqualTo(ERROR_PARAMETER);
+ }
+
private IntegerSubject assertMessageValidity(String message) {
return assertThat(mHdmiCecMessageValidator.isValid(buildMessage(message)));
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
index dea3896..2e4bed9 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
@@ -142,11 +142,18 @@
when(mContextSpy.getSystemService(Context.POWER_SERVICE)).thenReturn(powerManager);
when(mIPowerManagerMock.isInteractive()).thenReturn(true);
+ HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(mContextSpy);
+
mHdmiControlService = new HdmiControlService(mContextSpy) {
@Override
boolean isStandbyMessageReceived() {
return mStandbyMessageReceived;
}
+
+ @Override
+ HdmiCecConfig getHdmiCecConfig() {
+ return hdmiCecConfig;
+ }
};
mMyLooper = mTestLooper.getLooper();
@@ -390,42 +397,52 @@
Settings.Global.HDMI_CEC_VERSION,
null);
mHdmiControlService.setControlEnabled(true);
- assertThat(mHdmiControlService.getCecVersion()).isEqualTo(Constants.VERSION_1_4);
+ assertThat(mHdmiControlService.getCecVersion()).isEqualTo(
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b);
}
@Test
public void getCecVersion_1_4() {
- Settings.Global.putInt(mContextSpy.getContentResolver(), Settings.Global.HDMI_CEC_VERSION,
- Constants.VERSION_1_4);
+ mHdmiControlService.getHdmiCecConfig().setIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b);
mHdmiControlService.setControlEnabled(true);
- assertThat(mHdmiControlService.getCecVersion()).isEqualTo(Constants.VERSION_1_4);
+ assertThat(mHdmiControlService.getCecVersion()).isEqualTo(
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b);
}
@Test
public void getCecVersion_2_0() {
- Settings.Global.putInt(mContextSpy.getContentResolver(), Settings.Global.HDMI_CEC_VERSION,
- Constants.VERSION_2_0);
+ mHdmiControlService.getHdmiCecConfig().setIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
+ HdmiControlManager.HDMI_CEC_VERSION_2_0);
mHdmiControlService.setControlEnabled(true);
- assertThat(mHdmiControlService.getCecVersion()).isEqualTo(Constants.VERSION_2_0);
+ assertThat(mHdmiControlService.getCecVersion()).isEqualTo(
+ HdmiControlManager.HDMI_CEC_VERSION_2_0);
}
@Test
public void getCecVersion_change() {
- Settings.Global.putInt(mContextSpy.getContentResolver(), Settings.Global.HDMI_CEC_VERSION,
- Constants.VERSION_1_4);
+ mHdmiControlService.getHdmiCecConfig().setIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b);
mHdmiControlService.setControlEnabled(true);
- assertThat(mHdmiControlService.getCecVersion()).isEqualTo(Constants.VERSION_1_4);
+ assertThat(mHdmiControlService.getCecVersion()).isEqualTo(
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b);
- Settings.Global.putInt(mContextSpy.getContentResolver(), Settings.Global.HDMI_CEC_VERSION,
- Constants.VERSION_2_0);
+ mHdmiControlService.getHdmiCecConfig().setIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
+ HdmiControlManager.HDMI_CEC_VERSION_2_0);
mHdmiControlService.setControlEnabled(true);
- assertThat(mHdmiControlService.getCecVersion()).isEqualTo(Constants.VERSION_2_0);
+ assertThat(mHdmiControlService.getCecVersion()).isEqualTo(
+ HdmiControlManager.HDMI_CEC_VERSION_2_0);
}
@Test
public void handleGiveFeatures_cec14_featureAbort() {
- Settings.Global.putInt(mContextSpy.getContentResolver(), Settings.Global.HDMI_CEC_VERSION,
- Constants.VERSION_1_4);
+ mHdmiControlService.getHdmiCecConfig().setIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b);
mHdmiControlService.setControlEnabled(true);
mTestLooper.dispatchAll();
@@ -441,8 +458,9 @@
@Test
public void handleGiveFeatures_cec20_reportsFeatures() {
- Settings.Global.putInt(mContextSpy.getContentResolver(), Settings.Global.HDMI_CEC_VERSION,
- Constants.VERSION_2_0);
+ mHdmiControlService.getHdmiCecConfig().setIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
+ HdmiControlManager.HDMI_CEC_VERSION_2_0);
mHdmiControlService.setControlEnabled(true);
mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
mTestLooper.dispatchAll();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiUtilsTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiUtilsTest.java
index a8f3acf..dbf3b53 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiUtilsTest.java
@@ -20,6 +20,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.platform.test.annotations.Presubmit;
import android.util.Slog;
@@ -533,69 +534,84 @@
@Test
public void isEligibleAddressForCecVersion_1_4() {
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b,
Constants.ADDR_TV)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b,
Constants.ADDR_RECORDER_1)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b,
Constants.ADDR_RECORDER_2)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b,
Constants.ADDR_TUNER_1)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b,
Constants.ADDR_PLAYBACK_1)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b,
Constants.ADDR_AUDIO_SYSTEM)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b,
Constants.ADDR_TUNER_2)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b,
Constants.ADDR_TUNER_3)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b,
Constants.ADDR_PLAYBACK_2)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b,
Constants.ADDR_RECORDER_3)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b,
Constants.ADDR_TUNER_4)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b,
Constants.ADDR_PLAYBACK_3)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b,
Constants.ADDR_BACKUP_1)).isFalse();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b,
Constants.ADDR_BACKUP_2)).isFalse();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(
+ HdmiControlManager.HDMI_CEC_VERSION_1_4_b,
Constants.ADDR_SPECIFIC_USE)).isTrue();
}
@Test
public void isEligibleAddressForCecVersion_2_0() {
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0,
Constants.ADDR_TV)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0,
Constants.ADDR_RECORDER_1)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0,
Constants.ADDR_RECORDER_2)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0,
Constants.ADDR_TUNER_1)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0,
Constants.ADDR_PLAYBACK_1)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0,
Constants.ADDR_AUDIO_SYSTEM)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0,
Constants.ADDR_TUNER_2)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0,
Constants.ADDR_TUNER_3)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0,
Constants.ADDR_PLAYBACK_2)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0,
Constants.ADDR_RECORDER_3)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0,
Constants.ADDR_TUNER_4)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0,
Constants.ADDR_PLAYBACK_3)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0,
Constants.ADDR_BACKUP_1)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0,
Constants.ADDR_BACKUP_2)).isTrue();
- assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0,
+ assertThat(HdmiUtils.isEligibleAddressForCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0,
Constants.ADDR_SPECIFIC_USE)).isTrue();
}
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
index 0e4bfab..0a225a0 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
@@ -21,6 +21,7 @@
import static org.junit.Assert.assertTrue;
import android.annotation.Nullable;
+import android.content.Context;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.tv.cec.V1_0.SendMessageResult;
import android.media.AudioManager;
@@ -61,9 +62,12 @@
@Before
public void SetUp() {
mDeviceInfoForTests = new HdmiDeviceInfo(1001, 1234);
- HdmiControlService hdmiControlService =
- new HdmiControlService(InstrumentationRegistry.getTargetContext()) {
+ Context context = InstrumentationRegistry.getTargetContext();
+
+ HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(context);
+
+ HdmiControlService hdmiControlService = new HdmiControlService(context) {
@Override
void sendCecCommand(
HdmiCecMessage command, @Nullable SendMessageCallback callback) {
@@ -156,6 +160,11 @@
int pathToPortId(int path) {
return -1;
}
+
+ @Override
+ HdmiCecConfig getHdmiCecConfig() {
+ return hdmiCecConfig;
+ }
};
Looper looper = mTestLooper.getLooper();
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 cf7f741..7b9ccae 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -1127,7 +1127,8 @@
topActivity.setState(RESUMED, "true");
doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible(
any() /* starting */, anyInt() /* configChanges */,
- anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */);
+ anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */,
+ anyBoolean() /* userLeaving */);
topActivity.setShowWhenLocked(true);
// Verify the stack-top activity is occluded keyguard.
@@ -1173,7 +1174,7 @@
secondActivity.completeFinishing("test");
verify(secondActivity.mDisplayContent).ensureActivitiesVisible(null /* starting */,
0 /* configChanges */ , false /* preserveWindows */,
- true /* notifyClients */);
+ true /* notifyClients */, false /* userLeaving */);
// Finish the first activity
firstActivity.finishing = true;
@@ -1181,7 +1182,7 @@
firstActivity.completeFinishing("test");
verify(firstActivity.mDisplayContent, times(2)).ensureActivitiesVisible(null /* starting */,
0 /* configChanges */ , false /* preserveWindows */,
- true /* notifyClients */);
+ true /* notifyClients */, false /* userLeaving */);
}
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
index 28d5ffe..f77454d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -437,7 +437,7 @@
false /* newTask */, false /* keepCurTransition */, null /* options */);
middle.makeFinishingLocked();
- assertNull(mActivity.startingWindow);
+ assertNull(mActivity.mStartingWindow);
assertHasStartingWindow(middle);
final ActivityRecord top = new ActivityBuilder(mWm.mAtmService)
@@ -449,7 +449,7 @@
mStack.startActivityLocked(top, null /* focusedTopActivity */,
false /* newTask */, false /* keepCurTransition */, null /* options */);
- assertNull(middle.startingWindow);
+ assertNull(middle.mStartingWindow);
assertHasStartingWindow(top);
assertTrue(top.isVisible());
// The activity was visible by mVisibleSetFromTransferredStartingWindow, so after its
@@ -573,14 +573,14 @@
}
private void assertHasStartingWindow(ActivityRecord atoken) {
- assertNotNull(atoken.startingSurface);
+ assertNotNull(atoken.mStartingSurface);
assertNotNull(atoken.mStartingData);
- assertNotNull(atoken.startingWindow);
+ assertNotNull(atoken.mStartingWindow);
}
private void assertNoStartingWindow(ActivityRecord atoken) {
- assertNull(atoken.startingSurface);
- assertNull(atoken.startingWindow);
+ assertNull(atoken.mStartingSurface);
+ assertNull(atoken.mStartingWindow);
assertNull(atoken.mStartingData);
atoken.forAllWindows(windowState -> {
assertFalse(windowState.getBaseType() == TYPE_APPLICATION_STARTING);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index fbfc0e0..dc33b75 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -1533,11 +1533,12 @@
// The assertion will fail if DisplayArea#ensureActivitiesVisible is called twice.
assertFalse(called[0]);
called[0] = true;
- mDisplayContent.ensureActivitiesVisible(null, 0, false, false);
+ mDisplayContent.ensureActivitiesVisible(null, 0, false, false, false);
return null;
- }).when(mockTda).ensureActivitiesVisible(any(), anyInt(), anyBoolean(), anyBoolean());
+ }).when(mockTda).ensureActivitiesVisible(any(), anyInt(), anyBoolean(), anyBoolean(),
+ anyBoolean());
- mDisplayContent.ensureActivitiesVisible(null, 0, false, false);
+ mDisplayContent.ensureActivitiesVisible(null, 0, false, false, false);
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index d348389..80bffd1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -294,7 +294,7 @@
}).when(mSupervisor).endActivityVisibilityUpdate();
mTaskContainer.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
- false /* preserveWindows */, false /* notifyClients */);
+ false /* preserveWindows */, false /* notifyClients */, false /* userLeaving */);
assertFalse(mSupervisor.inActivityVisibilityUpdate());
assertThat(mCallbacksRecorder.mAdded).hasSize(2);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index 137cedd..5427470 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -100,7 +100,8 @@
doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible(
any() /* starting */, anyInt() /* configChanges */,
- anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */);
+ anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */,
+ anyBoolean() /* userLeaving */);
RecentsAnimationCallbacks recentsAnimation = startRecentsActivity(
mRecentsComponent, true /* getRecentsAnimation */);
@@ -191,7 +192,8 @@
doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible(
any() /* starting */, anyInt() /* configChanges */,
- anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */);
+ anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */,
+ anyBoolean() /* userLeaving */);
doReturn(app).when(mAtm).getProcessController(eq(recentActivity.processName), anyInt());
ClientLifecycleManager lifecycleManager = mAtm.getLifecycleManager();
doNothing().when(lifecycleManager).scheduleTransaction(any());
@@ -347,7 +349,8 @@
doReturn(TEST_USER_ID).when(mAtm).getCurrentUserId();
doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible(
any() /* starting */, anyInt() /* configChanges */,
- anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */);
+ anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */,
+ anyBoolean() /* userLeaving */);
startRecentsActivity(otherUserHomeActivity.getTask().getBaseIntent().getComponent(),
true);
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index a79a519..a8c24c9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -297,7 +297,7 @@
doReturn(true).when(mWmService.mRoot).hasAwakeDisplay();
// Called when moving activity to pinned stack.
doNothing().when(mWmService.mRoot).ensureActivitiesVisible(any(),
- anyInt(), anyBoolean(), anyBoolean());
+ anyInt(), anyBoolean(), anyBoolean(), anyBoolean());
spyOn(mWmService.mDisplayWindowSettings);
// Setup factory classes to prevent calls to native code.
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index db5c796..eb5f1f9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -117,7 +117,7 @@
window = WindowTestsBase.createWindow(null, TYPE_APPLICATION_STARTING, activity,
"Starting window", 0 /* ownerId */, 0 /* userId*/, false /* internalWindows */,
wm, mock(Session.class), iWindow, mPowerManagerWrapper);
- activity.startingWindow = window;
+ activity.mStartingWindow = window;
}
if (mRunnableWhenAddingSplashScreen != null) {
mRunnableWhenAddingSplashScreen.run();
@@ -126,7 +126,7 @@
return () -> {
synchronized (wm.mGlobalLock) {
activity.removeChild(window);
- activity.startingWindow = null;
+ activity.mStartingWindow = null;
}
};
}
@@ -173,10 +173,6 @@
}
@Override
- public void applyKeyguardPolicyLw(WindowState win, WindowState imeTarget) {
- }
-
- @Override
public void setAllowLockscreenWhenOn(int displayId, boolean allow) {
}
@@ -395,9 +391,4 @@
public boolean canDismissBootAnimation() {
return true;
}
-
- @Override
- public boolean setAodShowing(boolean aodShowing) {
- return false;
- }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 7a41c02..8fe65eb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -506,6 +506,14 @@
public void testTileAddRemoveChild() {
ITaskOrganizer listener = new ITaskOrganizer.Stub() {
@Override
+ public void addStartingWindow(ActivityManager.RunningTaskInfo info, IBinder appToken) {
+
+ }
+
+ @Override
+ public void removeStartingWindow(ActivityManager.RunningTaskInfo info) { }
+
+ @Override
public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) { }
@Override
@@ -563,6 +571,14 @@
final boolean[] called = {false};
ITaskOrganizer listener = new ITaskOrganizer.Stub() {
@Override
+ public void addStartingWindow(ActivityManager.RunningTaskInfo info, IBinder appToken) {
+
+ }
+
+ @Override
+ public void removeStartingWindow(ActivityManager.RunningTaskInfo info) { }
+
+ @Override
public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) { }
@Override
@@ -626,6 +642,14 @@
final ArrayMap<IBinder, RunningTaskInfo> lastReportedTiles = new ArrayMap<>();
ITaskOrganizer listener = new ITaskOrganizer.Stub() {
@Override
+ public void addStartingWindow(ActivityManager.RunningTaskInfo info, IBinder appToken) {
+
+ }
+
+ @Override
+ public void removeStartingWindow(ActivityManager.RunningTaskInfo info) { }
+
+ @Override
public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) { }
@Override
@@ -763,6 +787,10 @@
RunningTaskInfo mInfo;
@Override
+ public void addStartingWindow(ActivityManager.RunningTaskInfo info, IBinder appToken) { }
+ @Override
+ public void removeStartingWindow(ActivityManager.RunningTaskInfo info) { }
+ @Override
public void onTaskAppeared(RunningTaskInfo info, SurfaceControl leash) {
mInfo = info;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 88a3f97..75d2c51 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -178,9 +178,9 @@
final WindowState overlayWindow = spy(createWindow(null, TYPE_APPLICATION_OVERLAY,
"overlayWindow"));
overlayWindow.setHiddenWhileSuspended(true);
- verify(overlayWindow).hideLw(true, true);
+ verify(overlayWindow).hide(true /* doAnimation */, true /* requestAnim */);
overlayWindow.setHiddenWhileSuspended(false);
- verify(overlayWindow).showLw(true, true);
+ verify(overlayWindow).show(true /* doAnimation */, true /* requestAnim */);
}
@Test
@@ -205,7 +205,7 @@
final WindowState window = createWindow(null, TYPE_APPLICATION, "window");
window.setHasSurface(true);
assertTrue(window.isOnScreen());
- window.hideLw(false /* doAnimation */);
+ window.hide(false /* doAnimation */, false /* requestAnim */);
assertFalse(window.isOnScreen());
}
@@ -242,8 +242,8 @@
appWindow.mActivityRecord.setWindowingMode(initialMode);
// Make windows invisible
- appWindow.hideLw(false /* doAnimation */);
- imeWindow.hideLw(false /* doAnimation */);
+ appWindow.hide(false /* doAnimation */, false /* requestAnim */);
+ imeWindow.hide(false /* doAnimation */, false /* requestAnim */);
// Invisible window can't be IME targets even if they have the right flags.
assertFalse(appWindow.canBeImeTarget());
@@ -551,7 +551,7 @@
TYPE_BASE_APPLICATION, "startingApp");
final WindowState startingWindow = createWindow(null /* parent */,
TYPE_APPLICATION_STARTING, startingApp.mToken, "starting");
- startingApp.mActivityRecord.startingWindow = startingWindow;
+ startingApp.mActivityRecord.mStartingWindow = startingWindow;
final WindowState keyguardHostWindow = mNotificationShadeWindow;
final WindowState allDrawnApp = mAppWindow;
allDrawnApp.mActivityRecord.allDrawn = true;
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index d5fb3c5..6e20c62 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -348,7 +348,7 @@
win.mRelayoutCalled = true;
win.mHasSurface = true;
win.mHidden = false;
- win.showLw(false /* doAnimation */, false /* requestAnim */);
+ win.show(false /* doAnimation */, false /* requestAnim */);
}
}
@@ -1075,6 +1075,12 @@
mMoveToSecondaryOnEnter = move;
}
@Override
+ public void addStartingWindow(ActivityManager.RunningTaskInfo info, IBinder appToken) {
+ }
+ @Override
+ public void removeStartingWindow(ActivityManager.RunningTaskInfo info) {
+ }
+ @Override
public void onTaskAppeared(ActivityManager.RunningTaskInfo info, SurfaceControl leash) {
}
@Override
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index 64f8c58..632ad4c 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -1140,6 +1140,25 @@
}
/**
+ * Stops and unloads all models. This is intended as a clean-up call with the expectation that
+ * this instance is not used after.
+ * @hide
+ */
+ public void detach() {
+ synchronized (mLock) {
+ for (ModelData model : mModelDataMap.values()) {
+ forceStopAndUnloadModelLocked(model, null);
+ }
+ mModelDataMap.clear();
+ internalClearGlobalStateLocked();
+ if (mModule != null) {
+ mModule.detach();
+ mModule = null;
+ }
+ }
+ }
+
+ /**
* Stops and unloads a sound model, and removes any reference to the model if successful.
*
* @param modelData The model data to remove.
@@ -1170,7 +1189,7 @@
}
if (modelData.isModelStarted()) {
Slog.d(TAG, "Stopping previously started dangling model " + modelData.getHandle());
- if (mModule.stopRecognition(modelData.getHandle()) != STATUS_OK) {
+ if (mModule.stopRecognition(modelData.getHandle()) == STATUS_OK) {
modelData.setStopped();
modelData.setRequested(false);
} else {
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerInternal.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerInternal.java
index f77d490..a976257 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerInternal.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerInternal.java
@@ -27,6 +27,7 @@
import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
import android.media.permission.Identity;
+import android.os.IBinder;
import com.android.server.voiceinteraction.VoiceInteractionManagerService;
@@ -46,10 +47,12 @@
int STATUS_ERROR = SoundTrigger.STATUS_ERROR;
int STATUS_OK = SoundTrigger.STATUS_OK;
- Session attachAsOriginator(@NonNull Identity originatorIdentity);
+ Session attachAsOriginator(@NonNull Identity originatorIdentity,
+ @NonNull IBinder client);
Session attachAsMiddleman(@NonNull Identity middlemanIdentity,
- @NonNull Identity originatorIdentity);
+ @NonNull Identity originatorIdentity,
+ @NonNull IBinder client);
/**
* Dumps service-wide information.
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index 5999044..6c9f41c 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -226,33 +226,45 @@
class SoundTriggerServiceStub extends ISoundTriggerService.Stub {
@Override
- public ISoundTriggerSession attachAsOriginator(Identity originatorIdentity) {
+ public ISoundTriggerSession attachAsOriginator(Identity originatorIdentity,
+ @NonNull IBinder client) {
try (SafeCloseable ignored = PermissionUtil.establishIdentityDirect(
originatorIdentity)) {
- return new SoundTriggerSessionStub(newSoundTriggerHelper());
+ return new SoundTriggerSessionStub(newSoundTriggerHelper(), client);
}
}
@Override
public ISoundTriggerSession attachAsMiddleman(Identity originatorIdentity,
- Identity middlemanIdentity) {
+ Identity middlemanIdentity,
+ @NonNull IBinder client) {
try (SafeCloseable ignored = PermissionUtil.establishIdentityIndirect(mContext,
SOUNDTRIGGER_DELEGATE_IDENTITY, middlemanIdentity,
originatorIdentity)) {
- return new SoundTriggerSessionStub(newSoundTriggerHelper());
+ return new SoundTriggerSessionStub(newSoundTriggerHelper(), client);
}
}
}
class SoundTriggerSessionStub extends ISoundTriggerSession.Stub {
private final SoundTriggerHelper mSoundTriggerHelper;
+ // Used to detect client death.
+ private final IBinder mClient;
private final TreeMap<UUID, SoundModel> mLoadedModels = new TreeMap<>();
private final Object mCallbacksLock = new Object();
private final TreeMap<UUID, IRecognitionStatusCallback> mCallbacks = new TreeMap<>();
SoundTriggerSessionStub(
- SoundTriggerHelper soundTriggerHelper) {
+ SoundTriggerHelper soundTriggerHelper, @NonNull IBinder client) {
mSoundTriggerHelper = soundTriggerHelper;
+ mClient = client;
+ try {
+ mClient.linkToDeath(() -> {
+ clientDied();
+ }, 0);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to register death listener.", e);
+ }
}
@Override
@@ -790,6 +802,13 @@
}
}
+ private void clientDied() {
+ Slog.w(TAG, "Client died, cleaning up session.");
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "Client died, cleaning up session."));
+ mSoundTriggerHelper.detach();
+ }
+
/**
* Local end for a {@link SoundTriggerDetectionService}. Operations are queued up and
* executed when the service connects.
@@ -1457,10 +1476,19 @@
private class SessionImpl implements Session {
private final @NonNull SoundTriggerHelper mSoundTriggerHelper;
+ private final @NonNull IBinder mClient;
private SessionImpl(
- @NonNull SoundTriggerHelper soundTriggerHelper) {
+ @NonNull SoundTriggerHelper soundTriggerHelper, @NonNull IBinder client) {
mSoundTriggerHelper = soundTriggerHelper;
+ mClient = client;
+ try {
+ mClient.linkToDeath(() -> {
+ clientDied();
+ }, 0);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to register death listener.", e);
+ }
}
@Override
@@ -1507,22 +1535,31 @@
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
mSoundTriggerHelper.dump(fd, pw, args);
}
+
+ private void clientDied() {
+ Slog.w(TAG, "Client died, cleaning up session.");
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "Client died, cleaning up session."));
+ mSoundTriggerHelper.detach();
+ }
}
@Override
- public Session attachAsOriginator(@NonNull Identity originatorIdentity) {
+ public Session attachAsOriginator(@NonNull Identity originatorIdentity,
+ @NonNull IBinder client) {
try (SafeCloseable ignored = PermissionUtil.establishIdentityDirect(
originatorIdentity)) {
- return new SessionImpl(newSoundTriggerHelper());
+ return new SessionImpl(newSoundTriggerHelper(), client);
}
}
@Override
public Session attachAsMiddleman(@NonNull Identity middlemanIdentity,
- @NonNull Identity originatorIdentity) {
+ @NonNull Identity originatorIdentity,
+ @NonNull IBinder client) {
try (SafeCloseable ignored = PermissionUtil.establishIdentityIndirect(mContext,
SOUNDTRIGGER_DELEGATE_IDENTITY, middlemanIdentity, originatorIdentity)) {
- return new SessionImpl(newSoundTriggerHelper());
+ return new SessionImpl(newSoundTriggerHelper(), client);
}
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 547d253..2bcf3b5 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -257,12 +257,13 @@
@Override
public @NonNull IVoiceInteractionSoundTriggerSession createSoundTriggerSessionAsOriginator(
- @NonNull Identity originatorIdentity) {
+ @NonNull Identity originatorIdentity, IBinder client) {
Objects.requireNonNull(originatorIdentity);
try (SafeCloseable ignored = PermissionUtil.establishIdentityDirect(
originatorIdentity)) {
SoundTriggerSession session = new SoundTriggerSession(
- mSoundTriggerInternal.attachAsOriginator(IdentityContext.getNonNull()));
+ mSoundTriggerInternal.attachAsOriginator(IdentityContext.getNonNull(),
+ client));
synchronized (mSessions) {
mSessions.add(new WeakReference<>(session));
}
diff --git a/packages/CarSystemUI/res/values/themes.xml b/telephony/java/android/telephony/CarrierBandwidth.aidl
similarity index 63%
rename from packages/CarSystemUI/res/values/themes.xml
rename to telephony/java/android/telephony/CarrierBandwidth.aidl
index f82be3c..d0861b8 100644
--- a/packages/CarSystemUI/res/values/themes.xml
+++ b/telephony/java/android/telephony/CarrierBandwidth.aidl
@@ -1,13 +1,11 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/**
- * Copyright (c) 2018, The Android Open Source Project
+/*
+ * Copyright 2020 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
+ * 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,
@@ -15,9 +13,5 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
--->
-
-<resources>
- <style name="Theme.Notification" parent="Theme.DeviceDefault.NoActionBar.Notification">
- </style>
-</resources>
+package android.telephony;
+parcelable CarrierBandwidth;
\ No newline at end of file
diff --git a/telephony/java/android/telephony/CarrierBandwidth.java b/telephony/java/android/telephony/CarrierBandwidth.java
new file mode 100644
index 0000000..17747a3
--- /dev/null
+++ b/telephony/java/android/telephony/CarrierBandwidth.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2020 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.telephony;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Defines downlink and uplink capacity of a network in kbps
+ * @hide
+ */
+@SystemApi
+public final class CarrierBandwidth implements Parcelable {
+ /**
+ * Any field that is not reported shall be set to INVALID
+ */
+ public static final int INVALID = -1;
+
+ /**
+ * Estimated downlink capacity in kbps of the primary carrier.
+ * This bandwidth estimate shall be the estimated maximum sustainable link bandwidth.
+ * This will be {@link #INVALID} if the network is not connected
+ */
+ private int mPrimaryDownlinkCapacityKbps;
+
+ /**
+ * Estimated uplink capacity in kbps of the primary carrier.
+ * This bandwidth estimate shall be the estimated maximum sustainable link bandwidth.
+ * This will be {@link #INVALID} if the network is not connected
+ */
+ private int mPrimaryUplinkCapacityKbps;
+
+ /**
+ * Estimated downlink capacity in kbps of the secondary carrier in a dual connected network.
+ * This bandwidth estimate shall be the estimated maximum sustainable link bandwidth.
+ * This will be {@link #INVALID} if the network is not connected
+ */
+ private int mSecondaryDownlinkCapacityKbps;
+
+ /**
+ * Estimated uplink capacity in kbps of the secondary carrier in a dual connected network.
+ * This bandwidth estimate shall be the estimated maximum sustainable link bandwidth.
+ * This will be {@link #INVALID} if the network is not connected
+ */
+ private int mSecondaryUplinkCapacityKbps;
+
+ /** @hide **/
+ public CarrierBandwidth(Parcel in) {
+ mPrimaryDownlinkCapacityKbps = in.readInt();
+ mPrimaryUplinkCapacityKbps = in.readInt();
+ mSecondaryDownlinkCapacityKbps = in.readInt();
+ mSecondaryUplinkCapacityKbps = in.readInt();
+ }
+
+ /** @hide **/
+ public CarrierBandwidth() {
+ mPrimaryDownlinkCapacityKbps = INVALID;
+ mPrimaryUplinkCapacityKbps = INVALID;
+ mSecondaryDownlinkCapacityKbps = INVALID;
+ mSecondaryUplinkCapacityKbps = INVALID;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param primaryDownlinkCapacityKbps Estimated downlink capacity in kbps of
+ * the primary carrier.
+ * @param primaryUplinkCapacityKbps Estimated uplink capacity in kbps of
+ * the primary carrier.
+ * @param secondaryDownlinkCapacityKbps Estimated downlink capacity in kbps of
+ * the secondary carrier
+ * @param secondaryUplinkCapacityKbps Estimated uplink capacity in kbps of
+ * the secondary carrier
+ */
+ public CarrierBandwidth(int primaryDownlinkCapacityKbps, int primaryUplinkCapacityKbps,
+ int secondaryDownlinkCapacityKbps, int secondaryUplinkCapacityKbps) {
+ mPrimaryDownlinkCapacityKbps = primaryDownlinkCapacityKbps;
+ mPrimaryUplinkCapacityKbps = primaryUplinkCapacityKbps;
+ mSecondaryDownlinkCapacityKbps = secondaryDownlinkCapacityKbps;
+ mSecondaryUplinkCapacityKbps = secondaryUplinkCapacityKbps;
+ }
+
+ /**
+ * Retrieves the upstream bandwidth for the primary network in Kbps. This always only refers to
+ * the estimated first hop transport bandwidth.
+ * This will be INVALID if the network is not connected
+ *
+ * @return The estimated first hop upstream (device to network) bandwidth.
+ */
+ public int getPrimaryDownlinkCapacityKbps() {
+ return mPrimaryDownlinkCapacityKbps;
+ }
+
+ /**
+ * Retrieves the downstream bandwidth for the primary network in Kbps. This always only refers
+ * to the estimated first hop transport bandwidth.
+ * This will be INVALID if the network is not connected
+ *
+ * @return The estimated first hop downstream (network to device) bandwidth.
+ */
+ public int getPrimaryUplinkCapacityKbps() {
+ return mPrimaryUplinkCapacityKbps;
+ }
+
+ /**
+ * Retrieves the upstream bandwidth for the secondary network in Kbps. This always only refers
+ * to the estimated first hop transport bandwidth.
+ * This will be INVALID if the network is not connected
+ *
+ * @return The estimated first hop upstream (device to network) bandwidth.
+ */
+ public int getSecondaryDownlinkCapacityKbps() {
+ return mSecondaryDownlinkCapacityKbps;
+ }
+
+ /**
+ * Retrieves the downstream bandwidth for the secondary network in Kbps. This always only
+ * refers to the estimated first hop transport bandwidth.
+ * This will be INVALID if the network is not connected
+ *
+ * @return The estimated first hop downstream (network to device) bandwidth.
+ */
+ public int getSecondaryUplinkCapacityKbps() {
+ return mSecondaryUplinkCapacityKbps;
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ return "CarrierBandwidth: {primaryDownlinkCapacityKbps=" + mPrimaryDownlinkCapacityKbps
+ + " primaryUplinkCapacityKbps=" + mPrimaryUplinkCapacityKbps
+ + " secondaryDownlinkCapacityKbps=" + mSecondaryDownlinkCapacityKbps
+ + " secondaryUplinkCapacityKbps=" + mSecondaryUplinkCapacityKbps
+ + "}";
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(
+ mPrimaryDownlinkCapacityKbps,
+ mPrimaryUplinkCapacityKbps,
+ mSecondaryDownlinkCapacityKbps,
+ mSecondaryUplinkCapacityKbps);
+ }
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (o == null || !(o instanceof CallQuality) || hashCode() != o.hashCode()) {
+ return false;
+ }
+ if (this == o) {
+ return true;
+ }
+ CarrierBandwidth s = (CarrierBandwidth) o;
+ return (mPrimaryDownlinkCapacityKbps == s.mPrimaryDownlinkCapacityKbps
+ && mPrimaryUplinkCapacityKbps == s.mPrimaryUplinkCapacityKbps
+ && mSecondaryDownlinkCapacityKbps == s.mSecondaryDownlinkCapacityKbps
+ && mSecondaryDownlinkCapacityKbps == s.mSecondaryDownlinkCapacityKbps);
+ }
+
+ /**
+ * {@link Parcelable#describeContents}
+ */
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * {@link Parcelable#writeToParcel}
+ * @hide
+ */
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mPrimaryDownlinkCapacityKbps);
+ dest.writeInt(mPrimaryUplinkCapacityKbps);
+ dest.writeInt(mSecondaryDownlinkCapacityKbps);
+ dest.writeInt(mSecondaryUplinkCapacityKbps);
+ }
+
+ public static final @android.annotation.NonNull Parcelable.Creator<CarrierBandwidth> CREATOR =
+ new Parcelable.Creator() {
+ public CarrierBandwidth createFromParcel(Parcel in) {
+ return new CarrierBandwidth(in);
+ }
+
+ public CarrierBandwidth[] newArray(int size) {
+ return new CarrierBandwidth[size];
+ }
+ };
+}
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index f8a200a..8507d85 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.AccessNetworkConstants.TransportType;
@@ -635,7 +636,8 @@
.append(" cellIdentity=").append(mCellIdentity)
.append(" voiceSpecificInfo=").append(mVoiceSpecificInfo)
.append(" dataSpecificInfo=").append(mDataSpecificInfo)
- .append(" nrState=").append(nrStateToString(mNrState))
+ .append(" nrState=").append(Build.IS_DEBUGGABLE
+ ? nrStateToString(mNrState) : "****")
.append(" rRplmn=").append(mRplmn)
.append(" isUsingCarrierAggregation=").append(mIsUsingCarrierAggregation)
.append("}").toString();
diff --git a/telephony/java/android/telephony/PinResult.java b/telephony/java/android/telephony/PinResult.java
index c2a4f33..b8c1ffe 100644
--- a/telephony/java/android/telephony/PinResult.java
+++ b/telephony/java/android/telephony/PinResult.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -27,10 +28,16 @@
import java.util.Objects;
/**
- * Holds the result from a pin attempt.
+ * Holds the result from a PIN attempt.
+ *
+ * @see TelephonyManager#supplyIccLockPin
+ * @see TelephonyManager#supplyIccLockPuk
+ * @see TelephonyManager#setIccLockEnabled
+ * @see TelephonyManager#changeIccLockPin
*
* @hide
*/
+@SystemApi
public final class PinResult implements Parcelable {
/** @hide */
@IntDef({
@@ -64,24 +71,24 @@
private static final PinResult sFailedResult =
new PinResult(PinResult.PIN_RESULT_TYPE_FAILURE, -1);
- private final @PinResultType int mType;
+ private final @PinResultType int mResult;
private final int mAttemptsRemaining;
/**
- * Returns either success, incorrect or failure.
+ * Returns the result of the PIN attempt.
*
- * @see #PIN_RESULT_TYPE_SUCCESS
- * @see #PIN_RESULT_TYPE_INCORRECT
- * @see #PIN_RESULT_TYPE_FAILURE
- * @return The result type of the pin attempt.
+ * @return The result of the PIN attempt.
*/
- public @PinResultType int getType() {
- return mType;
+ public @PinResultType int getResult() {
+ return mResult;
}
/**
- * The number of pin attempts remaining.
+ * Returns the number of PIN attempts remaining.
+ * This will be set when {@link #getResult} is {@link #PIN_RESULT_TYPE_INCORRECT}.
+ * Indicates the number of attempts at entering the PIN before the SIM will be locked and
+ * require a PUK unlock to be performed.
*
* @return Number of attempts remaining.
*/
@@ -89,22 +96,32 @@
return mAttemptsRemaining;
}
+ /**
+ * Used to indicate a failed PIN attempt result.
+ *
+ * @return default PinResult for failure.
+ *
+ * @hide
+ */
@NonNull
public static PinResult getDefaultFailedResult() {
return sFailedResult;
}
/**
- * PinResult constructor
+ * PinResult constructor.
*
- * @param type The type of pin result.
+ * @param result The pin result value.
* @see #PIN_RESULT_TYPE_SUCCESS
* @see #PIN_RESULT_TYPE_INCORRECT
* @see #PIN_RESULT_TYPE_FAILURE
+ * @see #PIN_RESULT_TYPE_ABORTED
* @param attemptsRemaining Number of pin attempts remaining.
+ *
+ * @hide
*/
- public PinResult(@PinResultType int type, int attemptsRemaining) {
- mType = type;
+ public PinResult(@PinResultType int result, int attemptsRemaining) {
+ mResult = result;
mAttemptsRemaining = attemptsRemaining;
}
@@ -114,7 +131,7 @@
* @hide
*/
private PinResult(Parcel in) {
- mType = in.readInt();
+ mResult = in.readInt();
mAttemptsRemaining = in.readInt();
}
@@ -124,11 +141,11 @@
@NonNull
@Override
public String toString() {
- return "type: " + getType() + ", attempts remaining: " + getAttemptsRemaining();
+ return "result: " + getResult() + ", attempts remaining: " + getAttemptsRemaining();
}
/**
- * Required to be Parcelable
+ * Describe the contents of this object.
*/
@Override
public int describeContents() {
@@ -136,15 +153,17 @@
}
/**
- * Required to be Parcelable
+ * Write this object to a Parcel.
*/
@Override
public void writeToParcel(@NonNull Parcel out, int flags) {
- out.writeInt(mType);
+ out.writeInt(mResult);
out.writeInt(mAttemptsRemaining);
}
- /** Required to be Parcelable */
+ /**
+ * Parcel creator class.
+ */
public static final @NonNull Parcelable.Creator<PinResult> CREATOR = new Creator<PinResult>() {
public PinResult createFromParcel(Parcel in) {
return new PinResult(in);
@@ -156,7 +175,7 @@
@Override
public int hashCode() {
- return Objects.hash(mAttemptsRemaining, mType);
+ return Objects.hash(mAttemptsRemaining, mResult);
}
@Override
@@ -171,7 +190,7 @@
return false;
}
PinResult other = (PinResult) obj;
- return (mType == other.mType
+ return (mResult == other.mResult
&& mAttemptsRemaining == other.mAttemptsRemaining);
}
}
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 41b3ee6..dedb1af 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -1102,7 +1102,8 @@
.append(", isUsingCarrierAggregation=").append(isUsingCarrierAggregation())
.append(", mLteEarfcnRsrpBoost=").append(mLteEarfcnRsrpBoost)
.append(", mNetworkRegistrationInfos=").append(mNetworkRegistrationInfos)
- .append(", mNrFrequencyRange=").append(mNrFrequencyRange)
+ .append(", mNrFrequencyRange=").append(Build.IS_DEBUGGABLE
+ ? mNrFrequencyRange : FREQUENCY_RANGE_UNKNOWN)
.append(", mOperatorAlphaLongRaw=").append(mOperatorAlphaLongRaw)
.append(", mOperatorAlphaShortRaw=").append(mOperatorAlphaShortRaw)
.append(", mIsDataRoamingFromRegistration=")
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index e65b641..96f3ce0 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -8871,9 +8871,13 @@
return false;
}
- /** @hide */
+ /**
+ * @deprecated use {@link #supplyIccLockPin(String)} instead.
+ * @hide
+ */
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ @Deprecated
public int[] supplyPinReportResult(String pin) {
try {
ITelephony telephony = getITelephony();
@@ -8885,65 +8889,91 @@
return new int[0];
}
- /** @hide */
+ /**
+ * @deprecated use {@link #supplyIccLockPuk(String, String)} instead.
+ * @hide
+ */
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ @Deprecated
public int[] supplyPukReportResult(String puk, String pin) {
try {
ITelephony telephony = getITelephony();
if (telephony != null)
return telephony.supplyPukReportResultForSubscriber(getSubId(), puk, pin);
} catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelephony#]", e);
+ Log.e(TAG, "Error calling ITelephony#supplyPukReportResultForSubscriber", e);
}
return new int[0];
}
/**
- * Used when the user attempts to enter their pin.
+ * Supplies a PIN to unlock the ICC and returns the corresponding {@link PinResult}.
+ * Used when the user enters their ICC unlock PIN to attempt an unlock.
*
- * @param pin The user entered pin.
- * @return The result of the pin.
+ * @param pin The user entered PIN.
+ * @return The result of the PIN.
+ * @throws SecurityException if the caller doesn't have the permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ *
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
+ * app has carrier privileges (see {@link #hasCarrierPrivileges}).
*
* @hide
*/
- @Nullable
+ @SystemApi
+ @NonNull
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
- public PinResult supplyPinReportPinResult(@NonNull String pin) {
+ public PinResult supplyIccLockPin(@NonNull String pin) {
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
int[] result = telephony.supplyPinReportResultForSubscriber(getSubId(), pin);
return new PinResult(result[0], result[1]);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
}
} catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelephony#supplyPinReportResultForSubscriber", e);
+ Log.e(TAG, "Error calling ITelephony#supplyIccLockPin", e);
+ e.rethrowFromSystemServer();
}
- return null;
+ return PinResult.getDefaultFailedResult();
}
/**
- * Used when the user attempts to enter the puk or their pin.
+ * Supplies a PUK and PIN to unlock the ICC and returns the corresponding {@link PinResult}.
+ * Used when the user enters their ICC unlock PUK and PIN to attempt an unlock.
*
- * @param puk The product unblocking key.
- * @param pin The user entered pin.
- * @return The result of the pin.
+ * @param puk The product unlocking key.
+ * @param pin The user entered PIN.
+ * @return The result of the PUK and PIN.
+ * @throws SecurityException if the caller doesn't have the permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ *
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
+ * app has carrier privileges (see {@link #hasCarrierPrivileges}).
*
* @hide
*/
- @Nullable
+ @SystemApi
+ @NonNull
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
- public PinResult supplyPukReportPinResult(@NonNull String puk, @NonNull String pin) {
+ public PinResult supplyIccLockPuk(@NonNull String puk, @NonNull String pin) {
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
int[] result = telephony.supplyPukReportResultForSubscriber(getSubId(), puk, pin);
return new PinResult(result[0], result[1]);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
}
} catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelephony#]", e);
+ Log.e(TAG, "Error calling ITelephony#supplyIccLockPuk", e);
+ e.rethrowFromSystemServer();
}
- return null;
+ return PinResult.getDefaultFailedResult();
}
/**
@@ -13628,18 +13658,22 @@
}
/**
- * The IccLock state or password was changed successfully.
+ * Indicates that the ICC PIN lock state or PIN was changed successfully.
* @hide
*/
public static final int CHANGE_ICC_LOCK_SUCCESS = Integer.MAX_VALUE;
/**
- * Check whether ICC pin lock is enabled.
- * This is a sync call which returns the cached pin enabled state.
+ * Check whether ICC PIN lock is enabled.
+ * This is a sync call which returns the cached PIN enabled state.
*
- * @return {@code true} if ICC lock enabled, {@code false} if ICC lock disabled.
- *
+ * @return {@code true} if ICC PIN lock enabled, {@code false} if disabled.
* @throws SecurityException if the caller doesn't have the permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ *
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE}
+ * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
*
* @hide
*/
@@ -13651,81 +13685,124 @@
ITelephony telephony = getITelephony();
if (telephony != null) {
return telephony.isIccLockEnabled(getSubId());
+ } else {
+ throw new IllegalStateException("telephony service is null.");
}
} catch (RemoteException e) {
Log.e(TAG, "isIccLockEnabled RemoteException", e);
+ e.rethrowFromSystemServer();
}
return false;
}
/**
- * Set the ICC pin lock enabled or disabled.
+ * Enable or disable the ICC PIN lock.
*
- * If enable/disable ICC pin lock successfully, a value of {@link Integer#MAX_VALUE} is
- * returned.
- * If an incorrect old password is specified, the return value will indicate how many more
- * attempts the user can make to change the password before the SIM is locked.
- * Using PUK code to unlock SIM if enter the incorrect old password 3 times.
- *
- * @param enabled "true" for locked, "false" for unlocked.
- * @param password needed to change the ICC pin state, aka. Pin1
- * @return an integer representing the status of IccLock enabled or disabled in the following
- * three cases:
- * - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if enabled or disabled IccLock
- * successfully.
- * - Positive number and zero for remaining password attempts.
- * - Negative number for other failure cases (such like enabling/disabling PIN failed).
- *
+ * @param enabled "true" for locked, "false" for unlocked.
+ * @param pin needed to change the ICC PIN lock, aka. Pin1.
+ * @return the result of enabling or disabling the ICC PIN lock.
* @throws SecurityException if the caller doesn't have the permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ *
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
+ * app has carrier privileges (see {@link #hasCarrierPrivileges}).
*
* @hide
*/
+ @SystemApi
+ @NonNull
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
- public int setIccLockEnabled(boolean enabled, @NonNull String password) {
- checkNotNull(password, "setIccLockEnabled password can't be null.");
+ public PinResult setIccLockEnabled(boolean enabled, @NonNull String pin) {
+ checkNotNull(pin, "setIccLockEnabled pin can't be null.");
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
- return telephony.setIccLockEnabled(getSubId(), enabled, password);
+ int result = telephony.setIccLockEnabled(getSubId(), enabled, pin);
+ if (result == CHANGE_ICC_LOCK_SUCCESS) {
+ return new PinResult(PinResult.PIN_RESULT_TYPE_SUCCESS, 0);
+ } else if (result < 0) {
+ return PinResult.getDefaultFailedResult();
+ } else {
+ return new PinResult(PinResult.PIN_RESULT_TYPE_INCORRECT, result);
+ }
+ } else {
+ throw new IllegalStateException("telephony service is null.");
}
} catch (RemoteException e) {
Log.e(TAG, "setIccLockEnabled RemoteException", e);
+ e.rethrowFromSystemServer();
}
- return 0;
+ return PinResult.getDefaultFailedResult();
}
/**
- * Change the ICC password used in ICC pin lock.
+ * Change the ICC lock PIN.
*
- * If the password was changed successfully, a value of {@link Integer#MAX_VALUE} is returned.
- * If an incorrect old password is specified, the return value will indicate how many more
- * attempts the user can make to change the password before the SIM is locked.
- * Using PUK code to unlock SIM if enter the incorrect old password 3 times.
- *
- * @param oldPassword is the old password
- * @param newPassword is the new password
- * @return an integer representing the status of IccLock changed in the following three cases:
- * - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if changed IccLock successfully.
- * - Positive number and zero for remaining password attempts.
- * - Negative number for other failure cases (such like enabling/disabling PIN failed).
- *
+ * @param oldPin is the old PIN
+ * @param newPin is the new PIN
+ * @return The result of changing the ICC lock PIN.
* @throws SecurityException if the caller doesn't have the permission.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ *
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
+ * app has carrier privileges (see {@link #hasCarrierPrivileges}).
*
* @hide
*/
+ @SystemApi
+ @NonNull
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
- public int changeIccLockPassword(@NonNull String oldPassword, @NonNull String newPassword) {
- checkNotNull(oldPassword, "changeIccLockPassword oldPassword can't be null.");
- checkNotNull(newPassword, "changeIccLockPassword newPassword can't be null.");
+ public PinResult changeIccLockPin(@NonNull String oldPin, @NonNull String newPin) {
+ checkNotNull(oldPin, "changeIccLockPin oldPin can't be null.");
+ checkNotNull(newPin, "changeIccLockPin newPin can't be null.");
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
- return telephony.changeIccLockPassword(getSubId(), oldPassword, newPassword);
+ int result = telephony.changeIccLockPassword(getSubId(), oldPin, newPin);
+ if (result == CHANGE_ICC_LOCK_SUCCESS) {
+ return new PinResult(PinResult.PIN_RESULT_TYPE_SUCCESS, 0);
+ } else if (result < 0) {
+ return PinResult.getDefaultFailedResult();
+ } else {
+ return new PinResult(PinResult.PIN_RESULT_TYPE_INCORRECT, result);
+ }
+ } else {
+ throw new IllegalStateException("telephony service is null.");
}
} catch (RemoteException e) {
- Log.e(TAG, "changeIccLockPassword RemoteException", e);
+ Log.e(TAG, "changeIccLockPin RemoteException", e);
+ e.rethrowFromSystemServer();
}
- return 0;
+ return PinResult.getDefaultFailedResult();
+ }
+
+ /**
+ * Get carrier bandwidth. In case of Dual connected network this will report
+ * bandwidth per primary and secondary network.
+ * @return CarrierBandwidth with bandwidth of both primary and secondary carrier.
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ @NonNull
+ public CarrierBandwidth getCarrierBandwidth() {
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ return service.getCarrierBandwidth(getSubId());
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "getCarrierBandwidth RemoteException", ex);
+ ex.rethrowFromSystemServer();
+ }
+
+ //Should not reach. Adding return statement to make compiler happy
+ return null;
}
/**
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 51aa9cc..0bd4851 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -31,6 +31,7 @@
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telephony.CallForwardingInfo;
+import android.telephony.CarrierBandwidth;
import android.telephony.CarrierRestrictionRules;
import android.telephony.CellIdentity;
import android.telephony.CellInfo;
@@ -2240,4 +2241,10 @@
* @return true if dual connectivity is enabled else false
*/
boolean isNrDualConnectivityEnabled(int subId);
+
+ /**
+ * Get carrier bandwidth per primary and secondary carrier
+ * @return CarrierBandwidth with bandwidth of both primary and secondary carrier.
+ */
+ CarrierBandwidth getCarrierBandwidth(int subId);
}
diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt
index d235c80..dc96df6 100644
--- a/wifi/jarjar-rules.txt
+++ b/wifi/jarjar-rules.txt
@@ -89,8 +89,6 @@
rule android.util.LocalLog* com.android.wifi.x.@0
rule android.util.Rational* com.android.wifi.x.@0
-rule android.os.BasicShellCommandHandler* com.android.wifi.x.@0
-
# Use our statically linked bouncy castle library
rule org.bouncycastle.** com.android.wifi.x.@0
# Use our statically linked protobuf library