summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AconfigFlags.bp14
-rw-r--r--core/java/Android.bp5
-rw-r--r--core/java/android/app/trust/ITrustListener.aidl1
-rw-r--r--core/java/android/app/trust/TrustManager.java17
-rw-r--r--core/java/android/os/flags.aconfig8
-rw-r--r--core/java/com/android/internal/util/FileRotator.java24
-rw-r--r--core/jni/com_android_internal_os_Zygote.cpp13
-rw-r--r--core/tests/utiltests/src/com/android/internal/util/FileRotatorTest.java21
-rw-r--r--data/keyboards/qwerty.idc28
-rw-r--r--data/keyboards/qwerty.kcm508
-rw-r--r--data/keyboards/qwerty.kl131
-rw-r--r--data/keyboards/qwerty2.idc28
-rw-r--r--data/keyboards/qwerty2.kcm505
-rw-r--r--packages/CredentialManager/horologist/OWNERS4
-rw-r--r--packages/CredentialManager/shared/OWNERS4
-rw-r--r--packages/CredentialManager/wear/OWNERS4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java12
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java22
-rw-r--r--services/backup/backuplib/java/com/android/server/backup/TransportManager.java3
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java5
-rw-r--r--services/core/java/com/android/server/trust/TrustManagerService.java220
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java56
-rw-r--r--tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt3
27 files changed, 348 insertions, 1313 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 3fea8fc34d3c..55f5436eed90 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -18,6 +18,7 @@ java_defaults {
// Add java_aconfig_libraries to here to add them to the core framework
srcs: [
+ ":android.os.flags-aconfig-java{.generated_srcjars}",
":android.security.flags-aconfig-java{.generated_srcjars}",
":com.android.hardware.camera2-aconfig-java{.generated_srcjars}",
":com.android.window.flags.window-aconfig-java{.generated_srcjars}",
@@ -88,6 +89,19 @@ java_aconfig_library {
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+// OS
+aconfig_declarations {
+ name: "android.os.flags-aconfig",
+ package: "android.os",
+ srcs: ["core/java/android/os/*.aconfig"],
+}
+
+java_aconfig_library {
+ name: "android.os.flags-aconfig-java",
+ aconfig_declarations: "android.os.flags-aconfig",
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
// Security
aconfig_declarations {
name: "android.security.flags-aconfig",
diff --git a/core/java/Android.bp b/core/java/Android.bp
index 5d7d7ba2379c..da6a6d46c132 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -9,6 +9,11 @@ package {
default_applicable_licenses: ["frameworks_base_license"],
}
+aidl_library {
+ name: "HardwareBuffer_aidl",
+ hdrs: ["android/hardware/HardwareBuffer.aidl"],
+}
+
filegroup {
name: "framework-core-sources",
srcs: [
diff --git a/core/java/android/app/trust/ITrustListener.aidl b/core/java/android/app/trust/ITrustListener.aidl
index e4ac01195bcb..8d4478493b13 100644
--- a/core/java/android/app/trust/ITrustListener.aidl
+++ b/core/java/android/app/trust/ITrustListener.aidl
@@ -24,6 +24,7 @@ import java.util.List;
* {@hide}
*/
oneway interface ITrustListener {
+ void onEnabledTrustAgentsChanged(int userId);
void onTrustChanged(boolean enabled, boolean newlyUnlocked, int userId, int flags,
in List<String> trustGrantedMessages);
void onTrustManagedChanged(boolean managed, int userId);
diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java
index 62f755d0268c..3552ce0e5889 100644
--- a/core/java/android/app/trust/TrustManager.java
+++ b/core/java/android/app/trust/TrustManager.java
@@ -43,6 +43,7 @@ public class TrustManager {
private static final int MSG_TRUST_CHANGED = 1;
private static final int MSG_TRUST_MANAGED_CHANGED = 2;
private static final int MSG_TRUST_ERROR = 3;
+ private static final int MSG_ENABLED_TRUST_AGENTS_CHANGED = 4;
private static final String TAG = "TrustManager";
private static final String DATA_FLAGS = "initiatedByUser";
@@ -187,6 +188,13 @@ public class TrustManager {
}
@Override
+ public void onEnabledTrustAgentsChanged(int userId) {
+ final Message m = mHandler.obtainMessage(MSG_ENABLED_TRUST_AGENTS_CHANGED,
+ userId, 0, trustListener);
+ m.sendToTarget();
+ }
+
+ @Override
public void onTrustManagedChanged(boolean managed, int userId) {
mHandler.obtainMessage(MSG_TRUST_MANAGED_CHANGED, (managed ? 1 : 0), userId,
trustListener).sendToTarget();
@@ -283,6 +291,10 @@ public class TrustManager {
case MSG_TRUST_ERROR:
final CharSequence message = msg.peekData().getCharSequence(DATA_MESSAGE);
((TrustListener) msg.obj).onTrustError(message);
+ break;
+ case MSG_ENABLED_TRUST_AGENTS_CHANGED:
+ ((TrustListener) msg.obj).onEnabledTrustAgentsChanged(msg.arg1);
+ break;
}
}
};
@@ -316,5 +328,10 @@ public class TrustManager {
* @param message A message that should be displayed on the UI.
*/
void onTrustError(CharSequence message);
+
+ /**
+ * Reports that the enabled trust agents for the specified user has changed.
+ */
+ void onEnabledTrustAgentsChanged(int userId);
}
}
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
new file mode 100644
index 000000000000..851aa6dce560
--- /dev/null
+++ b/core/java/android/os/flags.aconfig
@@ -0,0 +1,8 @@
+package: "android.os"
+
+flag {
+ name: "disallow_cellular_null_ciphers_restriction"
+ namespace: "cellular_security"
+ description: "Guards a new UserManager user restriction that admins can use to require cellular encryption on their managed devices."
+ bug: "276752881"
+}
diff --git a/core/java/com/android/internal/util/FileRotator.java b/core/java/com/android/internal/util/FileRotator.java
index 5bc48c5172f0..c9d9926ba75a 100644
--- a/core/java/com/android/internal/util/FileRotator.java
+++ b/core/java/com/android/internal/util/FileRotator.java
@@ -19,6 +19,9 @@ package com.android.internal.util;
import android.annotation.NonNull;
import android.os.FileUtils;
import android.util.Log;
+import android.util.Pair;
+
+import libcore.io.IoUtils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
@@ -28,12 +31,12 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.Comparator;
import java.util.Objects;
+import java.util.TreeSet;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
-import libcore.io.IoUtils;
-
/**
* Utility that rotates files over time, similar to {@code logrotate}. There is
* a single "active" file, which is periodically rotated into historical files,
@@ -302,17 +305,24 @@ public class FileRotator {
public void readMatching(Reader reader, long matchStartMillis, long matchEndMillis)
throws IOException {
final FileInfo info = new FileInfo(mPrefix);
+ final TreeSet<Pair<Long, String>> readSet = new TreeSet<>(
+ Comparator.comparingLong(o -> o.first));
for (String name : mBasePath.list()) {
if (!info.parse(name)) continue;
- // read file when it overlaps
+ // Add file to set when it overlaps.
if (info.startMillis <= matchEndMillis && matchStartMillis <= info.endMillis) {
- if (LOGD) Log.d(TAG, "reading matching " + name);
-
- final File file = new File(mBasePath, name);
- readFile(file, reader);
+ readSet.add(new Pair(info.startMillis, name));
}
}
+
+ // Read files in ascending order of start timestamp.
+ for (Pair<Long, String> pair : readSet) {
+ final String name = pair.second;
+ if (LOGD) Log.d(TAG, "reading matching " + name);
+ final File file = new File(mBasePath, name);
+ readFile(file, reader);
+ }
}
/**
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index bbaea0a45798..418000f60ca1 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -1806,15 +1806,10 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids,
if (!is_system_server && getuid() == 0) {
const int rc = createProcessGroup(uid, getpid());
if (rc != 0) {
- if (rc == -ESRCH) {
- // If process is dead, treat this as a non-fatal error
- ALOGE("createProcessGroup(%d, %d) failed: %s", uid, /* pid= */ 0, strerror(-rc));
- } else {
- fail_fn(rc == -EROFS ? CREATE_ERROR("createProcessGroup failed, kernel missing "
- "CONFIG_CGROUP_CPUACCT?")
- : CREATE_ERROR("createProcessGroup(%d, %d) failed: %s", uid,
- /* pid= */ 0, strerror(-rc)));
- }
+ fail_fn(rc == -EROFS ? CREATE_ERROR("createProcessGroup failed, kernel missing "
+ "CONFIG_CGROUP_CPUACCT?")
+ : CREATE_ERROR("createProcessGroup(%d, %d) failed: %s", uid,
+ /* pid= */ 0, strerror(-rc)));
}
}
diff --git a/core/tests/utiltests/src/com/android/internal/util/FileRotatorTest.java b/core/tests/utiltests/src/com/android/internal/util/FileRotatorTest.java
index 952721320c90..73e47e1635b4 100644
--- a/core/tests/utiltests/src/com/android/internal/util/FileRotatorTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/FileRotatorTest.java
@@ -366,6 +366,16 @@ public class FileRotatorTest extends AndroidTestCase {
assertReadAll(rotate, "bar");
}
+ public void testReadSorted() throws Exception {
+ write("rotator.1024-2048", "2");
+ write("rotator.2048-4096", "3");
+ write("rotator.512-1024", "1");
+
+ final FileRotator rotate = new FileRotator(
+ mBasePath, PREFIX, SECOND_IN_MILLIS, SECOND_IN_MILLIS);
+ assertReadAll(rotate, "1", "2", "3");
+ }
+
public void testFileSystemInaccessible() throws Exception {
File inaccessibleDir = null;
String dirPath = getContext().getFilesDir() + File.separator + "inaccessible";
@@ -422,16 +432,7 @@ public class FileRotatorTest extends AndroidTestCase {
}
public void assertRead(String... expected) {
- assertEquals(expected.length, mActual.size());
-
- final ArrayList<String> actualCopy = new ArrayList<String>(mActual);
- for (String value : expected) {
- if (!actualCopy.remove(value)) {
- final String expectedString = Arrays.toString(expected);
- final String actualString = Arrays.toString(mActual.toArray());
- fail("expected: " + expectedString + " but was: " + actualString);
- }
- }
+ assertEquals(Arrays.asList(expected), mActual);
}
}
}
diff --git a/data/keyboards/qwerty.idc b/data/keyboards/qwerty.idc
deleted file mode 100644
index 375d78576548..000000000000
--- a/data/keyboards/qwerty.idc
+++ /dev/null
@@ -1,28 +0,0 @@
-# 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.
-
-#
-# Emulator keyboard configuration file #1.
-#
-
-touch.deviceType = touchScreen
-touch.orientationAware = 1
-
-keyboard.layout = qwerty
-keyboard.characterMap = qwerty
-keyboard.orientationAware = 1
-keyboard.builtIn = 1
-
-cursor.mode = navigation
-cursor.orientationAware = 1
diff --git a/data/keyboards/qwerty.kcm b/data/keyboards/qwerty.kcm
deleted file mode 100644
index f3e152418a4c..000000000000
--- a/data/keyboards/qwerty.kcm
+++ /dev/null
@@ -1,508 +0,0 @@
-# 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.
-
-#
-# Emulator keyboard character map #1.
-#
-# This file is no longer used as the platform's default keyboard character map.
-# Refer to Generic.kcm and Virtual.kcm instead.
-#
-
-type ALPHA
-
-key A {
- label: 'A'
- number: '2'
- base: 'a'
- shift, capslock: 'A'
- alt: '#'
- shift+alt, capslock+alt: none
-}
-
-key B {
- label: 'B'
- number: '2'
- base: 'b'
- shift, capslock: 'B'
- alt: '<'
- shift+alt, capslock+alt: none
-}
-
-key C {
- label: 'C'
- number: '2'
- base: 'c'
- shift, capslock: 'C'
- alt: '9'
- shift+alt, capslock+alt: '\u00e7'
-}
-
-key D {
- label: 'D'
- number: '3'
- base: 'd'
- shift, capslock: 'D'
- alt: '5'
- shift+alt, capslock+alt: none
-}
-
-key E {
- label: 'E'
- number: '3'
- base: 'e'
- shift, capslock: 'E'
- alt: '2'
- shift+alt, capslock+alt: '\u0301'
-}
-
-key F {
- label: 'F'
- number: '3'
- base: 'f'
- shift, capslock: 'F'
- alt: '6'
- shift+alt, capslock+alt: '\u00a5'
-}
-
-key G {
- label: 'G'
- number: '4'
- base: 'g'
- shift, capslock: 'G'
- alt: '-'
- shift+alt, capslock+alt: '_'
-}
-
-key H {
- label: 'H'
- number: '4'
- base: 'h'
- shift, capslock: 'H'
- alt: '['
- shift+alt, capslock+alt: '{'
-}
-
-key I {
- label: 'I'
- number: '4'
- base: 'i'
- shift, capslock: 'I'
- alt: '$'
- shift+alt, capslock+alt: '\u0302'
-}
-
-key J {
- label: 'J'
- number: '5'
- base: 'j'
- shift, capslock: 'J'
- alt: ']'
- shift+alt, capslock+alt: '}'
-}
-
-key K {
- label: 'K'
- number: '5'
- base: 'k'
- shift, capslock: 'K'
- alt: '"'
- shift+alt, capslock+alt: '~'
-}
-
-key L {
- label: 'L'
- number: '5'
- base: 'l'
- shift, capslock: 'L'
- alt: '\''
- shift+alt, capslock+alt: '`'
-}
-
-key M {
- label: 'M'
- number: '6'
- base: 'm'
- shift, capslock: 'M'
- alt: '!'
- shift+alt, capslock+alt: none
-}
-
-key N {
- label: 'N'
- number: '6'
- base: 'n'
- shift, capslock: 'N'
- alt: '>'
- shift+alt, capslock+alt: '\u0303'
-}
-
-key O {
- label: 'O'
- number: '6'
- base: 'o'
- shift, capslock: 'O'
- alt: '('
- shift+alt, capslock+alt: none
-}
-
-key P {
- label: 'P'
- number: '7'
- base: 'p'
- shift, capslock: 'P'
- alt: ')'
- shift+alt, capslock+alt: none
-}
-
-key Q {
- label: 'Q'
- number: '7'
- base: 'q'
- shift, capslock: 'Q'
- alt: '*'
- shift+alt, capslock+alt: '\u0300'
-}
-
-key R {
- label: 'R'
- number: '7'
- base: 'r'
- shift, capslock: 'R'
- alt: '3'
- shift+alt, capslock+alt: '\u20ac'
-}
-
-key S {
- label: 'S'
- number: '7'
- base: 's'
- shift, capslock: 'S'
- alt: '4'
- shift+alt, capslock+alt: '\u00df'
-}
-
-key T {
- label: 'T'
- number: '8'
- base: 't'
- shift, capslock: 'T'
- alt: '+'
- shift+alt, capslock+alt: '\u00a3'
-}
-
-key U {
- label: 'U'
- number: '8'
- base: 'u'
- shift, capslock: 'U'
- alt: '&'
- shift+alt, capslock+alt: '\u0308'
-}
-
-key V {
- label: 'V'
- number: '8'
- base: 'v'
- shift, capslock: 'V'
- alt: '='
- shift+alt, capslock+alt: '^'
-}
-
-key W {
- label: 'W'
- number: '9'
- base: 'w'
- shift, capslock: 'W'
- alt: '1'
- shift+alt, capslock+alt: none
-}
-
-key X {
- label: 'X'
- number: '9'
- base: 'x'
- shift, capslock: 'X'
- alt: '8'
- shift+alt, capslock+alt: '\uef00'
-}
-
-key Y {
- label: 'Y'
- number: '9'
- base: 'y'
- shift, capslock: 'Y'
- alt: '%'
- shift+alt, capslock+alt: '\u00a1'
-}
-
-key Z {
- label: 'Z'
- number: '9'
- base: 'z'
- shift, capslock: 'Z'
- alt: '7'
- shift+alt, capslock+alt: none
-}
-
-key COMMA {
- label: ','
- number: ','
- base: ','
- shift: ';'
- alt: ';'
- shift+alt: '|'
-}
-
-key PERIOD {
- label: '.'
- number: '.'
- base: '.'
- shift: ':'
- alt: ':'
- shift+alt: '\u2026'
-}
-
-key AT {
- label: '@'
- number: '0'
- base: '@'
- shift: '0'
- alt: '0'
- shift+alt: '\u2022'
-}
-
-key SLASH {
- label: '/'
- number: '/'
- base: '/'
- shift: '?'
- alt: '?'
- shift+alt: '\\'
-}
-
-key SPACE {
- label: ' '
- number: ' '
- base: ' '
- shift: ' '
- alt: '\uef01'
- shift+alt: '\uef01'
-}
-
-key ENTER {
- label: '\n'
- number: '\n'
- base: '\n'
- shift: '\n'
- alt: '\n'
- shift+alt: '\n'
-}
-
-key TAB {
- label: '\t'
- number: '\t'
- base: '\t'
- shift: '\t'
- alt: '\t'
- shift+alt: '\t'
-}
-
-key 0 {
- label: '0'
- number: '0'
- base: '0'
- shift: ')'
- alt: ')'
- shift+alt: ')'
-}
-
-key 1 {
- label: '1'
- number: '1'
- base: '1'
- shift: '!'
- alt: '!'
- shift+alt: '!'
-}
-
-key 2 {
- label: '2'
- number: '2'
- base: '2'
- shift: '@'
- alt: '@'
- shift+alt: '@'
-}
-
-key 3 {
- label: '3'
- number: '3'
- base: '3'
- shift: '#'
- alt: '#'
- shift+alt: '#'
-}
-
-key 4 {
- label: '4'
- number: '4'
- base: '4'
- shift: '$'
- alt: '$'
- shift+alt: '$'
-}
-
-key 5 {
- label: '5'
- number: '5'
- base: '5'
- shift: '%'
- alt: '%'
- shift+alt: '%'
-}
-
-key 6 {
- label: '6'
- number: '6'
- base: '6'
- shift: '^'
- alt: '^'
- shift+alt: '^'
-}
-
-key 7 {
- label: '7'
- number: '7'
- base: '7'
- shift: '&'
- alt: '&'
- shift+alt: '&'
-}
-
-key 8 {
- label: '8'
- number: '8'
- base: '8'
- shift: '*'
- alt: '*'
- shift+alt: '*'
-}
-
-key 9 {
- label: '9'
- number: '9'
- base: '9'
- shift: '('
- alt: '('
- shift+alt: '('
-}
-
-key GRAVE {
- label: '`'
- number: '`'
- base: '`'
- shift: '~'
- alt: '`'
- shift+alt: '~'
-}
-
-key MINUS {
- label: '-'
- number: '-'
- base: '-'
- shift: '_'
- alt: '-'
- shift+alt: '_'
-}
-
-key EQUALS {
- label: '='
- number: '='
- base: '='
- shift: '+'
- alt: '='
- shift+alt: '+'
-}
-
-key LEFT_BRACKET {
- label: '['
- number: '['
- base: '['
- shift: '{'
- alt: '['
- shift+alt: '{'
-}
-
-key RIGHT_BRACKET {
- label: ']'
- number: ']'
- base: ']'
- shift: '}'
- alt: ']'
- shift+alt: '}'
-}
-
-key BACKSLASH {
- label: '\\'
- number: '\\'
- base: '\\'
- shift: '|'
- alt: '\\'
- shift+alt: '|'
-}
-
-key SEMICOLON {
- label: ';'
- number: ';'
- base: ';'
- shift: ':'
- alt: ';'
- shift+alt: ':'
-}
-
-key APOSTROPHE {
- label: '\''
- number: '\''
- base: '\''
- shift: '"'
- alt: '\''
- shift+alt: '"'
-}
-
-key STAR {
- label: '*'
- number: '*'
- base: '*'
- shift: '*'
- alt: '*'
- shift+alt: '*'
-}
-
-key POUND {
- label: '#'
- number: '#'
- base: '#'
- shift: '#'
- alt: '#'
- shift+alt: '#'
-}
-
-key PLUS {
- label: '+'
- number: '+'
- base: '+'
- shift: '+'
- alt: '+'
- shift+alt: '+'
-}
diff --git a/data/keyboards/qwerty.kl b/data/keyboards/qwerty.kl
deleted file mode 100644
index 2fd99abbb9fe..000000000000
--- a/data/keyboards/qwerty.kl
+++ /dev/null
@@ -1,131 +0,0 @@
-# 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.
-
-#
-# Emulator keyboard layout #1.
-#
-# This file is no longer used as the platform's default keyboard layout.
-# Refer to Generic.kl instead.
-#
-
-key 399 GRAVE
-key 2 1
-key 3 2
-key 4 3
-key 5 4
-key 6 5
-key 7 6
-key 8 7
-key 9 8
-key 10 9
-key 11 0
-key 158 BACK
-key 230 SOFT_RIGHT
-key 60 SOFT_LEFT
-key 107 ENDCALL
-key 62 ENDCALL
-key 229 MENU
-key 139 MENU
-key 59 MENU
-key 127 SEARCH
-key 217 SEARCH
-key 228 POUND
-key 227 STAR
-key 231 CALL
-key 61 CALL
-key 232 DPAD_CENTER
-key 108 DPAD_DOWN
-key 103 DPAD_UP
-key 102 HOME
-key 105 DPAD_LEFT
-key 106 DPAD_RIGHT
-key 115 VOLUME_UP
-key 114 VOLUME_DOWN
-key 116 POWER
-key 212 CAMERA
-
-key 16 Q
-key 17 W
-key 18 E
-key 19 R
-key 20 T
-key 21 Y
-key 22 U
-key 23 I
-key 24 O
-key 25 P
-key 26 LEFT_BRACKET
-key 27 RIGHT_BRACKET
-key 43 BACKSLASH
-
-key 30 A
-key 31 S
-key 32 D
-key 33 F
-key 34 G
-key 35 H
-key 36 J
-key 37 K
-key 38 L
-key 39 SEMICOLON
-key 40 APOSTROPHE
-key 14 DEL
-
-key 44 Z
-key 45 X
-key 46 C
-key 47 V
-key 48 B
-key 49 N
-key 50 M
-key 51 COMMA
-key 52 PERIOD
-key 53 SLASH
-key 28 ENTER
-
-key 56 ALT_LEFT
-key 100 ALT_RIGHT
-key 42 SHIFT_LEFT
-key 54 SHIFT_RIGHT
-key 15 TAB
-key 57 SPACE
-key 150 EXPLORER
-key 155 ENVELOPE
-
-key 12 MINUS
-key 13 EQUALS
-key 215 AT
-
-# On an AT keyboard: ESC, F10
-key 1 BACK
-key 68 MENU
-
-# App switch = Overview key
-key 580 APP_SWITCH
-
-# Media control keys
-key 160 MEDIA_CLOSE
-key 161 MEDIA_EJECT
-key 163 MEDIA_NEXT
-key 164 MEDIA_PLAY_PAUSE
-key 165 MEDIA_PREVIOUS
-key 166 MEDIA_STOP
-key 167 MEDIA_RECORD
-key 168 MEDIA_REWIND
-
-key 142 SLEEP
-key 581 STEM_PRIMARY
-key 582 STEM_1
-key 583 STEM_2
-key 584 STEM_3
diff --git a/data/keyboards/qwerty2.idc b/data/keyboards/qwerty2.idc
deleted file mode 100644
index 369205ea3f98..000000000000
--- a/data/keyboards/qwerty2.idc
+++ /dev/null
@@ -1,28 +0,0 @@
-# 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.
-
-#
-# Emulator keyboard configuration file #2.
-#
-
-touch.deviceType = touchScreen
-touch.orientationAware = 1
-
-keyboard.layout = qwerty
-keyboard.characterMap = qwerty2
-keyboard.orientationAware = 1
-keyboard.builtIn = 1
-
-cursor.mode = navigation
-cursor.orientationAware = 1
diff --git a/data/keyboards/qwerty2.kcm b/data/keyboards/qwerty2.kcm
deleted file mode 100644
index b981d835bdfb..000000000000
--- a/data/keyboards/qwerty2.kcm
+++ /dev/null
@@ -1,505 +0,0 @@
-# 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.
-
-#
-# Emulator keyboard character map #2.
-#
-
-type ALPHA
-
-key A {
- label: 'A'
- number: '2'
- base: 'a'
- shift, capslock: 'A'
- alt: '\u00e1'
- shift+alt, capslock+alt: '\u00c1'
-}
-
-key B {
- label: 'B'
- number: '2'
- base: 'b'
- shift, capslock: 'B'
- alt: 'b'
- shift+alt, capslock+alt: 'B'
-}
-
-key C {
- label: 'C'
- number: '2'
- base: 'c'
- shift, capslock: 'C'
- alt: '\u00a9'
- shift+alt, capslock+alt: '\u00a2'
-}
-
-key D {
- label: 'D'
- number: '3'
- base: 'd'
- shift, capslock: 'D'
- alt: '\u00f0'
- shift+alt, capslock+alt: '\u00d0'
-}
-
-key E {
- label: 'E'
- number: '3'
- base: 'e'
- shift, capslock: 'E'
- alt: '\u00e9'
- shift+alt, capslock+alt: '\u00c9'
-}
-
-key F {
- label: 'F'
- number: '3'
- base: 'f'
- shift, capslock: 'F'
- alt: '['
- shift+alt, capslock+alt: '['
-}
-
-key G {
- label: 'G'
- number: '4'
- base: 'g'
- shift, capslock: 'G'
- alt: ']'
- shift+alt, capslock+alt: ']'
-}
-
-key H {
- label: 'H'
- number: '4'
- base: 'h'
- shift, capslock: 'H'
- alt: '<'
- shift+alt, capslock+alt: '<'
-}
-
-key I {
- label: 'I'
- number: '4'
- base: 'i'
- shift, capslock: 'I'
- alt: '\u00ed'
- shift+alt, capslock+alt: '\u00cd'
-}
-
-key J {
- label: 'J'
- number: '5'
- base: 'j'
- shift, capslock: 'J'
- alt: '>'
- shift+alt, capslock+alt: '>'
-}
-
-key K {
- label: 'K'
- number: '5'
- base: 'k'
- shift, capslock: 'K'
- alt: ';'
- shift+alt, capslock+alt: '~'
-}
-
-key L {
- label: 'L'
- number: '5'
- base: 'l'
- shift, capslock: 'L'
- alt: '\u00f8'
- shift+alt, capslock+alt: '\u00d8'
-}
-
-key M {
- label: 'M'
- number: '6'
- base: 'm'
- shift, capslock: 'M'
- alt: '\u00b5'
- shift+alt, capslock+alt: none
-}
-
-key N {
- label: 'N'
- number: '6'
- base: 'n'
- shift, capslock: 'N'
- alt: '\u00f1'
- shift+alt, capslock+alt: '\u00d1'
-}
-
-key O {
- label: 'O'
- number: '6'
- base: 'o'
- shift, capslock: 'O'
- alt: '\u00f3'
- shift+alt, capslock+alt: '\u00d3'
-}
-
-key P {
- label: 'P'
- number: '7'
- base: 'p'
- shift, capslock: 'P'
- alt: '\u00f6'
- shift+alt, capslock+alt: '\u00d6'
-}
-
-key Q {
- label: 'Q'
- number: '7'
- base: 'q'
- shift, capslock: 'Q'
- alt: '\u00e4'
- shift+alt, capslock+alt: '\u00c4'
-}
-
-key R {
- label: 'R'
- number: '7'
- base: 'r'
- shift, capslock: 'R'
- alt: '\u00ae'
- shift+alt, capslock+alt: 'R'
-}
-
-key S {
- label: 'S'
- number: '7'
- base: 's'
- shift, capslock: 'S'
- alt: '\u00df'
- shift+alt, capslock+alt: '\u00a7'
-}
-
-key T {
- label: 'T'
- number: '8'
- base: 't'
- shift, capslock: 'T'
- alt: '\u00fe'
- shift+alt, capslock+alt: '\u00de'
-}
-
-key U {
- label: 'U'
- number: '8'
- base: 'u'
- shift, capslock: 'U'
- alt: '\u00fa'
- shift+alt, capslock+alt: '\u00da'
-}
-
-key V {
- label: 'V'
- number: '8'
- base: 'v'
- shift, capslock: 'V'
- alt: 'v'
- shift+alt, capslock+alt: 'V'
-}
-
-key W {
- label: 'W'
- number: '9'
- base: 'w'
- shift, capslock: 'W'
- alt: '\u00e5'
- shift+alt, capslock+alt: '\u00c5'
-}
-
-key X {
- label: 'X'
- number: '9'
- base: 'x'
- shift, capslock: 'X'
- alt: 'x'
- shift+alt, capslock+alt: '\uef00'
-}
-
-key Y {
- label: 'Y'
- number: '9'
- base: 'y'
- shift, capslock: 'Y'
- alt: '\u00fc'
- shift+alt, capslock+alt: '\u00dc'
-}
-
-key Z {
- label: 'Z'
- number: '9'
- base: 'z'
- shift, capslock: 'Z'
- alt: '\u00e6'
- shift+alt, capslock+alt: '\u00c6'
-}
-
-key COMMA {
- label: ','
- number: ','
- base: ','
- shift: '<'
- alt: '\u00e7'
- shift+alt: '\u00c7'
-}
-
-key PERIOD {
- label: '.'
- number: '.'
- base: '.'
- shift: '>'
- alt: '.'
- shift+alt: '\u2026'
-}
-
-key AT {
- label: '@'
- number: '@'
- base: '@'
- shift: '@'
- alt: '@'
- shift+alt: '\u2022'
-}
-
-key SLASH {
- label: '/'
- number: '/'
- base: '/'
- shift: '?'
- alt: '\u00bf'
- shift+alt: '?'
-}
-
-key SPACE {
- label: ' '
- number: ' '
- base: ' '
- shift: ' '
- alt: '\uef01'
- shift+alt: '\uef01'
-}
-
-key ENTER {
- label: '\n'
- number: '\n'
- base: '\n'
- shift: '\n'
- alt: '\n'
- shift+alt: '\n'
-}
-
-key TAB {
- label: '\t'
- number: '\t'
- base: '\t'
- shift: '\t'
- alt: '\t'
- shift+alt: '\t'
-}
-
-key 0 {
- label: '0'
- number: '0'
- base: '0'
- shift: ')'
- alt: '\u02bc'
- shift+alt: ')'
-}
-
-key 1 {
- label: '1'
- number: '1'
- base: '1'
- shift: '!'
- alt: '\u00a1'
- shift+alt: '\u00b9'
-}
-
-key 2 {
- label: '2'
- number: '2'
- base: '2'
- shift: '@'
- alt: '\u00b2'
- shift+alt: '@'
-}
-
-key 3 {
- label: '3'
- number: '3'
- base: '3'
- shift: '#'
- alt: '\u00b3'
- shift+alt: '#'
-}
-
-key 4 {
- label: '4'
- number: '4'
- base: '4'
- shift: '$'
- alt: '\u00a4'
- shift+alt: '\u00a3'
-}
-
-key 5 {
- label: '5'
- number: '5'
- base: '5'
- shift: '%'
- alt: '\u20ac'
- shift+alt: '%'
-}
-
-key 6 {
- label: '6'
- number: '6'
- base: '6'
- shift: '^'
- alt: '\u00bc'
- shift+alt: '\u0302'
-}
-
-key 7 {
- label: '7'
- number: '7'
- base: '7'
- shift: '&'
- alt: '\u00bd'
- shift+alt: '&'
-}
-
-key 8 {
- label: '8'
- number: '8'
- base: '8'
- shift: '*'
- alt: '\u00be'
- shift+alt: '*'
-}
-
-key 9 {
- label: '9'
- number: '9'
- base: '9'
- shift: '('
- alt: '\u02bb'
- shift+alt: '('
-}
-
-key GRAVE {
- label: '`'
- number: '`'
- base: '`'
- shift: '~'
- alt: '\u0300'
- shift+alt: '\u0303'
-}
-
-key MINUS {
- label: '-'
- number: '-'
- base: '-'
- shift: '_'
- alt: '\u00a5'
- shift+alt: '_'
-}
-
-key EQUALS {
- label: '='
- number: '='
- base: '='
- shift: '+'
- alt: '\u00d7'
- shift+alt: '\u00f7'
-}
-
-key LEFT_BRACKET {
- label: '['
- number: '['
- base: '['
- shift: '{'
- alt: '\u00ab'
- shift+alt: '{'
-}
-
-key RIGHT_BRACKET {
- label: ']'
- number: ']'
- base: ']'
- shift: '}'
- alt: '\u00bb'
- shift+alt: '}'
-}
-
-key BACKSLASH {
- label: '\\'
- number: '\\'
- base: '\\'
- shift: '|'
- alt: '\u00ac'
- shift+alt: '\u00a6'
-}
-
-key SEMICOLON {
- label: ';'
- number: ';'
- base: ';'
- shift: ':'
- alt: '\u00b6'
- shift+alt: '\u00b0'
-}
-
-key APOSTROPHE {
- label: '\''
- number: '\''
- base: '\''
- shift: '"'
- alt: '\u0301'
- shift+alt: '\u0308'
-}
-
-key STAR {
- label: '*'
- number: '*'
- base: '*'
- shift: '*'
- alt: '*'
- shift+alt: '*'
-}
-
-key POUND {
- label: '#'
- number: '#'
- base: '#'
- shift: '#'
- alt: '#'
- shift+alt: '#'
-}
-
-key PLUS {
- label: '+'
- number: '+'
- base: '+'
- shift: '+'
- alt: '+'
- shift+alt: '+'
-}
diff --git a/packages/CredentialManager/horologist/OWNERS b/packages/CredentialManager/horologist/OWNERS
new file mode 100644
index 000000000000..b67932835b4a
--- /dev/null
+++ b/packages/CredentialManager/horologist/OWNERS
@@ -0,0 +1,4 @@
+include /core/java/android/credentials/OWNERS
+
+shuanghao@google.com
+gustavopagani@google.com
diff --git a/packages/CredentialManager/shared/OWNERS b/packages/CredentialManager/shared/OWNERS
new file mode 100644
index 000000000000..b67932835b4a
--- /dev/null
+++ b/packages/CredentialManager/shared/OWNERS
@@ -0,0 +1,4 @@
+include /core/java/android/credentials/OWNERS
+
+shuanghao@google.com
+gustavopagani@google.com
diff --git a/packages/CredentialManager/wear/OWNERS b/packages/CredentialManager/wear/OWNERS
new file mode 100644
index 000000000000..b67932835b4a
--- /dev/null
+++ b/packages/CredentialManager/wear/OWNERS
@@ -0,0 +1,4 @@
+include /core/java/android/credentials/OWNERS
+
+shuanghao@google.com
+gustavopagani@google.com
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index a08f540bb1b1..6507488c73f5 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -549,6 +549,18 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
dispatchErrorMessage(message);
}
+ @Override
+ public void onEnabledTrustAgentsChanged(int userId) {
+ Assert.isMainThread();
+
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onEnabledTrustAgentsChanged(userId);
+ }
+ }
+ }
+
private void handleSimSubscriptionInfoChanged() {
Assert.isMainThread();
mLogger.v("onSubscriptionInfoChanged()");
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index feff216310df..73940055c89f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -322,4 +322,9 @@ public class KeyguardUpdateMonitorCallback {
* Called when keyguard is going away or not going away.
*/
public void onKeyguardGoingAway() { }
+
+ /**
+ * Called when the enabled trust agents associated with the specified user.
+ */
+ public void onEnabledTrustAgentsChanged(int userId) { }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt
index d90f328719bb..e912053a85ca 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt
@@ -75,6 +75,8 @@ constructor(
override fun onTrustError(message: CharSequence?) = Unit
override fun onTrustManagedChanged(enabled: Boolean, userId: Int) = Unit
+
+ override fun onEnabledTrustAgentsChanged(userId: Int) = Unit
}
trustManager.registerTrustListener(callback)
logger.trustListenerRegistered()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
index f1269f2b012a..f4cf4eff8a7a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
@@ -452,5 +452,10 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum
public void onBiometricsCleared() {
update(false /* alwaysUpdate */);
}
+
+ @Override
+ public void onEnabledTrustAgentsChanged(int userId) {
+ update(false /* updateAlways */);
+ }
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index b1051af4ad15..417eb40eab54 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -144,6 +144,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
+import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -722,6 +723,18 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
}
@Test
+ public void testOnEnabledTrustAgentsChangedCallback() {
+ final Random random = new Random();
+ final int userId = random.nextInt();
+ final KeyguardUpdateMonitorCallback callback = mock(KeyguardUpdateMonitorCallback.class);
+
+ mKeyguardUpdateMonitor.registerCallback(callback);
+ mKeyguardUpdateMonitor.onEnabledTrustAgentsChanged(userId);
+
+ verify(callback).onEnabledTrustAgentsChanged(eq(userId));
+ }
+
+ @Test
public void trustAgentHasTrust_fingerprintLockout() {
// GIVEN user has trust
mKeyguardUpdateMonitor.onTrustChanged(true, true, getCurrentUser(), 0, null);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java
index 8f363efd9f51..d787ada90a73 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java
@@ -31,18 +31,23 @@ import androidx.test.filters.SmallTest;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.logging.KeyguardUpdateMonitorLogger;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
+import dagger.Lazy;
+
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 dagger.Lazy;
+import java.util.Random;
+
@SmallTest
@TestableLooper.RunWithLooper
@@ -169,4 +174,19 @@ public class KeyguardStateControllerTest extends SysuiTestCase {
verify(callback).onKeyguardDismissAmountChanged();
}
+ @Test
+ public void testOnEnabledTrustAgentsChangedCallback() {
+ final Random random = new Random();
+ final ArgumentCaptor<KeyguardUpdateMonitorCallback> updateCallbackCaptor =
+ ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class);
+
+ verify(mKeyguardUpdateMonitor).registerCallback(updateCallbackCaptor.capture());
+ final KeyguardStateController.Callback stateCallback =
+ mock(KeyguardStateController.Callback.class);
+ mKeyguardStateController.addCallback(stateCallback);
+
+ when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
+ updateCallbackCaptor.getValue().onEnabledTrustAgentsChanged(random.nextInt());
+ verify(stateCallback).onUnlockedChanged();
+ }
}
diff --git a/services/backup/backuplib/java/com/android/server/backup/TransportManager.java b/services/backup/backuplib/java/com/android/server/backup/TransportManager.java
index 930f49e4d117..ff5f509fb11b 100644
--- a/services/backup/backuplib/java/com/android/server/backup/TransportManager.java
+++ b/services/backup/backuplib/java/com/android/server/backup/TransportManager.java
@@ -706,6 +706,9 @@ public class TransportManager {
try {
String transportName = transport.name();
String transportDirName = transport.transportDirName();
+ if (transportName == null || transportDirName == null) {
+ return BackupManager.ERROR_TRANSPORT_INVALID;
+ }
registerTransport(transportComponent, transport);
// If registerTransport() hasn't thrown...
Slog.d(TAG, "Transport " + transportString + " registered");
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
index 846c2d9f3df7..a53d09678cd3 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
@@ -433,6 +433,11 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage
}
@Override
+ public void onEnabledTrustAgentsChanged(int userId) {
+
+ }
+
+ @Override
@NonNull
public List<FingerprintSensorPropertiesInternal> getSensorProperties() {
final List<FingerprintSensorPropertiesInternal> properties = new ArrayList<>();
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 2ef82d74ee37..e3abf0c43397 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -53,6 +53,7 @@ import android.os.Bundle;
import android.os.DeadObjectException;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.os.Message;
import android.os.PersistableBundle;
import android.os.RemoteException;
@@ -150,6 +151,8 @@ public class TrustManagerService extends SystemService {
private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
private final Receiver mReceiver = new Receiver();
+ private final Handler mHandler;
+
/* package */ final TrustArchive mArchive = new TrustArchive();
private final Context mContext;
private final LockPatternUtils mLockPatternUtils;
@@ -240,13 +243,40 @@ public class TrustManagerService extends SystemService {
private boolean mTrustAgentsCanRun = false;
private int mCurrentUser = UserHandle.USER_SYSTEM;
+ /**
+ * A class for providing dependencies to {@link TrustManagerService} in both production and test
+ * cases.
+ */
+ protected static class Injector {
+ private final LockPatternUtils mLockPatternUtils;
+ private final Looper mLooper;
+
+ public Injector(LockPatternUtils lockPatternUtils, Looper looper) {
+ mLockPatternUtils = lockPatternUtils;
+ mLooper = looper;
+ }
+
+ LockPatternUtils getLockPatternUtils() {
+ return mLockPatternUtils;
+ }
+
+ Looper getLooper() {
+ return mLooper;
+ }
+ }
+
public TrustManagerService(Context context) {
+ this(context, new Injector(new LockPatternUtils(context), Looper.myLooper()));
+ }
+
+ protected TrustManagerService(Context context, Injector injector) {
super(context);
mContext = context;
+ mHandler = createHandler(injector.getLooper());
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
- mLockPatternUtils = new LockPatternUtils(context);
- mStrongAuthTracker = new StrongAuthTracker(context);
+ mLockPatternUtils = injector.getLockPatternUtils();
+ mStrongAuthTracker = new StrongAuthTracker(context, injector.getLooper());
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
mSettingsObserver = new SettingsObserver(mHandler);
}
@@ -1392,6 +1422,23 @@ public class TrustManagerService extends SystemService {
}
}
+ private void dispatchOnEnabledTrustAgentsChanged(int userId) {
+ if (DEBUG) {
+ Log.i(TAG, "onEnabledTrustAgentsChanged(" + userId + ")");
+ }
+ for (int i = 0; i < mTrustListeners.size(); i++) {
+ try {
+ mTrustListeners.get(i).onEnabledTrustAgentsChanged(userId);
+ } catch (DeadObjectException e) {
+ Slog.d(TAG, "Removing dead TrustListener.");
+ mTrustListeners.remove(i);
+ i--;
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Exception while notifying TrustListener.", e);
+ }
+ }
+ }
+
private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
if (DEBUG) {
Log.i(TAG, "onTrustManagedChanged(" + managed + ", " + userId + ")");
@@ -1495,9 +1542,7 @@ public class TrustManagerService extends SystemService {
@Override
public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
enforceReportPermission();
- // coalesce refresh messages.
- mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
- mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
+ mHandler.obtainMessage(MSG_ENABLED_AGENTS_CHANGED, userId, 0).sendToTarget();
}
@Override
@@ -1808,88 +1853,91 @@ public class TrustManagerService extends SystemService {
}
}
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_REGISTER_LISTENER:
- addListener((ITrustListener) msg.obj);
- break;
- case MSG_UNREGISTER_LISTENER:
- removeListener((ITrustListener) msg.obj);
- break;
- case MSG_DISPATCH_UNLOCK_ATTEMPT:
- dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
- break;
- case MSG_USER_REQUESTED_UNLOCK:
- dispatchUserRequestedUnlock(msg.arg1, msg.arg2 != 0);
- break;
- case MSG_USER_MAY_REQUEST_UNLOCK:
- dispatchUserMayRequestUnlock(msg.arg1);
- break;
- case MSG_DISPATCH_UNLOCK_LOCKOUT:
- dispatchUnlockLockout(msg.arg1, msg.arg2);
- break;
- case MSG_ENABLED_AGENTS_CHANGED:
- refreshAgentList(UserHandle.USER_ALL);
- // This is also called when the security mode of a user changes.
- refreshDeviceLockedForUser(UserHandle.USER_ALL);
- break;
- case MSG_KEYGUARD_SHOWING_CHANGED:
- dispatchTrustableDowngrade();
- refreshDeviceLockedForUser(mCurrentUser);
- break;
- case MSG_START_USER:
- case MSG_CLEANUP_USER:
- case MSG_UNLOCK_USER:
- refreshAgentList(msg.arg1);
- break;
- case MSG_SWITCH_USER:
- mCurrentUser = msg.arg1;
- mSettingsObserver.updateContentObserver();
- refreshDeviceLockedForUser(UserHandle.USER_ALL);
- break;
- case MSG_STOP_USER:
- setDeviceLockedForUser(msg.arg1, true);
- break;
- case MSG_FLUSH_TRUST_USUALLY_MANAGED:
- SparseBooleanArray usuallyManaged;
- synchronized (mTrustUsuallyManagedForUser) {
- usuallyManaged = mTrustUsuallyManagedForUser.clone();
- }
+ private Handler createHandler(Looper looper) {
+ return new Handler(looper) {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_REGISTER_LISTENER:
+ addListener((ITrustListener) msg.obj);
+ break;
+ case MSG_UNREGISTER_LISTENER:
+ removeListener((ITrustListener) msg.obj);
+ break;
+ case MSG_DISPATCH_UNLOCK_ATTEMPT:
+ dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
+ break;
+ case MSG_USER_REQUESTED_UNLOCK:
+ dispatchUserRequestedUnlock(msg.arg1, msg.arg2 != 0);
+ break;
+ case MSG_USER_MAY_REQUEST_UNLOCK:
+ dispatchUserMayRequestUnlock(msg.arg1);
+ break;
+ case MSG_DISPATCH_UNLOCK_LOCKOUT:
+ dispatchUnlockLockout(msg.arg1, msg.arg2);
+ break;
+ case MSG_ENABLED_AGENTS_CHANGED:
+ refreshAgentList(UserHandle.USER_ALL);
+ // This is also called when the security mode of a user changes.
+ refreshDeviceLockedForUser(UserHandle.USER_ALL);
+ dispatchOnEnabledTrustAgentsChanged(msg.arg1);
+ break;
+ case MSG_KEYGUARD_SHOWING_CHANGED:
+ dispatchTrustableDowngrade();
+ refreshDeviceLockedForUser(mCurrentUser);
+ break;
+ case MSG_START_USER:
+ case MSG_CLEANUP_USER:
+ case MSG_UNLOCK_USER:
+ refreshAgentList(msg.arg1);
+ break;
+ case MSG_SWITCH_USER:
+ mCurrentUser = msg.arg1;
+ mSettingsObserver.updateContentObserver();
+ refreshDeviceLockedForUser(UserHandle.USER_ALL);
+ break;
+ case MSG_STOP_USER:
+ setDeviceLockedForUser(msg.arg1, true);
+ break;
+ case MSG_FLUSH_TRUST_USUALLY_MANAGED:
+ SparseBooleanArray usuallyManaged;
+ synchronized (mTrustUsuallyManagedForUser) {
+ usuallyManaged = mTrustUsuallyManagedForUser.clone();
+ }
- for (int i = 0; i < usuallyManaged.size(); i++) {
- int userId = usuallyManaged.keyAt(i);
- boolean value = usuallyManaged.valueAt(i);
- if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
- mLockPatternUtils.setTrustUsuallyManaged(value, userId);
+ for (int i = 0; i < usuallyManaged.size(); i++) {
+ int userId = usuallyManaged.keyAt(i);
+ boolean value = usuallyManaged.valueAt(i);
+ if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
+ mLockPatternUtils.setTrustUsuallyManaged(value, userId);
+ }
}
- }
- break;
- case MSG_REFRESH_DEVICE_LOCKED_FOR_USER:
- if (msg.arg2 == 1) {
- updateTrust(msg.arg1, 0 /* flags */, true /* isFromUnlock */, null);
- }
- final int unlockedUser = msg.getData().getInt(
- REFRESH_DEVICE_LOCKED_EXCEPT_USER, UserHandle.USER_NULL);
- refreshDeviceLockedForUser(msg.arg1, unlockedUser);
- break;
- case MSG_SCHEDULE_TRUST_TIMEOUT:
- boolean shouldOverride = msg.arg1 == 1 ? true : false;
- TimeoutType timeoutType =
- msg.arg2 == 1 ? TimeoutType.TRUSTABLE : TimeoutType.TRUSTED;
- handleScheduleTrustTimeout(shouldOverride, timeoutType);
- break;
- case MSG_REFRESH_TRUSTABLE_TIMERS_AFTER_AUTH:
- TrustableTimeoutAlarmListener trustableAlarm =
- mTrustableTimeoutAlarmListenerForUser.get(msg.arg1);
- if (trustableAlarm != null && trustableAlarm.isQueued()) {
- refreshTrustableTimers(msg.arg1);
- }
- break;
+ break;
+ case MSG_REFRESH_DEVICE_LOCKED_FOR_USER:
+ if (msg.arg2 == 1) {
+ updateTrust(msg.arg1, 0 /* flags */, true /* isFromUnlock */, null);
+ }
+ final int unlockedUser = msg.getData().getInt(
+ REFRESH_DEVICE_LOCKED_EXCEPT_USER, UserHandle.USER_NULL);
+ refreshDeviceLockedForUser(msg.arg1, unlockedUser);
+ break;
+ case MSG_SCHEDULE_TRUST_TIMEOUT:
+ boolean shouldOverride = msg.arg1 == 1 ? true : false;
+ TimeoutType timeoutType =
+ msg.arg2 == 1 ? TimeoutType.TRUSTABLE : TimeoutType.TRUSTED;
+ handleScheduleTrustTimeout(shouldOverride, timeoutType);
+ break;
+ case MSG_REFRESH_TRUSTABLE_TIMERS_AFTER_AUTH:
+ TrustableTimeoutAlarmListener trustableAlarm =
+ mTrustableTimeoutAlarmListenerForUser.get(msg.arg1);
+ if (trustableAlarm != null && trustableAlarm.isQueued()) {
+ refreshTrustableTimers(msg.arg1);
+ }
+ break;
+ }
}
- }
- };
+ };
+ }
private final PackageMonitor mPackageMonitor = new PackageMonitor() {
@Override
@@ -1987,8 +2035,8 @@ public class TrustManagerService extends SystemService {
SparseBooleanArray mStartFromSuccessfulUnlock = new SparseBooleanArray();
- public StrongAuthTracker(Context context) {
- super(context);
+ StrongAuthTracker(Context context, Looper looper) {
+ super(context, looper);
}
@Override
diff --git a/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java
index 33870f1d3b86..9851bc1b4be3 100644
--- a/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java
@@ -16,15 +16,26 @@
package com.android.server.trust;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.argThat;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+
+import android.Manifest;
import android.annotation.Nullable;
+import android.app.trust.ITrustListener;
+import android.app.trust.ITrustManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -36,11 +47,16 @@ import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.net.Uri;
import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.test.TestLooper;
import android.provider.Settings;
import android.service.trust.TrustAgentService;
import android.testing.TestableContext;
+import android.view.IWindowManager;
+import android.view.WindowManagerGlobal;
import androidx.test.core.app.ApplicationProvider;
@@ -55,13 +71,16 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
+import org.mockito.MockitoSession;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Random;
public class TrustManagerServiceTest {
@@ -255,6 +274,43 @@ public class TrustManagerServiceTest {
systemTrustAgent1);
}
+ @Test
+ public void reportEnabledTrustAgentsChangedInformsListener() throws RemoteException {
+ final LockPatternUtils utils = mock(LockPatternUtils.class);
+ final TrustManagerService service = new TrustManagerService(mMockContext,
+ new TrustManagerService.Injector(utils, mLooper.getLooper()));
+ final ITrustListener trustListener = mock(ITrustListener.class);
+ final IWindowManager windowManager = mock(IWindowManager.class);
+ final int userId = new Random().nextInt();
+
+ mMockContext.getTestablePermissions().setPermission(Manifest.permission.TRUST_LISTENER,
+ PERMISSION_GRANTED);
+
+ when(utils.getKnownTrustAgents(anyInt())).thenReturn(new ArrayList<>());
+
+ MockitoSession mockSession = mockitoSession()
+ .initMocks(this)
+ .mockStatic(ServiceManager.class)
+ .mockStatic(WindowManagerGlobal.class)
+ .startMocking();
+
+ doReturn(windowManager).when(() -> {
+ WindowManagerGlobal.getWindowManagerService();
+ });
+
+ service.onStart();
+ ArgumentCaptor<IBinder> binderArgumentCaptor = ArgumentCaptor.forClass(IBinder.class);
+ verify(() -> ServiceManager.addService(eq(Context.TRUST_SERVICE),
+ binderArgumentCaptor.capture(), anyBoolean(), anyInt()));
+ ITrustManager manager = ITrustManager.Stub.asInterface(binderArgumentCaptor.getValue());
+ manager.registerTrustListener(trustListener);
+ mLooper.dispatchAll();
+ manager.reportEnabledTrustAgentsChanged(userId);
+ mLooper.dispatchAll();
+ verify(trustListener).onEnabledTrustAgentsChanged(eq(userId));
+ mockSession.finishMocking();
+ }
+
private void addTrustAgent(ComponentName agentComponentName, boolean isSystemApp) {
ApplicationInfo applicationInfo = new ApplicationInfo();
if (isSystemApp) {
diff --git a/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt b/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt
index 583cfc781bd0..fe47fde9b268 100644
--- a/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt
+++ b/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt
@@ -96,6 +96,9 @@ class LockStateTrackingRule : TestRule {
override fun onTrustError(message: CharSequence) {
}
+
+ override fun onEnabledTrustAgentsChanged(userId: Int) {
+ }
}
data class TrustState(