diff options
83 files changed, 1490 insertions, 668 deletions
diff --git a/StubLibraries.bp b/StubLibraries.bp index fef95e813ec7..32101c791242 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -208,6 +208,16 @@ droidstubs { ///////////////////////////////////////////////////////////////////// java_defaults { + name: "android.jar_defaults", + sdk_version: "none", + system_modules: "none", + java_version: "1.8", + compile_dex: true, + defaults_visibility: ["//visibility:private"], + visibility: ["//visibility:public"], +} + +java_defaults { name: "android-non-updatable_defaults_stubs_current", libs: ["stub-annotations"], static_libs: ["framework-res-package-jar"], // Export package of framework-res diff --git a/cmds/svc/src/com/android/commands/svc/BluetoothCommand.java b/cmds/svc/src/com/android/commands/svc/BluetoothCommand.java deleted file mode 100644 index b572ce24390c..000000000000 --- a/cmds/svc/src/com/android/commands/svc/BluetoothCommand.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.commands.svc; - -import android.bluetooth.BluetoothAdapter; -import android.os.RemoteException; - -public class BluetoothCommand extends Svc.Command { - - public BluetoothCommand() { - super("bluetooth"); - } - - @Override - public String shortHelp() { - return "Control Bluetooth service"; - } - - @Override - public String longHelp() { - return shortHelp() + "\n" - + "\n" - + "usage: svc bluetooth [enable|disable]\n" - + " Turn Bluetooth on or off.\n\n"; - } - - @Override - public void run(String[] args) { - BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); - - if (adapter == null) { - System.err.println("Got a null BluetoothAdapter, is the system running?"); - return; - } - - if (args.length == 2 && "enable".equals(args[1])) { - adapter.enable(); - } else if (args.length == 2 && "disable".equals(args[1])) { - adapter.disable(); - } else { - System.err.println(longHelp()); - } - } -} diff --git a/cmds/svc/src/com/android/commands/svc/Svc.java b/cmds/svc/src/com/android/commands/svc/Svc.java index 2ed2678bc877..bbad984746a1 100644 --- a/cmds/svc/src/com/android/commands/svc/Svc.java +++ b/cmds/svc/src/com/android/commands/svc/Svc.java @@ -96,7 +96,7 @@ public class Svc { // `svc wifi` has been migrated to WifiShellCommand new UsbCommand(), new NfcCommand(), - new BluetoothCommand(), + // `svc bluetooth` has been migrated to BluetoothShellCommand new SystemServerCommand(), }; } diff --git a/cmds/svc/svc b/cmds/svc/svc index 95265e817c1b..a2c9de32b3d0 100755 --- a/cmds/svc/svc +++ b/cmds/svc/svc @@ -33,6 +33,25 @@ if [ "x$1" == "xdata" ]; then exit 1 fi +# `svc bluetooth` has been migrated to BluetoothShellCommand, +# simply perform translation to `cmd bluetooth set-bluetooth-enabled` here. +if [ "x$1" == "xbluetooth" ]; then + # `cmd wifi` by convention uses enabled/disabled + # instead of enable/disable + if [ "x$2" == "xenable" ]; then + exec cmd bluetooth_manager enable + elif [ "x$2" == "xdisable" ]; then + exec cmd bluetooth_manager disable + else + echo "Control the Bluetooth manager" + echo "" + echo "usage: svc bluetooth [enable|disable]" + echo " Turn Bluetooth on or off." + echo "" + fi + exit 1 +fi + export CLASSPATH=/system/framework/svc.jar exec app_process /system/bin com.android.commands.svc.Svc "$@" diff --git a/core/api/current.txt b/core/api/current.txt index dbc2a519214e..88f4eecbaaa4 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -30532,6 +30532,7 @@ package android.os { method public static final boolean is64Bit(); method public static boolean isApplicationUid(int); method public static final boolean isIsolated(); + method public static final boolean isSdkSandbox(); method public static final void killProcess(int); method public static final int myPid(); method public static final int myTid(); @@ -41759,9 +41760,12 @@ package android.telephony { field public static final int DATA_DISCONNECTED = 0; // 0x0 field public static final int DATA_DISCONNECTING = 4; // 0x4 field public static final int DATA_ENABLED_REASON_CARRIER = 2; // 0x2 + field public static final int DATA_ENABLED_REASON_OVERRIDE = 4; // 0x4 field public static final int DATA_ENABLED_REASON_POLICY = 1; // 0x1 field public static final int DATA_ENABLED_REASON_THERMAL = 3; // 0x3 + field public static final int DATA_ENABLED_REASON_UNKNOWN = -1; // 0xffffffff field public static final int DATA_ENABLED_REASON_USER = 0; // 0x0 + field public static final int DATA_HANDOVER_IN_PROGRESS = 5; // 0x5 field public static final int DATA_SUSPENDED = 3; // 0x3 field public static final int DATA_UNKNOWN = -1; // 0xffffffff field public static final int ERI_FLASH = 2; // 0x2 @@ -42030,6 +42034,8 @@ package android.telephony.data { method public String getMmsProxyAddressAsString(); method public int getMmsProxyPort(); method public android.net.Uri getMmsc(); + method public int getMtuV4(); + method public int getMtuV6(); method public int getMvnoType(); method public int getNetworkTypeBitmask(); method public String getOperatorNumeric(); @@ -42062,6 +42068,7 @@ package android.telephony.data { field public static final int TYPE_DEFAULT = 17; // 0x11 field public static final int TYPE_DUN = 8; // 0x8 field public static final int TYPE_EMERGENCY = 512; // 0x200 + field public static final int TYPE_ENTERPRISE = 16384; // 0x4000 field public static final int TYPE_FOTA = 32; // 0x20 field public static final int TYPE_HIPRI = 16; // 0x10 field public static final int TYPE_IA = 256; // 0x100 @@ -42086,10 +42093,14 @@ package android.telephony.data { method @NonNull public android.telephony.data.ApnSetting.Builder setMmsProxyAddress(@Nullable String); method @NonNull public android.telephony.data.ApnSetting.Builder setMmsProxyPort(int); method @NonNull public android.telephony.data.ApnSetting.Builder setMmsc(@Nullable android.net.Uri); + method @NonNull public android.telephony.data.ApnSetting.Builder setMtuV4(int); + method @NonNull public android.telephony.data.ApnSetting.Builder setMtuV6(int); method @NonNull public android.telephony.data.ApnSetting.Builder setMvnoType(int); method @NonNull public android.telephony.data.ApnSetting.Builder setNetworkTypeBitmask(int); method @NonNull public android.telephony.data.ApnSetting.Builder setOperatorNumeric(@Nullable String); method @NonNull public android.telephony.data.ApnSetting.Builder setPassword(@Nullable String); + method @NonNull public android.telephony.data.ApnSetting.Builder setPersistent(boolean); + method @NonNull public android.telephony.data.ApnSetting.Builder setProfileId(int); method @NonNull public android.telephony.data.ApnSetting.Builder setProtocol(int); method @Deprecated public android.telephony.data.ApnSetting.Builder setProxyAddress(java.net.InetAddress); method @NonNull public android.telephony.data.ApnSetting.Builder setProxyAddress(@Nullable String); diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index a9f0d2e54b21..a6278f87f485 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -290,6 +290,9 @@ package android.os { } public class Process { + method public static final int getAppUidForSdkSandboxUid(int); + method public static final boolean isSdkSandboxUid(int); + method public static final int toSdkSandboxUid(int); field public static final int NFC_UID = 1027; // 0x403 field public static final int VPN_UID = 1016; // 0x3f8 } diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 80ee1a583aa9..bb9af143b4b4 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -7089,7 +7089,7 @@ package android.net { public final class EthernetNetworkUpdateRequest implements android.os.Parcelable { method public int describeContents(); method @NonNull public android.net.IpConfiguration getIpConfiguration(); - method @NonNull public android.net.NetworkCapabilities getNetworkCapabilities(); + method @Nullable public android.net.NetworkCapabilities getNetworkCapabilities(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.net.EthernetNetworkUpdateRequest> CREATOR; } @@ -7099,7 +7099,7 @@ package android.net { ctor public EthernetNetworkUpdateRequest.Builder(@NonNull android.net.EthernetNetworkUpdateRequest); method @NonNull public android.net.EthernetNetworkUpdateRequest build(); method @NonNull public android.net.EthernetNetworkUpdateRequest.Builder setIpConfiguration(@NonNull android.net.IpConfiguration); - method @NonNull public android.net.EthernetNetworkUpdateRequest.Builder setNetworkCapabilities(@NonNull android.net.NetworkCapabilities); + method @NonNull public android.net.EthernetNetworkUpdateRequest.Builder setNetworkCapabilities(@Nullable android.net.NetworkCapabilities); } public final class MatchAllNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable { @@ -11999,6 +11999,7 @@ package android.telephony.data { field public static final String TYPE_DEFAULT_STRING = "default"; field public static final String TYPE_DUN_STRING = "dun"; field public static final String TYPE_EMERGENCY_STRING = "emergency"; + field public static final String TYPE_ENTERPRISE_STRING = "enterprise"; field public static final String TYPE_FOTA_STRING = "fota"; field public static final String TYPE_HIPRI_STRING = "hipri"; field public static final String TYPE_IA_STRING = "ia"; @@ -12070,21 +12071,23 @@ package android.telephony.data { public final class DataProfile implements android.os.Parcelable { method public int describeContents(); - method @NonNull public String getApn(); - method public int getAuthType(); - method public int getBearerBitmask(); + method @Deprecated @NonNull public String getApn(); + method @Nullable public android.telephony.data.ApnSetting getApnSetting(); + method @Deprecated public int getAuthType(); + method @Deprecated public int getBearerBitmask(); method @Deprecated public int getMtu(); - method public int getMtuV4(); - method public int getMtuV6(); - method @Nullable public String getPassword(); - method public int getProfileId(); - method public int getProtocolType(); - method public int getRoamingProtocolType(); - method public int getSupportedApnTypesBitmask(); + method @Deprecated public int getMtuV4(); + method @Deprecated public int getMtuV6(); + method @Deprecated @Nullable public String getPassword(); + method @Deprecated public int getProfileId(); + method @Deprecated public int getProtocolType(); + method @Deprecated public int getRoamingProtocolType(); + method @Deprecated public int getSupportedApnTypesBitmask(); + method @Nullable public android.telephony.data.TrafficDescriptor getTrafficDescriptor(); method public int getType(); - method @Nullable public String getUserName(); + method @Deprecated @Nullable public String getUserName(); method public boolean isEnabled(); - method public boolean isPersistent(); + method @Deprecated public boolean isPersistent(); method public boolean isPreferred(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.DataProfile> CREATOR; @@ -12097,21 +12100,23 @@ package android.telephony.data { ctor public DataProfile.Builder(); method @NonNull public android.telephony.data.DataProfile build(); method @NonNull public android.telephony.data.DataProfile.Builder enable(boolean); - method @NonNull public android.telephony.data.DataProfile.Builder setApn(@NonNull String); - method @NonNull public android.telephony.data.DataProfile.Builder setAuthType(int); - method @NonNull public android.telephony.data.DataProfile.Builder setBearerBitmask(int); + method @Deprecated @NonNull public android.telephony.data.DataProfile.Builder setApn(@NonNull String); + method @NonNull public android.telephony.data.DataProfile.Builder setApnSetting(@NonNull android.telephony.data.ApnSetting); + method @Deprecated @NonNull public android.telephony.data.DataProfile.Builder setAuthType(int); + method @Deprecated @NonNull public android.telephony.data.DataProfile.Builder setBearerBitmask(int); method @Deprecated @NonNull public android.telephony.data.DataProfile.Builder setMtu(int); - method @NonNull public android.telephony.data.DataProfile.Builder setMtuV4(int); - method @NonNull public android.telephony.data.DataProfile.Builder setMtuV6(int); - method @NonNull public android.telephony.data.DataProfile.Builder setPassword(@NonNull String); - method @NonNull public android.telephony.data.DataProfile.Builder setPersistent(boolean); + method @Deprecated @NonNull public android.telephony.data.DataProfile.Builder setMtuV4(int); + method @Deprecated @NonNull public android.telephony.data.DataProfile.Builder setMtuV6(int); + method @Deprecated @NonNull public android.telephony.data.DataProfile.Builder setPassword(@NonNull String); + method @Deprecated @NonNull public android.telephony.data.DataProfile.Builder setPersistent(boolean); method @NonNull public android.telephony.data.DataProfile.Builder setPreferred(boolean); - method @NonNull public android.telephony.data.DataProfile.Builder setProfileId(int); - method @NonNull public android.telephony.data.DataProfile.Builder setProtocolType(int); - method @NonNull public android.telephony.data.DataProfile.Builder setRoamingProtocolType(int); - method @NonNull public android.telephony.data.DataProfile.Builder setSupportedApnTypesBitmask(int); + method @Deprecated @NonNull public android.telephony.data.DataProfile.Builder setProfileId(int); + method @Deprecated @NonNull public android.telephony.data.DataProfile.Builder setProtocolType(int); + method @Deprecated @NonNull public android.telephony.data.DataProfile.Builder setRoamingProtocolType(int); + method @Deprecated @NonNull public android.telephony.data.DataProfile.Builder setSupportedApnTypesBitmask(int); + method @NonNull public android.telephony.data.DataProfile.Builder setTrafficDescriptor(@NonNull android.telephony.data.TrafficDescriptor); method @NonNull public android.telephony.data.DataProfile.Builder setType(int); - method @NonNull public android.telephony.data.DataProfile.Builder setUserName(@NonNull String); + method @Deprecated @NonNull public android.telephony.data.DataProfile.Builder setUserName(@NonNull String); } public abstract class DataService extends android.app.Service { diff --git a/core/api/test-current.txt b/core/api/test-current.txt index b631b7404c8e..252ca4d7c855 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1718,7 +1718,10 @@ package android.os { } public class Process { + method public static final int getAppUidForSdkSandboxUid(int); method public static final int getThreadScheduler(int) throws java.lang.IllegalArgumentException; + method public static final boolean isSdkSandboxUid(int); + method public static final int toSdkSandboxUid(int); field public static final int FIRST_APP_ZYGOTE_ISOLATED_UID = 90000; // 0x15f90 field public static final int FIRST_ISOLATED_UID = 99000; // 0x182b8 field public static final int LAST_APP_ZYGOTE_ISOLATED_UID = 98999; // 0x182b7 diff --git a/core/java/android/content/pm/IPackageInstallerSession.aidl b/core/java/android/content/pm/IPackageInstallerSession.aidl index f72288c670d9..9a7a949e3cd2 100644 --- a/core/java/android/content/pm/IPackageInstallerSession.aidl +++ b/core/java/android/content/pm/IPackageInstallerSession.aidl @@ -55,4 +55,5 @@ interface IPackageInstallerSession { int getParentSessionId(); boolean isStaged(); + int getInstallFlags(); } diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 3f8aedb31ea9..4030708d6a53 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -1432,6 +1432,18 @@ public class PackageInstaller { } /** + * @return Session's {@link SessionParams#installFlags}. + * @hide + */ + public int getInstallFlags() { + try { + return mSession.getInstallFlags(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * @return the session ID of the multi-package session that this belongs to or * {@link SessionInfo#INVALID_ID} if it does not belong to a multi-package session. */ diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java index a19b51b7811b..cf28c1639fac 100644 --- a/core/java/android/os/Bundle.java +++ b/core/java/android/os/Bundle.java @@ -989,7 +989,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { * Otherwise, this method might throw an exception or return {@code null}. * * @param key a String, or {@code null} - * @param clazz The type of the items inside the array + * @param clazz The type of the items inside the array. This is only verified when unparceling. * @return a Parcelable[] value, or {@code null} */ @SuppressLint({"ArrayReturn", "NullableCollection"}) @@ -1053,7 +1053,8 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { * Otherwise, this method might throw an exception or return {@code null}. * * @param key a String, or {@code null} - * @param clazz The type of the items inside the array list + * @param clazz The type of the items inside the array list. This is only verified when + * unparceling. * @return an ArrayList<T> value, or {@code null} */ @SuppressLint("NullableCollection") @@ -1103,6 +1104,8 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { * </ul> * * @param key a String, or null + * @param clazz The type of the items inside the sparse array. This is only verified when + * unparceling. * @return a SparseArray of T values, or null */ @SuppressWarnings("unchecked") diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java index 010459d06e8d..9e47a708162d 100644 --- a/core/java/android/os/IBinder.java +++ b/core/java/android/os/IBinder.java @@ -293,7 +293,10 @@ public interface IBinder { * * @return Returns the result from {@link Binder#onTransact}. A successful call * generally returns true; false generally means the transaction code was not - * understood. + * understood. For a oneway call to a different process false should never be + * returned. If a oneway call is made to code in the same process (usually to + * a C++ or Rust implementation), then there are no oneway semantics, and + * false can still be returned. */ public boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException; diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 2030571dffe9..a5395bdf1d56 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -277,6 +277,26 @@ public class Process { public static final int LAST_APPLICATION_UID = 19999; /** + * Defines the start of a range of UIDs going from this number to + * {@link #LAST_SDK_SANDBOX_UID} that are reserved for assigning to + * sdk sandbox processes. There is a 1-1 mapping between a sdk sandbox + * process UID and the app that it belongs to, which can be computed by + * subtracting (FIRST_SDK_SANDBOX_UID - FIRST_APPLICATION_UID) from the + * uid of a sdk sandbox process. + * + * Note that there are no GIDs associated with these processes; storage + * attribution for them will be done using project IDs. + * @hide + */ + public static final int FIRST_SDK_SANDBOX_UID = 20000; + + /** + * Last UID that is used for sdk sandbox processes. + * @hide + */ + public static final int LAST_SDK_SANDBOX_UID = 29999; + + /** * First uid used for fully isolated sandboxed processes spawned from an app zygote * @hide */ @@ -351,7 +371,7 @@ public class Process { * ** Keep in sync with utils/threads.h ** * *************************************** */ - + /** * Lowest available thread priority. Only for those who really, really * don't want to run if anything else is happening. @@ -360,7 +380,7 @@ public class Process { * {@link java.lang.Thread} class. */ public static final int THREAD_PRIORITY_LOWEST = 19; - + /** * Standard priority background threads. This gives your thread a slightly * lower than normal priority, so that it will have less chance of impacting @@ -370,7 +390,7 @@ public class Process { * {@link java.lang.Thread} class. */ public static final int THREAD_PRIORITY_BACKGROUND = 10; - + /** * Standard priority of threads that are currently running a user interface * that the user is interacting with. Applications can not normally @@ -381,7 +401,7 @@ public class Process { * {@link java.lang.Thread} class. */ public static final int THREAD_PRIORITY_FOREGROUND = -2; - + /** * Standard priority of system display threads, involved in updating * the user interface. Applications can not @@ -391,7 +411,7 @@ public class Process { * {@link java.lang.Thread} class. */ public static final int THREAD_PRIORITY_DISPLAY = -4; - + /** * Standard priority of the most important display threads, for compositing * the screen and retrieving input events. Applications can not normally @@ -608,19 +628,19 @@ public class Process { /** * Start a new process. - * + * * <p>If processes are enabled, a new process is created and the * static main() function of a <var>processClass</var> is executed there. * The process will continue running after this function returns. - * + * * <p>If processes are not enabled, a new thread in the caller's * process is created and main() of <var>processClass</var> called there. - * + * * <p>The niceName parameter, if not an empty string, is a custom name to * give to the process instead of using processClass. This allows you to * make easily identifyable processes even if you are using the same base * <var>processClass</var> to start them. - * + * * When invokeWith is not null, the process will be started as a fresh app * and not a zygote fork. Note that this is only allowed for uid 0 or when * runtimeFlags contains DEBUG_ENABLE_DEBUGGER. @@ -822,12 +842,55 @@ public class Process { } /** + * Returns whether the provided UID belongs to a SDK sandbox process. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + @TestApi + public static final boolean isSdkSandboxUid(int uid) { + uid = UserHandle.getAppId(uid); + return (uid >= FIRST_SDK_SANDBOX_UID && uid <= LAST_SDK_SANDBOX_UID); + } + + /** + * + * Returns the app process corresponding to an sdk sandbox process. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + @TestApi + public static final int getAppUidForSdkSandboxUid(int uid) { + return uid - (FIRST_SDK_SANDBOX_UID - FIRST_APPLICATION_UID); + } + + /** + * + * Returns the sdk sandbox process corresponding to an app process. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + @TestApi + public static final int toSdkSandboxUid(int uid) { + return uid + (FIRST_SDK_SANDBOX_UID - FIRST_APPLICATION_UID); + } + + /** + * Returns whether the current process is a sdk sandbox process. + */ + public static final boolean isSdkSandbox() { + return isSdkSandboxUid(myUid()); + } + + /** * Returns the UID assigned to a particular user name, or -1 if there is * none. If the given string consists of only numbers, it is converted * directly to a uid. */ public static final native int getUidForName(String name); - + /** * Returns the GID assigned to a particular user name, or -1 if there is * none. If the given string consists of only numbers, it is converted @@ -882,11 +945,11 @@ public class Process { /** * Set the priority of a thread, based on Linux priorities. - * + * * @param tid The identifier of the thread/process to change. * @param priority A Linux priority level, from -20 for highest scheduling * priority to 19 for lowest scheduling priority. - * + * * @throws IllegalArgumentException Throws IllegalArgumentException if * <var>tid</var> does not exist. * @throws SecurityException Throws SecurityException if your process does @@ -945,7 +1008,7 @@ public class Process { * @hide * @param pid The identifier of the process to change. * @param group The target group for this process from THREAD_GROUP_*. - * + * * @throws IllegalArgumentException Throws IllegalArgumentException if * <var>tid</var> does not exist. * @throws SecurityException Throws SecurityException if your process does @@ -1034,37 +1097,37 @@ public class Process { /** * Set the priority of the calling thread, based on Linux priorities. See * {@link #setThreadPriority(int, int)} for more information. - * + * * @param priority A Linux priority level, from -20 for highest scheduling * priority to 19 for lowest scheduling priority. - * + * * @throws IllegalArgumentException Throws IllegalArgumentException if * <var>tid</var> does not exist. * @throws SecurityException Throws SecurityException if your process does * not have permission to modify the given thread, or to use the given * priority. - * + * * @see #setThreadPriority(int, int) */ public static final native void setThreadPriority(int priority) throws IllegalArgumentException, SecurityException; - + /** * Return the current priority of a thread, based on Linux priorities. - * + * * @param tid The identifier of the thread/process. If tid equals zero, the priority of the * calling process/thread will be returned. - * + * * @return Returns the current priority, as a Linux priority level, * from -20 for highest scheduling priority to 19 for lowest scheduling * priority. - * + * * @throws IllegalArgumentException Throws IllegalArgumentException if * <var>tid</var> does not exist. */ public static final native int getThreadPriority(int tid) throws IllegalArgumentException; - + /** * Return the current scheduling policy of a thread, based on Linux. * @@ -1078,7 +1141,7 @@ public class Process { * * {@hide} */ - + @TestApi public static final native int getThreadScheduler(int tid) throws IllegalArgumentException; @@ -1104,7 +1167,7 @@ public class Process { /** * Determine whether the current environment supports multiple processes. - * + * * @return Returns true if the system can run in multiple processes, else * false if everything is running in a single process. * @@ -1131,9 +1194,9 @@ public class Process { /** * Change this process's argv[0] parameter. This can be useful to show * more descriptive information in things like the 'ps' command. - * + * * @param text The new name of this process. - * + * * {@hide} */ @UnsupportedAppUsage @@ -1162,12 +1225,12 @@ public class Process { /** * Send a signal to the given process. - * + * * @param pid The pid of the target process. * @param signal The signal to send. */ public static final native void sendSignal(int pid, int signal); - + /** * @hide * Private impl for avoiding a log message... DO NOT USE without doing @@ -1186,24 +1249,24 @@ public class Process { */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public static final native void sendSignalQuiet(int pid, int signal); - + /** @hide */ @UnsupportedAppUsage public static final native long getFreeMemory(); - + /** @hide */ @UnsupportedAppUsage public static final native long getTotalMemory(); - + /** @hide */ @UnsupportedAppUsage public static final native void readProcLines(String path, String[] reqFields, long[] outSizes); - + /** @hide */ @UnsupportedAppUsage public static final native int[] getPids(String path, int[] lastArray); - + /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PROC_TERM_MASK = 0xff; @@ -1274,7 +1337,7 @@ public class Process { /** @hide */ @UnsupportedAppUsage - public static final native boolean parseProcLine(byte[] buffer, int startIndex, + public static final native boolean parseProcLine(byte[] buffer, int startIndex, int endIndex, int[] format, String[] outStrings, long[] outLongs, float[] outFloats); /** @hide */ @@ -1283,10 +1346,10 @@ public class Process { /** * Gets the total Pss value for a given process, in bytes. - * + * * @param pid the process to the Pss for * @return the total Pss value for the given process in bytes, - * or -1 if the value cannot be determined + * or -1 if the value cannot be determined * @hide */ @UnsupportedAppUsage diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 39f87d558098..db724d2de30b 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -82,7 +82,6 @@ import android.os.SystemProperties; import android.os.UserHandle; import android.provider.MediaStore; import android.provider.Settings; -import android.sysprop.VoldProperties; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; @@ -1636,10 +1635,7 @@ public class StorageManager { * false not encrypted or file encrypted */ public static boolean isBlockEncrypted() { - if (!isEncrypted()) { - return false; - } - return RoSystemProperties.CRYPTO_BLOCK_ENCRYPTED; + return false; } /** {@hide} @@ -1649,18 +1645,7 @@ public class StorageManager { * false not encrypted, file encrypted or default block encrypted */ public static boolean isNonDefaultBlockEncrypted() { - if (!isBlockEncrypted()) { - return false; - } - - try { - IStorageManager storageManager = IStorageManager.Stub.asInterface( - ServiceManager.getService("mount")); - return storageManager.getPasswordType() != CRYPT_TYPE_DEFAULT; - } catch (RemoteException e) { - Log.e(TAG, "Error getting encryption type"); - return false; - } + return false; } /** {@hide} @@ -1674,8 +1659,7 @@ public class StorageManager { * framework, so no service needs to check for changes during their lifespan */ public static boolean isBlockEncrypting() { - final String state = VoldProperties.encrypt_progress().orElse(""); - return !"".equalsIgnoreCase(state); + return false; } /** {@hide} @@ -1690,8 +1674,7 @@ public class StorageManager { * framework, so no service needs to check for changes during their lifespan */ public static boolean inCryptKeeperBounce() { - final String status = VoldProperties.decrypt().orElse(""); - return "trigger_restart_min_framework".equals(status); + return false; } /** {@hide} */ diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java index b79b3d8083e8..0d5ef34c6f76 100644 --- a/core/java/android/provider/Telephony.java +++ b/core/java/android/provider/Telephony.java @@ -3589,7 +3589,7 @@ public final class Telephony { * @hide */ public static final Uri PREFERRED_APN_URI = Uri.parse( - "content://telephony/carriers/preferapn/subId/"); + "content://telephony/carriers/preferapn/subId"); /** * The {@code content://} style URL for the perferred APN set id. @@ -3597,8 +3597,15 @@ public final class Telephony { * @hide */ public static final Uri PREFERRED_APN_SET_URI = Uri.parse( - "content://telephony/carriers/preferapnset/subId/"); + "content://telephony/carriers/preferapnset/subId"); + /** + * The id of preferred APN. + * + * @see #PREFERRED_APN_URI + * @hide + */ + public static final String APN_ID = "apn_id"; /** * The column name for ENFORCE_MANAGED_URI, indicates whether DPC-owned APNs are enforced. diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index 5b9d69c2f9ff..e5c9adba46a9 100644 --- a/core/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -743,6 +743,7 @@ public class PhoneStateListener { * @see TelephonyManager#DATA_CONNECTING * @see TelephonyManager#DATA_CONNECTED * @see TelephonyManager#DATA_SUSPENDED + * @see TelephonyManager#DATA_HANDOVER_IN_PROGRESS * @deprecated Use {@link TelephonyCallback.DataConnectionStateListener} instead. */ @Deprecated diff --git a/core/java/android/telephony/TelephonyCallback.java b/core/java/android/telephony/TelephonyCallback.java index 3028a6d8f97a..e8960b8e35cd 100644 --- a/core/java/android/telephony/TelephonyCallback.java +++ b/core/java/android/telephony/TelephonyCallback.java @@ -792,6 +792,7 @@ public class TelephonyCallback { * @see TelephonyManager#DATA_CONNECTING * @see TelephonyManager#DATA_CONNECTED * @see TelephonyManager#DATA_SUSPENDED + * @see TelephonyManager#DATA_HANDOVER_IN_PROGRESS */ void onDataConnectionStateChanged(@TelephonyManager.DataState int state, @Annotation.NetworkType int networkType); @@ -1408,10 +1409,11 @@ public class TelephonyCallback { * * @param enabled {@code true} if data is enabled, otherwise disabled. * @param reason Reason for data enabled/disabled. - * See {@link TelephonyManager.DataEnabledReason}. + * See {@link TelephonyManager.DataEnabledChangedReason}. */ @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) - void onDataEnabledChanged(boolean enabled, @TelephonyManager.DataEnabledReason int reason); + void onDataEnabledChanged(boolean enabled, + @TelephonyManager.DataEnabledChangedReason int reason); } /** diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index a2ff69e15915..d4fc0c6336ba 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -3390,6 +3390,12 @@ public final class ViewRootImpl implements ViewParent, mReportNextDraw = false; pendingDrawFinished(); } + + // Make sure the consumer is not waiting if the view root was just made invisible. + if (mBLASTDrawConsumer != null) { + mBLASTDrawConsumer.accept(null); + mBLASTDrawConsumer = null; + } } } diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java index e6deada45fc1..a54f37cf54e2 100644 --- a/core/java/com/android/internal/widget/ConversationLayout.java +++ b/core/java/com/android/internal/widget/ConversationLayout.java @@ -150,6 +150,7 @@ public class ConversationLayout extends FrameLayout private Icon mShortcutIcon; private View mAppNameDivider; private TouchDelegateComposite mTouchDelegate = new TouchDelegateComposite(this); + private ArrayList<MessagingGroup> mToRecycle = new ArrayList<>(); public ConversationLayout(@NonNull Context context) { super(context); @@ -472,6 +473,12 @@ public class ConversationLayout extends FrameLayout updateTitleAndNamesDisplay(); updateConversationLayout(); + + // Recycle everything at the end of the update, now that we know it's no longer needed. + for (MessagingGroup group : mToRecycle) { + group.recycle(); + } + mToRecycle.clear(); } /** @@ -745,18 +752,18 @@ public class ConversationLayout extends FrameLayout MessagingGroup group = oldGroups.get(i); if (!mGroups.contains(group)) { List<MessagingMessage> messages = group.getMessages(); - Runnable endRunnable = () -> { - mMessagingLinearLayout.removeTransientView(group); - group.recycle(); - }; - boolean wasShown = group.isShown(); mMessagingLinearLayout.removeView(group); if (wasShown && !MessagingLinearLayout.isGone(group)) { mMessagingLinearLayout.addTransientView(group, 0); - group.removeGroupAnimated(endRunnable); + group.removeGroupAnimated(() -> { + mMessagingLinearLayout.removeTransientView(group); + group.recycle(); + }); } else { - endRunnable.run(); + // Defer recycling until after the update is done, since we may still need the + // old group around to perform other updates. + mToRecycle.add(group); } mMessages.removeAll(messages); mHistoricMessages.removeAll(messages); diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl index d16d9c619403..654b46164dcf 100644 --- a/core/java/com/android/internal/widget/ILockSettings.aidl +++ b/core/java/com/android/internal/widget/ILockSettings.aidl @@ -95,5 +95,4 @@ interface ILockSettings { boolean hasSecureLockScreen(); boolean tryUnlockWithCachedUnifiedChallenge(int userId); void removeCachedUnifiedChallenge(int userId); - void updateEncryptionPassword(int type, in byte[] password); } diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index cd1bbb6bc6fe..408decc9ca56 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -701,38 +701,14 @@ public class LockPatternUtils { return true; } - private void updateCryptoUserInfo(int userId) { - if (userId != UserHandle.USER_SYSTEM) { - return; - } - - final String ownerInfo = isOwnerInfoEnabled(userId) ? getOwnerInfo(userId) : ""; - - IBinder service = ServiceManager.getService("mount"); - if (service == null) { - Log.e(TAG, "Could not find the mount service to update the user info"); - return; - } - - IStorageManager storageManager = IStorageManager.Stub.asInterface(service); - try { - Log.d(TAG, "Setting owner info"); - storageManager.setField(StorageManager.OWNER_INFO_KEY, ownerInfo); - } catch (RemoteException e) { - Log.e(TAG, "Error changing user info", e); - } - } - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setOwnerInfo(String info, int userId) { setString(LOCK_SCREEN_OWNER_INFO, info, userId); - updateCryptoUserInfo(userId); } @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setOwnerInfoEnabled(boolean enabled, int userId) { setBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, enabled, userId); - updateCryptoUserInfo(userId); } @UnsupportedAppUsage @@ -787,17 +763,6 @@ public class LockPatternUtils { } /** - * Clears the encryption password. - */ - public void clearEncryptionPassword() { - try { - getLockSettings().updateEncryptionPassword(StorageManager.CRYPT_TYPE_DEFAULT, null); - } catch (RemoteException e) { - Log.e(TAG, "Couldn't clear encryption password"); - } - } - - /** * Retrieves the quality mode for {@code userHandle}. * @see DevicePolicyManager#getPasswordQuality(android.content.ComponentName) * @@ -988,24 +953,6 @@ public class LockPatternUtils { */ public void setVisiblePatternEnabled(boolean enabled, int userId) { setBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE, enabled, userId); - - // Update for crypto if owner - if (userId != UserHandle.USER_SYSTEM) { - return; - } - - IBinder service = ServiceManager.getService("mount"); - if (service == null) { - Log.e(TAG, "Could not find the mount service to update the user info"); - return; - } - - IStorageManager storageManager = IStorageManager.Stub.asInterface(service); - try { - storageManager.setField(StorageManager.PATTERN_VISIBLE_KEY, enabled ? "1" : "0"); - } catch (RemoteException e) { - Log.e(TAG, "Error changing pattern visible state", e); - } } public boolean isVisiblePatternEverChosen(int userId) { @@ -1016,23 +963,7 @@ public class LockPatternUtils { * Set whether the visible password is enabled for cryptkeeper screen. */ public void setVisiblePasswordEnabled(boolean enabled, int userId) { - // Update for crypto if owner - if (userId != UserHandle.USER_SYSTEM) { - return; - } - - IBinder service = ServiceManager.getService("mount"); - if (service == null) { - Log.e(TAG, "Could not find the mount service to update the user info"); - return; - } - - IStorageManager storageManager = IStorageManager.Stub.asInterface(service); - try { - storageManager.setField(StorageManager.PASSWORD_VISIBLE_KEY, enabled ? "1" : "0"); - } catch (RemoteException e) { - Log.e(TAG, "Error changing password visible state", e); - } + // No longer does anything. } /** diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 194002e9352f..1601b4772384 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -1565,6 +1565,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_graphics_classes), REG_JNI(register_android_graphics_BLASTBufferQueue), REG_JNI(register_android_graphics_GraphicBuffer), + REG_JNI(register_android_graphics_GraphicsStatsService), REG_JNI(register_android_graphics_SurfaceTexture), REG_JNI(register_android_database_CursorWindow), REG_JNI(register_android_database_SQLiteConnection), diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 597167026d19..5023927c2560 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -895,7 +895,7 @@ void SetThreadName(const std::string& thread_name) { // pthread_setname_np fails rather than truncating long strings. char buf[16]; // MAX_TASK_COMM_LEN=16 is hard-coded into bionic - strlcpy(buf, name_start_ptr, sizeof(buf) - 1); + strlcpy(buf, name_start_ptr, sizeof(buf)); errno = pthread_setname_np(pthread_self(), buf); if (errno != 0) { ALOGW("Unable to set the name of current thread to '%s': %s", buf, strerror(errno)); diff --git a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp index 0c05da551c8f..679a4f070290 100644 --- a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp +++ b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp @@ -34,6 +34,7 @@ #include <sys/mman.h> #include <sys/types.h> #include <sys/socket.h> +#include <sys/system_properties.h> #include <vector> namespace android { @@ -43,10 +44,10 @@ using android::base::StringPrintf; using android::zygote::ZygoteFailure; // WARNING: Knows a little about the wire protocol used to communicate with Zygote. -// TODO: Fix error handling. +// Commands and nice names have large arbitrary size limits to avoid dynamic memory allocation. constexpr size_t MAX_COMMAND_BYTES = 32768; -constexpr size_t NICE_NAME_BYTES = 50; +constexpr size_t NICE_NAME_BYTES = 128; // A buffer optionally bundled with a file descriptor from which we can fill it. // Does not own the file descriptor; destroying a NativeCommandBuffer does not @@ -190,6 +191,9 @@ class NativeCommandBuffer { size_t copy_len = std::min(name_len, NICE_NAME_BYTES - 1); memcpy(mNiceName, arg_start + NN_LENGTH, copy_len); mNiceName[copy_len] = '\0'; + if (haveWrapProperty()) { + return false; + } continue; } if (arg_end - arg_start == IW_LENGTH @@ -222,6 +226,8 @@ class NativeCommandBuffer { } saw_setgid = true; } + // ro.debuggable can be handled entirely in the child unless --invoke-with is also specified. + // Thus we do not need to check it here. } return saw_runtime_args && saw_setuid && saw_setgid; } @@ -249,6 +255,14 @@ class NativeCommandBuffer { } private: + bool haveWrapProperty() { + static const char* WRAP = "wrap."; + static const size_t WRAP_LENGTH = strlen(WRAP); + char propNameBuf[WRAP_LENGTH + NICE_NAME_BYTES]; + strcpy(propNameBuf, WRAP); + strlcpy(propNameBuf + WRAP_LENGTH, mNiceName, NICE_NAME_BYTES); + return __system_property_find(propNameBuf) != nullptr; + } // Picky version of atoi(). No sign or unexpected characters allowed. Return -1 on failure. static int digitsVal(char* start, char* end) { int result = 0; @@ -269,7 +283,7 @@ class NativeCommandBuffer { uint32_t mNext; // Index of first character past last line returned by readLine. int32_t mLinesLeft; // Lines in current command that haven't yet been read. int mFd; // Open file descriptor from which we can read more. -1 if none. - char mNiceName[NICE_NAME_BYTES]; + char mNiceName[NICE_NAME_BYTES]; // Always null terminated. char mBuffer[MAX_COMMAND_BYTES]; }; @@ -372,6 +386,7 @@ jboolean com_android_internal_os_ZygoteCommandBuffer_nativeForkRepeatedly( jint minUid, jstring managed_nice_name) { + ALOGI("Entering forkRepeatedly native zygote loop"); NativeCommandBuffer* n_buffer = reinterpret_cast<NativeCommandBuffer*>(j_buffer); int session_socket = n_buffer->getFd(); std::vector<int> session_socket_fds {session_socket}; @@ -400,7 +415,8 @@ jboolean com_android_internal_os_ZygoteCommandBuffer_nativeForkRepeatedly( socklen_t cred_size = sizeof credentials; if (getsockopt(n_buffer->getFd(), SOL_SOCKET, SO_PEERCRED, &credentials, &cred_size) == -1 || cred_size != sizeof credentials) { - fail_fn_1(CREATE_ERROR("ForkMany failed to get initial credentials, %s", strerror(errno))); + fail_fn_1(CREATE_ERROR("ForkRepeatedly failed to get initial credentials, %s", + strerror(errno))); } bool first_time = true; diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 2c10d78ebd32..aa0f386c9375 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2221,7 +2221,7 @@ <!-- Remote server that can provide NTP responses. --> <string translatable="false" name="config_ntpServer">time.android.com</string> <!-- Normal polling frequency in milliseconds --> - <integer name="config_ntpPollingInterval">86400000</integer> + <integer name="config_ntpPollingInterval">64800000</integer> <!-- Try-again polling interval in milliseconds, in case the network request failed --> <integer name="config_ntpPollingIntervalShorter">60000</integer> <!-- Number of times to try again with the shorter interval, before backing diff --git a/data/etc/car/com.android.carsystemui.xml b/data/etc/car/com.android.carsystemui.xml index a267d5650782..6c9103cb0f4f 100644 --- a/data/etc/car/com.android.carsystemui.xml +++ b/data/etc/car/com.android.carsystemui.xml @@ -24,5 +24,6 @@ <permission name="android.car.permission.CONTROL_CAR_CLIMATE"/> <permission name="android.car.permission.CONTROL_CAR_EVS_ACTIVITY"/> <permission name="android.car.permission.MONITOR_CAR_EVS_STATUS"/> + <permission name="android.car.permission.CONTROL_CAR_APP_LAUNCH"/> </privapp-permissions> </permissions> diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 82aff6027653..201ab956d31d 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -459,8 +459,8 @@ applications that come with the platform <permission name="android.permission.NEARBY_WIFI_DEVICES" /> <permission name="android.permission.OVERRIDE_WIFI_CONFIG" /> <!-- Permission needed for CTS test - ConcurrencyTest#testP2pExternalApprover - P2P external approver API sets require MANAGE_WIFI_AUTO_JOIN permission. --> - <permission name="android.permission.MANAGE_WIFI_AUTO_JOIN" /> + P2P external approver API sets require MANAGE_WIFI_NETWORK_SELECTION permission. --> + <permission name="android.permission.MANAGE_WIFI_NETWORK_SELECTION" /> <!-- Permission required for CTS test CarrierMessagingServiceWrapperTest --> <permission name="android.permission.BIND_CARRIER_SERVICES"/> <!-- Permission required for CTS test - MusicRecognitionManagerTest --> diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java index 31dd10a8ed53..e7961c94928c 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java @@ -108,6 +108,16 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato } } + /** + * XDH represents Curve 25519 providers. + */ + public static class XDH extends AndroidKeyStoreKeyPairGeneratorSpi { + // XDH is treated as EC. + public XDH() { + super(KeymasterDefs.KM_ALGORITHM_EC); + } + } + /* * These must be kept in sync with system/security/keystore/defaults.h */ @@ -242,6 +252,23 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato } catch (NullPointerException | IllegalArgumentException e) { throw new InvalidAlgorithmParameterException(e); } + } else if (params instanceof NamedParameterSpec) { + NamedParameterSpec namedSpec = (NamedParameterSpec) params; + // Android Keystore cannot support initialization from a NamedParameterSpec + // because an alias for the key is needed (a KeyGenParameterSpec cannot be + // constructed). + if (namedSpec.getName().equalsIgnoreCase(NamedParameterSpec.X25519.getName()) + || namedSpec.getName().equalsIgnoreCase( + NamedParameterSpec.ED25519.getName())) { + throw new IllegalArgumentException( + "This KeyPairGenerator cannot be initialized using NamedParameterSpec." + + " use " + KeyGenParameterSpec.class.getName() + " or " + + KeyPairGeneratorSpec.class.getName()); + } else { + throw new InvalidAlgorithmParameterException( + "Unsupported algorithm specified via NamedParameterSpec: " + + namedSpec.getName()); + } } else { throw new InvalidAlgorithmParameterException( "Unsupported params class: " + params.getClass().getName() diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java index 358104fffbf6..d31499e8b36d 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java @@ -83,16 +83,12 @@ public class AndroidKeyStoreProvider extends Provider { // java.security.KeyPairGenerator put("KeyPairGenerator.EC", PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$EC"); put("KeyPairGenerator.RSA", PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$RSA"); - put("KeyPairGenerator." + X25519_ALIAS, - PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$RSA"); - put("KeyPairGenerator." + ED25519_OID, - PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$RSA"); + put("KeyPairGenerator.XDH", PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$XDH"); // java.security.KeyFactory putKeyFactoryImpl("EC"); putKeyFactoryImpl("RSA"); - putKeyFactoryImpl(X25519_ALIAS); - putKeyFactoryImpl(ED25519_OID); + putKeyFactoryImpl("XDH"); // javax.crypto.KeyGenerator put("KeyGenerator.AES", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$AES"); diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index d9783e681a25..e69cf773d329 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -6831,7 +6831,8 @@ public class AudioManager { for (Integer format : formatsList) { int btSourceCodec = AudioSystem.audioFormatToBluetoothSourceCodec(format); if (btSourceCodec != BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID) { - codecConfigList.add(new BluetoothCodecConfig(btSourceCodec)); + codecConfigList.add( + new BluetoothCodecConfig.Builder().setCodecType(btSourceCodec).build()); } } return codecConfigList; diff --git a/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java b/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java index 72243f9e87d9..eba51c11487e 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java +++ b/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java @@ -511,7 +511,6 @@ public class EthernetManager { NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}) - @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) public void updateConfiguration( @NonNull String iface, @NonNull EthernetNetworkUpdateRequest request, diff --git a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.java b/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.java index a6269711055a..43f4c40f2d27 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.java +++ b/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.java @@ -24,36 +24,52 @@ import android.os.Parcelable; import java.util.Objects; -/** @hide */ +/** + * Represents a request to update an existing Ethernet interface. + * + * @see EthernetManager#updateConfiguration + * + * @hide + */ @SystemApi public final class EthernetNetworkUpdateRequest implements Parcelable { @NonNull private final IpConfiguration mIpConfig; - @NonNull + @Nullable private final NetworkCapabilities mNetworkCapabilities; + /** + * @return the new {@link IpConfiguration}. + */ @NonNull public IpConfiguration getIpConfiguration() { return new IpConfiguration(mIpConfig); } - @NonNull + /** + * Setting the {@link NetworkCapabilities} is optional in {@link EthernetNetworkUpdateRequest}. + * When set to null, the existing NetworkCapabilities are not updated. + * + * @return the new {@link NetworkCapabilities} or null. + */ + @Nullable public NetworkCapabilities getNetworkCapabilities() { - return new NetworkCapabilities(mNetworkCapabilities); + return mNetworkCapabilities == null ? null : new NetworkCapabilities(mNetworkCapabilities); } private EthernetNetworkUpdateRequest(@NonNull final IpConfiguration ipConfig, - @NonNull final NetworkCapabilities networkCapabilities) { + @Nullable final NetworkCapabilities networkCapabilities) { Objects.requireNonNull(ipConfig); - Objects.requireNonNull(networkCapabilities); - mIpConfig = new IpConfiguration(ipConfig); - mNetworkCapabilities = new NetworkCapabilities(networkCapabilities); + mIpConfig = ipConfig; + mNetworkCapabilities = networkCapabilities; } private EthernetNetworkUpdateRequest(@NonNull final Parcel source) { Objects.requireNonNull(source); - mIpConfig = IpConfiguration.CREATOR.createFromParcel(source); - mNetworkCapabilities = NetworkCapabilities.CREATOR.createFromParcel(source); + mIpConfig = source.readParcelable(IpConfiguration.class.getClassLoader(), + IpConfiguration.class); + mNetworkCapabilities = source.readParcelable(NetworkCapabilities.class.getClassLoader(), + NetworkCapabilities.class); } /** @@ -75,7 +91,8 @@ public final class EthernetNetworkUpdateRequest implements Parcelable { public Builder(@NonNull final EthernetNetworkUpdateRequest request) { Objects.requireNonNull(request); mBuilderIpConfig = new IpConfiguration(request.mIpConfig); - mBuilderNetworkCapabilities = new NetworkCapabilities(request.mNetworkCapabilities); + mBuilderNetworkCapabilities = null == request.mNetworkCapabilities + ? null : new NetworkCapabilities(request.mNetworkCapabilities); } /** @@ -85,7 +102,6 @@ public final class EthernetNetworkUpdateRequest implements Parcelable { */ @NonNull public Builder setIpConfiguration(@NonNull final IpConfiguration ipConfig) { - Objects.requireNonNull(ipConfig); mBuilderIpConfig = new IpConfiguration(ipConfig); return this; } @@ -96,9 +112,8 @@ public final class EthernetNetworkUpdateRequest implements Parcelable { * @return The builder to facilitate chaining. */ @NonNull - public Builder setNetworkCapabilities(@NonNull final NetworkCapabilities nc) { - Objects.requireNonNull(nc); - mBuilderNetworkCapabilities = new NetworkCapabilities(nc); + public Builder setNetworkCapabilities(@Nullable final NetworkCapabilities nc) { + mBuilderNetworkCapabilities = nc == null ? null : new NetworkCapabilities(nc); return this; } @@ -135,8 +150,8 @@ public final class EthernetNetworkUpdateRequest implements Parcelable { @Override public void writeToParcel(@NonNull Parcel dest, int flags) { - mIpConfig.writeToParcel(dest, flags); - mNetworkCapabilities.writeToParcel(dest, flags); + dest.writeParcelable(mIpConfig, flags); + dest.writeParcelable(mNetworkCapabilities, flags); } @Override diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java index 67d48f0000d5..1ddc78bb4d7c 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java +++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java @@ -36,6 +36,7 @@ import static com.android.net.module.util.NetworkStatsUtils.multiplySafeByRation import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.net.NetworkStats.State; import android.net.NetworkStatsHistory.Entry; import android.os.Binder; import android.service.NetworkStatsCollectionKeyProto; @@ -102,7 +103,7 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W private ArrayMap<Key, NetworkStatsHistory> mStats = new ArrayMap<>(); - private final long mBucketDuration; + private final long mBucketDurationMillis; private long mStartMillis; private long mEndMillis; @@ -115,8 +116,8 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W * @param bucketDuration duration of the buckets in this object, in milliseconds. * @hide */ - public NetworkStatsCollection(long bucketDuration) { - mBucketDuration = bucketDuration; + public NetworkStatsCollection(long bucketDurationMillis) { + mBucketDurationMillis = bucketDurationMillis; reset(); } @@ -148,7 +149,7 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W if (mStartMillis == Long.MAX_VALUE) { return Long.MAX_VALUE; } else { - return mStartMillis + mBucketDuration; + return mStartMillis + mBucketDurationMillis; } } @@ -184,10 +185,10 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W || time == SubscriptionPlan.TIME_UNKNOWN) { return time; } else { - final long mod = time % mBucketDuration; + final long mod = time % mBucketDurationMillis; if (mod > 0) { time -= mod; - time += mBucketDuration; + time += mBucketDurationMillis; } return time; } @@ -200,7 +201,7 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W || time == SubscriptionPlan.TIME_UNKNOWN) { return time; } else { - final long mod = time % mBucketDuration; + final long mod = time % mBucketDurationMillis; if (mod > 0) { time -= mod; } @@ -247,10 +248,10 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W // 180 days of history should be enough for anyone; if we end up needing // more, we'll dynamically grow the history object. final int bucketEstimate = (int) NetworkStatsUtils.constrain( - ((end - start) / mBucketDuration), 0, - (180 * DateUtils.DAY_IN_MILLIS) / mBucketDuration); + ((end - start) / mBucketDurationMillis), 0, + (180 * DateUtils.DAY_IN_MILLIS) / mBucketDurationMillis); final NetworkStatsHistory combined = new NetworkStatsHistory( - mBucketDuration, bucketEstimate, fields); + mBucketDurationMillis, bucketEstimate, fields); // shortcut when we know stats will be empty if (start == end) return combined; @@ -343,7 +344,7 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W // Finally we can slice data as originally requested final NetworkStatsHistory sliced = new NetworkStatsHistory( - mBucketDuration, bucketEstimate, fields); + mBucketDurationMillis, bucketEstimate, fields); sliced.recordHistory(combined, start, end); return sliced; } else { @@ -458,9 +459,9 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W // update when no existing, or when bucket duration changed NetworkStatsHistory updated = null; if (existing == null) { - updated = new NetworkStatsHistory(mBucketDuration, 10); - } else if (existing.getBucketDuration() != mBucketDuration) { - updated = new NetworkStatsHistory(existing, mBucketDuration); + updated = new NetworkStatsHistory(mBucketDurationMillis, 10); + } else if (existing.getBucketDuration() != mBucketDurationMillis) { + updated = new NetworkStatsHistory(existing, mBucketDurationMillis); } if (updated != null) { @@ -702,7 +703,7 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W private int estimateBuckets() { return (int) (Math.min(mEndMillis - mStartMillis, WEEK_IN_MILLIS * 5) - / mBucketDuration); + / mBucketDurationMillis); } private ArrayList<Key> getSortedKeys() { @@ -828,7 +829,7 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W * Builder class for {@link NetworkStatsCollection}. */ public static final class Builder { - private final long mBucketDuration; + private final long mBucketDurationMillis; private final ArrayMap<Key, NetworkStatsHistory> mEntries = new ArrayMap<>(); /** @@ -836,8 +837,8 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W * * @param bucketDuration Duration of the buckets of the object, in milliseconds. */ - public Builder(long bucketDuration) { - mBucketDuration = bucketDuration; + public Builder(long bucketDurationMillis) { + mBucketDurationMillis = bucketDurationMillis; } /** @@ -855,7 +856,7 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W final List<Entry> historyEntries = history.getEntries(); final NetworkStatsHistory.Builder historyBuilder = - new NetworkStatsHistory.Builder(mBucketDuration, historyEntries.size()); + new NetworkStatsHistory.Builder(mBucketDurationMillis, historyEntries.size()); for (Entry entry : historyEntries) { historyBuilder.addEntry(entry); } @@ -871,7 +872,8 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W */ @NonNull public NetworkStatsCollection build() { - final NetworkStatsCollection collection = new NetworkStatsCollection(mBucketDuration); + final NetworkStatsCollection collection = + new NetworkStatsCollection(mBucketDurationMillis); for (int i = 0; i < mEntries.size(); i++) { collection.recordHistory(mEntries.keyAt(i), mEntries.valueAt(i)); } @@ -883,7 +885,7 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W * the identifier that associate with the {@link NetworkStatsHistory} object to identify * a certain record in the {@link NetworkStatsCollection} object. */ - public static class Key { + public static final class Key { /** @hide */ public final NetworkIdentitySet ident; /** @hide */ @@ -903,7 +905,7 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W * @param set Set of the record, see {@code NetworkStats#SET_*}. * @param tag Tag of the record, see {@link TrafficStats#setThreadStatsTag(int)}. */ - public Key(@NonNull Set<NetworkIdentity> ident, int uid, int set, int tag) { + public Key(@NonNull Set<NetworkIdentity> ident, int uid, @State int set, int tag) { this(new NetworkIdentitySet(Objects.requireNonNull(ident)), uid, set, tag); } diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java index 151c90dd4155..3b93f1a1905f 100644 --- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java +++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java @@ -25,9 +25,9 @@ import static android.net.NetworkStats.UID_ALL; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; -import android.net.ConnectivityManager; import android.net.NetworkStats; import android.net.UnderlyingNetworkInfo; +import android.os.ServiceSpecificException; import android.os.StrictMode; import android.os.SystemClock; @@ -35,6 +35,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ProcFileReader; import com.android.net.module.util.CollectionUtils; +import com.android.server.BpfNetMaps; import libcore.io.IoUtils; @@ -74,6 +75,8 @@ public class NetworkStatsFactory { private final Context mContext; + private final BpfNetMaps mBpfNetMaps; + /** * Guards persistent data access in this class * @@ -170,6 +173,7 @@ public class NetworkStatsFactory { mStatsXtIfaceFmt = new File(procRoot, "net/xt_qtaguid/iface_stat_fmt"); mStatsXtUid = new File(procRoot, "net/xt_qtaguid/stats"); mUseBpfStats = useBpfStats; + mBpfNetMaps = new BpfNetMaps(); synchronized (mPersistentDataLock) { mPersistSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), -1); mTunAnd464xlatAdjustedStats = new NetworkStats(SystemClock.elapsedRealtime(), -1); @@ -297,12 +301,14 @@ public class NetworkStatsFactory { } @GuardedBy("mPersistentDataLock") - private void requestSwapActiveStatsMapLocked() { - // Do a active map stats swap. When the binder call successfully returns, - // the system server should be able to safely read and clean the inactive map - // without race problem. - final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class); - cm.swapActiveStatsMap(); + private void requestSwapActiveStatsMapLocked() throws IOException { + try { + // Do a active map stats swap. Once the swap completes, this code + // can read and clean the inactive map without races. + mBpfNetMaps.swapActiveStatsMap(); + } catch (ServiceSpecificException e) { + throw new IOException(e); + } } /** @@ -328,11 +334,7 @@ public class NetworkStatsFactory { final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0 /* initialSize */); if (mUseBpfStats) { - try { - requestSwapActiveStatsMapLocked(); - } catch (RuntimeException e) { - throw new IOException(e); - } + requestSwapActiveStatsMapLocked(); // Stats are always read from the inactive map, so they must be read after the // swap if (nativeReadNetworkStatsDetail(stats, mStatsXtUid.getAbsolutePath(), UID_ALL, diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java index ef6f39a5c040..f8355817bf59 100644 --- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java +++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java @@ -565,7 +565,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return new BpfMap<U32, U8>(UID_COUNTERSET_MAP_PATH, BpfMap.BPF_F_RDWR, U32.class, U8.class); } catch (ErrnoException e) { - Log.wtf(TAG, "Cannot create uid counter set map: " + e); + Log.wtf(TAG, "Cannot open uid counter set map: " + e); return null; } } @@ -576,7 +576,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return new BpfMap<CookieTagMapKey, CookieTagMapValue>(COOKIE_TAG_MAP_PATH, BpfMap.BPF_F_RDWR, CookieTagMapKey.class, CookieTagMapValue.class); } catch (ErrnoException e) { - Log.wtf(TAG, "Cannot create cookie tag map: " + e); + Log.wtf(TAG, "Cannot open cookie tag map: " + e); return null; } } @@ -587,7 +587,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return new BpfMap<StatsMapKey, StatsMapValue>(STATS_MAP_A_PATH, BpfMap.BPF_F_RDWR, StatsMapKey.class, StatsMapValue.class); } catch (ErrnoException e) { - Log.wtf(TAG, "Cannot create stats map A: " + e); + Log.wtf(TAG, "Cannot open stats map A: " + e); return null; } } @@ -598,7 +598,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return new BpfMap<StatsMapKey, StatsMapValue>(STATS_MAP_B_PATH, BpfMap.BPF_F_RDWR, StatsMapKey.class, StatsMapValue.class); } catch (ErrnoException e) { - Log.wtf(TAG, "Cannot create stats map B: " + e); + Log.wtf(TAG, "Cannot open stats map B: " + e); return null; } } @@ -609,7 +609,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return new BpfMap<UidStatsMapKey, StatsMapValue>(APP_UID_STATS_MAP_PATH, BpfMap.BPF_F_RDWR, UidStatsMapKey.class, StatsMapValue.class); } catch (ErrnoException e) { - Log.wtf(TAG, "Cannot create app uid stats map: " + e); + Log.wtf(TAG, "Cannot open app uid stats map: " + e); return null; } } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index d6f08c663ccd..981d8e403cd6 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -283,6 +283,12 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> public void disconnect() { synchronized (mProfileLock) { + if (getGroupId() != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { + for (CachedBluetoothDevice member : getMemberDevice()) { + Log.d(TAG, "Disconnect the member(" + member.getAddress() + ")"); + member.disconnect(); + } + } mDevice.disconnect(); } // Disconnect PBAP server in case its connected @@ -397,6 +403,12 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } mDevice.connect(); + if (getGroupId() != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { + for (CachedBluetoothDevice member : getMemberDevice()) { + Log.d(TAG, "connect the member(" + member.getAddress() + ")"); + member.connect(); + } + } } } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipSetCoordinatorProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipSetCoordinatorProfile.java index 6da249c2980e..c3f845ca8c0a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipSetCoordinatorProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipSetCoordinatorProfile.java @@ -59,7 +59,7 @@ public class CsipSetCoordinatorProfile implements LocalBluetoothProfile { // These callbacks run on the main thread. private final class CoordinatedSetServiceListener implements BluetoothProfile.ServiceListener { - @RequiresApi(32) + @RequiresApi(33) public void onServiceConnected(int profile, BluetoothProfile proxy) { if (VDBG) { Log.d(TAG, "Bluetooth service connected"); @@ -233,7 +233,7 @@ public class CsipSetCoordinatorProfile implements LocalBluetoothProfile { return NAME; } - @RequiresApi(32) + @RequiresApi(33) protected void finalize() { if (VDBG) { Log.d(TAG, "finalize()"); diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index ca4dcbbf230e..e6af794a0b48 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -510,8 +510,8 @@ <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" /> <uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" /> <!-- Permission needed for CTS test - ConcurrencyTest#testP2pExternalApprover - P2P external approver API sets require MANAGE_WIFI_AUTO_JOIN permission. --> - <uses-permission android:name="android.permission.MANAGE_WIFI_AUTO_JOIN" /> + P2P external approver API sets require MANAGE_WIFI_NETWORK_SELECTION permission. --> + <uses-permission android:name="android.permission.MANAGE_WIFI_NETWORK_SELECTION" /> <!-- Permission required for CTS tests to enable/disable rate limiting toasts. --> <uses-permission android:name="android.permission.MANAGE_TOAST_RATE_LIMITING" /> diff --git a/packages/SystemUI/docs/usb_audio.md b/packages/SystemUI/docs/usb_audio.md new file mode 100644 index 000000000000..66e2df944fbc --- /dev/null +++ b/packages/SystemUI/docs/usb_audio.md @@ -0,0 +1,30 @@ +# USB audio Permission and Confirmation warning dialog resource string id matrix table +### go/support-usb-access-aoc-offload-feature + + |---|------------|----------------|------------------|-----------------|--------------------| + | # | Permission |isUsbAudioDevice| hasAudioPlayback | hasAudioCapture | string resource ID | + |---|------------|----------------|------------------|-----------------|--------------------| + | 1 | TRUE | TRUE | TRUE | FALSE | usb_audio_device_ + permission_prompt | + |---|------------|----------------|------------------|-----------------|--------------------| + | 2 | TRUE | TRUE | FALSE | TRUE | usb_audio_device_ + permission_prompt | + |---|------------|----------------|------------------|-----------------|--------------------| + | 3 | TRUE | TRUE | TRUE | TRUE | usb_audio_device_ + permission_prompt | + |---|------------|----------------|------------------|-----------------|--------------------| + | 4 | TRUE | FALSE | N/A | N/A | usb_device_ + permission_prompt | + |---|------------|----------------|------------------|-----------------|--------------------| + | 5 | FALSE | TRUE | TRUE | FALSE | usb_audio_device_ + permission_prompt | + |---|------------|----------------|------------------|-----------------|--------------------| + | 6 | FALSE | TRUE | FALSE | TRUE | usb_audio_device_ + permission_prompt_warn + |---|------------|----------------|------------------|-----------------|--------------------| + | 7 | FALSE | TRUE | TRUE | TRUE | usb_audio_device_ + permission_prompt_warn + |---|------------|----------------|------------------|-----------------|--------------------| + | 8 | FALSE | FALSE | N/A | N/A | usb_device_ + permission_prompt | + |---|------------|----------------|------------------|-----------------|--------------------| diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index e1afd3fe6a30..4a7d7089d712 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -78,6 +78,18 @@ <!-- Checkbox label for USB device dialogs with warning text for USB device dialogs. [CHAR LIMIT=200]--> <string name="usb_device_permission_prompt_warn">Allow <xliff:g id="application" example= "Usb Mega Player">%1$s</xliff:g> to access <xliff:g id="usb_device" example="USB Headphones">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device.</string> + <!-- USB audio device permission dialog title. [CHAR LIMIT=200]--> + <string name="usb_audio_device_permission_prompt_title">Allow <xliff:g id="application" example= "Usb Mega Player">%1$s</xliff:g> to access <xliff:g id="usb_device" example="USB Headphones">%2$s</xliff:g>?</string> + + <!-- USB audio device confirm dialog title. [CHAR LIMIT=200]--> + <string name="usb_audio_device_confirm_prompt_title">Open <xliff:g id="application" example= "Usb Mega Player">%1$s</xliff:g> to handle <xliff:g id="usb_device" example="USB Headphones">%2$s</xliff:g>?</string> + + <!-- Checkbox label for USB audio device dialogs with warning text for USB audio device dialogs. [CHAR LIMIT=NONE]--> + <string name="usb_audio_device_prompt_warn">This app has not been granted record permission but could capture audio through this USB device. Using <xliff:g id="application" example= "Usb Mega Player">%1$s</xliff:g> with this device might prevent hearing calls, notifications and alarms.</string> + + <!-- Prompt for the USB audio device permission dialog [CHAR LIMIT=NONE] --> + <string name="usb_audio_device_prompt">Using <xliff:g id="application" example= "Usb Mega Player">%1$s</xliff:g> with this device might prevent hearing calls, notifications and alarms.</string> + <!-- Prompt for the USB accessory permission dialog [CHAR LIMIT=80] --> <string name="usb_accessory_permission_prompt">Allow <xliff:g id="application" example= "Usb Mega Player">%1$s</xliff:g> to access <xliff:g id="usb_accessory" example="USB Dock">%2$s</xliff:g>?</string> diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index e9f288d51317..9b52746800a8 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -112,6 +112,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationShadeDepthController; +import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.phone.BiometricUnlockController; import com.android.systemui.statusbar.phone.DozeParameters; @@ -324,6 +325,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, // the properties of the keyguard private final KeyguardUpdateMonitor mUpdateMonitor; + private final Lazy<NotificationShadeWindowController> mNotificationShadeWindowControllerLazy; /** * Last SIM state reported by the telephony system. @@ -846,7 +848,8 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, KeyguardStateController keyguardStateController, Lazy<KeyguardUnlockAnimationController> keyguardUnlockAnimationControllerLazy, UnlockedScreenOffAnimationController unlockedScreenOffAnimationController, - Lazy<NotificationShadeDepthController> notificationShadeDepthController) { + Lazy<NotificationShadeDepthController> notificationShadeDepthController, + Lazy<NotificationShadeWindowController> notificationShadeWindowControllerLazy) { super(context); mFalsingCollector = falsingCollector; mLockPatternUtils = lockPatternUtils; @@ -862,6 +865,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, mKeyguardDisplayManager = keyguardDisplayManager; dumpManager.registerDumpable(getClass().getName(), this); mDeviceConfig = deviceConfig; + mNotificationShadeWindowControllerLazy = notificationShadeWindowControllerLazy; mShowHomeOverLockscreen = mDeviceConfig.getBoolean( DeviceConfig.NAMESPACE_SYSTEMUI, NAV_BAR_HANDLE_SHOW_OVER_LOCKSCREEN, @@ -1889,10 +1893,13 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, Trace.beginSection( "KeyguardViewMediator#handleMessage START_KEYGUARD_EXIT_ANIM"); StartKeyguardExitAnimParams params = (StartKeyguardExitAnimParams) msg.obj; - handleStartKeyguardExitAnimation(params.startTime, params.fadeoutDuration, - params.mApps, params.mWallpapers, params.mNonApps, - params.mFinishedCallback); - mFalsingCollector.onSuccessfulUnlock(); + mNotificationShadeWindowControllerLazy.get().batchApplyWindowLayoutParams( + () -> { + handleStartKeyguardExitAnimation(params.startTime, + params.fadeoutDuration, params.mApps, params.mWallpapers, + params.mNonApps, params.mFinishedCallback); + mFalsingCollector.onSuccessfulUnlock(); + }); Trace.endSection(); break; case CANCEL_KEYGUARD_EXIT_ANIM: @@ -2190,10 +2197,12 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, mKeyguardGoingAwayRunnable.run(); } else { // TODO(bc-unlock): Fill parameters - handleStartKeyguardExitAnimation( - SystemClock.uptimeMillis() + mHideAnimation.getStartOffset(), - mHideAnimation.getDuration(), null /* apps */, null /* wallpapers */, - null /* nonApps */, null /* finishedCallback */); + mNotificationShadeWindowControllerLazy.get().batchApplyWindowLayoutParams(() -> { + handleStartKeyguardExitAnimation( + SystemClock.uptimeMillis() + mHideAnimation.getStartOffset(), + mHideAnimation.getDuration(), null /* apps */, null /* wallpapers */, + null /* nonApps */, null /* finishedCallback */); + }); } } Trace.endSection(); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java index cae9feeb62eb..88dcf6d35075 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java @@ -42,6 +42,7 @@ import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.NotificationShadeDepthController; +import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.KeyguardLiftController; @@ -97,7 +98,8 @@ public class KeyguardModule { KeyguardStateController keyguardStateController, Lazy<KeyguardUnlockAnimationController> keyguardUnlockAnimationController, UnlockedScreenOffAnimationController unlockedScreenOffAnimationController, - Lazy<NotificationShadeDepthController> notificationShadeDepthController) { + Lazy<NotificationShadeDepthController> notificationShadeDepthController, + Lazy<NotificationShadeWindowController> notificationShadeWindowController) { return new KeyguardViewMediator( context, falsingCollector, @@ -120,7 +122,8 @@ public class KeyguardModule { keyguardStateController, keyguardUnlockAnimationController, unlockedScreenOffAnimationController, - notificationShadeDepthController + notificationShadeDepthController, + notificationShadeWindowController ); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java index 6ea79af8b9ad..65ff5583e7d4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar; import android.view.ViewGroup; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.systemui.statusbar.phone.StatusBarWindowCallback; @@ -188,6 +189,14 @@ public interface NotificationShadeWindowController extends RemoteInputController default void setLightRevealScrimOpaque(boolean opaque) {} /** + * Defer any application of window {@link WindowManager.LayoutParams} until {@code scope} is + * fully applied. + */ + default void batchApplyWindowLayoutParams(@NonNull Runnable scope) { + scope.run(); + } + + /** * Custom listener to pipe data back to plugins about whether or not the status bar would be * collapsed if not for the plugin. * TODO: Find cleaner way to do this. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index 33c4109b3426..3ba66bff66bb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -145,6 +145,7 @@ import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationShadeDepthController; +import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.NotificationShelfController; import com.android.systemui.statusbar.PulseExpansionHandler; import com.android.systemui.statusbar.RemoteInputController; @@ -664,7 +665,9 @@ public class NotificationPanelViewController extends PanelViewController { NotificationLockscreenUserManager notificationLockscreenUserManager, NotificationEntryManager notificationEntryManager, KeyguardStateController keyguardStateController, - StatusBarStateController statusBarStateController, DozeLog dozeLog, + StatusBarStateController statusBarStateController, + NotificationShadeWindowController notificationShadeWindowController, + DozeLog dozeLog, DozeParameters dozeParameters, CommandQueue commandQueue, VibratorHelper vibratorHelper, LatencyTracker latencyTracker, PowerManager powerManager, AccessibilityManager accessibilityManager, @DisplayId int displayId, @@ -716,6 +719,7 @@ public class NotificationPanelViewController extends PanelViewController { dozeLog, keyguardStateController, (SysuiStatusBarStateController) statusBarStateController, + notificationShadeWindowController, vibratorHelper, statusBarKeyguardViewManager, latencyTracker, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java index 030a8951943d..8c76a1bf4f83 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java @@ -107,6 +107,12 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW private final SysuiColorExtractor mColorExtractor; private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController; private float mFaceAuthDisplayBrightness = LayoutParams.BRIGHTNESS_OVERRIDE_NONE; + /** + * Layout params would be aggregated and dispatched all at once if this is > 0. + * + * @see #batchApplyWindowLayoutParams(Runnable) + */ + private int mDeferWindowLayoutParams; @Inject public NotificationShadeWindowControllerImpl(Context context, WindowManager windowManager, @@ -433,6 +439,20 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW } } + private void applyWindowLayoutParams() { + if (mDeferWindowLayoutParams == 0 && mLp != null && mLp.copyFrom(mLpChanged) != 0) { + mWindowManager.updateViewLayout(mNotificationShadeView, mLp); + } + } + + @Override + public void batchApplyWindowLayoutParams(Runnable scope) { + mDeferWindowLayoutParams++; + scope.run(); + mDeferWindowLayoutParams--; + applyWindowLayoutParams(); + } + private void apply(State state) { applyKeyguardFlags(state); applyFocusableFlag(state); @@ -447,9 +467,8 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW applyHasTopUi(state); applyNotTouchable(state); applyStatusBarColorSpaceAgnosticFlag(state); - if (mLp != null && mLp.copyFrom(mLpChanged) != 0) { - mWindowManager.updateViewLayout(mNotificationShadeView, mLp); - } + applyWindowLayoutParams(); + if (mHasTopUi != mHasTopUiChanged) { whitelistIpcs(() -> { try { @@ -722,6 +741,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW pw.println(TAG + ":"); pw.println(" mKeyguardMaxRefreshRate=" + mKeyguardMaxRefreshRate); pw.println(" mKeyguardPreferredRefreshRate=" + mKeyguardPreferredRefreshRate); + pw.println(" mDeferWindowLayoutParams=" + mDeferWindowLayoutParams); pw.println(mCurrentState); if (mNotificationShadeView != null && mNotificationShadeView.getViewRootImpl() != null) { mNotificationShadeView.getViewRootImpl().dump(" ", pw); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java index 2bf16fc9e52c..040820e90790 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java @@ -54,6 +54,7 @@ import com.android.systemui.animation.Interpolators; import com.android.systemui.classifier.Classifier; import com.android.systemui.doze.DozeLog; import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.VibratorHelper; @@ -177,6 +178,7 @@ public abstract class PanelViewController { private boolean mExpandLatencyTracking; private final PanelView mView; private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; + private final NotificationShadeWindowController mNotificationShadeWindowController; protected final Resources mResources; protected final KeyguardStateController mKeyguardStateController; protected final SysuiStatusBarStateController mStatusBarStateController; @@ -215,6 +217,7 @@ public abstract class PanelViewController { DozeLog dozeLog, KeyguardStateController keyguardStateController, SysuiStatusBarStateController statusBarStateController, + NotificationShadeWindowController notificationShadeWindowController, VibratorHelper vibratorHelper, StatusBarKeyguardViewManager statusBarKeyguardViewManager, LatencyTracker latencyTracker, @@ -247,6 +250,7 @@ public abstract class PanelViewController { mResources = mView.getResources(); mKeyguardStateController = keyguardStateController; mStatusBarStateController = statusBarStateController; + mNotificationShadeWindowController = notificationShadeWindowController; mFlingAnimationUtils = flingAnimationUtilsBuilder .reset() .setMaxLengthSeconds(0.6f) @@ -743,34 +747,36 @@ public abstract class PanelViewController { if (isNaN(h)) { Log.wtf(TAG, "ExpandedHeight set to NaN"); } - if (mExpandLatencyTracking && h != 0f) { - DejankUtils.postAfterTraversal( - () -> mLatencyTracker.onActionEnd(LatencyTracker.ACTION_EXPAND_PANEL)); - mExpandLatencyTracking = false; - } - float maxPanelHeight = getMaxPanelHeight(); - if (mHeightAnimator == null) { - if (mTracking) { - float overExpansionPixels = Math.max(0, h - maxPanelHeight); - setOverExpansionInternal(overExpansionPixels, true /* isFromGesture */); + mNotificationShadeWindowController.batchApplyWindowLayoutParams(()-> { + if (mExpandLatencyTracking && h != 0f) { + DejankUtils.postAfterTraversal( + () -> mLatencyTracker.onActionEnd(LatencyTracker.ACTION_EXPAND_PANEL)); + mExpandLatencyTracking = false; + } + float maxPanelHeight = getMaxPanelHeight(); + if (mHeightAnimator == null) { + if (mTracking) { + float overExpansionPixels = Math.max(0, h - maxPanelHeight); + setOverExpansionInternal(overExpansionPixels, true /* isFromGesture */); + } + mExpandedHeight = Math.min(h, maxPanelHeight); + } else { + mExpandedHeight = h; } - mExpandedHeight = Math.min(h, maxPanelHeight); - } else { - mExpandedHeight = h; - } - // If we are closing the panel and we are almost there due to a slow decelerating - // interpolator, abort the animation. - if (mExpandedHeight < 1f && mExpandedHeight != 0f && mClosing) { - mExpandedHeight = 0f; - if (mHeightAnimator != null) { - mHeightAnimator.end(); + // If we are closing the panel and we are almost there due to a slow decelerating + // interpolator, abort the animation. + if (mExpandedHeight < 1f && mExpandedHeight != 0f && mClosing) { + mExpandedHeight = 0f; + if (mHeightAnimator != null) { + mHeightAnimator.end(); + } } - } - mExpandedFraction = Math.min(1f, - maxPanelHeight == 0 ? 0 : mExpandedHeight / maxPanelHeight); - onHeightUpdated(mExpandedHeight); - updatePanelExpansionAndVisibility(); + mExpandedFraction = Math.min(1f, + maxPanelHeight == 0 ? 0 : mExpandedHeight / maxPanelHeight); + onHeightUpdated(mExpandedHeight); + updatePanelExpansionAndVisibility(); + }); } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 071c8c9117ec..0eefc9404825 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -2937,9 +2937,8 @@ public class StatusBar extends SystemUI implements // turned off fully. boolean keyguardForDozing = mDozeServiceHost.getDozingRequested() && (!mDeviceInteractive || isGoingToSleep() && (isScreenFullyOff() || mIsKeyguard)); - boolean isWakingAndOccluded = isOccluded() && isWaking(); boolean shouldBeKeyguard = (mStatusBarStateController.isKeyguardRequested() - || keyguardForDozing) && !wakeAndUnlocking && !isWakingAndOccluded; + || keyguardForDozing) && !wakeAndUnlocking; if (keyguardForDozing) { updatePanelExpansionForKeyguard(); } @@ -3560,26 +3559,29 @@ public class StatusBar extends SystemUI implements public void onStartedWakingUp() { String tag = "StatusBar#onStartedWakingUp"; DejankUtils.startDetectingBlockingIpcs(tag); - mDeviceInteractive = true; - mWakeUpCoordinator.setWakingUp(true); - if (!mKeyguardBypassController.getBypassEnabled()) { - mHeadsUpManager.releaseAllImmediately(); - } - updateVisibleToUser(); - updateIsKeyguard(); - mDozeServiceHost.stopDozing(); - // This is intentionally below the stopDozing call above, since it avoids that we're - // unnecessarily animating the wakeUp transition. Animations should only be enabled - // once we fully woke up. - updateRevealEffect(true /* wakingUp */); - updateNotificationPanelTouchState(); - - // If we are waking up during the screen off animation, we should undo making the - // expanded visible (we did that so the LightRevealScrim would be visible). - if (mUnlockedScreenOffAnimationController.isScreenOffLightRevealAnimationPlaying()) { - makeExpandedInvisible(); - } + mNotificationShadeWindowController.batchApplyWindowLayoutParams(()-> { + mDeviceInteractive = true; + mWakeUpCoordinator.setWakingUp(true); + if (!mKeyguardBypassController.getBypassEnabled()) { + mHeadsUpManager.releaseAllImmediately(); + } + updateVisibleToUser(); + updateIsKeyguard(); + mDozeServiceHost.stopDozing(); + // This is intentionally below the stopDozing call above, since it avoids that we're + // unnecessarily animating the wakeUp transition. Animations should only be enabled + // once we fully woke up. + updateRevealEffect(true /* wakingUp */); + updateNotificationPanelTouchState(); + + // If we are waking up during the screen off animation, we should undo making the + // expanded visible (we did that so the LightRevealScrim would be visible). + if (mUnlockedScreenOffAnimationController + .isScreenOffLightRevealAnimationPlaying()) { + makeExpandedInvisible(); + } + }); DejankUtils.stopDetectingBlockingIpcs(tag); } @@ -3717,10 +3719,6 @@ public class StatusBar extends SystemUI implements == WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP; } - boolean isWaking() { - return mWakefulnessLifecycle.getWakefulness() == WakefulnessLifecycle.WAKEFULNESS_WAKING; - } - public void notifyBiometricAuthModeChanged() { mDozeServiceHost.updateDozing(); updateScrimController(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt index 12258136c011..67985b95dda4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt @@ -21,7 +21,7 @@ import android.app.IActivityManager import android.app.IUidObserver import android.app.Notification import android.app.Notification.CallStyle.CALL_TYPE_ONGOING -import android.content.Intent +import android.app.PendingIntent import android.util.Log import android.view.View import androidx.annotation.VisibleForTesting @@ -98,7 +98,7 @@ class OngoingCallController @Inject constructor( val newOngoingCallInfo = CallNotificationInfo( entry.sbn.key, entry.sbn.notification.`when`, - entry.sbn.notification.contentIntent?.intent, + entry.sbn.notification.contentIntent, entry.sbn.uid, entry.sbn.notification.extras.getInt( Notification.EXTRA_CALL_TYPE, -1) == CALL_TYPE_ONGOING, @@ -230,7 +230,6 @@ class OngoingCallController @Inject constructor( logger.logChipClicked() activityStarter.postStartActivityDismissingKeyguard( intent, - 0, ActivityLaunchAnimator.Controller.fromView( backgroundView, InteractionJankMonitor.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP) @@ -351,7 +350,7 @@ class OngoingCallController @Inject constructor( private data class CallNotificationInfo( val key: String, val callStartTime: Long, - val intent: Intent?, + val intent: PendingIntent?, val uid: Int, /** True if the call is currently ongoing (as opposed to incoming, screening, etc.). */ val isOngoing: Boolean, diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbAudioWarningDialogMessage.java b/packages/SystemUI/src/com/android/systemui/usb/UsbAudioWarningDialogMessage.java new file mode 100644 index 000000000000..df845e53a36b --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbAudioWarningDialogMessage.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.usb; + +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import android.annotation.IntDef; +import android.content.Context; +import android.content.Intent; +import android.content.res.Resources; +import android.util.Log; + +import com.android.systemui.R; + +import java.lang.annotation.Retention; + +/** + * USB Audio devices warning dialog messages help class. + */ +public class UsbAudioWarningDialogMessage { + private static final String TAG = "UsbAudioWarningDialogMessage"; + + @Retention(SOURCE) + @IntDef({TYPE_PERMISSION, TYPE_CONFIRM}) + public @interface DialogType {} + public static final int TYPE_PERMISSION = 0; + public static final int TYPE_CONFIRM = 1; + + private final int mDialogType; + private UsbDialogHelper mDialogHelper; + + public UsbAudioWarningDialogMessage(Context context, Intent intent, @DialogType int type) { + mDialogType = type; + try { + mDialogHelper = new UsbDialogHelper(context, intent); + } catch (IllegalStateException e) { + Log.e(TAG, "Unable to initialize UsbDialogHelper!", e); + } + } + + private boolean hasRecordPermission() { + return mDialogHelper.packageHasAudioRecordingPermission(); + } + + private boolean isUsbAudioDevice() { + return mDialogHelper.isUsbDevice() && (mDialogHelper.deviceHasAudioCapture() + || (mDialogHelper.deviceHasAudioPlayback())); + } + + private boolean hasAudioPlayback() { + return mDialogHelper.deviceHasAudioPlayback(); + } + + private boolean hasAudioCapture() { + return mDialogHelper.deviceHasAudioCapture(); + } + + /** + * According to USB audio warning dialog matrix table to return warning message id. + * @return string resId for USB audio warning dialog message, otherwise {ID_NULL}. + * See usb_audio.md for USB audio Permission and Confirmation warning dialog resource + * string id matrix table. + */ + public int getMessageId() { + if (!mDialogHelper.isUsbDevice()) { + return getUsbAccessoryPromptId(); + } + + if (hasRecordPermission() && isUsbAudioDevice()) { + // case# 1, 2, 3 + return R.string.usb_audio_device_prompt; + } else if (!hasRecordPermission() && isUsbAudioDevice() && hasAudioPlayback() + && !hasAudioCapture()) { + // case# 5 + return R.string.usb_audio_device_prompt; + } + + if (!hasRecordPermission() && isUsbAudioDevice() && hasAudioCapture()) { + // case# 6,7 + return R.string.usb_audio_device_prompt_warn; + } + + Log.w(TAG, "Only shows title with empty content description!"); + return Resources.ID_NULL; + } + + /** + * Gets prompt dialog title. + * @return string id for USB prompt dialog title. + */ + public int getPromptTitleId() { + return (mDialogType == TYPE_PERMISSION) + ? R.string.usb_audio_device_permission_prompt_title + : R.string.usb_audio_device_confirm_prompt_title; + } + + /** + * Gets USB Accessory prompt message id. + * @return string id for USB Accessory prompt message. + */ + public int getUsbAccessoryPromptId() { + return (mDialogType == TYPE_PERMISSION) + ? R.string.usb_accessory_permission_prompt : R.string.usb_accessory_confirm_prompt; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java index 21d700e41a40..3531f17bb6a1 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java @@ -24,6 +24,7 @@ import android.content.Intent; import android.content.PermissionChecker; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.content.res.Resources; import android.hardware.usb.IUsbManager; import android.hardware.usb.UsbAccessory; import android.hardware.usb.UsbDevice; @@ -35,7 +36,6 @@ import android.os.UserHandle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; -import android.view.Window; import android.view.WindowManager; import android.widget.CheckBox; import android.widget.CompoundButton; @@ -57,6 +57,7 @@ public class UsbConfirmActivity extends AlertActivity private ResolveInfo mResolveInfo; private boolean mPermissionGranted; private UsbDisconnectedReceiver mDisconnectedReceiver; + private UsbAudioWarningDialogMessage mUsbConfirmMessageHandler; @Override public void onCreate(Bundle icicle) { @@ -70,16 +71,19 @@ public class UsbConfirmActivity extends AlertActivity mAccessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY); mResolveInfo = (ResolveInfo) intent.getParcelableExtra("rinfo"); String packageName = intent.getStringExtra(UsbManager.EXTRA_PACKAGE); - + mUsbConfirmMessageHandler = new UsbAudioWarningDialogMessage( + getApplicationContext(), getIntent(), + UsbAudioWarningDialogMessage.TYPE_CONFIRM); PackageManager packageManager = getPackageManager(); String appName = mResolveInfo.loadLabel(packageManager).toString(); final AlertController.AlertParams ap = mAlertParams; - ap.mTitle = appName; + final int titleId = mUsbConfirmMessageHandler.getPromptTitleId(); + ap.mTitle = getString(titleId, appName, mDevice.getProductName()); boolean useRecordWarning = false; if (mDevice == null) { - ap.mMessage = getString(R.string.usb_accessory_confirm_prompt, appName, - mAccessory.getDescription()); + final int messageId = mUsbConfirmMessageHandler.getUsbAccessoryPromptId(); + ap.mMessage = getString(messageId, appName, mAccessory.getDescription()); mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mAccessory); } else { int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); @@ -91,11 +95,9 @@ public class UsbConfirmActivity extends AlertActivity boolean isAudioCaptureDevice = mDevice.getHasAudioCapture(); useRecordWarning = isAudioCaptureDevice && !hasRecordPermission; - int strID = useRecordWarning - ? R.string.usb_device_confirm_prompt_warn - : R.string.usb_device_confirm_prompt; - - ap.mMessage = getString(strID, appName, mDevice.getProductName()); + final int messageId = mUsbConfirmMessageHandler.getMessageId(); + ap.mMessage = (messageId != Resources.ID_NULL) ? getString(messageId, appName, + mDevice.getProductName()) : null; mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mDevice); } ap.mPositiveButtonText = getString(android.R.string.ok); diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDialogHelper.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDialogHelper.java new file mode 100644 index 000000000000..ab29a9e970c7 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDialogHelper.java @@ -0,0 +1,303 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.usb; + +import static android.Manifest.permission.RECORD_AUDIO; + +import android.app.Activity; +import android.app.PendingIntent; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.PermissionChecker; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.hardware.usb.IUsbManager; +import android.hardware.usb.UsbAccessory; +import android.hardware.usb.UsbDevice; +import android.hardware.usb.UsbManager; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.UserHandle; +import android.util.Log; + +/** + * Helper class to separate model and view for USB permission and confirm dialogs. + */ +public class UsbDialogHelper { + private static final String TAG = UsbDialogHelper.class.getSimpleName(); + private static final String EXTRA_RESOLVE_INFO = "rinfo"; + + private final UsbDevice mDevice; + private final UsbAccessory mAccessory; + private final ResolveInfo mResolveInfo; + private final String mPackageName; + private final CharSequence mAppName; + private final Context mContext; + private final PendingIntent mPendingIntent; + private final IUsbManager mUsbService; + private final int mUid; + private final boolean mCanBeDefault; + + private UsbDisconnectedReceiver mDisconnectedReceiver; + private boolean mIsUsbDevice; + private boolean mResponseSent; + + /** + * @param context The Context of the caller. + * @param intent The intent of the caller. + * @throws IllegalStateException Thrown if both UsbDevice and UsbAccessory are null or if the + * query for the matching ApplicationInfo is unsuccessful. + */ + public UsbDialogHelper(Context context, Intent intent) throws IllegalStateException { + mContext = context; + mDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); + mAccessory = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY); + mCanBeDefault = intent.getBooleanExtra(UsbManager.EXTRA_CAN_BE_DEFAULT, false); + if (mDevice == null && mAccessory == null) { + throw new IllegalStateException("Device and accessory are both null."); + } + if (mDevice != null) { + mIsUsbDevice = true; + } + mResolveInfo = intent.getParcelableExtra(EXTRA_RESOLVE_INFO); + PackageManager packageManager = mContext.getPackageManager(); + if (mResolveInfo != null) { + // If a ResolveInfo is provided it will be used to determine the activity to start + mUid = mResolveInfo.activityInfo.applicationInfo.uid; + mPackageName = mResolveInfo.activityInfo.packageName; + mPendingIntent = null; + } else { + mUid = intent.getIntExtra(Intent.EXTRA_UID, -1); + mPackageName = intent.getStringExtra(UsbManager.EXTRA_PACKAGE); + mPendingIntent = intent.getParcelableExtra(Intent.EXTRA_INTENT); + } + try { + ApplicationInfo aInfo = packageManager.getApplicationInfo(mPackageName, 0); + mAppName = aInfo.loadLabel(packageManager); + } catch (PackageManager.NameNotFoundException e) { + throw new IllegalStateException("unable to look up package name", e); + } + IBinder b = ServiceManager.getService(Context.USB_SERVICE); + mUsbService = IUsbManager.Stub.asInterface(b); + } + + /** + * Registers UsbDisconnectedReceiver to dismiss dialog automatically when device or accessory + * gets disconnected + * @param activity The activity to finish when device / accessory gets disconnected. + */ + public void registerUsbDisconnectedReceiver(Activity activity) { + if (mIsUsbDevice) { + mDisconnectedReceiver = new UsbDisconnectedReceiver(activity, mDevice); + } else { + mDisconnectedReceiver = new UsbDisconnectedReceiver(activity, mAccessory); + } + } + + /** + * Unregisters the UsbDisconnectedReceiver. To be called when the activity is destroyed. + * @param activity The activity registered to finish when device / accessory gets disconnected. + */ + public void unregisterUsbDisconnectedReceiver(Activity activity) { + if (mDisconnectedReceiver != null) { + try { + activity.unregisterReceiver(mDisconnectedReceiver); + } catch (Exception e) { + // pass + } + mDisconnectedReceiver = null; + } + } + + /** + * @return True if the intent contains a UsbDevice which can capture audio. + */ + public boolean deviceHasAudioCapture() { + return mDevice != null && mDevice.getHasAudioCapture(); + } + + /** + * @return True if the intent contains a UsbDevice which can play audio. + */ + public boolean deviceHasAudioPlayback() { + return mDevice != null && mDevice.getHasAudioPlayback(); + } + + /** + * @return True if the package has RECORD_AUDIO permission specified in its manifest. + */ + public boolean packageHasAudioRecordingPermission() { + return PermissionChecker.checkPermissionForPreflight(mContext, RECORD_AUDIO, + PermissionChecker.PID_UNKNOWN, mUid, mPackageName) + == android.content.pm.PackageManager.PERMISSION_GRANTED; + } + + /** + * @return True if the intent contains a UsbDevice. + */ + public boolean isUsbDevice() { + return mIsUsbDevice; + } + + /** + * @return True if the intent contains a UsbAccessory. + */ + public boolean isUsbAccessory() { + return !mIsUsbDevice; + } + + /** + * Grants USB permission to the device / accessory to the calling uid. + */ + public void grantUidAccessPermission() { + try { + if (mIsUsbDevice) { + mUsbService.grantDevicePermission(mDevice, mUid); + } else { + mUsbService.grantAccessoryPermission(mAccessory, mUid); + } + } catch (RemoteException e) { + Log.e(TAG, "IUsbService connection failed", e); + } + } + + /** + * Sets the package as default for the device / accessory. + */ + public void setDefaultPackage() { + final int userId = UserHandle.myUserId(); + try { + if (mIsUsbDevice) { + mUsbService.setDevicePackage(mDevice, mPackageName, userId); + } else { + mUsbService.setAccessoryPackage(mAccessory, mPackageName, userId); + } + } catch (RemoteException e) { + Log.e(TAG, "IUsbService connection failed", e); + } + } + + /** + * Clears the default package of the device / accessory. + */ + public void clearDefaultPackage() { + final int userId = UserHandle.myUserId(); + try { + if (mIsUsbDevice) { + mUsbService.setDevicePackage(mDevice, null, userId); + } else { + mUsbService.setAccessoryPackage(mAccessory, null, userId); + } + } catch (RemoteException e) { + Log.e(TAG, "IUsbService connection failed", e); + } + } + + /** + * Starts the activity which was selected to handle the device / accessory. + */ + public void confirmDialogStartActivity() { + final int userId = UserHandle.myUserId(); + Intent intent; + + if (mIsUsbDevice) { + intent = new Intent(UsbManager.ACTION_USB_DEVICE_ATTACHED); + intent.putExtra(UsbManager.EXTRA_DEVICE, mDevice); + } else { + intent = new Intent(UsbManager.ACTION_USB_ACCESSORY_ATTACHED); + intent.putExtra(UsbManager.EXTRA_ACCESSORY, mAccessory); + } + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setComponent( + new ComponentName(mResolveInfo.activityInfo.packageName, + mResolveInfo.activityInfo.name)); + try { + mContext.startActivityAsUser(intent, new UserHandle(userId)); + } catch (Exception e) { + Log.e(TAG, "Unable to start activity", e); + } + } + + /** + * Sends the result of the permission dialog via the provided PendingIntent. + * + * @param permissionGranted True if the user pressed ok in the permission dialog. + */ + public void sendPermissionDialogResponse(boolean permissionGranted) { + if (!mResponseSent) { + // send response via pending intent + Intent intent = new Intent(); + if (mIsUsbDevice) { + intent.putExtra(UsbManager.EXTRA_DEVICE, mDevice); + } else { + intent.putExtra(UsbManager.EXTRA_ACCESSORY, mAccessory); + } + intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, permissionGranted); + try { + mPendingIntent.send(mContext, 0, intent); + mResponseSent = true; + } catch (PendingIntent.CanceledException e) { + Log.w(TAG, "PendingIntent was cancelled"); + } + } + } + + /** + * @return A description of the device / accessory + */ + public String getDeviceDescription() { + String desc; + if (mIsUsbDevice) { + desc = mDevice.getProductName(); + if (desc == null) { + desc = mDevice.getDeviceName(); + } + } else { + // UsbAccessory + desc = mAccessory.getDescription(); + if (desc == null) { + desc = String.format("%s %s", mAccessory.getManufacturer(), mAccessory.getModel()); + } + } + return desc; + } + + /** + * Whether the calling package can set as default handler of the USB device or accessory. + * In case of a UsbAccessory this is the case if the calling package has an intent filter for + * {@link UsbManager#ACTION_USB_ACCESSORY_ATTACHED} with a usb-accessory filter matching the + * attached accessory. In case of a UsbDevice this is the case if the calling package has an + * intent filter for {@link UsbManager#ACTION_USB_DEVICE_ATTACHED} with a usb-device filter + * matching the attached device. + * + * @return True if the package can be default for the USB device. + */ + public boolean canBeDefault() { + return mCanBeDefault; + } + + /** + * @return The name of the app which requested permission or the name of the app which will be + * opened if the user allows it to handle the USB device. + */ + public CharSequence getAppName() { + return mAppName; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java index bfa50bcee270..4b7ee03c1471 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java @@ -24,6 +24,7 @@ import android.content.Intent; import android.content.PermissionChecker; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.content.res.Resources; import android.hardware.usb.IUsbManager; import android.hardware.usb.UsbAccessory; import android.hardware.usb.UsbDevice; @@ -59,6 +60,7 @@ public class UsbPermissionActivity extends AlertActivity private int mUid; private boolean mPermissionGranted; private UsbDisconnectedReceiver mDisconnectedReceiver; + private UsbAudioWarningDialogMessage mUsbAudioPermissionMessageHandler; @Override public void onCreate(Bundle icicle) { @@ -73,7 +75,9 @@ public class UsbPermissionActivity extends AlertActivity mUid = intent.getIntExtra(Intent.EXTRA_UID, -1); mPackageName = intent.getStringExtra(UsbManager.EXTRA_PACKAGE); boolean canBeDefault = intent.getBooleanExtra(UsbManager.EXTRA_CAN_BE_DEFAULT, false); - + mUsbAudioPermissionMessageHandler = new UsbAudioWarningDialogMessage( + getApplicationContext(), getIntent(), + UsbAudioWarningDialogMessage.TYPE_PERMISSION); PackageManager packageManager = getPackageManager(); ApplicationInfo aInfo; try { @@ -86,13 +90,14 @@ public class UsbPermissionActivity extends AlertActivity String appName = aInfo.loadLabel(packageManager).toString(); final AlertController.AlertParams ap = mAlertParams; - ap.mTitle = appName; + final int titleId = mUsbAudioPermissionMessageHandler.getPromptTitleId(); + ap.mTitle = getString(titleId, appName, mDevice.getProductName()); boolean useRecordWarning = false; if (mDevice == null) { // Accessory Case - ap.mMessage = getString(R.string.usb_accessory_permission_prompt, appName, - mAccessory.getDescription()); + final int messageId = mUsbAudioPermissionMessageHandler.getUsbAccessoryPromptId(); + ap.mMessage = getString(messageId, appName, mAccessory.getDescription()); mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mAccessory); } else { boolean hasRecordPermission = @@ -103,10 +108,9 @@ public class UsbPermissionActivity extends AlertActivity boolean isAudioCaptureDevice = mDevice.getHasAudioCapture(); useRecordWarning = isAudioCaptureDevice && !hasRecordPermission; - int strID = useRecordWarning - ? R.string.usb_device_permission_prompt_warn - : R.string.usb_device_permission_prompt; - ap.mMessage = getString(strID, appName, mDevice.getProductName()); + final int messageId = mUsbAudioPermissionMessageHandler.getMessageId(); + ap.mMessage = (messageId != Resources.ID_NULL) ? getString(messageId, appName, + mDevice.getProductName()) : null; mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mDevice); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java index 6d8645e44fb0..086cb1ab68fb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java @@ -51,6 +51,7 @@ import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.dump.DumpManager; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.statusbar.NotificationShadeDepthController; +import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; @@ -64,9 +65,6 @@ import com.android.systemui.util.DeviceConfigProxyFake; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; -import java.util.Optional; -import java.util.function.Function; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -75,6 +73,11 @@ import org.mockito.ArgumentMatchers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.Optional; +import java.util.function.Function; + +import dagger.Lazy; + @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest @@ -103,6 +106,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { private @Mock KeyguardUnlockAnimationController mKeyguardUnlockAnimationController; private @Mock UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController; private @Mock IKeyguardDrawnCallback mKeyguardDrawnCallback; + private @Mock Lazy<NotificationShadeWindowController> mNotificationShadeWindowControllerLazy; private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake(); private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock()); @@ -144,7 +148,8 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { mKeyguardStateController, () -> mKeyguardUnlockAnimationController, mUnlockedScreenOffAnimationController, - () -> mNotificationShadeDepthController); + () -> mNotificationShadeDepthController, + mNotificationShadeWindowControllerLazy); mViewMediator.start(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java index 13989d3f0ebe..5eaa60a6f157 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java @@ -23,7 +23,6 @@ import static com.android.keyguard.KeyguardClockSwitch.SMALL; import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; import static com.android.systemui.statusbar.StatusBarState.SHADE; import static com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED; -import static com.android.systemui.statusbar.notification.ViewGroupFadeHelper.reset; import static com.google.common.truth.Truth.assertThat; @@ -107,6 +106,7 @@ import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationShadeDepthController; +import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.NotificationShelfController; import com.android.systemui.statusbar.PulseExpansionHandler; import com.android.systemui.statusbar.StatusBarStateControllerImpl; @@ -305,6 +305,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { @Mock private NotificationsQSContainerController mNotificationsQSContainerController; @Mock + private NotificationShadeWindowController mNotificationShadeWindowController; + @Mock private FeatureFlags mFeatureFlags; private Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty(); private SysuiStatusBarStateController mStatusBarStateController; @@ -402,8 +404,10 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { when(mLayoutInflater.inflate(eq(R.layout.keyguard_bottom_area), any(), anyBoolean())) .thenReturn(mKeyguardBottomArea); when(mNotificationRemoteInputManager.isRemoteInputActive()).thenReturn(false); - - reset(mView); + doAnswer(invocation -> { + ((Runnable) invocation.getArgument(0)).run(); + return null; + }).when(mNotificationShadeWindowController).batchApplyWindowLayoutParams(any()); mNotificationPanelViewController = new NotificationPanelViewController(mView, mResources, @@ -412,8 +416,9 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { coordinator, expansionHandler, mDynamicPrivacyController, mKeyguardBypassController, mFalsingManager, new FalsingCollectorFake(), mNotificationLockscreenUserManager, mNotificationEntryManager, - mKeyguardStateController, mStatusBarStateController, mDozeLog, - mDozeParameters, mCommandQueue, mVibratorHelper, + mKeyguardStateController, mStatusBarStateController, + mNotificationShadeWindowController, + mDozeLog, mDozeParameters, mCommandQueue, mVibratorHelper, mLatencyTracker, mPowerManager, mAccessibilityManager, 0, mUpdateMonitor, mMetricsLogger, mActivityManager, mConfigurationController, () -> flingAnimationUtilsBuilder, mStatusBarTouchableRegionManager, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java index 90b8a74d88be..cb468108880a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java @@ -26,6 +26,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -225,4 +226,17 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase { assertThat((mLayoutParameters.getValue().flags & FLAG_NOT_FOCUSABLE) != 0).isTrue(); assertThat((mLayoutParameters.getValue().flags & FLAG_ALT_FOCUSABLE_IM) == 0).isTrue(); } + + @Test + public void batchApplyWindowLayoutParams_doesNotDispatchEvents() { + mNotificationShadeWindowController.setForceDozeBrightness(true); + verify(mWindowManager).updateViewLayout(any(), any()); + + clearInvocations(mWindowManager); + mNotificationShadeWindowController.batchApplyWindowLayoutParams(()-> { + mNotificationShadeWindowController.setForceDozeBrightness(false); + verify(mWindowManager, never()).updateViewLayout(any(), any()); + }); + verify(mWindowManager).updateViewLayout(any(), any()); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java index 20575ae504ad..2709e436a663 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java @@ -351,6 +351,10 @@ public class StatusBarTest extends SysuiTestCase { when(mStatusBarComponentFactory.create()).thenReturn(mStatusBarComponent); when(mStatusBarComponent.getNotificationShadeWindowViewController()).thenReturn( mNotificationShadeWindowViewController); + doAnswer(invocation -> { + ((Runnable) invocation.getArgument(0)).run(); + return null; + }).when(mNotificationShadeWindowController).batchApplyWindowLayoutParams(any()); mShadeController = new ShadeControllerImpl(mCommandQueue, mStatusBarStateController, mNotificationShadeWindowController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt index b385b7d62cff..45c6be936eb9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt @@ -22,7 +22,6 @@ import android.app.IUidObserver import android.app.Notification import android.app.PendingIntent import android.app.Person -import android.content.Intent import android.service.notification.NotificationListenerService.REASON_USER_STOPPED import android.testing.AndroidTestingRunner import android.testing.TestableLooper @@ -429,6 +428,19 @@ class OngoingCallControllerTest : SysuiTestCase() { .isEqualTo(OngoingCallLogger.OngoingCallEvents.ONGOING_CALL_CLICKED.id) } + /** Regression test for b/212467440. */ + @Test + fun chipClicked_activityStarterTriggeredWithUnmodifiedIntent() { + val notifEntry = createOngoingCallNotifEntry() + val pendingIntent = notifEntry.sbn.notification.contentIntent + notifCollectionListener.onEntryUpdated(notifEntry) + + chipView.performClick() + + // Ensure that the sysui didn't modify the notification's intent -- see b/212467440. + verify(mockActivityStarter).postStartActivityDismissingKeyguard(eq(pendingIntent), any()) + } + @Test fun notifyChipVisibilityChanged_visibleEventLogged() { controller.notifyChipVisibilityChanged(true) @@ -570,7 +582,6 @@ class OngoingCallControllerTest : SysuiTestCase() { notificationEntryBuilder.modifyNotification(context).setContentIntent(null) } else { val contentIntent = mock(PendingIntent::class.java) - `when`(contentIntent.intent).thenReturn(mock(Intent::class.java)) notificationEntryBuilder.modifyNotification(context).setContentIntent(contentIntent) } diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index b59cd4c0f212..1a39ffa393b3 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -1166,9 +1166,17 @@ public class NetworkManagementService extends INetworkManagementService.Stub { final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class); try { if (allowlist) { - cm.updateMeteredNetworkAllowList(uid, enable); + if (enable) { + cm.addUidToMeteredNetworkAllowList(uid); + } else { + cm.removeUidFromMeteredNetworkAllowList(uid); + } } else { - cm.updateMeteredNetworkDenyList(uid, enable); + if (enable) { + cm.addUidToMeteredNetworkDenyList(uid); + } else { + cm.removeUidFromMeteredNetworkDenyList(uid); + } } synchronized (mRulesLock) { if (enable) { diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 9266bb431aa5..8a83130f50fa 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -75,7 +75,6 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.content.pm.ProviderInfo; import android.content.pm.UserInfo; -import android.content.res.Configuration; import android.content.res.ObbInfo; import android.database.ContentObserver; import android.net.Uri; @@ -122,7 +121,6 @@ import android.provider.DocumentsContract; import android.provider.Downloads; import android.provider.MediaStore; import android.provider.Settings; -import android.sysprop.VoldProperties; import android.text.TextUtils; import android.text.format.DateUtils; import android.util.ArrayMap; @@ -1380,39 +1378,6 @@ class StorageManagerService extends IStorageManager.Stub private void handleDaemonConnected() { initIfBootedAndConnected(); resetIfBootedAndConnected(); - - // On an encrypted device we can't see system properties yet, so pull - // the system locale out of the mount service. - if ("".equals(VoldProperties.encrypt_progress().orElse(""))) { - copyLocaleFromMountService(); - } - } - - private void copyLocaleFromMountService() { - String systemLocale; - try { - systemLocale = getField(StorageManager.SYSTEM_LOCALE_KEY); - } catch (RemoteException e) { - return; - } - if (TextUtils.isEmpty(systemLocale)) { - return; - } - - Slog.d(TAG, "Got locale " + systemLocale + " from mount service"); - Locale locale = Locale.forLanguageTag(systemLocale); - Configuration config = new Configuration(); - config.setLocale(locale); - try { - ActivityManager.getService().updatePersistentConfigurationWithAttribution(config, - mContext.getOpPackageName(), mContext.getAttributionTag()); - } catch (RemoteException e) { - Slog.e(TAG, "Error setting system locale from mount service", e); - } - - // Temporary workaround for http://b/17945169. - Slog.d(TAG, "Setting system properties to " + systemLocale + " from mount service"); - SystemProperties.set("persist.sys.locale", locale.toLanguageTag()); } private final IVoldListener mListener = new IVoldListener.Stub() { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 9f59a5fc7253..3e0f26132d7e 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -13813,14 +13813,26 @@ public class ActivityManagerService extends IActivityManager.Stub return false; } - if (!Build.IS_DEBUGGABLE) { - int match = mContext.getPackageManager().checkSignatures( - ii.targetPackage, ii.packageName); - if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { + int match = mContext.getPackageManager().checkSignatures( + ii.targetPackage, ii.packageName); + if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { + if (Build.IS_DEBUGGABLE) { + String message = "Instrumentation test " + ii.packageName + + " doesn't have a signature matching the target " + + ii.targetPackage + + ", which would not be allowed on the production Android builds"; + if (callingUid != Process.ROOT_UID) { + Slog.e(TAG, message + + ". THIS WILL BE DISALLOWED ON FUTURE ANDROID VERSIONS" + + " unless from a rooted ADB shell."); + } else { + Slog.w(TAG, message); + } + } else { String msg = "Permission Denial: starting instrumentation " + className + " from pid=" + Binder.getCallingPid() - + ", uid=" + Binder.getCallingPid() + + ", uid=" + Binder.getCallingUid() + " not allowed because package " + ii.packageName + " does not have a signature matching the target " + ii.targetPackage; diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 7d5b7e535ca9..45f85edeff7e 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -1761,7 +1761,10 @@ public class LockSettingsService extends ILockSettings.Stub { } private void onPostPasswordChanged(LockscreenCredential newCredential, int userHandle) { - updateEncryptionPasswordIfNeeded(newCredential, userHandle); + if (userHandle == UserHandle.USER_SYSTEM && isDeviceEncryptionEnabled() && + shouldEncryptWithCredentials() && newCredential.isNone()) { + setCredentialRequiredToDecrypt(false); + } if (newCredential.isPattern()) { setBoolean(LockPatternUtils.PATTERN_EVER_CHOSEN_KEY, true, userHandle); } @@ -1770,26 +1773,6 @@ public class LockSettingsService extends ILockSettings.Stub { } /** - * Update device encryption password if calling user is USER_SYSTEM and device supports - * encryption. - */ - private void updateEncryptionPasswordIfNeeded(LockscreenCredential credential, int userHandle) { - // Update the device encryption password. - if (userHandle != UserHandle.USER_SYSTEM || !isDeviceEncryptionEnabled()) { - return; - } - if (!shouldEncryptWithCredentials()) { - updateEncryptionPassword(StorageManager.CRYPT_TYPE_DEFAULT, null); - return; - } - if (credential.isNone()) { - // Set the encryption password to default. - setCredentialRequiredToDecrypt(false); - } - updateEncryptionPassword(credential.getStorageCryptType(), credential.getCredential()); - } - - /** * Store the hash of the *current* password in the password history list, if device policy * enforces password history requirement. */ @@ -1883,34 +1866,6 @@ public class LockSettingsService extends ILockSettings.Stub { } } - /** Update the encryption password if it is enabled **/ - @Override - public void updateEncryptionPassword(final int type, final byte[] password) { - if (!hasSecureLockScreen() && password != null && password.length != 0) { - throw new UnsupportedOperationException( - "This operation requires the lock screen feature."); - } - if (!isDeviceEncryptionEnabled()) { - return; - } - final IBinder service = ServiceManager.getService("mount"); - if (service == null) { - Slog.e(TAG, "Could not find the mount service to update the encryption password"); - return; - } - - // TODO(b/120484642): This is a location where we still use a String for vold - String passwordString = password != null ? new String(password) : null; - mHandler.post(() -> { - IStorageManager storageManager = mInjector.getStorageManager(); - try { - storageManager.changeEncryptionPassword(type, passwordString); - } catch (RemoteException e) { - Slog.e(TAG, "Error changing encryption password", e); - } - }); - } - @VisibleForTesting /** Note: this method is overridden in unit tests */ protected void tieProfileLockToParent(int userId, LockscreenCredential password) { if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + userId); diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS index c219f80ac9c5..cba81c1f5961 100644 --- a/services/core/java/com/android/server/pm/OWNERS +++ b/services/core/java/com/android/server/pm/OWNERS @@ -16,6 +16,7 @@ per-file AbstractStatsBase.java = file:dex/OWNERS per-file BackgroundDexOptService.java = file:dex/OWNERS per-file CompilerStats.java = file:dex/OWNERS per-file DynamicCodeLoggingService.java = file:dex/OWNERS +per-file Installer.java = file:dex/OWNERS per-file InstructionSets.java = file:dex/OWNERS per-file OtaDexoptService.java = file:dex/OWNERS per-file OtaDexoptShellCommand.java = file:dex/OWNERS diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index d0e445749698..3ddcf17d0a47 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -126,6 +126,7 @@ import android.system.StructStat; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; +import android.util.EventLog; import android.util.ExceptionUtils; import android.util.MathUtils; import android.util.Slog; @@ -3097,6 +3098,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { if (mResolvedBaseFile == null) { mResolvedBaseFile = new File(appInfo.getBaseCodePath()); inheritFileLocked(mResolvedBaseFile); + } else if ((params.installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { + EventLog.writeEvent(0x534e4554, "219044664"); + + // Installing base.apk. Make sure the app is restarted. + params.setDontKillApp(false); } // Inherit splits if not overridden. @@ -3743,6 +3749,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } @Override + public int getInstallFlags() { + return params.installFlags; + } + + @Override public DataLoaderParamsParcel getDataLoaderParams() { mContext.enforceCallingOrSelfPermission(Manifest.permission.USE_INSTALLER_V2, null); return params.dataLoaderParams != null ? params.dataLoaderParams.getData() : null; diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 5b4084e9b229..265e6062f1d6 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -129,6 +129,7 @@ import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.WeakHashMap; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; @@ -142,6 +143,10 @@ class PackageManagerShellCommand extends ShellCommand { private final static String ART_PROFILE_SNAPSHOT_DEBUG_LOCATION = "/data/misc/profman/"; private static final int DEFAULT_STAGED_READY_TIMEOUT_MS = 60 * 1000; private static final String TAG = "PackageManagerShellCommand"; + private static final Set<String> UNSUPPORTED_INSTALL_CMD_OPTS = Set.of( + "--multi-package" + ); + private static final Set<String> UNSUPPORTED_SESSION_CREATE_OPTS = Collections.emptySet(); final IPackageManager mInterface; final LegacyPermissionManagerInternal mLegacyPermissionManager; @@ -1282,7 +1287,7 @@ class PackageManagerShellCommand extends ShellCommand { } private int runStreamingInstall() throws RemoteException { - final InstallParams params = makeInstallParams(); + final InstallParams params = makeInstallParams(UNSUPPORTED_INSTALL_CMD_OPTS); if (params.sessionParams.dataLoaderParams == null) { params.sessionParams.setDataLoaderParams( PackageManagerShellCommandDataLoader.getStreamingDataLoaderParams(this)); @@ -1291,7 +1296,7 @@ class PackageManagerShellCommand extends ShellCommand { } private int runIncrementalInstall() throws RemoteException { - final InstallParams params = makeInstallParams(); + final InstallParams params = makeInstallParams(UNSUPPORTED_INSTALL_CMD_OPTS); if (params.sessionParams.dataLoaderParams == null) { params.sessionParams.setDataLoaderParams( PackageManagerShellCommandDataLoader.getIncrementalDataLoaderParams(this)); @@ -1300,7 +1305,7 @@ class PackageManagerShellCommand extends ShellCommand { } private int runInstall() throws RemoteException { - return doRunInstall(makeInstallParams()); + return doRunInstall(makeInstallParams(UNSUPPORTED_INSTALL_CMD_OPTS)); } private int doRunInstall(final InstallParams params) throws RemoteException { @@ -1452,7 +1457,7 @@ class PackageManagerShellCommand extends ShellCommand { private int runInstallCreate() throws RemoteException { final PrintWriter pw = getOutPrintWriter(); - final InstallParams installParams = makeInstallParams(); + final InstallParams installParams = makeInstallParams(UNSUPPORTED_SESSION_CREATE_OPTS); final int sessionId = doCreateSession(installParams.sessionParams, installParams.installerPackageName, installParams.userId); @@ -2764,7 +2769,7 @@ class PackageManagerShellCommand extends ShellCommand { long stagedReadyTimeoutMs = DEFAULT_STAGED_READY_TIMEOUT_MS; } - private InstallParams makeInstallParams() { + private InstallParams makeInstallParams(Set<String> unsupportedOptions) { final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL); final InstallParams params = new InstallParams(); @@ -2776,6 +2781,9 @@ class PackageManagerShellCommand extends ShellCommand { boolean replaceExisting = true; boolean forceNonStaged = false; while ((opt = getNextOption()) != null) { + if (unsupportedOptions.contains(opt)) { + throw new IllegalArgumentException("Unsupported option " + opt); + } switch (opt) { case "-r": // ignore break; @@ -3674,7 +3682,7 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" [--user USER_ID] INTENT"); pw.println(" Prints all broadcast receivers that can handle the given INTENT."); pw.println(""); - pw.println(" install [-rtfdgw] [-i PACKAGE] [--user USER_ID|all|current]"); + pw.println(" install [-rtfdg] [-i PACKAGE] [--user USER_ID|all|current]"); pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]"); pw.println(" [--install-reason 0/1/2/3/4] [--originating-uri URI]"); pw.println(" [--referrer URI] [--abi ABI_NAME] [--force-sdk]"); diff --git a/services/core/java/com/android/server/pm/dex/OWNERS b/services/core/java/com/android/server/pm/dex/OWNERS index 052a4ca52afd..5ca8ddd1fe17 100644 --- a/services/core/java/com/android/server/pm/dex/OWNERS +++ b/services/core/java/com/android/server/pm/dex/OWNERS @@ -1,3 +1,4 @@ alanstokes@google.com jiakaiz@google.com ngeoffray@google.com +mast@google.com diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java index ee0e5ba916b9..e3dcfd0c89c0 100644 --- a/services/core/java/com/android/server/slice/SliceManagerService.java +++ b/services/core/java/com/android/server/slice/SliceManagerService.java @@ -247,6 +247,8 @@ public class SliceManagerService extends ISliceManager.Stub { if (autoGrantPermissions != null && callingPkg != null) { // Need to own the Uri to call in with permissions to grant. enforceOwner(callingPkg, uri, userId); + // b/208232850: Needs to verify caller before granting slice access + verifyCaller(callingPkg); for (String perm : autoGrantPermissions) { if (mContext.checkPermission(perm, pid, uid) == PERMISSION_GRANTED) { int providerUser = ContentProvider.getUserIdFromUri(uri, userId); diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index f17c9f9c0a53..9f1f13aacc68 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -203,8 +203,6 @@ import android.os.UpdateLock; import android.os.UserHandle; import android.os.UserManager; import android.os.WorkSource; -import android.os.storage.IStorageManager; -import android.os.storage.StorageManager; import android.provider.Settings; import android.service.dreams.DreamActivity; import android.service.voice.IVoiceInteractionSession; @@ -4209,11 +4207,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { SystemProperties.set("persist.sys.locale", locales.get(bestLocaleIndex).toLanguageTag()); LocaleList.setDefault(locales, bestLocaleIndex); - - final Message m = PooledLambda.obtainMessage( - ActivityTaskManagerService::sendLocaleToMountDaemonMsg, this, - locales.get(bestLocaleIndex)); - mH.sendMessage(m); } mTempConfig.seq = increaseConfigurationSeqLocked(); @@ -4367,17 +4360,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { Settings.System.putConfigurationForUser(resolver, config, userId); } - private void sendLocaleToMountDaemonMsg(Locale l) { - try { - IBinder service = ServiceManager.getService("mount"); - IStorageManager storageManager = IStorageManager.Stub.asInterface(service); - Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); - storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); - } catch (RemoteException e) { - Log.e(TAG, "Error storing locale for decryption UI", e); - } - } - private void expireStartAsCallerTokenMsg(IBinder permissionToken) { mStartActivitySources.remove(permissionToken); mExpiredStartAsCallerTokens.add(permissionToken); diff --git a/services/core/java/com/android/server/wm/MirrorActiveUids.java b/services/core/java/com/android/server/wm/MirrorActiveUids.java index 4e7f1d4cca18..b9aa9599babe 100644 --- a/services/core/java/com/android/server/wm/MirrorActiveUids.java +++ b/services/core/java/com/android/server/wm/MirrorActiveUids.java @@ -19,7 +19,7 @@ package com.android.server.wm; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import android.app.ActivityManager.ProcessState; -import android.util.SparseArray; +import android.util.SparseIntArray; import java.io.PrintWriter; @@ -29,15 +29,14 @@ import java.io.PrintWriter; * adjustment) or getting state from window manager (background start check). */ class MirrorActiveUids { - private final SparseArray<UidRecord> mUidStates = new SparseArray<>(); + /** Uid -> process state. */ + private final SparseIntArray mUidStates = new SparseIntArray(); + + /** Uid -> number of non-app visible windows belong to the uid. */ + private final SparseIntArray mNumNonAppVisibleWindowMap = new SparseIntArray(); synchronized void onUidActive(int uid, int procState) { - UidRecord r = mUidStates.get(uid); - if (r == null) { - r = new UidRecord(); - mUidStates.put(uid, r); - } - r.mProcState = procState; + mUidStates.put(uid, procState); } synchronized void onUidInactive(int uid) { @@ -45,22 +44,28 @@ class MirrorActiveUids { } synchronized void onUidProcStateChanged(int uid, int procState) { - final UidRecord r = mUidStates.get(uid); - if (r != null) { - r.mProcState = procState; + final int index = mUidStates.indexOfKey(uid); + if (index >= 0) { + mUidStates.setValueAt(index, procState); } } synchronized @ProcessState int getUidState(int uid) { - final UidRecord r = mUidStates.get(uid); - return r != null ? r.mProcState : PROCESS_STATE_NONEXISTENT; + return mUidStates.get(uid, PROCESS_STATE_NONEXISTENT); } /** Called when the surface of non-application (exclude toast) window is shown or hidden. */ synchronized void onNonAppSurfaceVisibilityChanged(int uid, boolean visible) { - final UidRecord r = mUidStates.get(uid); - if (r != null) { - r.mNumNonAppVisibleWindow += visible ? 1 : -1; + final int index = mNumNonAppVisibleWindowMap.indexOfKey(uid); + if (index >= 0) { + final int num = mNumNonAppVisibleWindowMap.valueAt(index) + (visible ? 1 : -1); + if (num > 0) { + mNumNonAppVisibleWindowMap.setValueAt(index, num); + } else { + mNumNonAppVisibleWindowMap.removeAt(index); + } + } else if (visible) { + mNumNonAppVisibleWindowMap.append(uid, 1); } } @@ -70,23 +75,15 @@ class MirrorActiveUids { * {@link VisibleActivityProcessTracker}. */ synchronized boolean hasNonAppVisibleWindow(int uid) { - final UidRecord r = mUidStates.get(uid); - return r != null && r.mNumNonAppVisibleWindow > 0; + return mNumNonAppVisibleWindowMap.get(uid) > 0; } synchronized void dump(PrintWriter pw, String prefix) { - pw.print(prefix + "NumNonAppVisibleWindowByUid:["); - for (int i = mUidStates.size() - 1; i >= 0; i--) { - final UidRecord r = mUidStates.valueAt(i); - if (r.mNumNonAppVisibleWindow > 0) { - pw.print(" " + mUidStates.keyAt(i) + ":" + r.mNumNonAppVisibleWindow); - } + pw.print(prefix + "NumNonAppVisibleWindowUidMap:["); + for (int i = mNumNonAppVisibleWindowMap.size() - 1; i >= 0; i--) { + pw.print(" " + mNumNonAppVisibleWindowMap.keyAt(i) + ":" + + mNumNonAppVisibleWindowMap.valueAt(i)); } pw.println("]"); } - - private static final class UidRecord { - @ProcessState int mProcState; - int mNumNonAppVisibleWindow; - } } diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 628e124877e9..9cd37b305dc6 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -3624,11 +3624,17 @@ class RootWindowContainer extends WindowContainer<DisplayContent> return new ArrayList<>(); } } else { + final RecentTasks recentTasks = mWindowManager.mAtmService.getRecentTasks(); + final int recentsComponentUid = recentTasks != null + ? recentTasks.getRecentsComponentUid() + : -1; final ArrayList<ActivityRecord> activities = new ArrayList<>(); - forAllRootTasks(rootTask -> { - if (!dumpVisibleRootTasksOnly || rootTask.shouldBeVisible(null)) { - activities.addAll(rootTask.getDumpActivitiesLocked(name)); + forAllLeafTasks(task -> { + final boolean isRecents = (task.effectiveUid == recentsComponentUid); + if (!dumpVisibleRootTasksOnly || task.shouldBeVisible(null) || isRecents) { + activities.addAll(task.getDumpActivitiesLocked(name)); } + return false; }); return activities; } diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java index 9864297de529..d31b007c56af 100644 --- a/services/core/java/com/android/server/wm/RunningTasks.java +++ b/services/core/java/com/android/server/wm/RunningTasks.java @@ -43,7 +43,11 @@ class RunningTasks { // Comparator to sort by last active time (descending) private static final Comparator<Task> LAST_ACTIVE_TIME_COMPARATOR = - (o1, o2) -> Long.signum(o2.lastActiveTime - o1.lastActiveTime); + (o1, o2) -> { + return o1.lastActiveTime == o2.lastActiveTime + ? Integer.signum(o2.mTaskId - o1.mTaskId) : + Long.signum(o2.lastActiveTime - o1.lastActiveTime); + }; private final TreeSet<Task> mTmpSortedSet = new TreeSet<>(LAST_ACTIVE_TIME_COMPARATOR); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 4258e073429e..575ae691dbe8 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -3277,9 +3277,6 @@ public class WindowManagerService extends IWindowManager.Stub if (!checkCallingPermission(permission.CONTROL_KEYGUARD, "dismissKeyguard")) { throw new SecurityException("Requires CONTROL_KEYGUARD permission"); } - if (mAtmInternal.isDreaming()) { - mAtmService.mTaskSupervisor.wakeUp("dismissKeyguard"); - } synchronized (mGlobalLock) { mPolicy.dismissKeyguardLw(callback, message); } diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java index a94fd074ff2e..2d8410bd12d2 100644 --- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java +++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java @@ -513,9 +513,14 @@ public class WindowManagerShellCommand extends ShellCommand { try (ZipOutputStream out = new ZipOutputStream(getRawOutputStream())) { ArrayList<Pair<String, ByteTransferPipe>> requestList = new ArrayList<>(); synchronized (mInternal.mGlobalLock) { + final RecentTasks recentTasks = mInternal.mAtmService.getRecentTasks(); + final int recentsComponentUid = recentTasks != null + ? recentTasks.getRecentsComponentUid() + : -1; // Request dump from all windows parallelly before writing to disk. mInternal.mRoot.forAllWindows(w -> { - if (w.isVisible()) { + final boolean isRecents = (w.mSession.mUid == recentsComponentUid); + if (w.isVisible() || isRecents) { ByteTransferPipe pipe = null; try { pipe = new ByteTransferPipe(); diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp index 9d3edd6e8b2e..07f0b871129f 100644 --- a/services/core/jni/onload.cpp +++ b/services/core/jni/onload.cpp @@ -103,7 +103,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) register_android_server_HardwarePropertiesManagerService(env); register_android_server_storage_AppFuse(env); register_android_server_SyntheticPasswordManager(env); - register_android_graphics_GraphicsStatsService(env); register_android_hardware_display_DisplayViewport(env); register_android_server_am_CachedAppOptimizer(env); register_android_server_am_LowMemDetector(env); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 2db6dc4093b7..f45d8d524572 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -8469,20 +8469,23 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { admin.getPackageName(), userId, "set-device-owner"); Slogf.i(LOG_TAG, "Device owner set: " + admin + " on user " + userId); + } - if (setProfileOwnerOnCurrentUserIfNecessary - && mInjector.userManagerIsHeadlessSystemUserMode()) { - int currentForegroundUser = getCurrentForegroundUserId(); - Slogf.i(LOG_TAG, "setDeviceOwner(): setting " + admin - + " as profile owner on user " + currentForegroundUser); - // Sets profile owner on current foreground user since - // the human user will complete the DO setup workflow from there. - manageUserUnchecked(/* deviceOwner= */ admin, /* profileOwner= */ admin, - /* managedUser= */ currentForegroundUser, /* adminExtras= */ null, - /* showDisclaimer= */ false); + if (setProfileOwnerOnCurrentUserIfNecessary + && mInjector.userManagerIsHeadlessSystemUserMode()) { + int currentForegroundUser; + synchronized (getLockObject()) { + currentForegroundUser = getCurrentForegroundUserId(); } - return true; + Slogf.i(LOG_TAG, "setDeviceOwner(): setting " + admin + + " as profile owner on user " + currentForegroundUser); + // Sets profile owner on current foreground user since + // the human user will complete the DO setup workflow from there. + manageUserUnchecked(/* deviceOwner= */ admin, /* profileOwner= */ admin, + /* managedUser= */ currentForegroundUser, /* adminExtras= */ null, + /* showDisclaimer= */ false); } + return true; } @Override diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java index c5f990d52b82..66e840b5120b 100644 --- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java +++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java @@ -112,7 +112,7 @@ public final class ProfcollectForwardingService extends SystemService { try { mIProfcollect.registerProviderStatusCallback(mProviderStatusCallback); } catch (RemoteException e) { - Log.e(LOG_TAG, e.getMessage()); + Log.e(LOG_TAG, "Failed to register provider status callback: " + e.getMessage()); } } @@ -123,7 +123,7 @@ public final class ProfcollectForwardingService extends SystemService { try { return !mIProfcollect.get_supported_provider().isEmpty(); } catch (RemoteException e) { - Log.e(LOG_TAG, e.getMessage()); + Log.e(LOG_TAG, "Failed to get supported provider: " + e.getMessage()); return false; } } @@ -219,7 +219,8 @@ public final class ProfcollectForwardingService extends SystemService { try { sSelfService.mIProfcollect.process(); } catch (RemoteException e) { - Log.e(LOG_TAG, e.getMessage()); + Log.e(LOG_TAG, "Failed to process profiles in background: " + + e.getMessage()); } }); return true; @@ -234,8 +235,11 @@ public final class ProfcollectForwardingService extends SystemService { // Event observers private void registerObservers() { - registerAppLaunchObserver(); - registerOTAObserver(); + BackgroundThread.get().getThreadHandler().post( + () -> { + registerAppLaunchObserver(); + registerOTAObserver(); + }); } private final AppLaunchObserver mAppLaunchObserver = new AppLaunchObserver(); @@ -264,7 +268,7 @@ public final class ProfcollectForwardingService extends SystemService { try { mIProfcollect.trace_once("applaunch"); } catch (RemoteException e) { - Log.e(LOG_TAG, e.getMessage()); + Log.e(LOG_TAG, "Failed to initiate trace: " + e.getMessage()); } }); } @@ -348,7 +352,7 @@ public final class ProfcollectForwardingService extends SystemService { .putExtra("filename", reportName); context.sendBroadcast(intent); } catch (RemoteException e) { - Log.e(LOG_TAG, e.getMessage()); + Log.e(LOG_TAG, "Failed to upload report: " + e.getMessage()); } }); } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java index a91298f73d08..10011fd4e6e3 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java @@ -31,7 +31,6 @@ import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; @@ -42,7 +41,6 @@ import static org.junit.Assert.assertFalse; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -158,16 +156,6 @@ public class WindowManagerServiceTests extends WindowTestsBase { } @Test - public void testDismissKeyguardCanWakeUp() { - doReturn(true).when(mWm).checkCallingPermission(anyString(), anyString()); - spyOn(mWm.mAtmInternal); - doReturn(true).when(mWm.mAtmInternal).isDreaming(); - doNothing().when(mWm.mAtmService.mTaskSupervisor).wakeUp(anyString()); - mWm.dismissKeyguard(null, "test-dismiss-keyguard"); - verify(mWm.mAtmService.mTaskSupervisor).wakeUp(anyString()); - } - - @Test public void testMoveWindowTokenToDisplay_NullToken_DoNothing() { mWm.moveWindowTokenToDisplay(null, mDisplayContent.getDisplayId()); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index e6ad68aafaec..7d501356d469 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -800,7 +800,6 @@ public class WindowStateTests extends WindowTestsBase { @Test public void testHasActiveVisibleWindow() { final int uid = ActivityBuilder.DEFAULT_FAKE_UID; - mAtm.mActiveUids.onUidActive(uid, 0 /* any proc state */); final WindowState app = createWindow(null, TYPE_APPLICATION, "app", uid); app.mActivityRecord.setVisible(false); @@ -828,6 +827,11 @@ public class WindowStateTests extends WindowTestsBase { // Make the application overlay window visible. It should be a valid active visible window. overlay.onSurfaceShownChanged(true); assertTrue(mAtm.hasActiveVisibleWindow(uid)); + + // The number of windows should be independent of the existence of uid state. + mAtm.mActiveUids.onUidInactive(uid); + mAtm.mActiveUids.onUidActive(uid, 0 /* any proc state */); + assertTrue(mAtm.mActiveUids.hasNonAppVisibleWindow(uid)); } @UseTestDisplay(addWindows = W_ACTIVITY) diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index cfaf176a1028..7c98a034ed8f 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -48,6 +48,7 @@ import android.telephony.ims.feature.RcsFeature; import com.android.internal.telephony.ICarrierConfigLoader; import com.android.telephony.Rlog; +import java.util.List; import java.util.concurrent.TimeUnit; /** @@ -559,9 +560,9 @@ public class CarrierConfigManager { KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool"; /** - * List of RIL radio technologies (See {@link ServiceState} {@code RIL_RADIO_TECHNOLOGY_*} - * constants) which support only a single data connection at a time. Some carriers do not - * support multiple pdp on UMTS. + * List of network type constants which support only a single data connection at a time. + * Some carriers do not support multiple PDP on UMTS. + * @see TelephonyManager NETWORK_TYPE_* */ public static final String KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY = "only_single_dc_allowed_int_array"; @@ -3669,11 +3670,19 @@ public class CarrierConfigManager { public static final String KEY_5G_WATCHDOG_TIME_MS_LONG = "5g_watchdog_time_ms_long"; /** - * Which NR types are unmetered. A string array containing the following keys: + * Which network types are unmetered. A string array that can contain network type names from + * {@link TelephonyManager#getNetworkTypeName(int)} in addition to the following NR keys: * NR_NSA - NR NSA is unmetered for sub-6 frequencies * NR_NSA_MMWAVE - NR NSA is unmetered for mmwave frequencies * NR_SA - NR SA is unmetered for sub-6 frequencies * NR_SA_MMWAVE - NR SA is unmetered for mmwave frequencies + * + * Note that this config only applies if an unmetered SubscriptionPlan is set via + * {@link SubscriptionManager#setSubscriptionPlans(int, List)} or an unmetered override is set + * via {@link SubscriptionManager#setSubscriptionOverrideUnmetered(int, boolean, int[], long)} + * or {@link SubscriptionManager#setSubscriptionOverrideUnmetered(int, boolean, long)}. + * If neither SubscriptionPlans nor an override are set, then no network types can be unmetered + * regardless of the value of this config. * TODO: remove other unmetered keys and replace with this * @hide */ @@ -3681,6 +3690,27 @@ public class CarrierConfigManager { "unmetered_network_types_string_array"; /** + * Which network types are unmetered when roaming. A string array that can contain network type + * names from {@link TelephonyManager#getNetworkTypeName(int)} in addition to the following + * NR keys: + * NR_NSA - NR NSA is unmetered when roaming for sub-6 frequencies + * NR_NSA_MMWAVE - NR NSA is unmetered when roaming for mmwave frequencies + * NR_SA - NR SA is unmetered when roaming for sub-6 frequencies + * NR_SA_MMWAVE - NR SA is unmetered when roaming for mmwave frequencies + * + * Note that this config only applies if an unmetered SubscriptionPlan is set via + * {@link SubscriptionManager#setSubscriptionPlans(int, List)} or an unmetered override is set + * via {@link SubscriptionManager#setSubscriptionOverrideUnmetered(int, boolean, int[], long)} + * or {@link SubscriptionManager#setSubscriptionOverrideUnmetered(int, boolean, long)}. + * If neither SubscriptionPlans nor an override are set, then no network types can be unmetered + * when roaming regardless of the value of this config. + * TODO: remove KEY_UNMETERED_NR_NSA_WHEN_ROAMING_BOOL and replace with this + * @hide + */ + public static final String KEY_ROAMING_UNMETERED_NETWORK_TYPES_STRING_ARRAY = + "roaming_unmetered_network_types_string_array"; + + /** * Whether NR (non-standalone) should be unmetered for all frequencies. * If either {@link #KEY_UNMETERED_NR_NSA_MMWAVE_BOOL} or * {@link #KEY_UNMETERED_NR_NSA_SUB6_BOOL} are true, then this value will be ignored. @@ -4335,6 +4365,56 @@ public class CarrierConfigManager { "gba_ua_tls_cipher_suite_int"; /** + * The data stall recovery timers array in milliseconds, each element is the delay before + * performining next recovery action. + * + * The default value of timers array are: [180000ms, 180000ms, 180000ms] (3 minutes) + * Array[0]: It's the timer between RECOVERY_ACTION GET_DATA_CALL_LIST and CLEANUP, if data + * stall symptom still occurred, it will perform next recovery action after 180000ms. + * Array[1]: It's the timer between RECOVERY_ACTION CLEANUP and RADIO_RESTART, if data stall + * symptom still occurred, it will perform next recovery action after 180000ms. + * Array[2]: It's the timer between RECOVERY_ACTION RADIO_RESTART and RESET_MODEM, if data stall + * symptom still occurred, it will perform next recovery action after 180000ms. + * + * See the {@code RECOVERY_ACTION_*} constants in + * {@link com.android.internal.telephony.data.DataStallRecoveryManager} + * @hide + */ + public static final String KEY_DATA_STALL_RECOVERY_TIMERS_LONG_ARRAY = + "data_stall_recovery_timers_long_array"; + + /** + * The data stall recovery action boolean array, we use this array to determine if the + * data stall recovery action needs to be skipped. + * + * For example, if the carrier use the same APN for both of IA and default type, + * the data call will not disconnect in modem side (so the RECOVERY_ACTION_CLEANUP + * did not effect). In this case, we can config the boolean variable of action + * RECOVERY_ACTION_CLEANUP to true, then it can be ignored to speed up the recovery + * action procedure. + * + * The default value of boolean array are: [false, false, false, false] + * Array[0]: When performing the recovery action, we can use this boolean value to determine + * if we need to perform RECOVERY_ACTION_GET_DATA_CALL_LIST. + * Array[1]: If data stall symptom still occurred, we can use this boolean value to determine + * if we need to perform RECOVERY_ACTION_CLEANUP. For example, if the carrier use the same APN + * for both of IA and default type, the data call will not disconnect in modem side + * (so the RECOVERY_ACTION_CLEANUP did not effect). In this case, we can config the boolean + * variable of action RECOVERY_ACTION_CLEANUP to true, then it can be ignored to speed up the + * recovery action procedure. + * Array[2]: If data stall symptom still occurred, we can use this boolean value to determine + * if we need to perform RECOVERY_ACTION_RADIO_RESTART. + * Array[3]: If data stall symptom still occurred, we can use this boolean value to determine + * if we need to perform RECOVERY_ACTION_MODEM_RESET. + * + * See the {@code RECOVERY_ACTION_*} constants in + * {@link com.android.internal.telephony.data.DataStallRecoveryManager} + * @hide + */ + public static final String KEY_DATA_STALL_RECOVERY_SHOULD_SKIP_BOOL_ARRAY = + "data_stall_recovery_should_skip_bool_array"; + + /** * Configs used by ImsServiceEntitlement. */ public static final class ImsServiceEntitlement { @@ -5512,7 +5592,7 @@ public class CarrierConfigManager { "telephony_network_capability_priorities_string_array"; /** - * Defines the rules for data retry. + * Defines the rules for data setup retry. * * The syntax of the retry rule: * 1. Retry based on {@link NetworkCapabilities}. Note that only APN-type network capabilities @@ -5544,8 +5624,34 @@ public class CarrierConfigManager { * // TODO: remove KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS * @hide */ - public static final String KEY_TELEPHONY_DATA_RETRY_RULES_STRING_ARRAY = - "telephony_data_retry_rules_string_array"; + public static final String KEY_TELEPHONY_DATA_SETUP_RETRY_RULES_STRING_ARRAY = + "telephony_data_setup_retry_rules_string_array"; + + /** + * Defines the rules for data handover retry. + * + * The syntax of the retry rule: + * 1. Retry when handover fails. + * "retry_interval=[n1|n2|n3|...], [maximum_retries=n]" + * + * For example, + * "retry_interval=1000|3000|5000, maximum_retries=10" means handover retry will happen in 1s, + * 3s, 5s, 5s, 5s....up to 10 times. + * + * 2. Retry when handover fails with certain fail causes. + * "retry_interval=[n1|n2|n3|...], fail_causes=[cause1|cause2|cause3|...], [maximum_retries=n] + * + * For example, + * "retry_interval=1000, maximum_retries=3, fail_causes=5" means handover retry every 1 second + * for up to 3 times when handover fails with the cause 5. + * + * "maximum_retries=0, fail_causes=6|10|67" means handover retry should not happen for those + * causes. + * + * @hide + */ + public static final String KEY_TELEPHONY_DATA_HANDOVER_RETRY_RULES_STRING_ARRAY = + "telephony_data_handover_retry_rules_string_array"; /** * The patterns of missed incoming call sms. This is the regular expression used for @@ -5906,7 +6012,7 @@ public class CarrierConfigManager { "others:max_retries=3, 5000, 5000, 5000"}); sDefaults.putLong(KEY_CARRIER_DATA_CALL_APN_DELAY_DEFAULT_LONG, 20000); sDefaults.putLong(KEY_CARRIER_DATA_CALL_APN_DELAY_FASTER_LONG, 3000); - sDefaults.putLong(KEY_CARRIER_DATA_CALL_APN_RETRY_AFTER_DISCONNECT_LONG, 10000); + sDefaults.putLong(KEY_CARRIER_DATA_CALL_APN_RETRY_AFTER_DISCONNECT_LONG, 3000); sDefaults.putInt(KEY_CARRIER_DATA_CALL_RETRY_NETWORK_REQUESTED_MAX_COUNT_INT, 3); sDefaults.putString(KEY_CARRIER_ERI_FILE_NAME_STRING, "eri.xml"); sDefaults.putInt(KEY_DURATION_BLOCKING_DISABLED_AFTER_EMERGENCY_INT, 7200); @@ -5919,14 +6025,9 @@ public class CarrierConfigManager { sDefaults.putStringArray(KEY_CARRIER_WLAN_DISALLOWED_APN_TYPES_STRING_ARRAY, new String[]{""}); sDefaults.putIntArray(KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY, - new int[]{ - 4, /* IS95A */ - 5, /* IS95B */ - 6, /* 1xRTT */ - 7, /* EVDO_0 */ - 8, /* EVDO_A */ - 12 /* EVDO_B */ - }); + new int[] {TelephonyManager.NETWORK_TYPE_CDMA, TelephonyManager.NETWORK_TYPE_1xRTT, + TelephonyManager.NETWORK_TYPE_EVDO_0, TelephonyManager.NETWORK_TYPE_EVDO_A, + TelephonyManager.NETWORK_TYPE_EVDO_B}); sDefaults.putStringArray(KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY, null); sDefaults.putStringArray(KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY, null); sDefaults.putString(KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING, null); @@ -6269,7 +6370,9 @@ public class CarrierConfigManager { sDefaults.putInt(KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0); sDefaults.putBoolean(KEY_ENABLE_NR_ADVANCED_WHILE_ROAMING_BOOL, true); sDefaults.putBoolean(KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL, false); - sDefaults.putStringArray(KEY_UNMETERED_NETWORK_TYPES_STRING_ARRAY, new String[0]); + sDefaults.putStringArray(KEY_UNMETERED_NETWORK_TYPES_STRING_ARRAY, new String[] { + "NR_NSA", "NR_NSA_MMWAVE", "NR_SA", "NR_SA_MMWAVE"}); + sDefaults.putStringArray(KEY_ROAMING_UNMETERED_NETWORK_TYPES_STRING_ARRAY, new String[0]); sDefaults.putBoolean(KEY_UNMETERED_NR_NSA_BOOL, false); sDefaults.putBoolean(KEY_UNMETERED_NR_NSA_MMWAVE_BOOL, false); sDefaults.putBoolean(KEY_UNMETERED_NR_NSA_SUB6_BOOL, false); @@ -6377,15 +6480,19 @@ public class CarrierConfigManager { "ims:40", "dun:30", "enterprise:20", "internet:20" }); sDefaults.putStringArray( - KEY_TELEPHONY_DATA_RETRY_RULES_STRING_ARRAY, new String[] { + KEY_TELEPHONY_DATA_SETUP_RETRY_RULES_STRING_ARRAY, new String[] { "capabilities=eims, retry_interval=1000, maximum_retries=20", - "fail_causes=8|27|28|29|30|32|33|35|50|51|111|-5|-6|65537|65538|-3|2253|" - + "2254, maximum_retries=0", // No retry for those causes + "fail_causes=8|27|28|29|30|32|33|35|50|51|111|-5|-6|65537|65538|-3|2252|" + + "2253|2254, maximum_retries=0", // No retry for those causes "capabilities=mms|supl|cbs, retry_interval=2000", "capabilities=internet|enterprise|dun|ims|fota, retry_interval=2500|3000|" + "5000|10000|15000|20000|40000|60000|120000|240000|" + "600000|1200000|1800000, maximum_retries=20" }); + sDefaults.putStringArray( + KEY_TELEPHONY_DATA_HANDOVER_RETRY_RULES_STRING_ARRAY, new String[] { + "retry_interval=1000|2000|4000|8000|16000, maximum_retries=5" + }); sDefaults.putStringArray(KEY_MISSED_INCOMING_CALL_SMS_PATTERN_STRING_ARRAY, new String[0]); sDefaults.putBoolean(KEY_DISABLE_DUN_APN_WHILE_ROAMING_WITH_PRESET_APN_BOOL, false); sDefaults.putString(KEY_DEFAULT_PREFERRED_APN_NAME_STRING, ""); @@ -6409,6 +6516,12 @@ public class CarrierConfigManager { sDefaults.putStringArray(KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY, new String[]{ "source=GERAN|UTRAN|EUTRAN|NGRAN|IWLAN, " + "target=GERAN|UTRAN|EUTRAN|NGRAN|IWLAN, type=allowed"}); + + // Default data stall recovery configurations. + sDefaults.putLongArray(KEY_DATA_STALL_RECOVERY_TIMERS_LONG_ARRAY, + new long[] {180000, 180000, 180000}); + sDefaults.putBooleanArray(KEY_DATA_STALL_RECOVERY_SHOULD_SKIP_BOOL_ARRAY, + new boolean[] {false, false, false, false}); } /** diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 390ffc751498..63ff2324d385 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -5985,6 +5985,7 @@ public class TelephonyManager { DATA_CONNECTED, DATA_SUSPENDED, DATA_DISCONNECTING, + DATA_HANDOVER_IN_PROGRESS, }) @Retention(RetentionPolicy.SOURCE) public @interface DataState{} @@ -6009,6 +6010,12 @@ public class TelephonyManager { public static final int DATA_DISCONNECTING = 4; /** + * Data connection state: Handover in progress. The connection is being transited from cellular + * network to IWLAN, or from IWLAN to cellular network. + */ + public static final int DATA_HANDOVER_IN_PROGRESS = 5; + + /** * Used for checking if the SDK version for {@link TelephonyManager#getDataState} is above Q. */ @ChangeId @@ -6024,6 +6031,7 @@ public class TelephonyManager { * @see #DATA_CONNECTED * @see #DATA_SUSPENDED * @see #DATA_DISCONNECTING + * @see #DATA_HANDOVER_IN_PROGRESS */ public int getDataState() { try { @@ -12534,6 +12542,25 @@ public class TelephonyManager { @Retention(RetentionPolicy.SOURCE) public @interface DataEnabledReason{} + /** @hide */ + @IntDef({ + DATA_ENABLED_REASON_UNKNOWN, + DATA_ENABLED_REASON_USER, + DATA_ENABLED_REASON_POLICY, + DATA_ENABLED_REASON_CARRIER, + DATA_ENABLED_REASON_THERMAL, + DATA_ENABLED_REASON_OVERRIDE + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DataEnabledChangedReason{} + + /** + * To indicate that data was enabled or disabled due to an unknown reason. + * Note that this is not a valid reason for {@link #setDataEnabledForReason(int, boolean)} and + * is only used to indicate that data enabled was changed. + */ + public static final int DATA_ENABLED_REASON_UNKNOWN = -1; + /** * To indicate that user enabled or disabled data. */ @@ -12561,6 +12588,13 @@ public class TelephonyManager { public static final int DATA_ENABLED_REASON_THERMAL = 3; /** + * To indicate data was enabled or disabled due to {@link MobileDataPolicy} overrides. + * Note that this is not a valid reason for {@link #setDataEnabledForReason(int, boolean)} and + * is only used to indicate that data enabled was changed due to an override. + */ + public static final int DATA_ENABLED_REASON_OVERRIDE = 4; + + /** * Control of data connection and provide the reason triggering the data connection control. * This can be called for following reasons * <ol> diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java index 8c02ffe12363..cb112cf3b93a 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -118,11 +118,9 @@ public class ApnSetting implements Parcelable { public static final int TYPE_VSIM = 1 << 12; // TODO: Refer to ApnTypes.VSIM /** APN type for BIP. */ public static final int TYPE_BIP = 1 << 13; // TODO: Refer to ApnTypes.BIP - /** - * APN type for ENTERPRISE. - * @hide - */ - public static final int TYPE_ENTERPRISE = TYPE_BIP << 1; + /** APN type for ENTERPRISE. */ + public static final int TYPE_ENTERPRISE = 1 << 14; //TODO: In future should be referenced from + // hardware.interfaces.radio.data.ApnTypes /** @hide */ @IntDef(flag = true, prefix = {"TYPE_"}, value = { @@ -355,6 +353,7 @@ public class ApnSetting implements Parcelable { * modem components or carriers. Non-system apps should use the integer variants instead. * @hide */ + @SystemApi public static final String TYPE_ENTERPRISE_STRING = "enterprise"; @@ -521,11 +520,11 @@ public class ApnSetting implements Parcelable { private final boolean mAlwaysOn; /** - * Returns the MTU size of the IPv4 mobile interface to which the APN connected. Note this value - * is used only if MTU size is not provided in {@link DataCallResponse}. + * Returns the default MTU (Maximum Transmission Unit) size in bytes of the IPv4 routes brought + * up by this APN setting. Note this value will only be used when MTU size is not provided + * in {@link DataCallResponse#getMtuV4()} during network bring up. * - * @return the MTU size of the APN - * @hide + * @return the MTU size in bytes of the route. */ public int getMtuV4() { return mMtuV4; @@ -533,10 +532,10 @@ public class ApnSetting implements Parcelable { /** * Returns the MTU size of the IPv6 mobile interface to which the APN connected. Note this value - * is used only if MTU size is not provided in {@link DataCallResponse}. + * will only be used when MTU size is not provided in {@link DataCallResponse#getMtuV6()} + * during network bring up. * - * @return the MTU size of the APN - * @hide + * @return the MTU size in bytes of the route. */ public int getMtuV6() { return mMtuV6; @@ -1753,25 +1752,25 @@ public class ApnSetting implements Parcelable { } /** - * Set the MTU size of the IPv4 mobile interface to which the APN connected. Note this value - * is used only if MTU size is not provided in {@link DataCallResponse}. + * Set the default MTU (Maximum Transmission Unit) size in bytes of the IPv4 routes brought + * up by this APN setting. Note this value will only be used when MTU size is not provided + * in {@link DataCallResponse#getMtuV4()} during network bring up. * - * @param mtuV4 the MTU size to set for the APN - * @hide + * @param mtuV4 the MTU size in bytes of the route. */ - public Builder setMtuV4(int mtuV4) { + public @NonNull Builder setMtuV4(int mtuV4) { this.mMtuV4 = mtuV4; return this; } /** - * Set the MTU size of the IPv6 mobile interface to which the APN connected. Note this value - * is used only if MTU size is not provided in {@link DataCallResponse}. + * Set the default MTU (Maximum Transmission Unit) size in bytes of the IPv6 routes brought + * up by this APN setting. Note this value will only be used when MTU size is not provided + * in {@link DataCallResponse#getMtuV6()} during network bring up. * - * @param mtuV6 the MTU size to set for the APN - * @hide + * @param mtuV6 the MTU size in bytes of the route. */ - public Builder setMtuV6(int mtuV6) { + public @NonNull Builder setMtuV6(int mtuV6) { this.mMtuV6 = mtuV6; return this; } @@ -1779,15 +1778,25 @@ public class ApnSetting implements Parcelable { /** * Sets the profile id to which the APN saved in modem. * - * @param profileId the profile id to set for the APN - * @hide + * @param profileId the profile id to set for the APN. */ - public Builder setProfileId(int profileId) { + public @NonNull Builder setProfileId(int profileId) { this.mProfileId = profileId; return this; } /** + * Set if the APN setting should be persistent/non-persistent in modem. + * + * @param isPersistent {@code true} if this APN setting should be persistent/non-persistent + * in modem. + * @return The same instance of the builder. + */ + public @NonNull Builder setPersistent(boolean isPersistent) { + return setModemCognitive(isPersistent); + } + + /** * Sets if the APN setting is to be set in modem. * * @param modemCognitive if the APN setting is to be set in modem diff --git a/telephony/java/android/telephony/data/DataProfile.java b/telephony/java/android/telephony/data/DataProfile.java index c1d16a9aaea7..ec04c1ae9522 100644 --- a/telephony/java/android/telephony/data/DataProfile.java +++ b/telephony/java/android/telephony/data/DataProfile.java @@ -38,8 +38,10 @@ import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** - * Description of a mobile data profile used for establishing - * data connections. + * Description of a mobile data profile used for establishing data networks. The data profile + * consist an {@link ApnSetting} which is needed for 2G/3G/4G networks bring up, and a + * {@link TrafficDescriptor} contains additional information that can be used for 5G standalone + * network bring up. * * @hide */ @@ -113,7 +115,9 @@ public final class DataProfile implements Parcelable { /** * @return Id of the data profile. + * @deprecated Use {@link #getApnSetting()} and {@link ApnSetting#getProfileId()} instead. */ + @Deprecated public int getProfileId() { if (mApnSetting != null) { return mApnSetting.getProfileId(); @@ -124,9 +128,10 @@ public final class DataProfile implements Parcelable { /** * @return The APN (Access Point Name) to establish data connection. This is a string * specifically defined by the carrier. + * @deprecated Use {@link #getApnSetting()} and {@link ApnSetting#getApnName()} instead. */ - @NonNull - public String getApn() { + @Deprecated + public @NonNull String getApn() { if (mApnSetting != null) { return TextUtils.emptyIfNull(mApnSetting.getApnName()); } @@ -135,7 +140,9 @@ public final class DataProfile implements Parcelable { /** * @return The connection protocol defined in 3GPP TS 27.007 section 10.1.1. + * @deprecated Use {@link #getApnSetting()} and {@link ApnSetting#getProtocol()} instead. */ + @Deprecated public @ProtocolType int getProtocolType() { if (mApnSetting != null) { return mApnSetting.getProtocol(); @@ -145,7 +152,9 @@ public final class DataProfile implements Parcelable { /** * @return The authentication protocol used for this PDP context. + * @deprecated Use {@link #getApnSetting()} and {@link ApnSetting#getAuthType()} instead. */ + @Deprecated public @AuthType int getAuthType() { if (mApnSetting != null) { return mApnSetting.getAuthType(); @@ -154,10 +163,11 @@ public final class DataProfile implements Parcelable { } /** - * @return The username for APN. Can be null. + * @return The username for APN. + * @deprecated Use {@link #getApnSetting()} and {@link ApnSetting#getUser()} instead. */ - @Nullable - public String getUserName() { + @Deprecated + public @Nullable String getUserName() { if (mApnSetting != null) { return mApnSetting.getUser(); } @@ -165,10 +175,11 @@ public final class DataProfile implements Parcelable { } /** - * @return The password for APN. Can be null. + * @return The password for APN. + * @deprecated Use {@link #getApnSetting()} and {@link ApnSetting#getPassword()} instead. */ - @Nullable - public String getPassword() { + @Deprecated + public @Nullable String getPassword() { if (mApnSetting != null) { return mApnSetting.getPassword(); } @@ -232,7 +243,9 @@ public final class DataProfile implements Parcelable { /** * @return The supported APN types bitmask. + * @deprecated Use {@link #getApnSetting()} and {@link ApnSetting#getApnTypeBitmask()} instead. */ + @Deprecated public @ApnType int getSupportedApnTypesBitmask() { if (mApnSetting != null) { return mApnSetting.getApnTypeBitmask(); @@ -242,7 +255,9 @@ public final class DataProfile implements Parcelable { /** * @return The connection protocol on roaming network defined in 3GPP TS 27.007 section 10.1.1. + * @deprecated Use {@link #getApnSetting()} and {@link ApnSetting#getRoamingProtocol()} instead. */ + @Deprecated public @ProtocolType int getRoamingProtocolType() { if (mApnSetting != null) { return mApnSetting.getRoamingProtocol(); @@ -252,7 +267,10 @@ public final class DataProfile implements Parcelable { /** * @return The bearer bitmask indicating the applicable networks for this data profile. + * @deprecated use {@link #getApnSetting()} and {@link ApnSetting#getNetworkTypeBitmask()} + * instead. */ + @Deprecated public @NetworkTypeBitMask int getBearerBitmask() { if (mApnSetting != null) { return mApnSetting.getNetworkTypeBitmask(); @@ -262,7 +280,8 @@ public final class DataProfile implements Parcelable { /** * @return The maximum transmission unit (MTU) size in bytes. - * @deprecated use {@link #getMtuV4} or {@link #getMtuV6} instead. + * @deprecated use {@link #getApnSetting()} and {@link ApnSetting#getMtuV4()}/ + * {@link ApnSetting#getMtuV6()} instead. */ @Deprecated public int getMtu() { @@ -272,7 +291,9 @@ public final class DataProfile implements Parcelable { /** * This replaces the deprecated method getMtu. * @return The maximum transmission unit (MTU) size in bytes, for IPv4. + * @deprecated use {@link #getApnSetting()} and {@link ApnSetting#getMtuV4()} instead. */ + @Deprecated public int getMtuV4() { if (mApnSetting != null) { return mApnSetting.getMtuV4(); @@ -282,7 +303,9 @@ public final class DataProfile implements Parcelable { /** * @return The maximum transmission unit (MTU) size in bytes, for IPv6. + * @deprecated use {@link #getApnSetting()} and {@link ApnSetting#getMtuV6()} instead. */ + @Deprecated public int getMtuV6() { if (mApnSetting != null) { return mApnSetting.getMtuV6(); @@ -292,7 +315,9 @@ public final class DataProfile implements Parcelable { /** * @return {@code true} if modem must persist this data profile. + * @deprecated Use {@link #getApnSetting()} and {@link ApnSetting#isPersistent()} instead. */ + @Deprecated public boolean isPersistent() { if (mApnSetting != null) { return mApnSetting.isPersistent(); @@ -320,16 +345,16 @@ public final class DataProfile implements Parcelable { } /** - * @return The APN setting - * @hide TODO: Remove before T is released. + * @return The APN setting {@link ApnSetting}, which is used to establish data network on + * 2G/3G/4G. */ public @Nullable ApnSetting getApnSetting() { return mApnSetting; } /** - * @return The traffic descriptor - * @hide TODO: Remove before T is released. + * @return The traffic descriptor {@link TrafficDescriptor}, which can be used to establish + * data network on 5G. */ public @Nullable TrafficDescriptor getTrafficDescriptor() { return mTrafficDescriptor; @@ -539,7 +564,10 @@ public final class DataProfile implements Parcelable { * * @param profileId Network domain. * @return The same instance of the builder. + * @deprecated use {@link #setApnSetting(ApnSetting)} and + * {@link ApnSetting.Builder#setProfileId(int)} instead. */ + @Deprecated public @NonNull Builder setProfileId(int profileId) { mProfileId = profileId; return this; @@ -551,7 +579,10 @@ public final class DataProfile implements Parcelable { * * @param apn Access point name * @return The same instance of the builder. + * @deprecated use {@link #setApnSetting(ApnSetting)} and + * {@link ApnSetting.Builder#setApnName(String)} instead. */ + @Deprecated public @NonNull Builder setApn(@NonNull String apn) { mApn = apn; return this; @@ -562,7 +593,10 @@ public final class DataProfile implements Parcelable { * * @param protocolType The connection protocol defined in 3GPP TS 27.007 section 10.1.1. * @return The same instance of the builder. + * @deprecated use {@link #setApnSetting(ApnSetting)} and + * {@link ApnSetting.Builder#setProtocol(int)} instead. */ + @Deprecated public @NonNull Builder setProtocolType(@ProtocolType int protocolType) { mProtocolType = protocolType; return this; @@ -573,7 +607,10 @@ public final class DataProfile implements Parcelable { * * @param authType The authentication type * @return The same instance of the builder. + * @deprecated use {@link #setApnSetting(ApnSetting)} and + * {@link ApnSetting.Builder#setAuthType(int)} instead. */ + @Deprecated public @NonNull Builder setAuthType(@AuthType int authType) { mAuthType = authType; return this; @@ -584,7 +621,10 @@ public final class DataProfile implements Parcelable { * * @param userName The user name * @return The same instance of the builder. + * @deprecated use {@link #setApnSetting(ApnSetting)} and + * {@link ApnSetting.Builder#setUser(String)} instead. */ + @Deprecated public @NonNull Builder setUserName(@NonNull String userName) { mUserName = userName; return this; @@ -595,7 +635,10 @@ public final class DataProfile implements Parcelable { * * @param password The password * @return The same instance of the builder. + * @deprecated use {@link #setApnSetting(ApnSetting)} and + * {@link ApnSetting.Builder#setPassword(String)} (int)} instead. */ + @Deprecated public @NonNull Builder setPassword(@NonNull String password) { mPassword = password; return this; @@ -628,7 +671,10 @@ public final class DataProfile implements Parcelable { * * @param supportedApnTypesBitmask The supported APN types bitmask. * @return The same instance of the builder. + * @deprecated use {@link #setApnSetting(ApnSetting)} and + * {@link ApnSetting.Builder#setApnTypeBitmask(int)} instead. */ + @Deprecated public @NonNull Builder setSupportedApnTypesBitmask(@ApnType int supportedApnTypesBitmask) { mSupportedApnTypesBitmask = supportedApnTypesBitmask; return this; @@ -639,7 +685,10 @@ public final class DataProfile implements Parcelable { * * @param protocolType The connection protocol defined in 3GPP TS 27.007 section 10.1.1. * @return The same instance of the builder. + * @deprecated use {@link #setApnSetting(ApnSetting)} and + * {@link ApnSetting.Builder#setRoamingProtocol(int)} instead. */ + @Deprecated public @NonNull Builder setRoamingProtocolType(@ProtocolType int protocolType) { mRoamingProtocolType = protocolType; return this; @@ -651,7 +700,10 @@ public final class DataProfile implements Parcelable { * @param bearerBitmask The bearer bitmask indicating the applicable networks for this data * profile. * @return The same instance of the builder. + * @deprecated use {@link #setApnSetting(ApnSetting)} and + * {@link ApnSetting.Builder#setNetworkTypeBitmask(int)} instead. */ + @Deprecated public @NonNull Builder setBearerBitmask(@NetworkTypeBitMask int bearerBitmask) { mBearerBitmask = bearerBitmask; return this; @@ -662,7 +714,9 @@ public final class DataProfile implements Parcelable { * * @param mtu The maximum transmission unit (MTU) size in bytes. * @return The same instance of the builder. - * @deprecated use {@link #setApnSetting(ApnSetting)} instead. + * @deprecated use {@link #setApnSetting(ApnSetting)} and + * {@link ApnSetting.Builder#setMtuV4(int)}/{@link ApnSetting.Builder#setMtuV6(int)} + * instead. */ @Deprecated public @NonNull Builder setMtu(int mtu) { @@ -672,11 +726,13 @@ public final class DataProfile implements Parcelable { /** * Set the maximum transmission unit (MTU) size in bytes, for IPv4. - * This replaces the deprecated method setMtu. * * @param mtu The maximum transmission unit (MTU) size in bytes. * @return The same instance of the builder. + * @deprecated Use {{@link #setApnSetting(ApnSetting)}} and + * {@link ApnSetting.Builder#setMtuV4(int)} instead. */ + @Deprecated public @NonNull Builder setMtuV4(int mtu) { mMtuV4 = mtu; return this; @@ -687,7 +743,10 @@ public final class DataProfile implements Parcelable { * * @param mtu The maximum transmission unit (MTU) size in bytes. * @return The same instance of the builder. + * @deprecated Use {{@link #setApnSetting(ApnSetting)}} and + * {@link ApnSetting.Builder#setMtuV6(int)} instead. */ + @Deprecated public @NonNull Builder setMtuV6(int mtu) { mMtuV6 = mtu; return this; @@ -712,19 +771,23 @@ public final class DataProfile implements Parcelable { * @param isPersistent {@code true} if this data profile was used to bring up the last * default (i.e internet) data connection successfully. * @return The same instance of the builder. + * @deprecated Use {{@link #setApnSetting(ApnSetting)}} and + * {@link ApnSetting.Builder#setPersistent(boolean)} instead. */ + @Deprecated public @NonNull Builder setPersistent(boolean isPersistent) { mPersistent = isPersistent; return this; } /** - * Set APN setting. + * Set the APN setting. Note that if an APN setting is not set here, then either + * {@link #setApn(String)} or {@link #setTrafficDescriptor(TrafficDescriptor)} must be + * called. Otherwise {@link IllegalArgumentException} will be thrown when {@link #build()} + * the data profile. * - * @param apnSetting APN setting - * @return The same instance of the builder - * - * @hide // TODO: Remove before T is released. + * @param apnSetting The APN setting. + * @return The same instance of the builder. */ public @NonNull Builder setApnSetting(@NonNull ApnSetting apnSetting) { mApnSetting = apnSetting; @@ -732,12 +795,13 @@ public final class DataProfile implements Parcelable { } /** - * Set traffic descriptor. - * - * @param trafficDescriptor Traffic descriptor - * @return The same instance of the builder + * Set the traffic descriptor. Note that if a traffic descriptor is not set here, then + * either {@link #setApnSetting(ApnSetting)} or {@link #setApn(String)} must be called. + * Otherwise {@link IllegalArgumentException} will be thrown when {@link #build()} the data + * profile. * - * @hide // TODO: Remove before T is released. + * @param trafficDescriptor The traffic descriptor. + * @return The same instance of the builder. */ public @NonNull Builder setTrafficDescriptor(@NonNull TrafficDescriptor trafficDescriptor) { mTrafficDescriptor = trafficDescriptor; @@ -745,9 +809,9 @@ public final class DataProfile implements Parcelable { } /** - * Build the DataProfile object + * Build the DataProfile object. * - * @return The data profile object + * @return The data profile object. */ public @NonNull DataProfile build() { if (mApnSetting == null && mApn != null) { diff --git a/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java index f0048248a5cc..b154a999c25f 100644 --- a/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java +++ b/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java @@ -47,6 +47,9 @@ public class SipDelegateAidlWrapper implements DelegateStateCallback, DelegateMe @Override public void sendMessage(SipMessage sipMessage, long configVersion) { SipDelegate d = mDelegate; + if (d == null) { + return; + } final long token = Binder.clearCallingIdentity(); try { mExecutor.execute(() -> d.sendMessage(sipMessage, configVersion)); @@ -58,6 +61,9 @@ public class SipDelegateAidlWrapper implements DelegateStateCallback, DelegateMe @Override public void notifyMessageReceived(String viaTransactionId) { SipDelegate d = mDelegate; + if (d == null) { + return; + } final long token = Binder.clearCallingIdentity(); try { mExecutor.execute(() -> d.notifyMessageReceived(viaTransactionId)); @@ -70,6 +76,9 @@ public class SipDelegateAidlWrapper implements DelegateStateCallback, DelegateMe @Override public void notifyMessageReceiveError(String viaTransactionId, int reason) { SipDelegate d = mDelegate; + if (d == null) { + return; + } final long token = Binder.clearCallingIdentity(); try { mExecutor.execute(() -> d.notifyMessageReceiveError(viaTransactionId, reason)); @@ -82,6 +91,9 @@ public class SipDelegateAidlWrapper implements DelegateStateCallback, DelegateMe @Override public void cleanupSession(String callId) { SipDelegate d = mDelegate; + if (d == null) { + return; + } final long token = Binder.clearCallingIdentity(); try { mExecutor.execute(() -> d.cleanupSession(callId)); diff --git a/tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt b/tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt index 1aec9b812e61..2e60f64b21e8 100644 --- a/tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt +++ b/tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt @@ -21,8 +21,6 @@ import com.android.codegen.BASE_BUILDER_CLASS import com.android.codegen.CANONICAL_BUILDER_CLASS import com.android.codegen.CODEGEN_NAME import com.android.codegen.CODEGEN_VERSION -import com.sun.tools.javac.code.Symbol -import com.sun.tools.javac.code.Type import java.io.File import java.io.FileNotFoundException import javax.annotation.processing.AbstractProcessor @@ -33,6 +31,7 @@ import javax.lang.model.element.AnnotationMirror import javax.lang.model.element.Element import javax.lang.model.element.ElementKind import javax.lang.model.element.TypeElement +import javax.lang.model.type.ExecutableType import javax.tools.Diagnostic private const val STALE_FILE_THRESHOLD_MS = 1000 @@ -102,14 +101,13 @@ class StaleDataclassProcessor: AbstractProcessor() { append(" ") append(elem.annotationMirrors.joinToString(" ", transform = { annotationToString(it) })) append(" ") - if (elem is Symbol) { - if (elem.type is Type.MethodType) { - append((elem.type as Type.MethodType).returnType) - } else { - append(elem.type) - } - append(" ") + val type = elem.asType() + if (type is ExecutableType) { + append(type.returnType) + } else { + append(type) } + append(" ") append(elem) } } @@ -234,4 +232,4 @@ class StaleDataclassProcessor: AbstractProcessor() { override fun getSupportedSourceVersion(): SourceVersion { return SourceVersion.latest() } -}
\ No newline at end of file +} |