diff options
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( |