diff options
79 files changed, 1618 insertions, 865 deletions
diff --git a/Android.bp b/Android.bp index 92f79d1fbef4..8e17f5524a38 100644 --- a/Android.bp +++ b/Android.bp @@ -769,7 +769,6 @@ filegroup { name: "framework-services-net-module-wifi-shared-srcs", srcs: [ "core/java/android/net/DhcpResults.java", - "core/java/android/net/util/IpUtils.java", "core/java/android/util/LocalLog.java", ], } diff --git a/StubLibraries.bp b/StubLibraries.bp index 9e087f020246..4e1de0ecf9d4 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -55,7 +55,24 @@ stubs_defaults { aidl: { local_include_dirs: ["telephony/java"], }, - libs: ["framework-internal-utils"], + // These are libs from framework-internal-utils that are required (i.e. being referenced) + // from framework-non-updatable-sources. Add more here when there's a need. + // DO NOT add the entire framework-internal-utils. It might cause unnecessary circular + // dependencies gets bigger. + libs: [ + "android.hardware.cas-V1.2-java", + "android.hardware.health-V1.0-java-constants", + "android.hardware.radio-V1.5-java", + "android.hardware.thermal-V1.0-java-constants", + "android.hardware.thermal-V2.0-java", + "android.hardware.tv.input-V1.0-java-constants", + "android.hardware.tv.tuner-V1.0-java-constants", + "android.hardware.usb-V1.0-java-constants", + "android.hardware.usb-V1.1-java-constants", + "android.hardware.usb.gadget-V1.0-java", + "android.hardware.vibrator-V1.3-java", + "framework-protos", + ], installable: false, annotations_enabled: true, previous_api: ":android.api.public.latest", @@ -140,6 +157,11 @@ droidstubs { api_file: "non-updatable-api/current.txt", removed_api_file: "non-updatable-api/removed.txt", }, + last_released: { + api_file: ":android-non-updatable.api.public.latest", + removed_api_file: ":android-non-updatable-removed.api.public.latest", + baseline_file: ":public-api-incompatibilities-with-last-released", + }, api_lint: { enabled: true, new_since: ":android-non-updatable.api.public.latest", @@ -202,6 +224,11 @@ droidstubs { api_file: "non-updatable-api/system-current.txt", removed_api_file: "non-updatable-api/system-removed.txt", }, + last_released: { + api_file: ":android-non-updatable.api.system.latest", + removed_api_file: ":android-non-updatable-removed.api.system.latest", + baseline_file: ":system-api-incompatibilities-with-last-released" + }, api_lint: { enabled: true, new_since: ":android-non-updatable.api.system.latest", @@ -281,6 +308,10 @@ droidstubs { api_file: "non-updatable-api/module-lib-current.txt", removed_api_file: "non-updatable-api/module-lib-removed.txt", }, + last_released: { + api_file: ":android-non-updatable.api.module-lib.latest", + removed_api_file: ":android-non-updatable-removed.api.module-lib.latest", + }, api_lint: { enabled: true, new_since: ":android-non-updatable.api.module-lib.latest", diff --git a/api/Android.bp b/api/Android.bp index cb6d448caf63..ffc4a2146594 100644 --- a/api/Android.bp +++ b/api/Android.bp @@ -63,6 +63,24 @@ genrule { } genrule { + name: "frameworks-base-api-removed-merged.txt", + srcs: [ + ":conscrypt.module.public.api{.public.removed-api.txt}", + ":framework-media{.public.removed-api.txt}", + ":framework-mediaprovider{.public.removed-api.txt}", + ":framework-permission{.public.removed-api.txt}", + ":framework-sdkextensions{.public.removed-api.txt}", + ":framework-statsd{.public.removed-api.txt}", + ":framework-tethering{.public.removed-api.txt}", + ":framework-wifi{.public.removed-api.txt}", + ":non-updatable-removed.txt", + ], + out: ["removed.txt"], + tools: ["metalava"], + cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)", +} + +genrule { name: "frameworks-base-api-system-current-merged.txt", srcs: [ ":framework-media{.system.api.txt}", @@ -80,6 +98,23 @@ genrule { } genrule { + name: "frameworks-base-api-system-removed-merged.txt", + srcs: [ + ":framework-media{.system.removed-api.txt}", + ":framework-mediaprovider{.system.removed-api.txt}", + ":framework-permission{.system.removed-api.txt}", + ":framework-sdkextensions{.system.removed-api.txt}", + ":framework-statsd{.system.removed-api.txt}", + ":framework-tethering{.system.removed-api.txt}", + ":framework-wifi{.system.removed-api.txt}", + ":non-updatable-system-removed.txt", + ], + out: ["system-removed.txt"], + tools: ["metalava"], + cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)", +} + +genrule { name: "frameworks-base-api-module-lib-current-merged.txt", srcs: [ ":framework-media{.module-lib.api.txt}", @@ -95,3 +130,34 @@ genrule { tools: ["metalava"], cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)", } + +genrule { + name: "frameworks-base-api-module-lib-removed-merged.txt", + srcs: [ + ":framework-media{.module-lib.removed-api.txt}", + ":framework-mediaprovider{.module-lib.removed-api.txt}", + ":framework-permission{.module-lib.removed-api.txt}", + ":framework-sdkextensions{.module-lib.removed-api.txt}", + ":framework-statsd{.module-lib.removed-api.txt}", + ":framework-tethering{.module-lib.removed-api.txt}", + ":framework-wifi{.module-lib.removed-api.txt}", + ":non-updatable-module-lib-removed.txt", + ], + out: ["module-lib-removed.txt"], + tools: ["metalava"], + cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)", +} + +genrule { + name: "combined-removed-dex", + srcs: [ + ":frameworks-base-api-removed-merged.txt", + ":frameworks-base-api-system-removed-merged.txt", + ":android.car-stubs-docs{.removed-api.txt}", + ":android.car-system-stubs-docs{.removed-api.txt}", + ], + tool_files: ["gen_combined_removed_dex.sh"], + tools: ["metalava"], + out: ["combined-removed-dex.txt"], + cmd: "$(location gen_combined_removed_dex.sh) $(location metalava) $(genDir) $(in) > $(out)", +} diff --git a/api/current.txt b/api/current.txt index e16876e45c87..27a035e3474a 100644 --- a/api/current.txt +++ b/api/current.txt @@ -9126,6 +9126,7 @@ package android.bluetooth.le { method public boolean getIncludeTxPowerLevel(); method public android.util.SparseArray<byte[]> getManufacturerSpecificData(); method public java.util.Map<android.os.ParcelUuid,byte[]> getServiceData(); + method @Nullable public java.util.List<android.os.ParcelUuid> getServiceSolicitationUuids(); method public java.util.List<android.os.ParcelUuid> getServiceUuids(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertiseData> CREATOR; @@ -9135,6 +9136,7 @@ package android.bluetooth.le { ctor public AdvertiseData.Builder(); method public android.bluetooth.le.AdvertiseData.Builder addManufacturerData(int, byte[]); method public android.bluetooth.le.AdvertiseData.Builder addServiceData(android.os.ParcelUuid, byte[]); + method @NonNull public android.bluetooth.le.AdvertiseData.Builder addServiceSolicitationUuid(@NonNull android.os.ParcelUuid); method public android.bluetooth.le.AdvertiseData.Builder addServiceUuid(android.os.ParcelUuid); method public android.bluetooth.le.AdvertiseData build(); method public android.bluetooth.le.AdvertiseData.Builder setIncludeDeviceName(boolean); @@ -47910,6 +47912,7 @@ package android.telephony { method @NonNull public android.os.Bundle getCarrierConfigValues(); method public static android.telephony.SmsManager getDefault(); method public static int getDefaultSmsSubscriptionId(); + method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int getSmsCapacityOnIcc(); method public static android.telephony.SmsManager getSmsManagerForSubscriptionId(int); method @RequiresPermission(android.Manifest.permission.SMS_FINANCIAL_TRANSACTIONS) public void getSmsMessagesForFinancialApp(android.os.Bundle, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.SmsManager.FinancialSmsCallback); method @Nullable @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getSmscAddress(); diff --git a/api/gen_combined_removed_dex.sh b/api/gen_combined_removed_dex.sh new file mode 100755 index 000000000000..9225fe8dfe85 --- /dev/null +++ b/api/gen_combined_removed_dex.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +metalava_path="$1" +tmp_dir="$2" +shift 2 + +# Convert each removed.txt to the "dex format" equivalent, and print all output. +for f in "$@"; do + "$metalava_path" --no-banner "$f" --dex-api "${tmp_dir}/tmp" + cat "${tmp_dir}/tmp" +done diff --git a/api/system-current.txt b/api/system-current.txt index ddf9c4d97e6f..e163e7d79255 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -11075,7 +11075,6 @@ package android.telephony { method public boolean disableCellBroadcastRange(int, int, int); method public boolean enableCellBroadcastRange(int, int, int); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getPremiumSmsConsent(@NonNull String); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSmsCapacityOnIcc(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void sendMultipartTextMessageWithoutPersisting(String, String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPremiumSmsConsent(@NonNull String, int); field public static final int PREMIUM_SMS_CONSENT_ALWAYS_ALLOW = 3; // 0x3 diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 1fce990e01c0..237175d42dd1 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -5718,8 +5718,8 @@ public class DevicePolicyManager { * System apps can always bypass VPN. * <p> Note that the system doesn't update the allowlist when packages are installed or * uninstalled, the admin app must call this method to keep the list up to date. - * <p> When {@code lockdownEnabled} is false {@code lockdownWhitelist} is ignored . When - * {@code lockdownEnabled} is {@code true} and {@code lockdownWhitelist} is {@code null} or + * <p> When {@code lockdownEnabled} is false {@code lockdownAllowlist} is ignored . When + * {@code lockdownEnabled} is {@code true} and {@code lockdownAllowlist} is {@code null} or * empty, only system apps can bypass VPN. * <p> Setting always-on VPN package to {@code null} or using * {@link #setAlwaysOnVpnPackage(ComponentName, String, boolean)} clears lockdown allowlist. @@ -5728,24 +5728,24 @@ public class DevicePolicyManager { * to remove an existing always-on VPN configuration * @param lockdownEnabled {@code true} to disallow networking when the VPN is not connected or * {@code false} otherwise. This has no effect when clearing. - * @param lockdownWhitelist Packages that will be able to access the network directly when VPN + * @param lockdownAllowlist Packages that will be able to access the network directly when VPN * is in lockdown mode but not connected. Has no effect when clearing. * @throws SecurityException if {@code admin} is not a device or a profile * owner. * @throws NameNotFoundException if {@code vpnPackage} or one of - * {@code lockdownWhitelist} is not installed. + * {@code lockdownAllowlist} is not installed. * @throws UnsupportedOperationException if {@code vpnPackage} exists but does * not support being set as always-on, or if always-on VPN is not * available. */ public void setAlwaysOnVpnPackage(@NonNull ComponentName admin, @Nullable String vpnPackage, - boolean lockdownEnabled, @Nullable Set<String> lockdownWhitelist) + boolean lockdownEnabled, @Nullable Set<String> lockdownAllowlist) throws NameNotFoundException { throwIfParentInstance("setAlwaysOnVpnPackage"); if (mService != null) { try { mService.setAlwaysOnVpnPackage(admin, vpnPackage, lockdownEnabled, - lockdownWhitelist == null ? null : new ArrayList<>(lockdownWhitelist)); + lockdownAllowlist == null ? null : new ArrayList<>(lockdownAllowlist)); } catch (ServiceSpecificException e) { switch (e.errorCode) { case ERROR_VPN_PACKAGE_NOT_FOUND: @@ -5820,9 +5820,9 @@ public class DevicePolicyManager { throwIfParentInstance("getAlwaysOnVpnLockdownWhitelist"); if (mService != null) { try { - final List<String> whitelist = - mService.getAlwaysOnVpnLockdownWhitelist(admin); - return whitelist == null ? null : new HashSet<>(whitelist); + final List<String> allowlist = + mService.getAlwaysOnVpnLockdownAllowlist(admin); + return allowlist == null ? null : new HashSet<>(allowlist); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/admin/FreezePeriod.java b/core/java/android/app/admin/FreezePeriod.java index 657f0177097e..eb6efec1c330 100644 --- a/core/java/android/app/admin/FreezePeriod.java +++ b/core/java/android/app/admin/FreezePeriod.java @@ -39,8 +39,8 @@ import java.util.List; public class FreezePeriod { private static final String TAG = "FreezePeriod"; - private static final int DUMMY_YEAR = 2001; - static final int DAYS_IN_YEAR = 365; // 365 since DUMMY_YEAR is not a leap year + private static final int SENTINEL_YEAR = 2001; + static final int DAYS_IN_YEAR = 365; // 365 since SENTINEL_YEAR is not a leap year private final MonthDay mStart; private final MonthDay mEnd; @@ -60,9 +60,9 @@ public class FreezePeriod { */ public FreezePeriod(MonthDay start, MonthDay end) { mStart = start; - mStartDay = mStart.atYear(DUMMY_YEAR).getDayOfYear(); + mStartDay = mStart.atYear(SENTINEL_YEAR).getDayOfYear(); mEnd = end; - mEndDay = mEnd.atYear(DUMMY_YEAR).getDayOfYear(); + mEndDay = mEnd.atYear(SENTINEL_YEAR).getDayOfYear(); } /** @@ -166,9 +166,9 @@ public class FreezePeriod { endYearAdjustment = 1; } } - final LocalDate startDate = LocalDate.ofYearDay(DUMMY_YEAR, mStartDay).withYear( + final LocalDate startDate = LocalDate.ofYearDay(SENTINEL_YEAR, mStartDay).withYear( now.getYear() + startYearAdjustment); - final LocalDate endDate = LocalDate.ofYearDay(DUMMY_YEAR, mEndDay).withYear( + final LocalDate endDate = LocalDate.ofYearDay(SENTINEL_YEAR, mEndDay).withYear( now.getYear() + endYearAdjustment); return new Pair<>(startDate, endDate); } @@ -176,13 +176,13 @@ public class FreezePeriod { @Override public String toString() { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd"); - return LocalDate.ofYearDay(DUMMY_YEAR, mStartDay).format(formatter) + " - " - + LocalDate.ofYearDay(DUMMY_YEAR, mEndDay).format(formatter); + return LocalDate.ofYearDay(SENTINEL_YEAR, mStartDay).format(formatter) + " - " + + LocalDate.ofYearDay(SENTINEL_YEAR, mEndDay).format(formatter); } /** @hide */ private static MonthDay dayOfYearToMonthDay(int dayOfYear) { - LocalDate date = LocalDate.ofYearDay(DUMMY_YEAR, dayOfYear); + LocalDate date = LocalDate.ofYearDay(SENTINEL_YEAR, dayOfYear); return MonthDay.of(date.getMonth(), date.getDayOfMonth()); } @@ -191,7 +191,7 @@ public class FreezePeriod { * @hide */ private static int dayOfYearDisregardLeapYear(LocalDate date) { - return date.withYear(DUMMY_YEAR).getDayOfYear(); + return date.withYear(SENTINEL_YEAR).getDayOfYear(); } /** diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 9c6a274ccf8c..3ad8b4b5294f 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -197,12 +197,12 @@ interface IDevicePolicyManager { void setCertInstallerPackage(in ComponentName who, String installerPackage); String getCertInstallerPackage(in ComponentName who); - boolean setAlwaysOnVpnPackage(in ComponentName who, String vpnPackage, boolean lockdown, in List<String> lockdownWhitelist); + boolean setAlwaysOnVpnPackage(in ComponentName who, String vpnPackage, boolean lockdown, in List<String> lockdownAllowlist); String getAlwaysOnVpnPackage(in ComponentName who); String getAlwaysOnVpnPackageForUser(int userHandle); boolean isAlwaysOnVpnLockdownEnabled(in ComponentName who); boolean isAlwaysOnVpnLockdownEnabledForUser(int userHandle); - List<String> getAlwaysOnVpnLockdownWhitelist(in ComponentName who); + List<String> getAlwaysOnVpnLockdownAllowlist(in ComponentName who); void addPersistentPreferredActivity(in ComponentName admin, in IntentFilter filter, in ComponentName activity); void clearPackagePersistentPreferredActivities(in ComponentName admin, String packageName); diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 3c7d8fca20a4..872c37771128 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -2529,7 +2529,7 @@ public final class BluetoothAdapter { * Create a listening, insecure RFCOMM Bluetooth socket with Service Record. * <p>The link key is not required to be authenticated, i.e the communication may be * vulnerable to Person In the Middle attacks. For Bluetooth 2.1 devices, - * the link will be encrypted, as encryption is mandartory. + * the link will be encrypted, as encryption is mandatory. * For legacy devices (pre Bluetooth 2.1 devices) the link will not * be encrypted. Use {@link #listenUsingRfcommWithServiceRecord}, if an * encrypted and authenticated communication channel is desired. @@ -2568,7 +2568,7 @@ public final class BluetoothAdapter { * an input and output capability or just has the ability to display a numeric key, * a secure socket connection is not possible and this socket can be used. * Use {@link #listenUsingInsecureRfcommWithServiceRecord}, if encryption is not required. - * For Bluetooth 2.1 devices, the link will be encrypted, as encryption is mandartory. + * For Bluetooth 2.1 devices, the link will be encrypted, as encryption is mandatory. * For more details, refer to the Security Model section 5.2 (vol 3) of * Bluetooth Core Specification version 2.1 + EDR. * <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming diff --git a/core/java/android/bluetooth/le/AdvertiseData.java b/core/java/android/bluetooth/le/AdvertiseData.java index 5fd825837647..573b93232642 100644 --- a/core/java/android/bluetooth/le/AdvertiseData.java +++ b/core/java/android/bluetooth/le/AdvertiseData.java @@ -16,6 +16,7 @@ package android.bluetooth.le; +import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.ParcelUuid; @@ -43,17 +44,22 @@ public final class AdvertiseData implements Parcelable { @Nullable private final List<ParcelUuid> mServiceUuids; + @Nullable + private final List<ParcelUuid> mServiceSolicitationUuids; + private final SparseArray<byte[]> mManufacturerSpecificData; private final Map<ParcelUuid, byte[]> mServiceData; private final boolean mIncludeTxPowerLevel; private final boolean mIncludeDeviceName; private AdvertiseData(List<ParcelUuid> serviceUuids, + List<ParcelUuid> serviceSolicitationUuids, SparseArray<byte[]> manufacturerData, Map<ParcelUuid, byte[]> serviceData, boolean includeTxPowerLevel, boolean includeDeviceName) { mServiceUuids = serviceUuids; + mServiceSolicitationUuids = serviceSolicitationUuids; mManufacturerSpecificData = manufacturerData; mServiceData = serviceData; mIncludeTxPowerLevel = includeTxPowerLevel; @@ -69,6 +75,14 @@ public final class AdvertiseData implements Parcelable { } /** + * Returns a list of service solicitation UUIDs within the advertisement that we invite to connect. + */ + @Nullable + public List<ParcelUuid> getServiceSolicitationUuids() { + return mServiceSolicitationUuids; + } + + /** * Returns an array of manufacturer Id and the corresponding manufacturer specific data. The * manufacturer id is a non-negative number assigned by Bluetooth SIG. */ @@ -102,8 +116,8 @@ public final class AdvertiseData implements Parcelable { */ @Override public int hashCode() { - return Objects.hash(mServiceUuids, mManufacturerSpecificData, mServiceData, - mIncludeDeviceName, mIncludeTxPowerLevel); + return Objects.hash(mServiceUuids, mServiceSolicitationUuids, mManufacturerSpecificData, + mServiceData, mIncludeDeviceName, mIncludeTxPowerLevel); } /** @@ -119,6 +133,7 @@ public final class AdvertiseData implements Parcelable { } AdvertiseData other = (AdvertiseData) obj; return Objects.equals(mServiceUuids, other.mServiceUuids) + && Objects.equals(mServiceSolicitationUuids, other.mServiceSolicitationUuids) && BluetoothLeUtils.equals(mManufacturerSpecificData, other.mManufacturerSpecificData) && BluetoothLeUtils.equals(mServiceData, other.mServiceData) @@ -128,7 +143,8 @@ public final class AdvertiseData implements Parcelable { @Override public String toString() { - return "AdvertiseData [mServiceUuids=" + mServiceUuids + ", mManufacturerSpecificData=" + return "AdvertiseData [mServiceUuids=" + mServiceUuids + ", mServiceSolicitationUuids=" + + mServiceSolicitationUuids + ", mManufacturerSpecificData=" + BluetoothLeUtils.toString(mManufacturerSpecificData) + ", mServiceData=" + BluetoothLeUtils.toString(mServiceData) + ", mIncludeTxPowerLevel=" + mIncludeTxPowerLevel + ", mIncludeDeviceName=" @@ -143,6 +159,8 @@ public final class AdvertiseData implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeTypedArray(mServiceUuids.toArray(new ParcelUuid[mServiceUuids.size()]), flags); + dest.writeTypedArray(mServiceSolicitationUuids.toArray( + new ParcelUuid[mServiceSolicitationUuids.size()]), flags); // mManufacturerSpecificData could not be null. dest.writeInt(mManufacturerSpecificData.size()); @@ -174,6 +192,11 @@ public final class AdvertiseData implements Parcelable { builder.addServiceUuid(uuid); } + ArrayList<ParcelUuid> solicitationUuids = in.createTypedArrayList(ParcelUuid.CREATOR); + for (ParcelUuid uuid : solicitationUuids) { + builder.addServiceSolicitationUuid(uuid); + } + int manufacturerSize = in.readInt(); for (int i = 0; i < manufacturerSize; ++i) { int manufacturerId = in.readInt(); @@ -198,6 +221,8 @@ public final class AdvertiseData implements Parcelable { public static final class Builder { @Nullable private List<ParcelUuid> mServiceUuids = new ArrayList<ParcelUuid>(); + @Nullable + private List<ParcelUuid> mServiceSolicitationUuids = new ArrayList<ParcelUuid>(); private SparseArray<byte[]> mManufacturerSpecificData = new SparseArray<byte[]>(); private Map<ParcelUuid, byte[]> mServiceData = new ArrayMap<ParcelUuid, byte[]>(); private boolean mIncludeTxPowerLevel; @@ -207,17 +232,31 @@ public final class AdvertiseData implements Parcelable { * Add a service UUID to advertise data. * * @param serviceUuid A service UUID to be advertised. - * @throws IllegalArgumentException If the {@code serviceUuids} are null. + * @throws IllegalArgumentException If the {@code serviceUuid} is null. */ public Builder addServiceUuid(ParcelUuid serviceUuid) { if (serviceUuid == null) { - throw new IllegalArgumentException("serivceUuids are null"); + throw new IllegalArgumentException("serviceUuid is null"); } mServiceUuids.add(serviceUuid); return this; } /** + * Add a service solicitation UUID to advertise data. + * + * @param serviceSolicitationUuid A service solicitation UUID to be advertised. + * @throws IllegalArgumentException If the {@code serviceSolicitationUuid} is null. + */ + @NonNull + public Builder addServiceSolicitationUuid(@NonNull ParcelUuid serviceSolicitationUuid) { + if (serviceSolicitationUuid == null) { + throw new IllegalArgumentException("serviceSolicitationUuid is null"); + } + mServiceSolicitationUuids.add(serviceSolicitationUuid); + return this; + } + /** * Add service data to advertise data. * * @param serviceDataUuid 16-bit UUID of the service the data is associated with @@ -279,8 +318,9 @@ public final class AdvertiseData implements Parcelable { * Build the {@link AdvertiseData}. */ public AdvertiseData build() { - return new AdvertiseData(mServiceUuids, mManufacturerSpecificData, mServiceData, - mIncludeTxPowerLevel, mIncludeDeviceName); + return new AdvertiseData(mServiceUuids, mServiceSolicitationUuids, + mManufacturerSpecificData, mServiceData, mIncludeTxPowerLevel, + mIncludeDeviceName); } } } diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java index 13c5ff690973..5f166f4a41da 100644 --- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java +++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java @@ -507,6 +507,33 @@ public final class BluetoothLeAdvertiser { + num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT; } } + if (data.getServiceSolicitationUuids() != null) { + int num16BitUuids = 0; + int num32BitUuids = 0; + int num128BitUuids = 0; + for (ParcelUuid uuid : data.getServiceSolicitationUuids()) { + if (BluetoothUuid.is16BitUuid(uuid)) { + ++num16BitUuids; + } else if (BluetoothUuid.is32BitUuid(uuid)) { + ++num32BitUuids; + } else { + ++num128BitUuids; + } + } + // 16 bit service uuids are grouped into one field when doing advertising. + if (num16BitUuids != 0) { + size += OVERHEAD_BYTES_PER_FIELD + num16BitUuids * BluetoothUuid.UUID_BYTES_16_BIT; + } + // 32 bit service uuids are grouped into one field when doing advertising. + if (num32BitUuids != 0) { + size += OVERHEAD_BYTES_PER_FIELD + num32BitUuids * BluetoothUuid.UUID_BYTES_32_BIT; + } + // 128 bit service uuids are grouped into one field when doing advertising. + if (num128BitUuids != 0) { + size += OVERHEAD_BYTES_PER_FIELD + + num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT; + } + } for (ParcelUuid uuid : data.getServiceData().keySet()) { int uuidLen = BluetoothUuid.uuidToBytes(uuid).length; size += OVERHEAD_BYTES_PER_FIELD + uuidLen diff --git a/core/java/android/net/KeepalivePacketData.java b/core/java/android/net/KeepalivePacketData.java index e21cb44f72d8..5877f1f4e269 100644 --- a/core/java/android/net/KeepalivePacketData.java +++ b/core/java/android/net/KeepalivePacketData.java @@ -22,9 +22,10 @@ import static android.net.InvalidPacketException.ERROR_INVALID_PORT; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.SystemApi; -import android.net.util.IpUtils; import android.util.Log; +import com.android.net.module.util.IpUtils; + import java.net.InetAddress; /** diff --git a/core/java/android/net/NattKeepalivePacketData.java b/core/java/android/net/NattKeepalivePacketData.java index 22288b6205d7..c4f8fc281f25 100644 --- a/core/java/android/net/NattKeepalivePacketData.java +++ b/core/java/android/net/NattKeepalivePacketData.java @@ -22,11 +22,12 @@ import static android.net.InvalidPacketException.ERROR_INVALID_PORT; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.net.util.IpUtils; import android.os.Parcel; import android.os.Parcelable; import android.system.OsConstants; +import com.android.net.module.util.IpUtils; + import java.net.Inet4Address; import java.net.InetAddress; import java.nio.ByteBuffer; diff --git a/core/java/android/net/NetworkSpecifier.java b/core/java/android/net/NetworkSpecifier.java index 160259e39813..6ef496b1f6fe 100644 --- a/core/java/android/net/NetworkSpecifier.java +++ b/core/java/android/net/NetworkSpecifier.java @@ -22,10 +22,14 @@ import android.annotation.SystemApi; /** * Describes specific properties of a requested network for use in a {@link NetworkRequest}. * - * Applications cannot instantiate this class by themselves, but can obtain instances of - * subclasses of this class via other APIs. + * This as an abstract class. Applications shouldn't instantiate this class by themselves, but can + * obtain instances of subclasses of this class via other APIs. */ public abstract class NetworkSpecifier { + /** + * Create a placeholder object. Please use subclasses of this class in a {@link NetworkRequest} + * to request a network. + */ public NetworkSpecifier() {} /** diff --git a/core/java/android/net/util/IpUtils.java b/core/java/android/net/util/IpUtils.java deleted file mode 100644 index e037c4035aca..000000000000 --- a/core/java/android/net/util/IpUtils.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.util; - -import java.net.Inet6Address; -import java.net.InetAddress; -import java.nio.BufferOverflowException; -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; -import java.nio.ShortBuffer; - -import static android.system.OsConstants.IPPROTO_TCP; -import static android.system.OsConstants.IPPROTO_UDP; - -/** - * @hide - */ -public class IpUtils { - /** - * Converts a signed short value to an unsigned int value. Needed - * because Java does not have unsigned types. - */ - private static int intAbs(short v) { - return v & 0xFFFF; - } - - /** - * Performs an IP checksum (used in IP header and across UDP - * payload) on the specified portion of a ByteBuffer. The seed - * allows the checksum to commence with a specified value. - */ - private static int checksum(ByteBuffer buf, int seed, int start, int end) { - int sum = seed; - final int bufPosition = buf.position(); - - // set position of original ByteBuffer, so that the ShortBuffer - // will be correctly initialized - buf.position(start); - ShortBuffer shortBuf = buf.asShortBuffer(); - - // re-set ByteBuffer position - buf.position(bufPosition); - - final int numShorts = (end - start) / 2; - for (int i = 0; i < numShorts; i++) { - sum += intAbs(shortBuf.get(i)); - } - start += numShorts * 2; - - // see if a singleton byte remains - if (end != start) { - short b = buf.get(start); - - // make it unsigned - if (b < 0) { - b += 256; - } - - sum += b * 256; - } - - sum = ((sum >> 16) & 0xFFFF) + (sum & 0xFFFF); - sum = ((sum + ((sum >> 16) & 0xFFFF)) & 0xFFFF); - int negated = ~sum; - return intAbs((short) negated); - } - - private static int pseudoChecksumIPv4( - ByteBuffer buf, int headerOffset, int protocol, int transportLen) { - int partial = protocol + transportLen; - partial += intAbs(buf.getShort(headerOffset + 12)); - partial += intAbs(buf.getShort(headerOffset + 14)); - partial += intAbs(buf.getShort(headerOffset + 16)); - partial += intAbs(buf.getShort(headerOffset + 18)); - return partial; - } - - private static int pseudoChecksumIPv6( - ByteBuffer buf, int headerOffset, int protocol, int transportLen) { - int partial = protocol + transportLen; - for (int offset = 8; offset < 40; offset += 2) { - partial += intAbs(buf.getShort(headerOffset + offset)); - } - return partial; - } - - private static byte ipversion(ByteBuffer buf, int headerOffset) { - return (byte) ((buf.get(headerOffset) & (byte) 0xf0) >> 4); - } - - public static short ipChecksum(ByteBuffer buf, int headerOffset) { - byte ihl = (byte) (buf.get(headerOffset) & 0x0f); - return (short) checksum(buf, 0, headerOffset, headerOffset + ihl * 4); - } - - private static short transportChecksum(ByteBuffer buf, int protocol, - int ipOffset, int transportOffset, int transportLen) { - if (transportLen < 0) { - throw new IllegalArgumentException("Transport length < 0: " + transportLen); - } - int sum; - byte ver = ipversion(buf, ipOffset); - if (ver == 4) { - sum = pseudoChecksumIPv4(buf, ipOffset, protocol, transportLen); - } else if (ver == 6) { - sum = pseudoChecksumIPv6(buf, ipOffset, protocol, transportLen); - } else { - throw new UnsupportedOperationException("Checksum must be IPv4 or IPv6"); - } - - sum = checksum(buf, sum, transportOffset, transportOffset + transportLen); - if (protocol == IPPROTO_UDP && sum == 0) { - sum = (short) 0xffff; - } - return (short) sum; - } - - public static short udpChecksum(ByteBuffer buf, int ipOffset, int transportOffset) { - int transportLen = intAbs(buf.getShort(transportOffset + 4)); - return transportChecksum(buf, IPPROTO_UDP, ipOffset, transportOffset, transportLen); - } - - public static short tcpChecksum(ByteBuffer buf, int ipOffset, int transportOffset, - int transportLen) { - return transportChecksum(buf, IPPROTO_TCP, ipOffset, transportOffset, transportLen); - } - - public static String addressAndPortToString(InetAddress address, int port) { - return String.format( - (address instanceof Inet6Address) ? "[%s]:%d" : "%s:%d", - address.getHostAddress(), port); - } - - public static boolean isValidUdpOrTcpPort(int port) { - return port > 0 && port < 65536; - } -} diff --git a/core/java/android/uwb/UwbManager.java b/core/java/android/uwb/UwbManager.java new file mode 100644 index 000000000000..8097dc6dca11 --- /dev/null +++ b/core/java/android/uwb/UwbManager.java @@ -0,0 +1,269 @@ +/* + * Copyright 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.uwb; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.SuppressLint; +import android.os.PersistableBundle; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.List; +import java.util.Set; +import java.util.concurrent.Executor; + +/** + * This class provides a way to perform Ultra Wideband (UWB) operations such as querying the + * device's capabilities and determining the distance and angle between the local device and a + * remote device. + * + * <p>To get a {@link UwbManager}, call the <code>Context.getSystemService(UwbManager.class)</code>. + * + * @hide + */ +public final class UwbManager { + /** + * Interface for receiving UWB adapter state changes + */ + public interface AdapterStateCallback { + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = { + STATE_CHANGED_REASON_SESSION_STARTED, + STATE_CHANGED_REASON_ALL_SESSIONS_CLOSED, + STATE_CHANGED_REASON_SYSTEM_POLICY, + STATE_CHANGED_REASON_SYSTEM_BOOT, + STATE_CHANGED_REASON_ERROR_UNKNOWN}) + @interface StateChangedReason {} + + /** + * Indicates that the state change was due to opening of first UWB session + */ + int STATE_CHANGED_REASON_SESSION_STARTED = 0; + + /** + * Indicates that the state change was due to closure of all UWB sessions + */ + int STATE_CHANGED_REASON_ALL_SESSIONS_CLOSED = 1; + + /** + * Indicates that the state change was due to changes in system policy + */ + int STATE_CHANGED_REASON_SYSTEM_POLICY = 2; + + /** + * Indicates that the current state is due to a system boot + */ + int STATE_CHANGED_REASON_SYSTEM_BOOT = 3; + + /** + * Indicates that the state change was due to some unknown error + */ + int STATE_CHANGED_REASON_ERROR_UNKNOWN = 4; + + /** + * Invoked when underlying UWB adapter's state is changed + * <p>Invoked with the adapter's current state after registering an + * {@link AdapterStateCallback} using + * {@link UwbManager#registerAdapterStateCallback(Executor, AdapterStateCallback)}. + * + * <p>Possible values for the state to change are + * {@link #STATE_CHANGED_REASON_SESSION_STARTED}, + * {@link #STATE_CHANGED_REASON_ALL_SESSIONS_CLOSED}, + * {@link #STATE_CHANGED_REASON_SYSTEM_POLICY}, + * {@link #STATE_CHANGED_REASON_SYSTEM_BOOT}, + * {@link #STATE_CHANGED_REASON_ERROR_UNKNOWN}. + * + * @param isEnabled true when UWB adapter is enabled, false when it is disabled + * @param reason the reason for the state change + */ + void onStateChanged(boolean isEnabled, @StateChangedReason int reason); + } + + /** + * Use <code>Context.getSystemService(UwbManager.class)</code> to get an instance. + */ + private UwbManager() { + throw new UnsupportedOperationException(); + } + /** + * Register an {@link AdapterStateCallback} to listen for UWB adapter state changes + * <p>The provided callback will be invoked by the given {@link Executor}. + * + * <p>When first registering a callback, the callbacks's + * {@link AdapterStateCallback#onStateChanged(boolean, int)} is immediately invoked to indicate + * the current state of the underlying UWB adapter with the most recent + * {@link AdapterStateCallback.StateChangedReason} that caused the change. + * + * @param executor an {@link Executor} to execute given callback + * @param callback user implementation of the {@link AdapterStateCallback} + */ + public void registerAdapterStateCallback(Executor executor, AdapterStateCallback callback) { + throw new UnsupportedOperationException(); + } + + /** + * Unregister the specified {@link AdapterStateCallback} + * <p>The same {@link AdapterStateCallback} object used when calling + * {@link #registerAdapterStateCallback(Executor, AdapterStateCallback)} must be used. + * + * <p>Callbacks are automatically unregistered when application process goes away + * + * @param callback user implementation of the {@link AdapterStateCallback} + */ + public void unregisterAdapterStateCallback(AdapterStateCallback callback) { + throw new UnsupportedOperationException(); + } + + /** + * Get a {@link PersistableBundle} with the supported UWB protocols and parameters. + * <p>The {@link PersistableBundle} should be parsed using a support library + * + * <p>Android reserves the '^android.*' namespace</p> + * + * @return {@link PersistableBundle} of the device's supported UWB protocols and parameters + */ + @NonNull + public PersistableBundle getSpecificationInfo() { + throw new UnsupportedOperationException(); + } + + /** + * Check if ranging is supported, regardless of ranging method + * + * @return true if ranging is supported + */ + public boolean isRangingSupported() { + throw new UnsupportedOperationException(); + } + + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = { + ANGLE_OF_ARRIVAL_SUPPORT_TYPE_NONE, + ANGLE_OF_ARRIVAL_SUPPORT_TYPE_2D, + ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_HEMISPHERICAL, + ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_SPHERICAL}) + public @interface AngleOfArrivalSupportType {} + + /** + * Indicate absence of support for angle of arrival measurement + */ + public static final int ANGLE_OF_ARRIVAL_SUPPORT_TYPE_NONE = 1; + + /** + * Indicate support for planar angle of arrival measurement, due to antenna + * limitation. Typically requires at least two antennas. + */ + public static final int ANGLE_OF_ARRIVAL_SUPPORT_TYPE_2D = 2; + + /** + * Indicate support for three dimensional angle of arrival measurement. + * Typically requires at least three antennas. However, due to antenna + * arrangement, a platform may only support hemi-spherical azimuth angles + * ranging from -pi/2 to pi/2 + */ + public static final int ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_HEMISPHERICAL = 2; + + /** + * Indicate support for three dimensional angle of arrival measurement. + * Typically requires at least three antennas. This mode supports full + * azimuth angles ranging from -pi to pi. + */ + public static final int ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_SPHERICAL = 3; + + + /** + * Gets the {@link AngleOfArrivalSupportType} supported on this platform + * <p>Possible return values are + * {@link #ANGLE_OF_ARRIVAL_SUPPORT_TYPE_NONE}, + * {@link #ANGLE_OF_ARRIVAL_SUPPORT_TYPE_2D}, + * {@link #ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_HEMISPHERICAL}, + * {@link #ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_SPHERICAL}. + * + * @return angle of arrival type supported + */ + @AngleOfArrivalSupportType + public int getAngleOfArrivalSupport() { + throw new UnsupportedOperationException(); + } + + /** + * Get a {@link List} of supported channel numbers based on the device's current location + * <p>The returned values are ordered by the system's desired ordered of use, with the first + * entry being the most preferred. + * + * <p>Channel numbers are defined based on the IEEE 802.15.4z standard for UWB. + * + * @return {@link List} of supported channel numbers ordered by preference + */ + @NonNull + public List<Integer> getSupportedChannelNumbers() { + throw new UnsupportedOperationException(); + } + + /** + * Get a {@link List} of supported preamble code indices + * <p> Preamble code indices are defined based on the IEEE 802.15.4z standard for UWB. + * + * @return {@link List} of supported preamble code indices + */ + @NonNull + public Set<Integer> getSupportedPreambleCodeIndices() { + throw new UnsupportedOperationException(); + } + + /** + * Get the timestamp resolution for events in nanoseconds + * <p>This value defines the maximum error of all timestamps for events reported to + * {@link RangingSession.Callback}. + * + * @return the timestamp resolution in nanoseconds + */ + @SuppressLint("MethodNameUnits") + public long elapsedRealtimeResolutionNanos() { + throw new UnsupportedOperationException(); + } + + /** + * Get the number of simultaneous sessions allowed in the system + * + * @return the maximum allowed number of simultaneously open {@link RangingSession} instances. + */ + public int getMaxSimultaneousSessions() { + throw new UnsupportedOperationException(); + } + + /** + * Get the maximum number of remote devices in a {@link RangingSession} when the local device + * is the initiator. + * + * @return the maximum number of remote devices per {@link RangingSession} + */ + public int getMaxRemoteDevicesPerInitiatorSession() { + throw new UnsupportedOperationException(); + } + + /** + * Get the maximum number of remote devices in a {@link RangingSession} when the local device + * is a responder. + * + * @return the maximum number of remote devices per {@link RangingSession} + */ + public int getMaxRemoteDevicesPerResponderSession() { + throw new UnsupportedOperationException(); + } +} diff --git a/core/java/com/android/ims/internal/uce/presence/PresCmdId.aidl b/core/java/com/android/ims/internal/uce/presence/PresCmdID.aidl index 6ece045ffcf7..6ece045ffcf7 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresCmdId.aidl +++ b/core/java/com/android/ims/internal/uce/presence/PresCmdID.aidl diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 4b661ca3ab80..236e67a1ea70 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -951,7 +951,7 @@ public class ChooserActivity extends ResolverActivity implements updateStickyContentPreview(); if (shouldShowStickyContentPreview() || mChooserMultiProfilePagerAdapter - .getCurrentRootAdapter().getContentPreviewRowCount() != 0) { + .getCurrentRootAdapter().getSystemRowCount() != 0) { logActionShareWithPreview(); } return postRebuildListInternal(rebuildCompleted); @@ -1316,13 +1316,14 @@ public class ChooserActivity extends ResolverActivity implements ViewGroup parent) { ViewGroup contentPreviewLayout = (ViewGroup) layoutInflater.inflate( R.layout.chooser_grid_preview_image, parent, false); + ViewGroup imagePreview = contentPreviewLayout.findViewById(R.id.content_preview_image_area); final ViewGroup actionRow = (ViewGroup) contentPreviewLayout.findViewById(R.id.chooser_action_row); //TODO: addActionButton(actionRow, createCopyButton()); addActionButton(actionRow, createNearbyButton(targetIntent)); - mPreviewCoord = new ContentPreviewCoordinator(contentPreviewLayout, true); + mPreviewCoord = new ContentPreviewCoordinator(contentPreviewLayout, false); String action = targetIntent.getAction(); if (Intent.ACTION_SEND.equals(action)) { @@ -1342,7 +1343,7 @@ public class ChooserActivity extends ResolverActivity implements if (imageUris.size() == 0) { Log.i(TAG, "Attempted to display image preview area with zero" + " available images detected in EXTRA_STREAM list"); - contentPreviewLayout.setVisibility(View.GONE); + imagePreview.setVisibility(View.GONE); return contentPreviewLayout; } @@ -2680,7 +2681,7 @@ public class ChooserActivity extends ResolverActivity implements final int bottomInset = mSystemWindowInsets != null ? mSystemWindowInsets.bottom : 0; int offset = bottomInset; - int rowsToShow = gridAdapter.getContentPreviewRowCount() + int rowsToShow = gridAdapter.getSystemRowCount() + gridAdapter.getProfileRowCount() + gridAdapter.getServiceTargetRowCount() + gridAdapter.getCallerAndRankedTargetRowCount(); @@ -3273,7 +3274,7 @@ public class ChooserActivity extends ResolverActivity implements public int getRowCount() { return (int) ( - getContentPreviewRowCount() + getSystemRowCount() + getProfileRowCount() + getServiceTargetRowCount() + getCallerAndRankedTargetRowCount() @@ -3289,7 +3290,7 @@ public class ChooserActivity extends ResolverActivity implements * content preview. Not to be confused with the sticky content preview which is above the * personal and work tabs. */ - public int getContentPreviewRowCount() { + public int getSystemRowCount() { // For the tabbed case we show the sticky content preview above the tabs, // please refer to shouldShowStickyContentPreview if (shouldShowTabs()) { @@ -3299,8 +3300,7 @@ public class ChooserActivity extends ResolverActivity implements return 0; } - if (mHideContentPreview || mChooserListAdapter == null - || mChooserListAdapter.getCount() == 0) { + if (mChooserListAdapter == null || mChooserListAdapter.getCount() == 0) { return 0; } @@ -3342,7 +3342,7 @@ public class ChooserActivity extends ResolverActivity implements @Override public int getItemCount() { return (int) ( - getContentPreviewRowCount() + getSystemRowCount() + getProfileRowCount() + getServiceTargetRowCount() + getCallerAndRankedTargetRowCount() @@ -3397,7 +3397,7 @@ public class ChooserActivity extends ResolverActivity implements public int getItemViewType(int position) { int count; - int countSum = (count = getContentPreviewRowCount()); + int countSum = (count = getSystemRowCount()); if (count > 0 && position < countSum) return VIEW_TYPE_CONTENT_PREVIEW; countSum += (count = getProfileRowCount()); @@ -3621,7 +3621,7 @@ public class ChooserActivity extends ResolverActivity implements } int getListPosition(int position) { - position -= getContentPreviewRowCount() + getProfileRowCount(); + position -= getSystemRowCount() + getProfileRowCount(); final int serviceCount = mChooserListAdapter.getServiceTargetCount(); final int serviceRows = (int) Math.ceil((float) serviceCount diff --git a/core/jni/android_os_HwParcel.cpp b/core/jni/android_os_HwParcel.cpp index ff336ee64b54..4c4443fc29c3 100644 --- a/core/jni/android_os_HwParcel.cpp +++ b/core/jni/android_os_HwParcel.cpp @@ -990,6 +990,8 @@ static jobject JHwParcel_native_readStrongBinder(JNIEnv *env, jobject thiz) { } if (!validateCanUseHwBinder(binder)) { + jniThrowException(env, "java/lang/IllegalArgumentException", + "Local binder is not supported in Java"); return nullptr; } diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp index 9ae3d160be98..9c7ee0c641a6 100644 --- a/core/jni/android_os_Parcel.cpp +++ b/core/jni/android_os_Parcel.cpp @@ -638,50 +638,77 @@ static jboolean android_os_Parcel_hasFileDescriptors(jlong nativePtr) return ret; } +// String tries to allocate itself on the stack, within a known size, but will +// make a heap allocation if not. +template <size_t StackReserve> +class StackString { +public: + StackString(JNIEnv* env, jstring str) : mEnv(env), mJStr(str) { + LOG_ALWAYS_FATAL_IF(str == nullptr); + mSize = env->GetStringLength(str); + if (mSize > StackReserve) { + mStr = new jchar[mSize]; + } else { + mStr = &mBuffer[0]; + } + mEnv->GetStringRegion(str, 0, mSize, mStr); + } + ~StackString() { + if (mStr != &mBuffer[0]) { + delete[] mStr; + } + } + const jchar* str() { return mStr; } + jsize size() { return mSize; } + +private: + JNIEnv* mEnv; + jstring mJStr; + + jchar mBuffer[StackReserve]; + // pointer to &mBuffer[0] if string fits in mBuffer, otherwise owned + jchar* mStr; + jsize mSize; +}; + +// This size is chosen to be longer than most interface descriptors. +// Ones longer than this will be allocated on the heap. +typedef StackString<64> InterfaceDescriptorString; + static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jclass clazz, jlong nativePtr, jstring name) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); - if (parcel != NULL) { - // In the current implementation, the token is just the serialized interface name that - // the caller expects to be invoking - const jchar* str = env->GetStringCritical(name, 0); - if (str != NULL) { - parcel->writeInterfaceToken(String16( - reinterpret_cast<const char16_t*>(str), - env->GetStringLength(name))); - env->ReleaseStringCritical(name, str); - } + if (parcel != nullptr) { + InterfaceDescriptorString descriptor(env, name); + parcel->writeInterfaceToken(reinterpret_cast<const char16_t*>(descriptor.str()), + descriptor.size()); } } static void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jlong nativePtr, jstring name) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); - if (parcel != NULL) { - const jchar* str = env->GetStringCritical(name, 0); - if (str) { - IPCThreadState* threadState = IPCThreadState::self(); - const int32_t oldPolicy = threadState->getStrictModePolicy(); - const bool isValid = parcel->enforceInterface( - reinterpret_cast<const char16_t*>(str), - env->GetStringLength(name), - threadState); - env->ReleaseStringCritical(name, str); - if (isValid) { - const int32_t newPolicy = threadState->getStrictModePolicy(); - if (oldPolicy != newPolicy) { - // Need to keep the Java-level thread-local strict - // mode policy in sync for the libcore - // enforcements, which involves an upcall back - // into Java. (We can't modify the - // Parcel.enforceInterface signature, as it's - // pseudo-public, and used via AIDL - // auto-generation...) - set_dalvik_blockguard_policy(env, newPolicy); - } - return; // everything was correct -> return silently + if (parcel != nullptr) { + InterfaceDescriptorString descriptor(env, name); + IPCThreadState* threadState = IPCThreadState::self(); + const int32_t oldPolicy = threadState->getStrictModePolicy(); + const bool isValid = + parcel->enforceInterface(reinterpret_cast<const char16_t*>(descriptor.str()), + descriptor.size(), threadState); + if (isValid) { + const int32_t newPolicy = threadState->getStrictModePolicy(); + if (oldPolicy != newPolicy) { + // Need to keep the Java-level thread-local strict + // mode policy in sync for the libcore + // enforcements, which involves an upcall back + // into Java. (We can't modify the + // Parcel.enforceInterface signature, as it's + // pseudo-public, and used via AIDL + // auto-generation...) + set_dalvik_blockguard_policy(env, newPolicy); } + return; // everything was correct -> return silently } } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 80f73f043068..9b90b0a24922 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -511,6 +511,7 @@ <protected-broadcast android:name="android.telecom.action.NUISANCE_CALL_STATUS_CHANGED" /> <protected-broadcast android:name="android.telecom.action.PHONE_ACCOUNT_REGISTERED" /> <protected-broadcast android:name="android.telecom.action.PHONE_ACCOUNT_UNREGISTERED" /> + <protected-broadcast android:name="android.telecom.action.POST_CALL" /> <protected-broadcast android:name="android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION" /> <protected-broadcast android:name="android.telephony.action.CARRIER_CONFIG_CHANGED" /> <protected-broadcast android:name="android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED" /> diff --git a/core/xsd/vts/Android.bp b/core/xsd/vts/Android.bp index 4b43b4136076..ca655f18149c 100644 --- a/core/xsd/vts/Android.bp +++ b/core/xsd/vts/Android.bp @@ -40,7 +40,3 @@ cc_test { ], test_config: "vts_permission_validate_test.xml", } - -vts_config { - name: "VtsValidatePermission", -} diff --git a/core/xsd/vts/AndroidTest.xml b/core/xsd/vts/AndroidTest.xml deleted file mode 100644 index e5cc9a0f74ee..000000000000 --- a/core/xsd/vts/AndroidTest.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2019 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<configuration description="Config for VTS VtsValidatePermission."> - <option name="config-descriptor:metadata" key="plan" value="vts-treble" /> - <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher"> - <option name="abort-on-push-failure" value="false"/> - <option name="push-group" value="HostDrivenTest.push"/> - <option name="push" value="DATA/etc/permission.xsd->/data/local/tmp/permission.xsd"/> - </target_preparer> - <test class="com.android.tradefed.testtype.VtsMultiDeviceTest"> - <option name="test-module-name" value="VtsValidatePermission"/> - <option name="binary-test-source" value="_32bit::DATA/nativetest/vts_permission_validate_test/vts_permission_validate_test" /> - <option name="binary-test-source" value="_64bit::DATA/nativetest64/vts_permission_validate_test/vts_permission_validate_test" /> - <option name="binary-test-type" value="gtest"/> - <option name="test-timeout" value="30s"/> - </test> -</configuration> diff --git a/libs/hwui/service/GraphicsStatsService.cpp b/libs/hwui/service/GraphicsStatsService.cpp index 644d5fbd5bf9..e4198017aee0 100644 --- a/libs/hwui/service/GraphicsStatsService.cpp +++ b/libs/hwui/service/GraphicsStatsService.cpp @@ -559,6 +559,7 @@ void GraphicsStatsService::finishDumpInMemory(Dump* dump, AStatsEventList* data, AStatsEvent_writeBool(event, !lastFullDay); AStatsEvent_build(event); } + delete dump; } diff --git a/non-updatable-api/Android.bp b/non-updatable-api/Android.bp index 4037781c1844..00b901992b90 100644 --- a/non-updatable-api/Android.bp +++ b/non-updatable-api/Android.bp @@ -23,13 +23,31 @@ filegroup { } filegroup { + name: "non-updatable-removed.txt", + srcs: ["removed.txt"], + visibility: ["//frameworks/base/api"], +} + +filegroup { name: "non-updatable-system-current.txt", srcs: ["system-current.txt"], visibility: ["//frameworks/base/api"], } filegroup { + name: "non-updatable-system-removed.txt", + srcs: ["system-removed.txt"], + visibility: ["//frameworks/base/api"], +} + +filegroup { name: "non-updatable-module-lib-current.txt", srcs: ["module-lib-current.txt"], visibility: ["//frameworks/base/api"], } + +filegroup { + name: "non-updatable-module-lib-removed.txt", + srcs: ["module-lib-removed.txt"], + visibility: ["//frameworks/base/api"], +} diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt index 8a36837d10d5..1aa5a5dd2ad7 100644 --- a/non-updatable-api/current.txt +++ b/non-updatable-api/current.txt @@ -9126,6 +9126,7 @@ package android.bluetooth.le { method public boolean getIncludeTxPowerLevel(); method public android.util.SparseArray<byte[]> getManufacturerSpecificData(); method public java.util.Map<android.os.ParcelUuid,byte[]> getServiceData(); + method @Nullable public java.util.List<android.os.ParcelUuid> getServiceSolicitationUuids(); method public java.util.List<android.os.ParcelUuid> getServiceUuids(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertiseData> CREATOR; @@ -9135,6 +9136,7 @@ package android.bluetooth.le { ctor public AdvertiseData.Builder(); method public android.bluetooth.le.AdvertiseData.Builder addManufacturerData(int, byte[]); method public android.bluetooth.le.AdvertiseData.Builder addServiceData(android.os.ParcelUuid, byte[]); + method @NonNull public android.bluetooth.le.AdvertiseData.Builder addServiceSolicitationUuid(@NonNull android.os.ParcelUuid); method public android.bluetooth.le.AdvertiseData.Builder addServiceUuid(android.os.ParcelUuid); method public android.bluetooth.le.AdvertiseData build(); method public android.bluetooth.le.AdvertiseData.Builder setIncludeDeviceName(boolean); @@ -46078,6 +46080,7 @@ package android.telephony { method @NonNull public android.os.Bundle getCarrierConfigValues(); method public static android.telephony.SmsManager getDefault(); method public static int getDefaultSmsSubscriptionId(); + method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int getSmsCapacityOnIcc(); method public static android.telephony.SmsManager getSmsManagerForSubscriptionId(int); method @RequiresPermission(android.Manifest.permission.SMS_FINANCIAL_TRANSACTIONS) public void getSmsMessagesForFinancialApp(android.os.Bundle, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.SmsManager.FinancialSmsCallback); method @Nullable @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getSmscAddress(); diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt index b67c22c27cb8..2b3e7815d060 100644 --- a/non-updatable-api/system-current.txt +++ b/non-updatable-api/system-current.txt @@ -9957,7 +9957,6 @@ package android.telephony { method public boolean disableCellBroadcastRange(int, int, int); method public boolean enableCellBroadcastRange(int, int, int); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getPremiumSmsConsent(@NonNull String); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSmsCapacityOnIcc(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void sendMultipartTextMessageWithoutPersisting(String, String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPremiumSmsConsent(@NonNull String, int); field public static final int PREMIUM_SMS_CONSENT_ALWAYS_ALLOW = 3; // 0x3 diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java index 9ff868467531..f7f3cbb7d332 100644 --- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java @@ -321,6 +321,9 @@ public class DynamicSystemInstallationService extends Service if (!isDynamicSystemInstalled() && (getStatus() != STATUS_READY)) { Log.e(TAG, "Trying to discard AOT while there is no complete installation"); + // Stop foreground state and dismiss stale notification. + stopForeground(STOP_FOREGROUND_REMOVE); + resetTaskAndStop(); return; } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java index fbcd6ba0ff47..42dde4064a97 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java @@ -205,7 +205,8 @@ public class ScreenshotNotificationsController { mPublicNotificationBuilder .setContentTitle(mResources.getString(R.string.screenshot_saved_title)) .setContentText(mResources.getString(R.string.screenshot_saved_text)) - .setContentIntent(PendingIntent.getActivity(mContext, 0, launchIntent, 0)) + .setContentIntent(PendingIntent + .getActivity(mContext, 0, launchIntent, PendingIntent.FLAG_IMMUTABLE)) .setWhen(now) .setAutoCancel(true) .setColor(mContext.getColor( @@ -213,7 +214,8 @@ public class ScreenshotNotificationsController { mNotificationBuilder .setContentTitle(mResources.getString(R.string.screenshot_saved_title)) .setContentText(mResources.getString(R.string.screenshot_saved_text)) - .setContentIntent(PendingIntent.getActivity(mContext, 0, launchIntent, 0)) + .setContentIntent(PendingIntent + .getActivity(mContext, 0, launchIntent, PendingIntent.FLAG_IMMUTABLE)) .setWhen(now) .setAutoCancel(true) .setColor(mContext.getColor( diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java b/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java index b25df5f9c07f..5e7280840bb9 100644 --- a/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java +++ b/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java @@ -104,9 +104,13 @@ public class LeakReporter { .setContentText(String.format( "SystemUI has detected %d leaked objects. Tap to send", garbageCount)) .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) - .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0, + .setContentIntent(PendingIntent.getActivityAsUser( + mContext, + 0, getIntent(hprofFile, dumpFile), - PendingIntent.FLAG_UPDATE_CURRENT, null, UserHandle.CURRENT)); + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE, + null, + UserHandle.CURRENT)); notiMan.notify(TAG, 0, builder.build()); } catch (IOException e) { Log.e(TAG, "Couldn't dump heap for leak", e); diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp index 257538d6216d..5526c657b874 100644 --- a/packages/Tethering/Android.bp +++ b/packages/Tethering/Android.bp @@ -101,6 +101,7 @@ java_defaults { ], libs: [ "framework-tethering", + "framework-wifi", ], jarjar_rules: "jarjar-rules.txt", optimize: { diff --git a/packages/Tethering/src/android/net/ip/IpServer.java b/packages/Tethering/src/android/net/ip/IpServer.java index 336124dc1b90..52d59fcdc19b 100644 --- a/packages/Tethering/src/android/net/ip/IpServer.java +++ b/packages/Tethering/src/android/net/ip/IpServer.java @@ -616,7 +616,7 @@ public class IpServer extends StateMachine { if (VDBG) Log.d(TAG, "configureIPv4(" + enabled + ")"); if (enabled) { - mIpv4Address = requestIpv4Address(); + mIpv4Address = requestIpv4Address(true /* useLastAddress */); } if (mIpv4Address == null) { @@ -661,14 +661,14 @@ public class IpServer extends StateMachine { return configureDhcp(enabled, mIpv4Address, mStaticIpv4ClientAddr); } - private LinkAddress requestIpv4Address() { + private LinkAddress requestIpv4Address(final boolean useLastAddress) { if (mStaticIpv4ServerAddr != null) return mStaticIpv4ServerAddr; if (mInterfaceType == TetheringManager.TETHERING_BLUETOOTH) { return new LinkAddress(BLUETOOTH_IFACE_ADDR); } - return mPrivateAddressCoordinator.requestDownstreamAddress(this); + return mPrivateAddressCoordinator.requestDownstreamAddress(this, useLastAddress); } private boolean startIPv6() { @@ -957,7 +957,7 @@ public class IpServer extends StateMachine { } final LinkAddress deprecatedLinkAddress = mIpv4Address; - mIpv4Address = requestIpv4Address(); + mIpv4Address = requestIpv4Address(false); if (mIpv4Address == null) { mLog.e("Fail to request a new downstream prefix"); return; diff --git a/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java b/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java index fd9e36080c80..6276c4e2aa7d 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java @@ -15,7 +15,10 @@ */ package com.android.networkstack.tethering; +import static android.net.NetworkCapabilities.TRANSPORT_VPN; +import static android.net.TetheringManager.TETHERING_BLUETOOTH; import static android.net.TetheringManager.TETHERING_WIFI_P2P; +import static android.net.util.PrefixUtils.asIpPrefix; import static java.util.Arrays.asList; @@ -23,12 +26,11 @@ import android.content.Context; import android.net.ConnectivityManager; import android.net.IpPrefix; import android.net.LinkAddress; -import android.net.LinkProperties; import android.net.Network; import android.net.ip.IpServer; -import android.net.util.PrefixUtils; import android.util.ArrayMap; import android.util.ArraySet; +import android.util.SparseArray; import androidx.annotation.Nullable; @@ -58,9 +60,6 @@ public class PrivateAddressCoordinator { private static final int MAX_UBYTE = 256; private static final int BYTE_MASK = 0xff; - // reserved for bluetooth tethering. - private static final int BLUETOOTH_RESERVED = 44; - private static final int WIFI_P2P_RESERVED = 49; private static final byte DEFAULT_ID = (byte) 42; // Upstream monitor would be stopped when tethering is down. When tethering restart, downstream @@ -75,9 +74,12 @@ public class PrivateAddressCoordinator { // Tethering use 192.168.0.0/16 that has 256 contiguous class C network numbers. private static final String DEFAULT_TETHERING_PREFIX = "192.168.0.0/16"; private static final String LEGACY_WIFI_P2P_IFACE_ADDRESS = "192.168.49.1/24"; + private static final String LEGACY_BLUETOOTH_IFACE_ADDRESS = "192.168.44.1/24"; private final IpPrefix mTetheringPrefix; private final ConnectivityManager mConnectivityMgr; private final TetheringConfiguration mConfig; + // keyed by downstream type(TetheringManager.TETHERING_*). + private final SparseArray<LinkAddress> mCachedAddresses; public PrivateAddressCoordinator(Context context, TetheringConfiguration config) { mDownstreams = new ArraySet<>(); @@ -86,20 +88,33 @@ public class PrivateAddressCoordinator { mConnectivityMgr = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE); mConfig = config; + mCachedAddresses = new SparseArray<>(); + // Reserved static addresses for bluetooth and wifi p2p. + mCachedAddresses.put(TETHERING_BLUETOOTH, new LinkAddress(LEGACY_BLUETOOTH_IFACE_ADDRESS)); + mCachedAddresses.put(TETHERING_WIFI_P2P, new LinkAddress(LEGACY_WIFI_P2P_IFACE_ADDRESS)); } /** * Record a new upstream IpPrefix which may conflict with tethering downstreams. - * The downstreams will be notified if a conflict is found. + * The downstreams will be notified if a conflict is found. When updateUpstreamPrefix is called, + * UpstreamNetworkState must have an already populated LinkProperties. */ - public void updateUpstreamPrefix(final Network network, final LinkProperties lp) { - final ArrayList<IpPrefix> ipv4Prefixes = getIpv4Prefixes(lp.getAllLinkAddresses()); + public void updateUpstreamPrefix(final UpstreamNetworkState ns) { + // Do not support VPN as upstream. Normally, networkCapabilities is not expected to be null, + // but just checking to be sure. + if (ns.networkCapabilities != null && ns.networkCapabilities.hasTransport(TRANSPORT_VPN)) { + removeUpstreamPrefix(ns.network); + return; + } + + final ArrayList<IpPrefix> ipv4Prefixes = getIpv4Prefixes( + ns.linkProperties.getAllLinkAddresses()); if (ipv4Prefixes.isEmpty()) { - removeUpstreamPrefix(network); + removeUpstreamPrefix(ns.network); return; } - mUpstreamPrefixMap.put(network, ipv4Prefixes); + mUpstreamPrefixMap.put(ns.network, ipv4Prefixes); handleMaybePrefixConflict(ipv4Prefixes); } @@ -108,7 +123,7 @@ public class PrivateAddressCoordinator { for (LinkAddress address : linkAddresses) { if (!address.isIpv4()) continue; - list.add(PrefixUtils.asIpPrefix(address)); + list.add(asIpPrefix(address)); } return list; @@ -147,21 +162,23 @@ public class PrivateAddressCoordinator { mUpstreamPrefixMap.removeAll(toBeRemoved); } - private boolean isReservedSubnet(final int subnet) { - return subnet == BLUETOOTH_RESERVED || subnet == WIFI_P2P_RESERVED; - } - /** * Pick a random available address and mark its prefix as in use for the provided IpServer, * returns null if there is no available address. */ @Nullable - public LinkAddress requestDownstreamAddress(final IpServer ipServer) { + public LinkAddress requestDownstreamAddress(final IpServer ipServer, boolean useLastAddress) { if (mConfig.shouldEnableWifiP2pDedicatedIp() && ipServer.interfaceType() == TETHERING_WIFI_P2P) { return new LinkAddress(LEGACY_WIFI_P2P_IFACE_ADDRESS); } + final LinkAddress cachedAddress = mCachedAddresses.get(ipServer.interfaceType()); + if (useLastAddress && cachedAddress != null + && !isConflictWithUpstream(asIpPrefix(cachedAddress))) { + return cachedAddress; + } + // Address would be 192.168.[subAddress]/24. final byte[] bytes = mTetheringPrefix.getRawAddress(); final int subAddress = getRandomSubAddr(); @@ -169,9 +186,8 @@ public class PrivateAddressCoordinator { bytes[3] = getSanitizedAddressSuffix(subAddress, (byte) 0, (byte) 1, (byte) 0xff); for (int i = 0; i < MAX_UBYTE; i++) { final int newSubNet = (subNet + i) & BYTE_MASK; - if (isReservedSubnet(newSubNet)) continue; - bytes[2] = (byte) newSubNet; + final InetAddress addr; try { addr = InetAddress.getByAddress(bytes); @@ -179,20 +195,23 @@ public class PrivateAddressCoordinator { throw new IllegalStateException("Invalid address, shouldn't happen.", e); } - final IpPrefix prefix = new IpPrefix(addr, PREFIX_LENGTH); - // Check whether this prefix is in use. - if (isDownstreamPrefixInUse(prefix)) continue; - // Check whether this prefix is conflict with any current upstream network. - if (isConflictWithUpstream(prefix)) continue; + if (isConflict(new IpPrefix(addr, PREFIX_LENGTH))) continue; mDownstreams.add(ipServer); - return new LinkAddress(addr, PREFIX_LENGTH); + final LinkAddress newAddress = new LinkAddress(addr, PREFIX_LENGTH); + mCachedAddresses.put(ipServer.interfaceType(), newAddress); + return newAddress; } // No available address. return null; } + private boolean isConflict(final IpPrefix prefix) { + // Check whether this prefix is in use or conflict with any current upstream network. + return isDownstreamPrefixInUse(prefix) || isConflictWithUpstream(prefix); + } + /** Get random sub address value. Return value is in 0 ~ 0xffff. */ @VisibleForTesting public int getRandomSubAddr() { @@ -236,13 +255,24 @@ public class PrivateAddressCoordinator { return prefix1.contains(prefix2.getAddress()); } - private boolean isDownstreamPrefixInUse(final IpPrefix source) { + // InUse Prefixes are prefixes of mCachedAddresses which are active downstream addresses, last + // downstream addresses(reserved for next time) and static addresses(e.g. bluetooth, wifi p2p). + private boolean isDownstreamPrefixInUse(final IpPrefix prefix) { // This class always generates downstream prefixes with the same prefix length, so // prefixes cannot be contained in each other. They can only be equal to each other. + for (int i = 0; i < mCachedAddresses.size(); i++) { + if (prefix.equals(asIpPrefix(mCachedAddresses.valueAt(i)))) return true; + } + + // IpServer may use manually-defined address (mStaticIpv4ServerAddr) which does not include + // in mCachedAddresses. for (IpServer downstream : mDownstreams) { - final IpPrefix prefix = getDownstreamPrefix(downstream); - if (source.equals(prefix)) return true; + final IpPrefix target = getDownstreamPrefix(downstream); + if (target == null) continue; + + if (isConflictPrefix(prefix, target)) return true; } + return false; } @@ -250,7 +280,7 @@ public class PrivateAddressCoordinator { final LinkAddress address = downstream.getAddress(); if (address == null) return null; - return PrefixUtils.asIpPrefix(address); + return asIpPrefix(address); } void dump(final IndentingPrintWriter pw) { @@ -260,11 +290,19 @@ public class PrivateAddressCoordinator { pw.println(mUpstreamPrefixMap.keyAt(i) + " - " + mUpstreamPrefixMap.valueAt(i)); } pw.decreaseIndent(); + pw.println("mDownstreams:"); pw.increaseIndent(); for (IpServer ipServer : mDownstreams) { pw.println(ipServer.interfaceType() + " - " + ipServer.getAddress()); } pw.decreaseIndent(); + + pw.println("mCachedAddresses:"); + pw.increaseIndent(); + for (int i = 0; i < mCachedAddresses.size(); i++) { + pw.println(mCachedAddresses.keyAt(i) + " - " + mCachedAddresses.valueAt(i)); + } + pw.decreaseIndent(); } } diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java index 64d5025807e7..474f4e8b603a 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java @@ -1678,14 +1678,6 @@ public class Tethering { } } - private void addUpstreamPrefixes(final UpstreamNetworkState ns) { - mPrivateAddressCoordinator.updateUpstreamPrefix(ns.network, ns.linkProperties); - } - - private void removeUpstreamPrefixes(final UpstreamNetworkState ns) { - mPrivateAddressCoordinator.removeUpstreamPrefix(ns.network); - } - @VisibleForTesting void handleUpstreamNetworkMonitorCallback(int arg1, Object o) { if (arg1 == UpstreamNetworkMonitor.NOTIFY_LOCAL_PREFIXES) { @@ -1696,10 +1688,10 @@ public class Tethering { final UpstreamNetworkState ns = (UpstreamNetworkState) o; switch (arg1) { case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES: - addUpstreamPrefixes(ns); + mPrivateAddressCoordinator.updateUpstreamPrefix(ns); break; case UpstreamNetworkMonitor.EVENT_ON_LOST: - removeUpstreamPrefixes(ns); + mPrivateAddressCoordinator.removeUpstreamPrefix(ns.network); break; } diff --git a/packages/Tethering/tests/privileged/src/android/net/ip/DadProxyTest.java b/packages/Tethering/tests/privileged/src/android/net/ip/DadProxyTest.java index 747d3e803026..95e36fa18f42 100644 --- a/packages/Tethering/tests/privileged/src/android/net/ip/DadProxyTest.java +++ b/packages/Tethering/tests/privileged/src/android/net/ip/DadProxyTest.java @@ -33,7 +33,6 @@ import android.net.MacAddress; import android.net.TestNetworkInterface; import android.net.TestNetworkManager; import android.net.util.InterfaceParams; -import android.net.util.IpUtils; import android.net.util.TetheringUtils; import android.os.Handler; import android.os.HandlerThread; @@ -46,6 +45,7 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.net.module.util.IpUtils; import com.android.testutils.TapPacketReader; import org.junit.After; diff --git a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java index 1a976adc60e0..2eb75895ac3e 100644 --- a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java +++ b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java @@ -47,6 +47,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doAnswer; @@ -230,7 +231,8 @@ public class IpServerTest { dispatchTetherConnectionChanged(upstreamIface, lp, 0); } reset(mNetd, mCallback, mAddressCoordinator); - when(mAddressCoordinator.requestDownstreamAddress(any())).thenReturn(mTestAddress); + when(mAddressCoordinator.requestDownstreamAddress(any(), anyBoolean())).thenReturn( + mTestAddress); } private void setUpDhcpServer() throws Exception { @@ -250,7 +252,8 @@ public class IpServerTest { @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); when(mSharedLog.forSubComponent(anyString())).thenReturn(mSharedLog); - when(mAddressCoordinator.requestDownstreamAddress(any())).thenReturn(mTestAddress); + when(mAddressCoordinator.requestDownstreamAddress(any(), anyBoolean())).thenReturn( + mTestAddress); when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(true /* default value */); mBpfCoordinator = spy(new BpfCoordinator( @@ -372,7 +375,7 @@ public class IpServerTest { dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED); InOrder inOrder = inOrder(mCallback, mNetd, mAddressCoordinator); - inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any()); + inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any(), eq(true)); inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg -> IFACE_NAME.equals(cfg.ifName) && assertContainsFlag(cfg.flags, IF_STATE_UP))); inOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME); @@ -393,7 +396,7 @@ public class IpServerTest { dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_LOCAL_ONLY); InOrder inOrder = inOrder(mCallback, mNetd, mAddressCoordinator); - inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any()); + inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any(), eq(true)); inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg -> IFACE_NAME.equals(cfg.ifName) && assertNotContainsFlag(cfg.flags, IF_STATE_UP))); inOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME); @@ -607,7 +610,7 @@ public class IpServerTest { final ArgumentCaptor<LinkProperties> lpCaptor = ArgumentCaptor.forClass(LinkProperties.class); InOrder inOrder = inOrder(mNetd, mCallback, mAddressCoordinator); - inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any()); + inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any(), eq(true)); inOrder.verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, IFACE_NAME); // One for ipv4 route, one for ipv6 link local route. inOrder.verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(IFACE_NAME), @@ -620,11 +623,12 @@ public class IpServerTest { // Simulate the DHCP server receives DHCPDECLINE on MirrorLink and then signals // onNewPrefixRequest callback. final LinkAddress newAddress = new LinkAddress("192.168.100.125/24"); - when(mAddressCoordinator.requestDownstreamAddress(any())).thenReturn(newAddress); + when(mAddressCoordinator.requestDownstreamAddress(any(), anyBoolean())).thenReturn( + newAddress); eventCallbacks.onNewPrefixRequest(new IpPrefix("192.168.42.0/24")); mLooper.dispatchAll(); - inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any()); + inOrder.verify(mAddressCoordinator).requestDownstreamAddress(any(), eq(false)); inOrder.verify(mNetd).tetherApplyDnsInterfaces(); inOrder.verify(mCallback).updateLinkProperties(eq(mIpServer), lpCaptor.capture()); verifyNoMoreInteractions(mCallback); diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java index 8e93c2e447b3..191eb6e71149 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java @@ -15,10 +15,15 @@ */ package com.android.networkstack.tethering; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; +import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; +import static android.net.NetworkCapabilities.TRANSPORT_VPN; +import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.TetheringManager.TETHERING_ETHERNET; import static android.net.TetheringManager.TETHERING_USB; import static android.net.TetheringManager.TETHERING_WIFI; import static android.net.TetheringManager.TETHERING_WIFI_P2P; +import static android.net.util.PrefixUtils.asIpPrefix; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; @@ -30,14 +35,12 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.net.ConnectivityManager; -import android.net.InetAddresses; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.Network; +import android.net.NetworkCapabilities; import android.net.ip.IpServer; -import android.net.util.NetworkConstants; -import android.net.util.PrefixUtils; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -48,13 +51,10 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import java.util.List; - @RunWith(AndroidJUnit4.class) @SmallTest public final class PrivateAddressCoordinatorTest { - private static final String TEST_MOBILE_IFNAME = "test_rmnet_data0"; - private static final String TEST_WIFI_IFNAME = "test_wlan0"; + private static final String TEST_IFNAME = "test0"; @Mock private IpServer mHotspotIpServer; @Mock private IpServer mUsbIpServer; @@ -65,11 +65,12 @@ public final class PrivateAddressCoordinatorTest { @Mock private TetheringConfiguration mConfig; private PrivateAddressCoordinator mPrivateAddressCoordinator; - private final IpPrefix mBluetoothPrefix = new IpPrefix("192.168.44.0/24"); + private final LinkAddress mBluetoothAddress = new LinkAddress("192.168.44.1/24"); private final LinkAddress mLegacyWifiP2pAddress = new LinkAddress("192.168.49.1/24"); private final Network mWifiNetwork = new Network(1); private final Network mMobileNetwork = new Network(2); - private final Network[] mAllNetworks = {mMobileNetwork, mWifiNetwork}; + private final Network mVpnNetwork = new Network(3); + private final Network[] mAllNetworks = {mMobileNetwork, mWifiNetwork, mVpnNetwork}; private void setUpIpServers() throws Exception { when(mUsbIpServer.interfaceType()).thenReturn(TETHERING_USB); @@ -90,127 +91,140 @@ public final class PrivateAddressCoordinatorTest { } @Test - public void testDownstreamPrefixRequest() throws Exception { - LinkAddress address = mPrivateAddressCoordinator.requestDownstreamAddress( - mHotspotIpServer); - final IpPrefix hotspotPrefix = PrefixUtils.asIpPrefix(address); - assertNotEquals(hotspotPrefix, mBluetoothPrefix); + public void testRequestDownstreamAddressWithoutUsingLastAddress() throws Exception { + final IpPrefix bluetoothPrefix = asIpPrefix(mBluetoothAddress); + final LinkAddress address = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, false /* useLastAddress */); + final IpPrefix hotspotPrefix = asIpPrefix(address); + assertNotEquals(hotspotPrefix, bluetoothPrefix); + when(mHotspotIpServer.getAddress()).thenReturn(address); - address = mPrivateAddressCoordinator.requestDownstreamAddress( - mHotspotIpServer); - final IpPrefix testDupRequest = PrefixUtils.asIpPrefix(address); + final LinkAddress newAddress = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, false /* useLastAddress */); + final IpPrefix testDupRequest = asIpPrefix(newAddress); assertNotEquals(hotspotPrefix, testDupRequest); - assertNotEquals(mBluetoothPrefix, testDupRequest); + assertNotEquals(bluetoothPrefix, testDupRequest); mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer); - address = mPrivateAddressCoordinator.requestDownstreamAddress( - mUsbIpServer); - final IpPrefix usbPrefix = PrefixUtils.asIpPrefix(address); - assertNotEquals(usbPrefix, mBluetoothPrefix); + final LinkAddress usbAddress = mPrivateAddressCoordinator.requestDownstreamAddress( + mUsbIpServer, false /* useLastAddress */); + final IpPrefix usbPrefix = asIpPrefix(usbAddress); + assertNotEquals(usbPrefix, bluetoothPrefix); assertNotEquals(usbPrefix, hotspotPrefix); mPrivateAddressCoordinator.releaseDownstream(mUsbIpServer); } @Test - public void testRequestDownstreamAddress() throws Exception { - LinkAddress expectedAddress = new LinkAddress("192.168.43.42/24"); - int fakeSubAddr = 0x2b00; + public void testSanitizedAddress() throws Exception { + int fakeSubAddr = 0x2b00; // 43.0. when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeSubAddr); LinkAddress actualAddress = mPrivateAddressCoordinator.requestDownstreamAddress( - mHotspotIpServer); - assertEquals(actualAddress, expectedAddress); + mHotspotIpServer, false /* useLastAddress */); + assertEquals(new LinkAddress("192.168.43.42/24"), actualAddress); mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer); - fakeSubAddr = 0x2b01; + fakeSubAddr = 0x2d01; // 45.1. when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeSubAddr); actualAddress = mPrivateAddressCoordinator.requestDownstreamAddress( - mHotspotIpServer); - assertEquals(actualAddress, expectedAddress); + mHotspotIpServer, false /* useLastAddress */); + assertEquals(new LinkAddress("192.168.45.42/24"), actualAddress); mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer); - fakeSubAddr = 0x2bff; + fakeSubAddr = 0x2eff; // 46.255. when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeSubAddr); actualAddress = mPrivateAddressCoordinator.requestDownstreamAddress( - mHotspotIpServer); - assertEquals(actualAddress, expectedAddress); + mHotspotIpServer, false /* useLastAddress */); + assertEquals(new LinkAddress("192.168.46.42/24"), actualAddress); mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer); - expectedAddress = new LinkAddress("192.168.43.5/24"); - fakeSubAddr = 0x2b05; + fakeSubAddr = 0x2f05; // 47.5. when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeSubAddr); actualAddress = mPrivateAddressCoordinator.requestDownstreamAddress( - mHotspotIpServer); - assertEquals(actualAddress, expectedAddress); + mHotspotIpServer, false /* useLastAddress */); + assertEquals(new LinkAddress("192.168.47.5/24"), actualAddress); mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer); } - private int getBluetoothSubAddress() { - final byte[] rawAddress = mBluetoothPrefix.getRawAddress(); - int bluetoothSubNet = rawAddress[2] & 0xff; - return (bluetoothSubNet << 8) + 0x5; - } - @Test - public void testReserveBluetoothPrefix() throws Exception { - when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(getBluetoothSubAddress()); - LinkAddress address = mPrivateAddressCoordinator.requestDownstreamAddress( - mHotspotIpServer); - final IpPrefix hotspotPrefix = PrefixUtils.asIpPrefix(address); - assertNotEquals("Should not get reserved prefix: ", mBluetoothPrefix, hotspotPrefix); + public void testReservedPrefix() throws Exception { + // - Test bluetooth prefix is reserved. + when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn( + getSubAddress(mBluetoothAddress.getAddress().getAddress())); + final LinkAddress hotspotAddress = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, false /* useLastAddress */); + final IpPrefix hotspotPrefix = asIpPrefix(hotspotAddress); + assertNotEquals(asIpPrefix(mBluetoothAddress), hotspotPrefix); mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer); + + // - Test previous enabled hotspot prefix(cached prefix) is reserved. + when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn( + getSubAddress(hotspotAddress.getAddress().getAddress())); + final LinkAddress usbAddress = mPrivateAddressCoordinator.requestDownstreamAddress( + mUsbIpServer, false /* useLastAddress */); + final IpPrefix usbPrefix = asIpPrefix(usbAddress); + assertNotEquals(asIpPrefix(mBluetoothAddress), usbPrefix); + assertNotEquals(hotspotPrefix, usbPrefix); + mPrivateAddressCoordinator.releaseDownstream(mUsbIpServer); + + // - Test wifi p2p prefix is reserved. + when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn( + getSubAddress(mLegacyWifiP2pAddress.getAddress().getAddress())); + final LinkAddress etherAddress = mPrivateAddressCoordinator.requestDownstreamAddress( + mEthernetIpServer, false /* useLastAddress */); + final IpPrefix etherPrefix = asIpPrefix(etherAddress); + assertNotEquals(asIpPrefix(mLegacyWifiP2pAddress), etherPrefix); + assertNotEquals(asIpPrefix(mBluetoothAddress), etherPrefix); + assertNotEquals(hotspotPrefix, etherPrefix); + mPrivateAddressCoordinator.releaseDownstream(mEthernetIpServer); } @Test - public void testNoConflictDownstreamPrefix() throws Exception { + public void testRequestLastDownstreamAddress() throws Exception { final int fakeHotspotSubAddr = 0x2b05; final IpPrefix predefinedPrefix = new IpPrefix("192.168.43.0/24"); when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeHotspotSubAddr); - LinkAddress address = mPrivateAddressCoordinator.requestDownstreamAddress( - mHotspotIpServer); - final IpPrefix hotspotPrefix = PrefixUtils.asIpPrefix(address); - assertEquals("Wrong wifi prefix: ", predefinedPrefix, hotspotPrefix); - when(mHotspotIpServer.getAddress()).thenReturn(address); + final LinkAddress hotspotAddress = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, true /* useLastAddress */); + assertEquals("Wrong wifi prefix: ", predefinedPrefix, asIpPrefix(hotspotAddress)); + when(mHotspotIpServer.getAddress()).thenReturn(hotspotAddress); - address = mPrivateAddressCoordinator.requestDownstreamAddress( - mUsbIpServer); - final IpPrefix usbPrefix = PrefixUtils.asIpPrefix(address); - assertNotEquals(predefinedPrefix, usbPrefix); + final LinkAddress usbAddress = mPrivateAddressCoordinator.requestDownstreamAddress( + mUsbIpServer, true /* useLastAddress */); + assertNotEquals(predefinedPrefix, asIpPrefix(usbAddress)); mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer); mPrivateAddressCoordinator.releaseDownstream(mUsbIpServer); - address = mPrivateAddressCoordinator.requestDownstreamAddress( - mUsbIpServer); - final IpPrefix allowUseFreePrefix = PrefixUtils.asIpPrefix(address); - assertEquals("Fail to reselect available prefix: ", predefinedPrefix, allowUseFreePrefix); - } - private LinkProperties buildUpstreamLinkProperties(boolean withIPv4, boolean withIPv6, - boolean isMobile) { - final String testIface; - final String testIpv4Address; - if (isMobile) { - testIface = TEST_MOBILE_IFNAME; - testIpv4Address = "10.0.0.1"; - } else { - testIface = TEST_WIFI_IFNAME; - testIpv4Address = "192.168.43.5"; - } + final int newFakeSubAddr = 0x3c05; + when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeHotspotSubAddr); + + final LinkAddress newHotspotAddress = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, true /* useLastAddress */); + assertEquals(hotspotAddress, newHotspotAddress); + final LinkAddress newUsbAddress = mPrivateAddressCoordinator.requestDownstreamAddress( + mUsbIpServer, true /* useLastAddress */); + assertEquals(usbAddress, newUsbAddress); + } + private UpstreamNetworkState buildUpstreamNetworkState(final Network network, + final LinkAddress v4Addr, final LinkAddress v6Addr, final NetworkCapabilities cap) { final LinkProperties prop = new LinkProperties(); - prop.setInterfaceName(testIface); + prop.setInterfaceName(TEST_IFNAME); + if (v4Addr != null) prop.addLinkAddress(v4Addr); - if (withIPv4) { - prop.addLinkAddress( - new LinkAddress(InetAddresses.parseNumericAddress(testIpv4Address), - NetworkConstants.IPV4_ADDR_BITS)); - } + if (v6Addr != null) prop.addLinkAddress(v6Addr); + + return new UpstreamNetworkState(prop, cap, network); + } - if (withIPv6) { - prop.addLinkAddress( - new LinkAddress(InetAddresses.parseNumericAddress("2001:db8::"), - NetworkConstants.RFC7421_PREFIX_LENGTH)); + private NetworkCapabilities makeNetworkCapabilities(final int transportType) { + final NetworkCapabilities cap = new NetworkCapabilities(); + cap.addTransportType(transportType); + if (transportType == TRANSPORT_VPN) { + cap.removeCapability(NET_CAPABILITY_NOT_VPN); } - return prop; + + return cap; } @Test @@ -220,57 +234,81 @@ public final class PrivateAddressCoordinatorTest { final IpPrefix predefinedPrefix = new IpPrefix("192.168.43.0/24"); // Force always get subAddress "43.5" for conflict testing. when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeHotspotSubAddr); - // 1. Enable hotspot with prefix 192.168.43.0/24 + // - Enable hotspot with prefix 192.168.43.0/24 final LinkAddress hotspotAddr = mPrivateAddressCoordinator.requestDownstreamAddress( - mHotspotIpServer); - final IpPrefix hotspotPrefix = PrefixUtils.asIpPrefix(hotspotAddr); + mHotspotIpServer, true /* useLastAddress */); + final IpPrefix hotspotPrefix = asIpPrefix(hotspotAddr); assertEquals("Wrong wifi prefix: ", predefinedPrefix, hotspotPrefix); when(mHotspotIpServer.getAddress()).thenReturn(hotspotAddr); - // 2. Update v6 only mobile network, hotspot prefix should not be removed. - List<String> testConflicts; - final LinkProperties v6OnlyMobileProp = buildUpstreamLinkProperties(false, true, true); - mPrivateAddressCoordinator.updateUpstreamPrefix(mMobileNetwork, v6OnlyMobileProp); + // - test mobile network with null NetworkCapabilities. Ideally this should not happen + // because NetworkCapabilities update should always happen before LinkProperties update + // and the UpstreamNetworkState update, just make sure no crash in this case. + final UpstreamNetworkState noCapUpstream = buildUpstreamNetworkState(mMobileNetwork, + new LinkAddress("10.0.0.8/24"), null, null); + mPrivateAddressCoordinator.updateUpstreamPrefix(noCapUpstream); + verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); + // - test mobile upstream with no address. + final UpstreamNetworkState noAddress = buildUpstreamNetworkState(mMobileNetwork, + null, null, makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(noCapUpstream); + verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); + // - Update v6 only mobile network, hotspot prefix should not be removed. + final UpstreamNetworkState v6OnlyMobile = buildUpstreamNetworkState(mMobileNetwork, + null, new LinkAddress("2001:db8::/64"), + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(v6OnlyMobile); verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); mPrivateAddressCoordinator.removeUpstreamPrefix(mMobileNetwork); - // 3. Update v4 only mobile network, hotspot prefix should not be removed. - final LinkProperties v4OnlyMobileProp = buildUpstreamLinkProperties(true, false, true); - mPrivateAddressCoordinator.updateUpstreamPrefix(mMobileNetwork, v4OnlyMobileProp); + // - Update v4 only mobile network, hotspot prefix should not be removed. + final UpstreamNetworkState v4OnlyMobile = buildUpstreamNetworkState(mMobileNetwork, + new LinkAddress("10.0.0.8/24"), null, + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(v4OnlyMobile); verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); - // 4. Update v4v6 mobile network, hotspot prefix should not be removed. - final LinkProperties v4v6MobileProp = buildUpstreamLinkProperties(true, true, true); - mPrivateAddressCoordinator.updateUpstreamPrefix(mMobileNetwork, v4v6MobileProp); + // - Update v4v6 mobile network, hotspot prefix should not be removed. + final UpstreamNetworkState v4v6Mobile = buildUpstreamNetworkState(mMobileNetwork, + new LinkAddress("10.0.0.8/24"), new LinkAddress("2001:db8::/64"), + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(v4v6Mobile); verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); - // 5. Update v6 only wifi network, hotspot prefix should not be removed. - final LinkProperties v6OnlyWifiProp = buildUpstreamLinkProperties(false, true, false); - mPrivateAddressCoordinator.updateUpstreamPrefix(mWifiNetwork, v6OnlyWifiProp); + // - Update v6 only wifi network, hotspot prefix should not be removed. + final UpstreamNetworkState v6OnlyWifi = buildUpstreamNetworkState(mWifiNetwork, + null, new LinkAddress("2001:db8::/64"), makeNetworkCapabilities(TRANSPORT_WIFI)); + mPrivateAddressCoordinator.updateUpstreamPrefix(v6OnlyWifi); verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); mPrivateAddressCoordinator.removeUpstreamPrefix(mWifiNetwork); - // 6. Update v4 only wifi network, it conflict with hotspot prefix. - final LinkProperties v4OnlyWifiProp = buildUpstreamLinkProperties(true, false, false); - mPrivateAddressCoordinator.updateUpstreamPrefix(mWifiNetwork, v4OnlyWifiProp); + // - Update vpn network, it conflict with hotspot prefix but VPN networks are ignored. + final UpstreamNetworkState v4OnlyVpn = buildUpstreamNetworkState(mVpnNetwork, + new LinkAddress("192.168.43.5/24"), null, makeNetworkCapabilities(TRANSPORT_VPN)); + mPrivateAddressCoordinator.updateUpstreamPrefix(v4OnlyVpn); + verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); + // - Update v4 only wifi network, it conflict with hotspot prefix. + final UpstreamNetworkState v4OnlyWifi = buildUpstreamNetworkState(mWifiNetwork, + new LinkAddress("192.168.43.5/24"), null, makeNetworkCapabilities(TRANSPORT_WIFI)); + mPrivateAddressCoordinator.updateUpstreamPrefix(v4OnlyWifi); verify(mHotspotIpServer).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); reset(mHotspotIpServer); - // 7. Restart hotspot again and its prefix is different previous. + // - Restart hotspot again and its prefix is different previous. mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer); final LinkAddress hotspotAddr2 = mPrivateAddressCoordinator.requestDownstreamAddress( - mHotspotIpServer); - final IpPrefix hotspotPrefix2 = PrefixUtils.asIpPrefix(hotspotAddr2); + mHotspotIpServer, true /* useLastAddress */); + final IpPrefix hotspotPrefix2 = asIpPrefix(hotspotAddr2); assertNotEquals(hotspotPrefix, hotspotPrefix2); when(mHotspotIpServer.getAddress()).thenReturn(hotspotAddr2); - mPrivateAddressCoordinator.updateUpstreamPrefix(mWifiNetwork, v4OnlyWifiProp); + mPrivateAddressCoordinator.updateUpstreamPrefix(v4OnlyWifi); verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); - // 7. Usb tethering can be enabled and its prefix is different with conflict one. + // - Usb tethering can be enabled and its prefix is different with conflict one. final LinkAddress usbAddr = mPrivateAddressCoordinator.requestDownstreamAddress( - mUsbIpServer); - final IpPrefix usbPrefix = PrefixUtils.asIpPrefix(usbAddr); + mUsbIpServer, true /* useLastAddress */); + final IpPrefix usbPrefix = asIpPrefix(usbAddr); assertNotEquals(predefinedPrefix, usbPrefix); assertNotEquals(hotspotPrefix2, usbPrefix); when(mUsbIpServer.getAddress()).thenReturn(usbAddr); - // 8. Disable wifi upstream, then wifi's prefix can be selected again. + // - Disable wifi upstream, then wifi's prefix can be selected again. mPrivateAddressCoordinator.removeUpstreamPrefix(mWifiNetwork); final LinkAddress ethAddr = mPrivateAddressCoordinator.requestDownstreamAddress( - mEthernetIpServer); - final IpPrefix ethPrefix = PrefixUtils.asIpPrefix(ethAddr); + mEthernetIpServer, true /* useLastAddress */); + final IpPrefix ethPrefix = asIpPrefix(ethAddr); assertEquals(predefinedPrefix, ethPrefix); } @@ -283,9 +321,9 @@ public final class PrivateAddressCoordinatorTest { private void assertReseveredWifiP2pPrefix() throws Exception { LinkAddress address = mPrivateAddressCoordinator.requestDownstreamAddress( - mHotspotIpServer); - final IpPrefix hotspotPrefix = PrefixUtils.asIpPrefix(address); - final IpPrefix legacyWifiP2pPrefix = PrefixUtils.asIpPrefix(mLegacyWifiP2pAddress); + mHotspotIpServer, true /* useLastAddress */); + final IpPrefix hotspotPrefix = asIpPrefix(address); + final IpPrefix legacyWifiP2pPrefix = asIpPrefix(mLegacyWifiP2pAddress); assertNotEquals(legacyWifiP2pPrefix, hotspotPrefix); mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer); } @@ -303,7 +341,7 @@ public final class PrivateAddressCoordinatorTest { // If #shouldEnableWifiP2pDedicatedIp() is enabled, wifi P2P gets the configured address. LinkAddress address = mPrivateAddressCoordinator.requestDownstreamAddress( - mWifiP2pIpServer); + mWifiP2pIpServer, true /* useLastAddress */); assertEquals(mLegacyWifiP2pAddress, address); mPrivateAddressCoordinator.releaseDownstream(mWifiP2pIpServer); } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 8a1baf25481b..b59f7645445d 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -1126,7 +1126,6 @@ public class ConnectivityService extends IConnectivityManager.Stub // Listen to package add and removal events for all users. intentFilter = new IntentFilter(); - intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED); intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); intentFilter.addDataScheme("package"); diff --git a/services/core/java/com/android/server/MountServiceIdler.java b/services/core/java/com/android/server/MountServiceIdler.java index 6bc1a570b7c0..0f4c94bc8d4f 100644 --- a/services/core/java/com/android/server/MountServiceIdler.java +++ b/services/core/java/com/android/server/MountServiceIdler.java @@ -113,6 +113,7 @@ public class MountServiceIdler extends JobService { JobInfo.Builder builder = new JobInfo.Builder(MOUNT_JOB_ID, sIdleService); builder.setRequiresDeviceIdle(true); builder.setRequiresBatteryNotLow(true); + builder.setRequiresCharging(true); builder.setMinimumLatency(nextScheduleTime); tm.schedule(builder.build()); } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 09c0ba37028a..d990c1e9fbe1 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -3318,6 +3318,10 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public boolean setProcessMemoryTrimLevel(String process, int userId, int level) throws RemoteException { + if (!isCallerShell()) { + EventLog.writeEvent(0x534e4554, 160390416, Binder.getCallingUid(), ""); + throw new SecurityException("Only shell can call it"); + } synchronized (this) { final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel"); if (app == null) { diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java index 01fa9e755bd6..8625a6f470c5 100644 --- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java +++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java @@ -47,7 +47,6 @@ import android.net.NetworkAgent; import android.net.NetworkUtils; import android.net.SocketKeepalive.InvalidSocketException; import android.net.TcpKeepalivePacketData; -import android.net.util.IpUtils; import android.net.util.KeepaliveUtils; import android.os.Binder; import android.os.Handler; @@ -63,6 +62,7 @@ import android.util.Pair; import com.android.internal.R; import com.android.internal.util.HexDump; import com.android.internal.util.IndentingPrintWriter; +import com.android.net.module.util.IpUtils; import java.io.FileDescriptor; import java.net.InetAddress; diff --git a/services/core/java/com/android/server/connectivity/PacManager.java b/services/core/java/com/android/server/connectivity/PacManager.java index de302fc01f2d..198de78ecfa6 100644 --- a/services/core/java/com/android/server/connectivity/PacManager.java +++ b/services/core/java/com/android/server/connectivity/PacManager.java @@ -154,7 +154,7 @@ public class PacManager { mNetThreadHandler = new Handler(netThread.getLooper()); mPacRefreshIntent = PendingIntent.getBroadcast( - context, 0, new Intent(ACTION_PAC_REFRESH), 0); + context, 0, new Intent(ACTION_PAC_REFRESH), PendingIntent.FLAG_IMMUTABLE); context.registerReceiver(new PacRefreshIntentReceiver(), new IntentFilter(ACTION_PAC_REFRESH)); mConnectivityHandler = handler; diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 8e1fccd07f7a..2f15918d3064 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -380,8 +380,8 @@ public class Vpn { } } - public boolean checkInterfacePresent(final Vpn vpn, final String iface) { - return vpn.jniCheck(iface) == 0; + public boolean isInterfacePresent(final Vpn vpn, final String iface) { + return vpn.jniCheck(iface) != 0; } } @@ -1130,7 +1130,13 @@ public class Vpn { return mNetworkInfo; } - public int getNetId() { + /** + * Return netId of current running VPN network. + * + * @return a netId if there is a running VPN network or NETID_UNSET if there is no running VPN + * network or network is null. + */ + public synchronized int getNetId() { final NetworkAgent agent = mNetworkAgent; if (null == agent) return NETID_UNSET; final Network network = agent.getNetwork(); @@ -1708,7 +1714,7 @@ public class Vpn { /** * Return the configuration of the currently running VPN. */ - public VpnConfig getVpnConfig() { + public synchronized VpnConfig getVpnConfig() { enforceControlPermission(); return mConfig; } @@ -2755,7 +2761,10 @@ public class Vpn { final LinkProperties lp = cm.getLinkProperties(network); if (lp != null && lp.getAllInterfaceNames().contains(mOuterInterface)) { final NetworkInfo networkInfo = cm.getNetworkInfo(network); - if (networkInfo != null) mOuterConnection.set(networkInfo.getType()); + if (networkInfo != null) { + mOuterConnection.set(networkInfo.getType()); + break; + } } } } @@ -2986,7 +2995,7 @@ public class Vpn { checkInterruptAndDelay(false); // Check if the interface is gone while we are waiting. - if (mDeps.checkInterfacePresent(Vpn.this, mConfig.interfaze)) { + if (!mDeps.isInterfacePresent(Vpn.this, mConfig.interfaze)) { throw new IllegalStateException(mConfig.interfaze + " is gone"); } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java index 66652ca26e54..535284083d11 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecController.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java @@ -16,6 +16,8 @@ package com.android.server.hdmi; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.hardware.hdmi.HdmiPortInfo; import android.hardware.tv.cec.V1_0.CecMessage; import android.hardware.tv.cec.V1_0.HotplugEvent; @@ -725,6 +727,7 @@ final class HdmiCecController { private IHdmiCec mHdmiCec; private final Object mLock = new Object(); private int mPhysicalAddress = INVALID_PHYSICAL_ADDRESS; + @Nullable private HdmiCecCallback mCallback; @Override public String nativeInit() { @@ -733,7 +736,7 @@ final class HdmiCecController { boolean connectToHal() { try { - mHdmiCec = IHdmiCec.getService(); + mHdmiCec = IHdmiCec.getService(true); try { mHdmiCec.linkToDeath(this, HDMI_CEC_HAL_DEATH_COOKIE); } catch (RemoteException e) { @@ -747,7 +750,8 @@ final class HdmiCecController { } @Override - public void setCallback(HdmiCecCallback callback) { + public void setCallback(@NonNull HdmiCecCallback callback) { + mCallback = callback; try { mHdmiCec.setCallback(callback); } catch (RemoteException e) { @@ -887,6 +891,10 @@ final class HdmiCecController { if (cookie == HDMI_CEC_HAL_DEATH_COOKIE) { HdmiLogger.error(TAG, "Service died cokkie : " + cookie + "; reconnecting"); connectToHal(); + // Reconnect the callback + if (mCallback != null) { + setCallback(mCallback); + } } } diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java index bc78d66037fe..c3cb42f95cc6 100644 --- a/services/core/java/com/android/server/notification/PreferencesHelper.java +++ b/services/core/java/com/android/server/notification/PreferencesHelper.java @@ -75,6 +75,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -173,6 +174,8 @@ public class PreferencesHelper implements RankingConfig { private boolean mAllowInvalidShortcuts = false; + private Map<String, List<String>> mOemLockedApps = new HashMap(); + public PreferencesHelper(Context context, PackageManager pm, RankingHandler rankingHandler, ZenModeHelper zenHelper, NotificationChannelLogger notificationChannelLogger, AppOpsManager appOpsManager, @@ -314,6 +317,12 @@ public class PreferencesHelper implements RankingConfig { } channel.setImportanceLockedByCriticalDeviceFunction( r.defaultAppLockedImportance); + channel.setImportanceLockedByOEM(r.oemLockedImportance); + if (!channel.isImportanceLockedByOEM()) { + if (r.oemLockedChannels.contains(channel.getId())) { + channel.setImportanceLockedByOEM(true); + } + } boolean isInvalidShortcutChannel = channel.getConversationId() != null && channel.getConversationId().contains( @@ -396,6 +405,14 @@ public class PreferencesHelper implements RankingConfig { r.visibility = visibility; r.showBadge = showBadge; r.bubblePreference = bubblePreference; + if (mOemLockedApps.containsKey(r.pkg)) { + List<String> channels = mOemLockedApps.get(r.pkg); + if (channels == null || channels.isEmpty()) { + r.oemLockedImportance = true; + } else { + r.oemLockedChannels = channels; + } + } try { createDefaultChannelIfNeededLocked(r); @@ -1149,8 +1166,10 @@ public class PreferencesHelper implements RankingConfig { String channelId = appSplit.length == 2 ? appSplit[1] : null; synchronized (mPackagePreferences) { + boolean foundApp = false; for (PackagePreferences r : mPackagePreferences.values()) { if (r.pkg.equals(appName)) { + foundApp = true; if (channelId == null) { // lock all channels for the app r.oemLockedImportance = true; @@ -1168,6 +1187,14 @@ public class PreferencesHelper implements RankingConfig { } } } + if (!foundApp) { + List<String> channels = + mOemLockedApps.getOrDefault(appName, new ArrayList<>()); + if (channelId != null) { + channels.add(channelId); + } + mOemLockedApps.put(appName, channels); + } } } } diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java index 0dfa081e7695..48ec9b4b502d 100644 --- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java +++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java @@ -337,6 +337,7 @@ public class BackgroundDexOptService extends JobService { private int idleOptimizePackages(PackageManagerService pm, ArraySet<String> pkgs, long lowStorageThreshold) { ArraySet<String> updatedPackages = new ArraySet<>(); + ArraySet<String> updatedPackagesDueToSecondaryDex = new ArraySet<>(); try { final boolean supportSecondaryDex = supportSecondaryDex(); @@ -391,11 +392,14 @@ public class BackgroundDexOptService extends JobService { } int secondaryResult = optimizePackages(pm, pkgs, lowStorageThreshold, - /*isForPrimaryDex*/ false, updatedPackages); + /*isForPrimaryDex*/ false, updatedPackagesDueToSecondaryDex); return secondaryResult; } finally { // Always let the pinner service know about changes. notifyPinService(updatedPackages); + // Only notify IORap the primary dex opt, because we don't want to + // invalidate traces unnecessary due to b/161633001 and that it's + // better to have a trace than no trace at all. notifyPackagesUpdated(updatedPackages); } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 4f0c707a1dae..9d0a5c4787fd 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3649,6 +3649,8 @@ public class PackageManagerService extends IPackageManager.Stub PackageParser.readConfigUseRoundIcon(mContext.getResources()); mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L); + + Slog.i(TAG, "Fix for b/169414761 is applied"); } /** @@ -11096,6 +11098,8 @@ public class PackageManagerService extends IPackageManager.Stub mSettings.addRenamedPackageLPw(parsedPackage.getRealPackage(), originalPkgSetting.name); mTransferredPackages.add(originalPkgSetting.name); + } else { + mSettings.removeRenamedPackageLPw(parsedPackage.getPackageName()); } } if (pkgSetting.sharedUser != null) { diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index a0feb94fd3fc..0f5d9781c612 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -476,6 +476,10 @@ public final class Settings { return mRenamedPackages.put(pkgName, origPkgName); } + void removeRenamedPackageLPw(String pkgName) { + mRenamedPackages.remove(pkgName); + } + public boolean canPropagatePermissionToInstantApp(String permName) { return mPermissions.canPropagatePermissionToInstantApp(permName); } diff --git a/services/core/java/com/android/server/pm/permission/OWNERS b/services/core/java/com/android/server/pm/permission/OWNERS index 01dc01efaca8..0e88862e01b1 100644 --- a/services/core/java/com/android/server/pm/permission/OWNERS +++ b/services/core/java/com/android/server/pm/permission/OWNERS @@ -1,4 +1,5 @@ moltmann@google.com +zhanghai@google.com per-file DefaultPermissionGrantPolicy.java = hackbod@android.com per-file DefaultPermissionGrantPolicy.java = jsharkey@android.com per-file DefaultPermissionGrantPolicy.java = svetoslavganov@google.com @@ -7,3 +8,4 @@ per-file DefaultPermissionGrantPolicy.java = yamasani@google.com per-file DefaultPermissionGrantPolicy.java = patb@google.com per-file DefaultPermissionGrantPolicy.java = eugenesusla@google.com per-file DefaultPermissionGrantPolicy.java = moltmann@google.com +per-file DefaultPermissionGrantPolicy.java = zhanghai@google.com diff --git a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java index c4e03f5c65f5..aa76a07bc9c7 100644 --- a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java +++ b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java @@ -16,8 +16,6 @@ package com.android.server.wm; -import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; - import static com.android.server.wm.ActivityStack.TAG_VISIBILITY; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY; @@ -174,12 +172,7 @@ class EnsureActivitiesVisibleHelper { } final int windowingMode = mContiner.getWindowingMode(); - if (windowingMode == WINDOWING_MODE_FREEFORM) { - // The visibility of tasks and the activities they contain in freeform stack are - // determined individually unlike other stacks where the visibility or fullscreen - // status of an activity in a previous task affects other. - mBehindFullscreenActivity = !mContainerShouldBeVisible; - } else if (!mBehindFullscreenActivity && mContiner.isActivityTypeHome() + if (!mBehindFullscreenActivity && mContiner.isActivityTypeHome() && r.isRootOfTask()) { if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + mContiner + " stackShouldBeVisible=" + mContainerShouldBeVisible diff --git a/services/core/xsd/vts/Android.mk b/services/core/xsd/vts/Android.mk deleted file mode 100644 index 6dc2c437a2f9..000000000000 --- a/services/core/xsd/vts/Android.mk +++ /dev/null @@ -1,22 +0,0 @@ -# -# Copyright (C) 2019 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE := VtsValidateDefaultPermissions -include test/vts/tools/build/Android.host_config.mk diff --git a/services/core/xsd/vts/AndroidTest.xml b/services/core/xsd/vts/AndroidTest.xml deleted file mode 100644 index 4f3b2ef1ace1..000000000000 --- a/services/core/xsd/vts/AndroidTest.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2019 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<configuration description="Config for VTS VtsValidateDefaultPermissions."> - <option name="config-descriptor:metadata" key="plan" value="vts-treble" /> - <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher"> - <option name="abort-on-push-failure" value="false"/> - <option name="push-group" value="HostDrivenTest.push"/> - <option name="push" value="DATA/etc/default-permissions.xsd->/data/local/tmp/default-permissions.xsd"/> - </target_preparer> - <test class="com.android.tradefed.testtype.VtsMultiDeviceTest"> - <option name="test-module-name" value="VtsValidateDefaultPermissions"/> - <option name="binary-test-source" value="_32bit::DATA/nativetest/vts_defaultPermissions_validate_test/vts_defaultPermissions_validate_test" /> - <option name="binary-test-source" value="_64bit::DATA/nativetest64/vts_defaultPermissions_validate_test/vts_defaultPermissions_validate_test" /> - <option name="binary-test-type" value="gtest"/> - <option name="test-timeout" value="30s"/> - </test> -</configuration> diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index c6b93d6ca4f4..0da47ca90f5e 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -480,38 +480,38 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { private static final int STATUS_BAR_DISABLE2_MASK = StatusBarManager.DISABLE2_QUICK_SETTINGS; - private static final Set<String> SECURE_SETTINGS_WHITELIST; - private static final Set<String> SECURE_SETTINGS_DEVICEOWNER_WHITELIST; - private static final Set<String> GLOBAL_SETTINGS_WHITELIST; + private static final Set<String> SECURE_SETTINGS_ALLOWLIST; + private static final Set<String> SECURE_SETTINGS_DEVICEOWNER_ALLOWLIST; + private static final Set<String> GLOBAL_SETTINGS_ALLOWLIST; private static final Set<String> GLOBAL_SETTINGS_DEPRECATED; - private static final Set<String> SYSTEM_SETTINGS_WHITELIST; + private static final Set<String> SYSTEM_SETTINGS_ALLOWLIST; private static final Set<Integer> DA_DISALLOWED_POLICIES; // A collection of user restrictions that are deprecated and should simply be ignored. private static final Set<String> DEPRECATED_USER_RESTRICTIONS; private static final String AB_DEVICE_KEY = "ro.build.ab_update"; static { - SECURE_SETTINGS_WHITELIST = new ArraySet<>(); - SECURE_SETTINGS_WHITELIST.add(Settings.Secure.DEFAULT_INPUT_METHOD); - SECURE_SETTINGS_WHITELIST.add(Settings.Secure.SKIP_FIRST_USE_HINTS); - SECURE_SETTINGS_WHITELIST.add(Settings.Secure.INSTALL_NON_MARKET_APPS); - - SECURE_SETTINGS_DEVICEOWNER_WHITELIST = new ArraySet<>(); - SECURE_SETTINGS_DEVICEOWNER_WHITELIST.addAll(SECURE_SETTINGS_WHITELIST); - SECURE_SETTINGS_DEVICEOWNER_WHITELIST.add(Settings.Secure.LOCATION_MODE); - - GLOBAL_SETTINGS_WHITELIST = new ArraySet<>(); - GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.ADB_ENABLED); - GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.ADB_WIFI_ENABLED); - GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.AUTO_TIME); - GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.AUTO_TIME_ZONE); - GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.DATA_ROAMING); - GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.USB_MASS_STORAGE_ENABLED); - GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.WIFI_SLEEP_POLICY); - GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.STAY_ON_WHILE_PLUGGED_IN); - GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN); - GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.PRIVATE_DNS_MODE); - GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.PRIVATE_DNS_SPECIFIER); + SECURE_SETTINGS_ALLOWLIST = new ArraySet<>(); + SECURE_SETTINGS_ALLOWLIST.add(Settings.Secure.DEFAULT_INPUT_METHOD); + SECURE_SETTINGS_ALLOWLIST.add(Settings.Secure.SKIP_FIRST_USE_HINTS); + SECURE_SETTINGS_ALLOWLIST.add(Settings.Secure.INSTALL_NON_MARKET_APPS); + + SECURE_SETTINGS_DEVICEOWNER_ALLOWLIST = new ArraySet<>(); + SECURE_SETTINGS_DEVICEOWNER_ALLOWLIST.addAll(SECURE_SETTINGS_ALLOWLIST); + SECURE_SETTINGS_DEVICEOWNER_ALLOWLIST.add(Settings.Secure.LOCATION_MODE); + + GLOBAL_SETTINGS_ALLOWLIST = new ArraySet<>(); + GLOBAL_SETTINGS_ALLOWLIST.add(Settings.Global.ADB_ENABLED); + GLOBAL_SETTINGS_ALLOWLIST.add(Settings.Global.ADB_WIFI_ENABLED); + GLOBAL_SETTINGS_ALLOWLIST.add(Settings.Global.AUTO_TIME); + GLOBAL_SETTINGS_ALLOWLIST.add(Settings.Global.AUTO_TIME_ZONE); + GLOBAL_SETTINGS_ALLOWLIST.add(Settings.Global.DATA_ROAMING); + GLOBAL_SETTINGS_ALLOWLIST.add(Settings.Global.USB_MASS_STORAGE_ENABLED); + GLOBAL_SETTINGS_ALLOWLIST.add(Settings.Global.WIFI_SLEEP_POLICY); + GLOBAL_SETTINGS_ALLOWLIST.add(Settings.Global.STAY_ON_WHILE_PLUGGED_IN); + GLOBAL_SETTINGS_ALLOWLIST.add(Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN); + GLOBAL_SETTINGS_ALLOWLIST.add(Settings.Global.PRIVATE_DNS_MODE); + GLOBAL_SETTINGS_ALLOWLIST.add(Settings.Global.PRIVATE_DNS_SPECIFIER); GLOBAL_SETTINGS_DEPRECATED = new ArraySet<>(); GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.BLUETOOTH_ON); @@ -520,11 +520,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.NETWORK_PREFERENCE); GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.WIFI_ON); - SYSTEM_SETTINGS_WHITELIST = new ArraySet<>(); - SYSTEM_SETTINGS_WHITELIST.add(Settings.System.SCREEN_BRIGHTNESS); - SYSTEM_SETTINGS_WHITELIST.add(Settings.System.SCREEN_BRIGHTNESS_FLOAT); - SYSTEM_SETTINGS_WHITELIST.add(Settings.System.SCREEN_BRIGHTNESS_MODE); - SYSTEM_SETTINGS_WHITELIST.add(Settings.System.SCREEN_OFF_TIMEOUT); + SYSTEM_SETTINGS_ALLOWLIST = new ArraySet<>(); + SYSTEM_SETTINGS_ALLOWLIST.add(Settings.System.SCREEN_BRIGHTNESS); + SYSTEM_SETTINGS_ALLOWLIST.add(Settings.System.SCREEN_BRIGHTNESS_FLOAT); + SYSTEM_SETTINGS_ALLOWLIST.add(Settings.System.SCREEN_BRIGHTNESS_MODE); + SYSTEM_SETTINGS_ALLOWLIST.add(Settings.System.SCREEN_OFF_TIMEOUT); DA_DISALLOWED_POLICIES = new ArraySet<>(); DA_DISALLOWED_POLICIES.add(DeviceAdminInfo.USES_POLICY_DISABLE_CAMERA); @@ -1231,13 +1231,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { String startUserSessionMessage = null; String endUserSessionMessage = null; - // The whitelist of packages that can access cross profile calendar APIs. - // This whitelist should be in default an empty list, which indicates that no package - // is whitelisted. + // The allowlist of packages that can access cross profile calendar APIs. + // This allowlist should be in default an empty list, which indicates that no package + // is allowed. List<String> mCrossProfileCalendarPackages = Collections.emptyList(); - // The whitelist of packages that the admin has enabled to be able to request consent from - // the user to communicate cross-profile. By default, no packages are whitelisted, which is + // The allowlist of packages that the admin has enabled to be able to request consent from + // the user to communicate cross-profile. By default, no packages are allowed, which is // represented as an empty list. List<String> mCrossProfilePackages = Collections.emptyList(); @@ -2818,7 +2818,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final IIntentSender.Stub mLocalSender = new IIntentSender.Stub() { @Override - public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken, + public void send(int code, Intent intent, String resolvedType, IBinder allowlistToken, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { final int status = intent.getIntExtra( PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE); @@ -7067,7 +7067,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { */ @Override public boolean setAlwaysOnVpnPackage(ComponentName who, String vpnPackage, boolean lockdown, - List<String> lockdownWhitelist) + List<String> lockdownAllowlist) throws SecurityException { enforceProfileOrDeviceOwner(who); @@ -7079,10 +7079,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { DevicePolicyManager.ERROR_VPN_PACKAGE_NOT_FOUND, vpnPackage); } - if (vpnPackage != null && lockdown && lockdownWhitelist != null) { - for (String packageName : lockdownWhitelist) { + if (vpnPackage != null && lockdown && lockdownAllowlist != null) { + for (String packageName : lockdownAllowlist) { if (!isPackageInstalledForUser(packageName, userId)) { - Slog.w(LOG_TAG, "Non-existent package in VPN whitelist: " + packageName); + Slog.w(LOG_TAG, "Non-existent package in VPN allowlist: " + packageName); throw new ServiceSpecificException( DevicePolicyManager.ERROR_VPN_PACKAGE_NOT_FOUND, packageName); } @@ -7090,7 +7090,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } // If some package is uninstalled after the check above, it will be ignored by CM. if (!mInjector.getConnectivityManager().setAlwaysOnVpnPackageForUser( - userId, vpnPackage, lockdown, lockdownWhitelist)) { + userId, vpnPackage, lockdown, lockdownAllowlist)) { throw new UnsupportedOperationException(); } DevicePolicyEventLogger @@ -7098,7 +7098,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { .setAdmin(who) .setStrings(vpnPackage) .setBoolean(lockdown) - .setInt(lockdownWhitelist != null ? lockdownWhitelist.size() : 0) + .setInt(lockdownAllowlist != null ? lockdownAllowlist.size() : 0) .write(); }); synchronized (getLockObject()) { @@ -7151,7 +7151,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } @Override - public List<String> getAlwaysOnVpnLockdownWhitelist(ComponentName admin) + public List<String> getAlwaysOnVpnLockdownAllowlist(ComponentName admin) throws SecurityException { enforceProfileOrDeviceOwner(admin); @@ -11911,7 +11911,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return; } - if (!GLOBAL_SETTINGS_WHITELIST.contains(setting) + if (!GLOBAL_SETTINGS_ALLOWLIST.contains(setting) && !UserManager.isDeviceInDemoMode(mContext)) { throw new SecurityException(String.format( "Permission denial: device owners cannot update %1$s", setting)); @@ -11939,7 +11939,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { synchronized (getLockObject()) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); - if (!SYSTEM_SETTINGS_WHITELIST.contains(setting)) { + if (!SYSTEM_SETTINGS_ALLOWLIST.contains(setting)) { throw new SecurityException(String.format( "Permission denial: device owners cannot update %1$s", setting)); } @@ -12083,12 +12083,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (isDeviceOwner(who, callingUserId)) { - if (!SECURE_SETTINGS_DEVICEOWNER_WHITELIST.contains(setting) + if (!SECURE_SETTINGS_DEVICEOWNER_ALLOWLIST.contains(setting) && !isCurrentUserDemo()) { throw new SecurityException(String.format( "Permission denial: Device owners cannot update %1$s", setting)); } - } else if (!SECURE_SETTINGS_WHITELIST.contains(setting) && !isCurrentUserDemo()) { + } else if (!SECURE_SETTINGS_ALLOWLIST.contains(setting) && !isCurrentUserDemo()) { throw new SecurityException(String.format( "Permission denial: Profile owners cannot update %1$s", setting)); } @@ -13859,7 +13859,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void markProfileOwnerOnOrganizationOwnedDevice(ComponentName who, int userId) { // As the caller is the system, it must specify the component name of the profile owner - // as a sanity / safety check. + // as a safety check. Objects.requireNonNull(who); if (!mHasFeature) { @@ -13895,7 +13895,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @GuardedBy("getLockObject()") private void markProfileOwnerOnOrganizationOwnedDeviceUncheckedLocked( ComponentName who, int userId) { - // Sanity check: Make sure that the user has a profile owner and that the specified + // Make sure that the user has a profile owner and that the specified // component is the profile owner of that user. if (!isProfileOwner(who, userId)) { throw new IllegalArgumentException(String.format( diff --git a/services/net/java/android/net/TcpKeepalivePacketData.java b/services/net/java/android/net/TcpKeepalivePacketData.java index c0c386b3046e..4875c7cc4263 100644 --- a/services/net/java/android/net/TcpKeepalivePacketData.java +++ b/services/net/java/android/net/TcpKeepalivePacketData.java @@ -19,11 +19,12 @@ import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS; import android.annotation.NonNull; import android.annotation.Nullable; -import android.net.util.IpUtils; import android.os.Parcel; import android.os.Parcelable; import android.system.OsConstants; +import com.android.net.module.util.IpUtils; + import java.net.InetAddress; import java.net.UnknownHostException; import java.nio.ByteBuffer; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java index 4dc8ad9d0a98..a118e0df1338 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java @@ -2670,6 +2670,96 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test + public void testLockChannelsForOEM_onlyGivenPkg_appDoesNotExistYet() { + mHelper.lockChannelsForOEM(new String[] {PKG_O}); + + NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); + NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW); + mHelper.createNotificationChannel(PKG_O, 3, a, true, false); + mHelper.createNotificationChannel(PKG_N_MR1, 30, b, false, false); + + assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false) + .isImportanceLockedByOEM()); + assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 30, b.getId(), false) + .isImportanceLockedByOEM()); + } + + @Test + public void testLockChannelsForOEM_channelSpecific_appDoesNotExistYet() { + mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"}); + + NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); + NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW); + NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT); + // different uids, same package + mHelper.createNotificationChannel(PKG_O, 3, a, true, false); + mHelper.createNotificationChannel(PKG_O, 3, b, false, false); + mHelper.createNotificationChannel(PKG_O, 30, c, true, true); + + assertFalse(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false) + .isImportanceLockedByOEM()); + assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false) + .isImportanceLockedByOEM()); + assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false) + .isImportanceLockedByOEM()); + } + + @Test + public void testLockChannelsForOEM_onlyGivenPkg_appDoesNotExistYet_restoreData() + throws Exception { + mHelper.lockChannelsForOEM(new String[] {PKG_O}); + + final String xml = "<ranking version=\"1\">\n" + + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n" + + "<channel id=\"a\" name=\"a\" importance=\"3\"/>" + + "<channel id=\"b\" name=\"b\" importance=\"3\"/>" + + "</package>" + + "<package name=\"" + PKG_N_MR1 + "\" uid=\"" + UID_N_MR1 + "\" >\n" + + "<channel id=\"a\" name=\"a\" importance=\"3\"/>" + + "<channel id=\"b\" name=\"b\" importance=\"3\"/>" + + "</package>" + + "</ranking>"; + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())), + null); + parser.nextTag(); + mHelper.readXml(parser, false, UserHandle.USER_ALL); + + assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, "a", false) + .isImportanceLockedByOEM()); + assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "b", false) + .isImportanceLockedByOEM()); + } + + @Test + public void testLockChannelsForOEM_channelSpecific_appDoesNotExistYet_restoreData() + throws Exception { + mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"}); + + final String xml = "<ranking version=\"1\">\n" + + "<package name=\"" + PKG_O + "\" uid=\"" + 3 + "\" >\n" + + "<channel id=\"a\" name=\"a\" importance=\"3\"/>" + + "<channel id=\"b\" name=\"b\" importance=\"3\"/>" + + "</package>" + + "<package name=\"" + PKG_O + "\" uid=\"" + 30 + "\" >\n" + + "<channel id=\"c\" name=\"c\" importance=\"3\"/>" + + "</package>" + + "</ranking>"; + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())), + null); + parser.nextTag(); + mHelper.readXml(parser, false, UserHandle.USER_ALL); + + assertFalse(mHelper.getNotificationChannel(PKG_O, 3, "a", false) + .isImportanceLockedByOEM()); + assertTrue(mHelper.getNotificationChannel(PKG_O, 3, "b", false) + .isImportanceLockedByOEM()); + assertTrue(mHelper.getNotificationChannel(PKG_O, 30, "c", false) + .isImportanceLockedByOEM()); + } + + @Test public void testLockChannelsForOEM_channelSpecific_clearData() { NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); mHelper.getImportance(PKG_O, UID_O); diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index b406da3c9ba9..9f16543c410e 100755 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -2137,7 +2137,13 @@ public final class Call { /** * Obtains a list of canned, pre-configured message responses to present to the user as - * ways of rejecting this {@code Call} using via a text message. + * ways of rejecting an incoming {@code Call} using via a text message. + * <p> + * <em>Note:</em> Since canned responses may be loaded from the file system, they are not + * guaranteed to be present when this {@link Call} is first added to the {@link InCallService} + * via {@link InCallService#onCallAdded(Call)}. The callback + * {@link Call.Callback#onCannedTextResponsesLoaded(Call, List)} will be called when/if canned + * responses for the call become available. * * @see #reject(boolean, String) * diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java index 4d9311c282f7..49f183151e27 100644 --- a/telecomm/java/android/telecom/CallScreeningService.java +++ b/telecomm/java/android/telecom/CallScreeningService.java @@ -64,7 +64,7 @@ import com.android.internal.telecom.ICallScreeningService; * </li> * </ol> * <p> - * <h2>Becoming the {@link CallScreeningService}</h2> + * <h2>Becoming the CallScreeningService</h2> * Telecom will bind to a single app chosen by the user which implements the * {@link CallScreeningService} API when there are new incoming and outgoing calls. * <p> @@ -90,7 +90,27 @@ import com.android.internal.telecom.ICallScreeningService; * } * } * } + * } * </pre> + * + * <h2>CallScreeningService Lifecycle</h2> + * + * The framework binds to the {@link CallScreeningService} implemented by the user-chosen app + * filling the {@link android.app.role.RoleManager#ROLE_CALL_SCREENING} role when incoming calls are + * received (prior to ringing) and when outgoing calls are placed. The platform calls the + * {@link #onScreenCall(Call.Details)} method to provide your service with details about the call. + * <p> + * For incoming calls, the {@link CallScreeningService} must call + * {@link #respondToCall(Call.Details, CallResponse)} within 5 seconds of being bound to indicate to + * the platform whether the call should be blocked or not. Your app must do this even if it is + * primarily performing caller ID operations and not screening calls. It is important to perform + * screening operations in a timely matter as the user's device will not begin ringing until the + * response is received (or the timeout is hit). A {@link CallScreeningService} may choose to + * perform local database lookups to help determine if a call should be screened or not; care should + * be taken to ensure the timeout is not repeatedly hit, causing delays in the incoming call flow. + * <p> + * If your app provides a caller ID experience, it should launch an activity to show the caller ID + * information from {@link #onScreenCall(Call.Details)}. */ public abstract class CallScreeningService extends Service { /** @@ -339,7 +359,7 @@ public abstract class CallScreeningService extends Service { } /** - * Called when a new incoming or outgoing call is added which is not in the user's contact list. + * Called when a new incoming or outgoing call is added. * <p> * A {@link CallScreeningService} must indicate whether an incoming call is allowed or not by * calling @@ -347,21 +367,32 @@ public abstract class CallScreeningService extends Service { * Your app can tell if a call is an incoming call by checking to see if * {@link Call.Details#getCallDirection()} is {@link Call.Details#DIRECTION_INCOMING}. * <p> - * Note: The {@link Call.Details} instance provided to a call screening service will only have - * the following properties set. The rest of the {@link Call.Details} properties will be set to - * their default value or {@code null}. + * <em>Note:</em> A {@link CallScreeningService} must respond to a call within 5 seconds. After + * this time, the framework will unbind from the {@link CallScreeningService} and ignore its + * response. + * <p> + * <em>Note:</em> The {@link Call.Details} instance provided to a call screening service will + * only have the following properties set. The rest of the {@link Call.Details} properties will + * be set to their default value or {@code null}. * <ul> * <li>{@link Call.Details#getCallDirection()}</li> + * <li>{@link Call.Details#getCallerNumberVerificationStatus()}</li> * <li>{@link Call.Details#getConnectTimeMillis()}</li> * <li>{@link Call.Details#getCreationTimeMillis()}</li> * <li>{@link Call.Details#getHandle()}</li> - * <li>{@link Call.Details#getHandlePresentation()}</li> * </ul> * <p> * Only calls where the {@link Call.Details#getHandle() handle} {@link Uri#getScheme() scheme} * is {@link PhoneAccount#SCHEME_TEL} are passed for call * screening. Further, only calls which are not in the user's contacts are passed for - * screening. For outgoing calls, no post-dial digits are passed. + * screening, unless the {@link CallScreeningService} has been granted + * {@link Manifest.permission#READ_CONTACTS} permission by the user. For outgoing calls, no + * post-dial digits are passed. + * <p> + * Calls with a {@link Call.Details#getHandlePresentation()} of + * {@link TelecomManager#PRESENTATION_RESTRICTED}, {@link TelecomManager#PRESENTATION_UNKNOWN} + * or {@link TelecomManager#PRESENTATION_PAYPHONE} presentation are not provided to the + * {@link CallScreeningService}. * * @param callDetails Information about a new call, see {@link Call.Details}. */ @@ -376,6 +407,13 @@ public abstract class CallScreeningService extends Service { * <p> * Calls to this method are ignored unless the {@link Call.Details#getCallDirection()} is * {@link Call.Details#DIRECTION_INCOMING}. + * <p> + * For incoming calls, a {@link CallScreeningService} MUST call this method within 5 seconds of + * {@link #onScreenCall(Call.Details)} being invoked by the platform. + * <p> + * Calls which are blocked/rejected will be logged to the system call log with a call type of + * {@link android.provider.CallLog.Calls#BLOCKED_TYPE} and + * {@link android.provider.CallLog.Calls#BLOCK_REASON_CALL_SCREENING_SERVICE} block reason. * * @param callDetails The call to allow. * <p> diff --git a/telephony/java/android/telephony/BinderCacheManager.java b/telephony/java/android/telephony/BinderCacheManager.java new file mode 100644 index 000000000000..0d3e2fe7591c --- /dev/null +++ b/telephony/java/android/telephony/BinderCacheManager.java @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony; + +import android.annotation.NonNull; +import android.os.IBinder; +import android.os.IInterface; +import android.os.RemoteException; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.NoSuchElementException; +import java.util.concurrent.atomic.AtomicReference; + +/** + * Keeps track of the connection to a Binder node, refreshes the cache if the node dies, and lets + * interested parties register listeners on the node to be notified when the node has died via the + * registered {@link Runnable}. + * @param <T> The IInterface representing the Binder type that this manager will be managing the + * cache of. + * @hide + */ +public class BinderCacheManager<T extends IInterface> { + + /** + * Factory class for creating new IInterfaces in the case that {@link #getBinder()} is + * called and there is no active binder available. + * @param <T> The IInterface that should be cached and returned to the caller when + * {@link #getBinder()} is called until the Binder node dies. + */ + public interface BinderInterfaceFactory<T> { + /** + * @return A new instance of the Binder node, which will be cached until it dies. + */ + T create(); + } + + /** + * Tracks the cached Binder node as well as the listeners that were associated with that + * Binder node during its lifetime. If the Binder node dies, the listeners will be called and + * then this tracker will be unlinked and cleaned up. + */ + private class BinderDeathTracker implements IBinder.DeathRecipient { + + private final T mConnection; + private final HashMap<Object, Runnable> mListeners = new HashMap<>(); + + /** + * Create a tracker to cache the Binder node and add the ability to listen for the cached + * interface's death. + */ + BinderDeathTracker(@NonNull T connection) { + mConnection = connection; + try { + mConnection.asBinder().linkToDeath(this, 0 /*flags*/); + } catch (RemoteException e) { + // isAlive will return false. + } + } + + public boolean addListener(Object key, Runnable r) { + synchronized (mListeners) { + if (!isAlive()) return false; + mListeners.put(key, r); + return true; + } + } + + public void removeListener(Object runnableKey) { + synchronized (mListeners) { + mListeners.remove(runnableKey); + } + } + + @Override + public void binderDied() { + ArrayList<Runnable> listeners; + synchronized (mListeners) { + listeners = new ArrayList<>(mListeners.values()); + mListeners.clear(); + try { + mConnection.asBinder().unlinkToDeath(this, 0 /*flags*/); + } catch (NoSuchElementException e) { + // No need to worry about this, this means the death recipient was never linked. + } + } + listeners.forEach(Runnable::run); + } + + /** + * @return The cached Binder. + */ + public T getConnection() { + return mConnection; + } + + /** + * @return true if the cached Binder is alive at the time of calling, false otherwise. + */ + public boolean isAlive() { + return mConnection.asBinder().isBinderAlive(); + } + } + + private final BinderInterfaceFactory<T> mBinderInterfaceFactory; + private final AtomicReference<BinderDeathTracker> mCachedConnection; + + /** + * Create a new instance, which manages a cached IInterface and creates new ones using the + * provided factory when the cached IInterface dies. + * @param factory The factory used to create new Instances of the cached IInterface when it + * dies. + */ + public BinderCacheManager(BinderInterfaceFactory<T> factory) { + mBinderInterfaceFactory = factory; + mCachedConnection = new AtomicReference<>(); + } + + /** + * Get the binder node connection and add a Runnable to be run if this Binder dies. Once this + * Runnable is run, the Runnable itself is discarded and must be added again. + * <p> + * Note: There should be no assumptions here as to which Thread this Runnable is called on. If + * the Runnable should be called on a specific thread, it should be up to the caller to handle + * that in the runnable implementation. + * @param runnableKey The Key associated with this runnable so that it can be removed later + * using {@link #removeRunnable(Object)} if needed. + * @param deadRunnable The runnable that will be run if the cached Binder node dies. + * @return T if the runnable was added or {@code null} if the connection is not alive right now + * and the associated runnable was never added. + */ + public T listenOnBinder(Object runnableKey, Runnable deadRunnable) { + if (runnableKey == null || deadRunnable == null) return null; + BinderDeathTracker tracker = getTracker(); + if (tracker == null) return null; + + boolean addSucceeded = tracker.addListener(runnableKey, deadRunnable); + return addSucceeded ? tracker.getConnection() : null; + } + + /** + * @return The cached Binder node. May return null if the requested Binder node is not currently + * available. + */ + public T getBinder() { + BinderDeathTracker tracker = getTracker(); + return (tracker != null) ? tracker.getConnection() : null; + } + + /** + * Removes a previously registered runnable associated with the returned cached Binder node + * using the key it was registered with in {@link #listenOnBinder} if the runnable still exists. + * @param runnableKey The key that was used to register the Runnable earlier. + * @return The cached Binder node that the runnable used to registered to or null if the cached + * Binder node is not alive anymore. + */ + public T removeRunnable(Object runnableKey) { + if (runnableKey == null) return null; + BinderDeathTracker tracker = getTracker(); + if (tracker == null) return null; + tracker.removeListener(runnableKey); + return tracker.getConnection(); + } + + /** + * @return The BinderDeathTracker container, which contains the cached IInterface instance or + * null if it is not available right now. + */ + private BinderDeathTracker getTracker() { + return mCachedConnection.updateAndGet((oldVal) -> { + BinderDeathTracker tracker = oldVal; + // Update cache if no longer alive. BinderDied will eventually be called on the tracker, + // which will call listeners & clean up. + if (tracker == null || !tracker.isAlive()) { + T binder = mBinderInterfaceFactory.create(); + tracker = (binder != null) ? new BinderDeathTracker(binder) : null; + + } + return (tracker != null && tracker.isAlive()) ? tracker : null; + }); + } + +} diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index d6ce40c24b78..af49dc4bb9b3 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -2091,17 +2091,25 @@ public final class SmsManager { } /** - * Gets the total capacity of SMS storage on RUIM and SIM cards - * <p> - * This is the number of 176 byte EF-SMS records which can be stored on the RUIM or SIM card. + * Gets the total capacity of SMS storage on the SIM card. + * * <p> - * See 3GPP TS 31.102 - 4.2.25 - EF-SMS for more information + * This is the number of 176 byte EF-SMS records which can be stored on the SIM card. + * See 3GPP TS 31.102 - 4.2.25 - EF-SMS for more information. + * </p> * - * @return the total number of SMS records which can be stored on the RUIM or SIM cards. - * @hide + * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation + * dialog. If this method is called on a device that has multiple active subscriptions, this + * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined + * default subscription is defined, the subscription ID associated with this method will be + * INVALID, which will result in the operation being completed on the subscription associated + * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation + * is performed on the correct subscription. + * </p> + * + * @return the total number of SMS records which can be stored on the SIM card. */ - @SystemApi - @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int getSmsCapacityOnIcc() { int ret = 0; try { @@ -2110,7 +2118,7 @@ public final class SmsManager { ret = iccISms.getSmsCapacityOnIccForSubscriber(getSubscriptionId()); } } catch (RemoteException ex) { - //ignore it + throw new RuntimeException(ex); } return ret; } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 66eadb5f71e0..26b669a70cf8 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -85,8 +85,6 @@ import android.telephony.emergency.EmergencyNumber; import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories; import android.telephony.ims.ImsMmTelManager; import android.telephony.ims.aidl.IImsConfig; -import android.telephony.ims.aidl.IImsMmTelFeature; -import android.telephony.ims.aidl.IImsRcsFeature; import android.telephony.ims.aidl.IImsRegistration; import android.telephony.ims.feature.MmTelFeature; import android.telephony.ims.stub.ImsRegistrationImplBase; @@ -94,7 +92,6 @@ import android.text.TextUtils; import android.util.Log; import android.util.Pair; -import com.android.ims.internal.IImsServiceFeatureCallback; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.CellNetworkScanResult; @@ -7309,80 +7306,6 @@ public class TelephonyManager { } /** - * Returns the {@link IImsMmTelFeature} that corresponds to the given slot Id and MMTel - * feature or {@link null} if the service is not available. If an MMTelFeature is available, the - * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates. - * @param slotIndex The SIM slot that we are requesting the {@link IImsMmTelFeature} for. - * @param callback Listener that will send updates to ImsManager when there are updates to - * ImsServiceController. - * @return {@link IImsMmTelFeature} interface for the feature specified or {@code null} if - * it is unavailable. - * @hide - */ - public @Nullable IImsMmTelFeature getImsMmTelFeatureAndListen(int slotIndex, - IImsServiceFeatureCallback callback) { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) { - return telephony.getMmTelFeatureAndListen(slotIndex, callback); - } - } catch (RemoteException e) { - Rlog.e(TAG, "getImsMmTelFeatureAndListen, RemoteException: " - + e.getMessage()); - } - return null; - } - - /** - * Returns the {@link IImsRcsFeature} that corresponds to the given slot Id and RCS - * feature for emergency calling or {@link null} if the service is not available. If an - * RcsFeature is available, the {@link IImsServiceFeatureCallback} callback is registered as a - * listener for feature updates. - * @param slotIndex The SIM slot that we are requesting the {@link IImsRcsFeature} for. - * @param callback Listener that will send updates to ImsManager when there are updates to - * ImsServiceController. - * @return {@link IImsRcsFeature} interface for the feature specified or {@code null} if - * it is unavailable. - * @hide - */ - public @Nullable IImsRcsFeature getImsRcsFeatureAndListen(int slotIndex, - IImsServiceFeatureCallback callback) { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) { - return telephony.getRcsFeatureAndListen(slotIndex, callback); - } - } catch (RemoteException e) { - Rlog.e(TAG, "getImsRcsFeatureAndListen, RemoteException: " - + e.getMessage()); - } - return null; - } - - /** - * Unregister a IImsServiceFeatureCallback previously associated with an ImsFeature through - * {@link #getImsMmTelFeatureAndListen(int, IImsServiceFeatureCallback)} or - * {@link #getImsRcsFeatureAndListen(int, IImsServiceFeatureCallback)}. - * @param slotIndex The SIM slot associated with the callback. - * @param featureType The {@link android.telephony.ims.feature.ImsFeature.FeatureType} - * associated with the callback. - * @param callback The callback to be unregistered. - * @hide - */ - public void unregisterImsFeatureCallback(int slotIndex, int featureType, - IImsServiceFeatureCallback callback) { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) { - telephony.unregisterImsFeatureCallback(slotIndex, featureType, callback); - } - } catch (RemoteException e) { - Rlog.e(TAG, "unregisterImsFeatureCallback, RemoteException: " - + e.getMessage()); - } - } - - /** * @return the {@IImsRegistration} interface that corresponds with the slot index and feature. * @param slotIndex The SIM slot corresponding to the ImsService ImsRegistration is active for. * @param feature An integer indicating the feature that we wish to get the ImsRegistration for. diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java index f6c14e67306b..ee2fce7e7dd5 100644 --- a/telephony/java/android/telephony/ims/ImsMmTelManager.java +++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java @@ -59,6 +59,7 @@ import java.util.function.Consumer; * manager. */ public class ImsMmTelManager implements RegistrationManager { + private static final String TAG = "ImsMmTelManager"; /** * @hide @@ -809,7 +810,7 @@ public class ImsMmTelManager implements RegistrationManager { } try { - getITelephony().isMmTelCapabilitySupported(mSubId, new IIntegerConsumer.Stub() { + iTelephony.isMmTelCapabilitySupported(mSubId, new IIntegerConsumer.Stub() { @Override public void accept(int result) { executor.execute(() -> callback.accept(result == 1)); diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java index da7311c08307..8a05bdfc8401 100644 --- a/telephony/java/android/telephony/ims/ImsService.java +++ b/telephony/java/android/telephony/ims/ImsService.java @@ -16,6 +16,7 @@ package android.telephony.ims; +import android.annotation.LongDef; import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.Service; @@ -41,6 +42,11 @@ import android.util.SparseArray; import com.android.ims.internal.IImsFeatureStatusCallback; import com.android.internal.annotations.VisibleForTesting; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.HashMap; +import java.util.Map; + /** * Main ImsService implementation, which binds via the Telephony ImsResolver. Services that extend * ImsService must register the service in their AndroidManifest to be detected by the framework. @@ -98,6 +104,32 @@ public class ImsService extends Service { private static final String LOG_TAG = "ImsService"; /** + * This ImsService supports the capability to place emergency calls over MMTEL. + * @hide This is encoded into the {@link ImsFeature#FEATURE_EMERGENCY_MMTEL}, but we will be + * adding other capabilities in a central location, so track this capability here as well. + */ + public static final long CAPABILITY_EMERGENCY_OVER_MMTEL = 1 << 0; + + /** + * @hide + */ + @LongDef(flag = true, + prefix = "CAPABILITY_", + value = { + CAPABILITY_EMERGENCY_OVER_MMTEL + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ImsServiceCapability {} + + /** + * Used for logging purposes, see {@link #getCapabilitiesString(long)} + * @hide + */ + private static final Map<Long, String> CAPABILITIES_LOG_MAP = new HashMap<Long, String>() {{ + put(CAPABILITY_EMERGENCY_OVER_MMTEL, "EMERGENCY_OVER_MMTEL"); + }}; + + /** * The intent that must be defined as an intent-filter in the AndroidManifest of the ImsService. * @hide */ @@ -409,4 +441,30 @@ public class ImsService extends Service { public ImsRegistrationImplBase getRegistration(int slotId) { return new ImsRegistrationImplBase(); } + + /** + * @return A string representation of the ImsService capabilties for logging. + * @hide + */ + public static String getCapabilitiesString(@ImsServiceCapability long caps) { + StringBuffer result = new StringBuffer(); + result.append("capabilities={ "); + // filter incrementally fills 0s from left to right. This is used to keep filtering out + // more bits in the long until the remaining leftmost bits are all zero. + long filter = 0xFFFFFFFFFFFFFFFFL; + // position of iterator to potentially print capability. + long i = 0; + while ((caps & filter) != 0 && i <= 63) { + long bitToCheck = (1L << i); + if ((caps & bitToCheck) != 0) { + result.append(CAPABILITIES_LOG_MAP.getOrDefault(bitToCheck, bitToCheck + "?")); + result.append(" "); + } + // shift left by one and fill in another 1 on the leftmost bit. + filter <<= 1; + i++; + } + result.append("}"); + return result.toString(); + } }
\ No newline at end of file diff --git a/telephony/java/android/telephony/ims/aidl/IImsMmTelListener.aidl b/telephony/java/android/telephony/ims/aidl/IImsMmTelListener.aidl index 7bbe30a444b9..52464703c608 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsMmTelListener.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsMmTelListener.aidl @@ -27,8 +27,11 @@ import com.android.ims.internal.IImsCallSession; * See MmTelFeature#Listener for more information. * {@hide} */ -oneway interface IImsMmTelListener { + // This interface is not considered oneway because we need to ensure that these operations are + // processed by telephony before the control flow returns to the ImsService to perform + // operations on the IImsCallSession. +interface IImsMmTelListener { void onIncomingCall(IImsCallSession c, in Bundle extras); void onRejectedCall(in ImsCallProfile callProfile, in ImsReasonInfo reason); - void onVoiceMessageCountUpdate(int count); + oneway void onVoiceMessageCountUpdate(int count); } diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl index 9e461420e126..e01ea9179452 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl @@ -22,6 +22,8 @@ import android.telephony.ims.aidl.IRcsUceControllerCallback; import android.telephony.ims.aidl.IRcsUcePublishStateCallback; import android.telephony.ims.aidl.IImsRegistrationCallback; +import com.android.ims.ImsFeatureContainer; +import com.android.ims.internal.IImsServiceFeatureCallback; import com.android.internal.telephony.IIntegerConsumer; /** @@ -50,4 +52,8 @@ interface IImsRcsController { void setUceSettingEnabled(int subId, boolean isEnabled); void registerUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c); void unregisterUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c); + + // Internal commands that should not be made public + void registerRcsFeatureCallback(int slotId, in IImsServiceFeatureCallback callback); + void unregisterImsFeatureCallback(in IImsServiceFeatureCallback callback); } diff --git a/telephony/java/com/android/ims/ImsFeatureContainer.aidl b/telephony/java/com/android/ims/ImsFeatureContainer.aidl new file mode 100644 index 000000000000..9706f20c59ca --- /dev/null +++ b/telephony/java/com/android/ims/ImsFeatureContainer.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims; + +parcelable ImsFeatureContainer;
\ No newline at end of file diff --git a/telephony/java/com/android/ims/ImsFeatureContainer.java b/telephony/java/com/android/ims/ImsFeatureContainer.java new file mode 100644 index 000000000000..b259679ea1bf --- /dev/null +++ b/telephony/java/com/android/ims/ImsFeatureContainer.java @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims; + +import android.annotation.NonNull; +import android.os.IBinder; +import android.os.Parcel; +import android.os.Parcelable; +import android.telephony.ims.ImsService; +import android.telephony.ims.aidl.IImsConfig; +import android.telephony.ims.aidl.IImsRegistration; +import android.telephony.ims.feature.ImsFeature; + +import java.util.Objects; + +/** + * Contains an IBinder linking to the appropriate ImsFeature as well as the associated + * interfaces. + * @hide + */ +public final class ImsFeatureContainer implements Parcelable { + /** + * ImsFeature that is being tracked. + */ + public final IBinder imsFeature; + + /** + * IImsConfig interface that should be associated with the ImsFeature. + */ + public final android.telephony.ims.aidl.IImsConfig imsConfig; + + /** + * IImsRegistration interface that should be associated with this ImsFeature. + */ + public final IImsRegistration imsRegistration; + + /** + * State of the feature that is being tracked. + */ + private @ImsFeature.ImsState int mState = ImsFeature.STATE_UNAVAILABLE; + + /** + * Capabilities of this ImsService. + */ + private @ImsService.ImsServiceCapability long mCapabilities; + /** + * Contains the ImsFeature IBinder as well as the ImsService interfaces associated with + * that feature. + * @param iFace IBinder connection to the ImsFeature. + * @param iConfig IImsConfig interface associated with the ImsFeature. + * @param iReg IImsRegistration interface associated with the ImsFeature + * @param initialCaps The initial capabilities that the ImsService supports. + */ + public ImsFeatureContainer(@NonNull IBinder iFace, @NonNull IImsConfig iConfig, + @NonNull IImsRegistration iReg, long initialCaps) { + imsFeature = iFace; + imsConfig = iConfig; + imsRegistration = iReg; + mCapabilities = initialCaps; + } + + /** + * Create an ImsFeatureContainer from a Parcel. + */ + private ImsFeatureContainer(Parcel in) { + imsFeature = in.readStrongBinder(); + imsConfig = IImsConfig.Stub.asInterface(in.readStrongBinder()); + imsRegistration = IImsRegistration.Stub.asInterface(in.readStrongBinder()); + mState = in.readInt(); + mCapabilities = in.readLong(); + } + + /** + * @return the capabilties that are associated with the ImsService that this ImsFeature + * belongs to. + */ + public @ImsService.ImsServiceCapability long getCapabilities() { + return mCapabilities; + } + + /** + * Update the capabilities that are associated with the ImsService that this ImsFeature + * belongs to. + */ + public void setCapabilities(@ImsService.ImsServiceCapability long caps) { + mCapabilities = caps; + } + + /** + * @return The state of the ImsFeature. + */ + public @ImsFeature.ImsState int getState() { + return mState; + } + + /** + * Set the state that is associated with the ImsService that this ImsFeature + * belongs to. + */ + public void setState(@ImsFeature.ImsState int state) { + mState = state; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ImsFeatureContainer that = (ImsFeatureContainer) o; + return imsFeature.equals(that.imsFeature) && + imsConfig.equals(that.imsConfig) && + imsRegistration.equals(that.imsRegistration) && + mState == that.getState() && + mCapabilities == that.getCapabilities(); + } + + @Override + public int hashCode() { + return Objects.hash(imsFeature, imsConfig, imsRegistration, mState, mCapabilities); + } + + @Override + public String toString() { + return "FeatureContainer{" + + "imsFeature=" + imsFeature + + ", imsConfig=" + imsConfig + + ", imsRegistration=" + imsRegistration + + ", state=" + ImsFeature.STATE_LOG_MAP.get(mState) + + ", capabilities = " + ImsService.getCapabilitiesString(mCapabilities) + + '}'; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeStrongBinder(imsFeature); + dest.writeStrongInterface(imsConfig); + dest.writeStrongInterface(imsRegistration); + dest.writeInt(mState); + dest.writeLong(mCapabilities); + } + + + public static final Creator<ImsFeatureContainer> CREATOR = new Creator<ImsFeatureContainer>() { + @Override + public ImsFeatureContainer createFromParcel(Parcel source) { + return new ImsFeatureContainer(source); + } + + @Override + public ImsFeatureContainer[] newArray(int size) { + return new ImsFeatureContainer[size]; + } + }; +} diff --git a/telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl b/telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl index 9a9cf5325310..f5f67bd36ec3 100644 --- a/telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl +++ b/telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl @@ -16,13 +16,18 @@ package com.android.ims.internal; +import com.android.ims.ImsFeatureContainer; /** - * Interface from ImsResolver to ImsServiceProxy in ImsManager. - * Callback to ImsManager when a feature changes in the ImsServiceController. + * Interface from ImsResolver to FeatureConnections. + * Callback to FeatureConnections when a feature's status changes. * {@hide} */ oneway interface IImsServiceFeatureCallback { - void imsFeatureCreated(int slotId, int feature); - void imsFeatureRemoved(int slotId, int feature); - void imsStatusChanged(int slotId, int feature, int status); + void imsFeatureCreated(in ImsFeatureContainer feature); + // Reason defined in FeatureConnector.UnavailableReason + void imsFeatureRemoved(int reason); + // Status defined in ImsFeature.ImsState. + void imsStatusChanged(int status); + //Capabilities defined in ImsService.ImsServiceCapability + void updateCapabilities(long capabilities); }
\ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 659d9cd38faf..934103ebe2b6 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -828,22 +828,14 @@ interface ITelephony { * as well as registering the MmTelFeature for callbacks using the IImsServiceFeatureCallback * interface. */ - IImsMmTelFeature getMmTelFeatureAndListen(int slotId, in IImsServiceFeatureCallback callback); - - /** - * Get IImsRcsFeature binder from ImsResolver that corresponds to the subId and RCS feature - * as well as registering the RcsFeature for callbacks using the IImsServiceFeatureCallback - * interface. - */ - IImsRcsFeature getRcsFeatureAndListen(int slotId, in IImsServiceFeatureCallback callback); + void registerMmTelFeatureCallback(int slotId, in IImsServiceFeatureCallback callback); /** * Unregister a callback that was previously registered through - * {@link #getMmTelFeatureAndListen} or {@link #getRcsFeatureAndListen}. This should always be - * called when the callback is no longer being used. + * {@link #registerMmTelFeatureCallback}. This should always be called when the callback is no + * longer being used. */ - void unregisterImsFeatureCallback(int slotId, int featureType, - in IImsServiceFeatureCallback callback); + void unregisterImsFeatureCallback(in IImsServiceFeatureCallback callback); /** * Returns the IImsRegistration associated with the slot and feature specified. diff --git a/tests/RollbackTest/Android.bp b/tests/RollbackTest/Android.bp index 2be4ae6bb214..a23df920b396 100644 --- a/tests/RollbackTest/Android.bp +++ b/tests/RollbackTest/Android.bp @@ -29,7 +29,12 @@ java_test_host { name: "StagedRollbackTest", srcs: ["StagedRollbackTest/src/**/*.java"], libs: ["tradefed"], - static_libs: ["testng", "compatibility-tradefed", "RollbackTestLib"], + static_libs: [ + "compatibility-tradefed", + "frameworks-base-hostutils", + "RollbackTestLib", + "testng", + ], test_suites: ["general-tests"], test_config: "StagedRollbackTest.xml", data: [":com.android.apex.apkrollback.test_v1"], @@ -39,7 +44,7 @@ java_test_host { name: "NetworkStagedRollbackTest", srcs: ["NetworkStagedRollbackTest/src/**/*.java"], libs: ["tradefed"], - static_libs: ["RollbackTestLib"], + static_libs: ["RollbackTestLib", "frameworks-base-hostutils"], test_suites: ["general-tests"], test_config: "NetworkStagedRollbackTest.xml", } diff --git a/tests/StagedInstallTest/Android.bp b/tests/StagedInstallTest/Android.bp index 1e286bb15c49..30f3f185203c 100644 --- a/tests/StagedInstallTest/Android.bp +++ b/tests/StagedInstallTest/Android.bp @@ -28,6 +28,7 @@ java_test_host { "testng", "compatibility-tradefed", "module_test_util", + "frameworks-base-hostutils", ], data: [ ":com.android.apex.cts.shim.v2_prebuilt", diff --git a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java index 86d5fd80c108..e259c9efbfcd 100644 --- a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java +++ b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeTrue; import com.android.ddmlib.Log; +import com.android.tests.rollback.host.AbandonSessionsRule; import com.android.tests.util.ModuleTestUtils; import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; @@ -29,6 +30,7 @@ import com.android.tradefed.util.ProcessInfo; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -39,7 +41,9 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test { private static final String TAG = StagedInstallInternalTest.class.getSimpleName(); private static final long SYSTEM_SERVER_TIMEOUT_MS = 60 * 1000; - private boolean mWasRoot = false; + + @Rule + public AbandonSessionsRule mHostTestRule = new AbandonSessionsRule(this); private static final String SHIM_V2 = "com.android.apex.cts.shim.v2.apex"; private static final String APK_A = "TestAppAv1.apk"; @@ -71,21 +75,11 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test { @Before public void setUp() throws Exception { - mWasRoot = getDevice().isAdbRoot(); - if (!mWasRoot) { - getDevice().enableAdbRoot(); - } cleanUp(); - // Abandon all staged sessions - getDevice().executeShellCommand("pm install-abandon $(pm get-stagedsessions --only-ready " - + "--only-parent --only-sessionid)"); } @After public void tearDown() throws Exception { - if (!mWasRoot) { - getDevice().disableAdbRoot(); - } cleanUp(); } @@ -150,8 +144,11 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test { private void restartSystemServer() throws Exception { // Restart the system server - long oldStartTime = getDevice().getProcessByName("system_server").getStartTime(); + final long oldStartTime = getDevice().getProcessByName("system_server").getStartTime(); + + getDevice().enableAdbRoot(); // Need root to restart system server assertThat(getDevice().executeShellCommand("am restart")).contains("Restart the system"); + getDevice().disableAdbRoot(); // Wait for new system server process to start long start = System.currentTimeMillis(); diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java index c895420157d7..85704d033634 100644 --- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java +++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java @@ -213,7 +213,7 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork { public void connect() { assertNotEquals("MockNetworkAgents can only be connected once", - getNetworkInfo().getDetailedState(), NetworkInfo.DetailedState.CONNECTED); + mNetworkInfo.getDetailedState(), NetworkInfo.DetailedState.CONNECTED); mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null); mNetworkAgent.sendNetworkInfo(mNetworkInfo); } @@ -268,10 +268,6 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork { return mNetworkAgent; } - public NetworkInfo getNetworkInfo() { - return mNetworkInfo; - } - public NetworkCapabilities getNetworkCapabilities() { return mNetworkCapabilities; } diff --git a/tests/net/java/android/net/util/IpUtilsTest.java b/tests/net/java/android/net/util/IpUtilsTest.java deleted file mode 100644 index 193d85d0013a..000000000000 --- a/tests/net/java/android/net/util/IpUtilsTest.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.util; - -import static org.junit.Assert.assertEquals; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.nio.ByteBuffer; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class IpUtilsTest { - - private static final int IPV4_HEADER_LENGTH = 20; - private static final int IPV6_HEADER_LENGTH = 40; - private static final int TCP_HEADER_LENGTH = 20; - private static final int UDP_HEADER_LENGTH = 8; - private static final int IP_CHECKSUM_OFFSET = 10; - private static final int TCP_CHECKSUM_OFFSET = 16; - private static final int UDP_CHECKSUM_OFFSET = 6; - - private int getUnsignedByte(ByteBuffer buf, int offset) { - return buf.get(offset) & 0xff; - } - - private int getChecksum(ByteBuffer buf, int offset) { - return getUnsignedByte(buf, offset) * 256 + getUnsignedByte(buf, offset + 1); - } - - private void assertChecksumEquals(int expected, short actual) { - assertEquals(Integer.toHexString(expected), Integer.toHexString(actual & 0xffff)); - } - - // Generate test packets using Python code like this:: - // - // from scapy import all as scapy - // - // def JavaPacketDefinition(bytes): - // out = " ByteBuffer packet = ByteBuffer.wrap(new byte[] {\n " - // for i in xrange(len(bytes)): - // out += "(byte) 0x%02x" % ord(bytes[i]) - // if i < len(bytes) - 1: - // if i % 4 == 3: - // out += ",\n " - // else: - // out += ", " - // out += "\n });" - // return out - // - // packet = (scapy.IPv6(src="2001:db8::1", dst="2001:db8::2") / - // scapy.UDP(sport=12345, dport=7) / - // "hello") - // print JavaPacketDefinition(str(packet)) - - @Test - public void testIpv6TcpChecksum() throws Exception { - // packet = (scapy.IPv6(src="2001:db8::1", dst="2001:db8::2", tc=0x80) / - // scapy.TCP(sport=12345, dport=7, - // seq=1692871236, ack=128376451, flags=16, - // window=32768) / - // "hello, world") - ByteBuffer packet = ByteBuffer.wrap(new byte[] { - (byte) 0x68, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x20, (byte) 0x06, (byte) 0x40, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, - (byte) 0x30, (byte) 0x39, (byte) 0x00, (byte) 0x07, - (byte) 0x64, (byte) 0xe7, (byte) 0x2a, (byte) 0x44, - (byte) 0x07, (byte) 0xa6, (byte) 0xde, (byte) 0x83, - (byte) 0x50, (byte) 0x10, (byte) 0x80, (byte) 0x00, - (byte) 0xee, (byte) 0x71, (byte) 0x00, (byte) 0x00, - (byte) 0x68, (byte) 0x65, (byte) 0x6c, (byte) 0x6c, - (byte) 0x6f, (byte) 0x2c, (byte) 0x20, (byte) 0x77, - (byte) 0x6f, (byte) 0x72, (byte) 0x6c, (byte) 0x64 - }); - - // Check that a valid packet has checksum 0. - int transportLen = packet.limit() - IPV6_HEADER_LENGTH; - assertEquals(0, IpUtils.tcpChecksum(packet, 0, IPV6_HEADER_LENGTH, transportLen)); - - // Check that we can calculate the checksum from scratch. - int sumOffset = IPV6_HEADER_LENGTH + TCP_CHECKSUM_OFFSET; - int sum = getUnsignedByte(packet, sumOffset) * 256 + getUnsignedByte(packet, sumOffset + 1); - assertEquals(0xee71, sum); - - packet.put(sumOffset, (byte) 0); - packet.put(sumOffset + 1, (byte) 0); - assertChecksumEquals(sum, IpUtils.tcpChecksum(packet, 0, IPV6_HEADER_LENGTH, transportLen)); - - // Check that writing the checksum back into the packet results in a valid packet. - packet.putShort( - sumOffset, - IpUtils.tcpChecksum(packet, 0, IPV6_HEADER_LENGTH, transportLen)); - assertEquals(0, IpUtils.tcpChecksum(packet, 0, IPV6_HEADER_LENGTH, transportLen)); - } - - @Test - public void testIpv4UdpChecksum() { - // packet = (scapy.IP(src="192.0.2.1", dst="192.0.2.2", tos=0x40) / - // scapy.UDP(sport=32012, dport=4500) / - // "\xff") - ByteBuffer packet = ByteBuffer.wrap(new byte[] { - (byte) 0x45, (byte) 0x40, (byte) 0x00, (byte) 0x1d, - (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x40, (byte) 0x11, (byte) 0xf6, (byte) 0x8b, - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x01, - (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x02, - (byte) 0x7d, (byte) 0x0c, (byte) 0x11, (byte) 0x94, - (byte) 0x00, (byte) 0x09, (byte) 0xee, (byte) 0x36, - (byte) 0xff - }); - - // Check that a valid packet has IP checksum 0 and UDP checksum 0xffff (0 is not a valid - // UDP checksum, so the udpChecksum rewrites 0 to 0xffff). - assertEquals(0, IpUtils.ipChecksum(packet, 0)); - assertEquals((short) 0xffff, IpUtils.udpChecksum(packet, 0, IPV4_HEADER_LENGTH)); - - // Check that we can calculate the checksums from scratch. - final int ipSumOffset = IP_CHECKSUM_OFFSET; - final int ipSum = getChecksum(packet, ipSumOffset); - assertEquals(0xf68b, ipSum); - - packet.put(ipSumOffset, (byte) 0); - packet.put(ipSumOffset + 1, (byte) 0); - assertChecksumEquals(ipSum, IpUtils.ipChecksum(packet, 0)); - - final int udpSumOffset = IPV4_HEADER_LENGTH + UDP_CHECKSUM_OFFSET; - final int udpSum = getChecksum(packet, udpSumOffset); - assertEquals(0xee36, udpSum); - - packet.put(udpSumOffset, (byte) 0); - packet.put(udpSumOffset + 1, (byte) 0); - assertChecksumEquals(udpSum, IpUtils.udpChecksum(packet, 0, IPV4_HEADER_LENGTH)); - - // Check that writing the checksums back into the packet results in a valid packet. - packet.putShort(ipSumOffset, IpUtils.ipChecksum(packet, 0)); - packet.putShort(udpSumOffset, IpUtils.udpChecksum(packet, 0, IPV4_HEADER_LENGTH)); - assertEquals(0, IpUtils.ipChecksum(packet, 0)); - assertEquals((short) 0xffff, IpUtils.udpChecksum(packet, 0, IPV4_HEADER_LENGTH)); - } -} diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java index f2b7c1ea2ba7..1df510987d25 100644 --- a/tests/net/java/com/android/server/connectivity/VpnTest.java +++ b/tests/net/java/com/android/server/connectivity/VpnTest.java @@ -1263,7 +1263,7 @@ public class VpnTest { } @Override - public boolean checkInterfacePresent(final Vpn vpn, final String iface) { + public boolean isInterfacePresent(final Vpn vpn, final String iface) { return true; } } diff --git a/tests/RollbackTest/lib/src/com/android/tests/rollback/host/AbandonSessionsRule.java b/tests/utils/hostutils/src/com/android/tests/rollback/host/AbandonSessionsRule.java index b08621314ee0..b08621314ee0 100644 --- a/tests/RollbackTest/lib/src/com/android/tests/rollback/host/AbandonSessionsRule.java +++ b/tests/utils/hostutils/src/com/android/tests/rollback/host/AbandonSessionsRule.java diff --git a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl index cf2cb4ae5eb4..57055f78d03d 100644 --- a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl +++ b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package android.net.wifi.p2p.servicediscovery; +package android.net.wifi.p2p.nsd; parcelable WifiP2pServiceInfo; diff --git a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl index d5a1e8f505a9..e4d28bb2d39f 100644 --- a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl +++ b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package android.net.wifi.p2p.servicediscovery; +package android.net.wifi.p2p.nsd; parcelable WifiP2pServiceRequest; diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt index e253ae25659e..eef08b54f570 100644 --- a/wifi/jarjar-rules.txt +++ b/wifi/jarjar-rules.txt @@ -70,7 +70,6 @@ rule android.net.util.NetworkConstants* com.android.wifi.x.@0 rule android.net.util.InterfaceParams* com.android.wifi.x.@0 rule android.net.util.SharedLog* com.android.wifi.x.@0 rule android.net.util.NetUtils* com.android.wifi.x.@0 -rule android.net.util.IpUtils* com.android.wifi.x.@0 rule androidx.annotation.** com.android.wifi.x.@0 |