diff options
91 files changed, 1897 insertions, 759 deletions
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb index 29bcfe046b98..1bd90a8eafae 100644 --- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb +++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb @@ -1,6 +1,6 @@ drops { android_build_drop { - build_id: "6508977" + build_id: "7197701" target: "CtsShim" source_file: "aosp_arm64/CtsShimPriv.apk" } @@ -8,5 +8,5 @@ drops { version: "" version_group: "" git_project: "platform/frameworks/base" - git_branch: "rvc-dev" + git_branch: "sc-dev" } diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb index be172e6122cf..544bca029888 100644 --- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb +++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb @@ -1,6 +1,6 @@ drops { android_build_drop { - build_id: "6508977" + build_id: "7197701" target: "CtsShim" source_file: "aosp_arm64/CtsShim.apk" } @@ -8,5 +8,5 @@ drops { version: "" version_group: "" git_project: "platform/frameworks/base" - git_branch: "rvc-dev" + git_branch: "sc-dev" } diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb index 13eca13c9308..72386bb88465 100644 --- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb +++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb @@ -1,6 +1,6 @@ drops { android_build_drop { - build_id: "6508977" + build_id: "7197701" target: "CtsShim" source_file: "aosp_x86_64/CtsShimPriv.apk" } @@ -8,5 +8,5 @@ drops { version: "" version_group: "" git_project: "platform/frameworks/base" - git_branch: "rvc-dev" + git_branch: "sc-dev" } diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb index 2e863fe57f3c..893eac214daa 100644 --- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb +++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb @@ -1,6 +1,6 @@ drops { android_build_drop { - build_id: "6508977" + build_id: "7197701" target: "CtsShim" source_file: "aosp_x86_64/CtsShim.apk" } @@ -8,5 +8,5 @@ drops { version: "" version_group: "" git_project: "platform/frameworks/base" - git_branch: "rvc-dev" + git_branch: "sc-dev" } diff --git a/Android.bp b/Android.bp index 39c80132345e..d40f11598553 100644 --- a/Android.bp +++ b/Android.bp @@ -834,17 +834,20 @@ filegroup { ], } -// keep these files in sync with the package/Tethering/jarjar-rules.txt for the tethering module. +// keep these files in sync with the package/Tethering/jarjar-rules.txt and +// package/Connectivity/jarjar-rules.txt for the tethering module and connectivity module. filegroup { - name: "framework-tethering-shared-srcs", + name: "framework-connectivity-shared-srcs", srcs: [ "core/java/android/util/LocalLog.java", + // This should be android.util.IndentingPrintWriter, but it's not available in all branches. "core/java/com/android/internal/util/IndentingPrintWriter.java", "core/java/com/android/internal/util/IState.java", "core/java/com/android/internal/util/MessageUtils.java", "core/java/com/android/internal/util/State.java", "core/java/com/android/internal/util/StateMachine.java", "core/java/com/android/internal/util/TrafficStatsConstants.java", + "core/java/com/android/internal/util/WakeupMessage.java", ], } diff --git a/cmds/app_process/Android.bp b/cmds/app_process/Android.bp index 4e5b3bac5713..0eff83c99282 100644 --- a/cmds/app_process/Android.bp +++ b/cmds/app_process/Android.bp @@ -22,13 +22,9 @@ cc_binary { multilib: { lib32: { - // TODO(b/142944043): Remove version script when libsigchain is a DSO. - version_script: "version-script32.txt", suffix: "32", }, lib64: { - // TODO(b/142944043): Remove version script when libsigchain is a DSO. - version_script: "version-script64.txt", suffix: "64", }, }, @@ -43,6 +39,13 @@ cc_binary { "libhidlbase", "liblog", "libnativeloader", + + // Even though app_process doesn't call into libsigchain, we need to + // make sure it's in the DT list of app_process, as we want all code + // in app_process and the libraries it loads to find libsigchain + // symbols before libc symbols. + "libsigchain", + "libutils", // This is a list of libraries that need to be included in order to avoid @@ -52,8 +55,6 @@ cc_binary { "libwilhelm", ], - whole_static_libs: ["libsigchain"], - compile_multilib: "both", cflags: [ diff --git a/cmds/app_process/version-script32.txt b/cmds/app_process/version-script32.txt deleted file mode 100644 index 70810e0b7173..000000000000 --- a/cmds/app_process/version-script32.txt +++ /dev/null @@ -1,15 +0,0 @@ -{ -global: - EnsureFrontOfChain; - AddSpecialSignalHandlerFn; - RemoveSpecialSignalHandlerFn; - SkipAddSignalHandler; - bsd_signal; - sigaction; - sigaction64; - signal; - sigprocmask; - sigprocmask64; -local: - *; -}; diff --git a/cmds/app_process/version-script64.txt b/cmds/app_process/version-script64.txt deleted file mode 100644 index 7bcd76b50f87..000000000000 --- a/cmds/app_process/version-script64.txt +++ /dev/null @@ -1,14 +0,0 @@ -{ -global: - EnsureFrontOfChain; - AddSpecialSignalHandlerFn; - RemoveSpecialSignalHandlerFn; - SkipAddSignalHandler; - sigaction; - sigaction64; - signal; - sigprocmask; - sigprocmask64; -local: - *; -}; diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 7c6ff8ede3cc..992b57f356c5 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -58,6 +58,16 @@ package android.net { method @Nullable public byte[] getWatchlistConfigHash(); } + public class PacProxyManager { + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void addPacProxyInstalledListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.PacProxyManager.PacProxyInstalledListener); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void removePacProxyInstalledListener(@NonNull android.net.PacProxyManager.PacProxyInstalledListener); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setCurrentProxyScriptUrl(@Nullable android.net.ProxyInfo); + } + + public static interface PacProxyManager.PacProxyInstalledListener { + method public void onPacProxyInstalled(@Nullable android.net.Network, @NonNull android.net.ProxyInfo); + } + public final class Proxy { method public static void setHttpProxyConfiguration(@Nullable android.net.ProxyInfo); } diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 1984ddca2cb9..da56f45e9d6e 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -6409,12 +6409,12 @@ package android.net.util { package android.net.vcn { public class VcnManager { - method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void addVcnNetworkPolicyListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.vcn.VcnManager.VcnNetworkPolicyListener); + method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void addVcnNetworkPolicyChangeListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener); method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.vcn.VcnNetworkPolicyResult applyVcnNetworkPolicy(@NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties); - method public void removeVcnNetworkPolicyListener(@NonNull android.net.vcn.VcnManager.VcnNetworkPolicyListener); + method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void removeVcnNetworkPolicyChangeListener(@NonNull android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener); } - public static interface VcnManager.VcnNetworkPolicyListener { + public static interface VcnManager.VcnNetworkPolicyChangeListener { method public void onPolicyChanged(); } @@ -10143,7 +10143,7 @@ package android.telephony { method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isLteCdmaEvdoGsmWcdmaEnabled(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isMobileDataPolicyEnabled(int); - method public boolean isNrDualConnectivityEnabled(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isNrDualConnectivityEnabled(); method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isOpportunisticNetworkEnabled(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isPotentialEmergencyNumber(@NonNull String); @@ -10227,6 +10227,7 @@ package android.telephony { field public static final int CALL_WAITING_STATUS_NOT_SUPPORTED = 4; // 0x4 field public static final int CALL_WAITING_STATUS_UNKNOWN_ERROR = 3; // 0x3 field public static final String CAPABILITY_ALLOWED_NETWORK_TYPES_USED = "CAPABILITY_ALLOWED_NETWORK_TYPES_USED"; + field public static final String CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE = "CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE"; field public static final String CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE = "CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE"; field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1 @@ -12300,6 +12301,7 @@ package android.util { package android.uwb { public final class AngleMeasurement implements android.os.Parcelable { + ctor public AngleMeasurement(double, double, double); method public int describeContents(); method @FloatRange(from=0.0, to=1.0) public double getConfidenceLevel(); method @FloatRange(from=0.0, to=3.141592653589793) public double getErrorRadians(); @@ -12308,14 +12310,6 @@ package android.uwb { field @NonNull public static final android.os.Parcelable.Creator<android.uwb.AngleMeasurement> CREATOR; } - public static final class AngleMeasurement.Builder { - ctor public AngleMeasurement.Builder(); - method @NonNull public android.uwb.AngleMeasurement build(); - method @NonNull public android.uwb.AngleMeasurement.Builder setConfidenceLevel(double); - method @NonNull public android.uwb.AngleMeasurement.Builder setErrorRadians(double); - method @NonNull public android.uwb.AngleMeasurement.Builder setRadians(double); - } - public final class AngleOfArrivalMeasurement implements android.os.Parcelable { method public int describeContents(); method @Nullable public android.uwb.AngleMeasurement getAltitude(); @@ -12325,10 +12319,9 @@ package android.uwb { } public static final class AngleOfArrivalMeasurement.Builder { - ctor public AngleOfArrivalMeasurement.Builder(); + ctor public AngleOfArrivalMeasurement.Builder(@NonNull android.uwb.AngleMeasurement); method @NonNull public android.uwb.AngleOfArrivalMeasurement build(); method @NonNull public android.uwb.AngleOfArrivalMeasurement.Builder setAltitude(@NonNull android.uwb.AngleMeasurement); - method @NonNull public android.uwb.AngleOfArrivalMeasurement.Builder setAzimuth(@NonNull android.uwb.AngleMeasurement); } public final class DistanceMeasurement implements android.os.Parcelable { @@ -12428,7 +12421,7 @@ package android.uwb { public final class UwbManager { method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public long elapsedRealtimeResolutionNanos(); method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public android.os.PersistableBundle getSpecificationInfo(); - method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public AutoCloseable openRangingSession(@NonNull android.os.PersistableBundle, @NonNull java.util.concurrent.Executor, @NonNull android.uwb.RangingSession.Callback); + method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public android.os.CancellationSignal openRangingSession(@NonNull android.os.PersistableBundle, @NonNull java.util.concurrent.Executor, @NonNull android.uwb.RangingSession.Callback); method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void registerAdapterStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.uwb.UwbManager.AdapterStateCallback); method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void unregisterAdapterStateCallback(@NonNull android.uwb.UwbManager.AdapterStateCallback); } diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 331a0b125ee2..267d029d53fe 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -117,11 +117,13 @@ import android.net.EthernetManager; import android.net.IEthernetManager; import android.net.IIpSecService; import android.net.INetworkPolicyManager; +import android.net.IPacProxyManager; import android.net.IVpnManager; import android.net.IpSecManager; import android.net.NetworkPolicyManager; import android.net.NetworkScoreManager; import android.net.NetworkWatchlistManager; +import android.net.PacProxyManager; import android.net.TetheringManager; import android.net.VpnManager; import android.net.lowpan.ILowpanManager; @@ -346,6 +348,15 @@ public final class SystemServiceRegistry { // (which extends it). SYSTEM_SERVICE_NAMES.put(android.text.ClipboardManager.class, Context.CLIPBOARD_SERVICE); + registerService(Context.PAC_PROXY_SERVICE, PacProxyManager.class, + new CachedServiceFetcher<PacProxyManager>() { + @Override + public PacProxyManager createService(ContextImpl ctx) throws ServiceNotFoundException { + IBinder b = ServiceManager.getServiceOrThrow(Context.PAC_PROXY_SERVICE); + IPacProxyManager service = IPacProxyManager.Stub.asInterface(b); + return new PacProxyManager(ctx.getOuterContext(), service); + }}); + registerService(Context.NETD_SERVICE, IBinder.class, new StaticServiceFetcher<IBinder>() { @Override public IBinder createService() throws ServiceNotFoundException { diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 9c8856650ae0..aa6127904400 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -3451,6 +3451,7 @@ public abstract class Context { VIBRATOR_SERVICE, //@hide: STATUS_BAR_SERVICE, CONNECTIVITY_SERVICE, + PAC_PROXY_SERVICE, VCN_MANAGEMENT_SERVICE, //@hide: IP_MEMORY_STORE_SERVICE, IPSEC_SERVICE, @@ -4017,6 +4018,17 @@ public abstract class Context { public static final String CONNECTIVITY_SERVICE = "connectivity"; /** + * Use with {@link #getSystemService(String)} to retrieve a {@link + * android.net.PacProxyManager} for handling management of + * pac proxy information. + * + * @see #getSystemService(String) + * @see android.net.PacProxyManager + * @hide + */ + public static final String PAC_PROXY_SERVICE = "pac_proxy"; + + /** * Use with {@link #getSystemService(String)} to retrieve a {@link android.net.vcn.VcnManager} * for managing Virtual Carrier Networks * diff --git a/core/java/android/net/IPacProxyInstalledListener.aidl b/core/java/android/net/IPacProxyInstalledListener.aidl new file mode 100644 index 000000000000..b1f946e02215 --- /dev/null +++ b/core/java/android/net/IPacProxyInstalledListener.aidl @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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; + +import android.net.Network; +import android.net.ProxyInfo; + +/** {@hide} */ +oneway interface IPacProxyInstalledListener { + void onPacProxyInstalled(in Network network, in ProxyInfo proxy); +} diff --git a/core/java/android/net/IPacProxyManager.aidl b/core/java/android/net/IPacProxyManager.aidl new file mode 100644 index 000000000000..8f65c56662ef --- /dev/null +++ b/core/java/android/net/IPacProxyManager.aidl @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2021, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing perNmissions and + * limitations under the License. + */ + +package android.net; + +import android.net.IPacProxyInstalledListener; +import android.net.ProxyInfo; + +/** {@hide} */ +interface IPacProxyManager +{ + void addListener(IPacProxyInstalledListener listener); + void removeListener(IPacProxyInstalledListener listener); + void setCurrentProxyScriptUrl(in ProxyInfo proxyInfo); +} diff --git a/core/java/android/net/NetworkScore.aidl b/core/java/android/net/NetworkScore.aidl new file mode 100644 index 000000000000..af12dcf7f17a --- /dev/null +++ b/core/java/android/net/NetworkScore.aidl @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2021, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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; + +parcelable NetworkScore; + diff --git a/core/java/android/net/NetworkScore.java b/core/java/android/net/NetworkScore.java new file mode 100644 index 000000000000..f47801002296 --- /dev/null +++ b/core/java/android/net/NetworkScore.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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; + +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Object representing the quality of a network as perceived by the user. + * + * A NetworkScore object represents the characteristics of a network that affects how good the + * network is considered for a particular use. + * @hide + */ +// TODO : @SystemApi when the implementation is complete +public final class NetworkScore implements Parcelable { + // This will be removed soon. Do *NOT* depend on it for any new code that is not part of + // a migration. + private final int mLegacyInt; + + /** @hide */ + NetworkScore(final int legacyInt) { + this.mLegacyInt = legacyInt; + } + + private NetworkScore(@NonNull final Parcel in) { + mLegacyInt = in.readInt(); + } + + public int getLegacyInt() { + return mLegacyInt; + } + + @Override + public String toString() { + return "Score(" + mLegacyInt + ")"; + } + + @Override + public void writeToParcel(@NonNull final Parcel dest, final int flags) { + dest.writeInt(mLegacyInt); + } + + @Override + public int describeContents() { + return 0; + } + + @NonNull public static final Creator<NetworkScore> CREATOR = new Creator<>() { + @Override + @NonNull + public NetworkScore createFromParcel(@NonNull final Parcel in) { + return new NetworkScore(in); + } + + @Override + @NonNull + public NetworkScore[] newArray(int size) { + return new NetworkScore[size]; + } + }; + + /** + * A builder for NetworkScore. + */ + public static final class Builder { + private static final int INVALID_LEGACY_INT = Integer.MIN_VALUE; + private int mLegacyInt = INVALID_LEGACY_INT; + + /** + * Sets the legacy int for this score. + * + * Do not rely on this. It will be gone by the time S is released. + * + * @param score the legacy int + * @return this + */ + @NonNull + public Builder setLegacyInt(final int score) { + mLegacyInt = score; + return this; + } + + /** + * Builds this NetworkScore. + * @return The built NetworkScore object. + */ + @NonNull + public NetworkScore build() { + return new NetworkScore(mLegacyInt); + } + } +} diff --git a/core/java/android/net/PacProxyManager.java b/core/java/android/net/PacProxyManager.java new file mode 100644 index 000000000000..8f7ad8c335ca --- /dev/null +++ b/core/java/android/net/PacProxyManager.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.RequiresPermission; +import android.annotation.SystemApi; +import android.annotation.SystemService; +import android.content.Context; +import android.os.Binder; +import android.os.RemoteException; + +import com.android.internal.annotations.GuardedBy; + +import java.util.HashMap; +import java.util.Objects; +import java.util.concurrent.Executor; + +/** + * @hide + */ +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) +@SystemService(Context.PAC_PROXY_SERVICE) +public class PacProxyManager { + private final Context mContext; + private final IPacProxyManager mService; + @GuardedBy("mListenerMap") + private final HashMap<PacProxyInstalledListener, PacProxyInstalledListenerProxy> + mListenerMap = new HashMap<>(); + + /** @hide */ + public PacProxyManager(Context context, IPacProxyManager service) { + Objects.requireNonNull(service, "missing IPacProxyManager"); + mContext = context; + mService = service; + } + + /** + * Add a listener to start monitoring events reported by PacProxyService. + */ + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_STACK, + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, + android.Manifest.permission.NETWORK_SETTINGS}) + public void addPacProxyInstalledListener(@NonNull Executor executor, + @NonNull PacProxyInstalledListener listener) { + try { + synchronized (mListenerMap) { + final PacProxyInstalledListenerProxy listenerProxy = + new PacProxyInstalledListenerProxy(executor, listener); + + if (null != mListenerMap.putIfAbsent(listener, listenerProxy)) { + throw new IllegalStateException("Listener is already added."); + } + mService.addListener(listenerProxy); + } + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Remove the listener to stop monitoring the event of PacProxyInstalledListener. + */ + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_STACK, + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, + android.Manifest.permission.NETWORK_SETTINGS}) + public void removePacProxyInstalledListener(@NonNull PacProxyInstalledListener listener) { + try { + synchronized (mListenerMap) { + final PacProxyInstalledListenerProxy listenerProxy = mListenerMap.remove(listener); + if (listenerProxy == null) return; + mService.removeListener(listenerProxy); + } + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Updates the PAC Proxy Installer with current Proxy information. + */ + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_STACK, + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, + android.Manifest.permission.NETWORK_SETTINGS}) + public void setCurrentProxyScriptUrl(@Nullable ProxyInfo proxy) { + try { + mService.setCurrentProxyScriptUrl(proxy); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * A callback interface for monitoring changes of PAC proxy information. + */ + public interface PacProxyInstalledListener { + /** + * Notify that the PAC proxy has been installed. Note that this method will be called with + * a ProxyInfo with an empty PAC URL when the PAC proxy is removed. + * + * This method supports different PAC proxies per-network but not all devices might support + * per-network proxies. In that case it will be applied globally. + * + * @param network the network for which this proxy installed. + * @param proxy the installed proxy. + */ + void onPacProxyInstalled(@Nullable Network network, @NonNull ProxyInfo proxy); + } + + /** + * PacProxyInstalledListener proxy for PacProxyInstalledListener object. + * @hide + */ + public class PacProxyInstalledListenerProxy extends IPacProxyInstalledListener.Stub { + private final Executor mExecutor; + private final PacProxyInstalledListener mListener; + + PacProxyInstalledListenerProxy(Executor executor, PacProxyInstalledListener listener) { + mExecutor = executor; + mListener = listener; + } + + @Override + public void onPacProxyInstalled(Network network, ProxyInfo proxy) { + Binder.withCleanCallingIdentity(() -> { + mExecutor.execute(() -> { + mListener.onPacProxyInstalled(network, proxy); + }); + }); + } + } +} diff --git a/core/java/android/net/PacProxySelector.java b/core/java/android/net/PacProxySelector.java index 326943a27d4e..84b7eecd2027 100644 --- a/core/java/android/net/PacProxySelector.java +++ b/core/java/android/net/PacProxySelector.java @@ -51,7 +51,7 @@ public class PacProxySelector extends ProxySelector { ServiceManager.getService(PROXY_SERVICE)); if (mProxyService == null) { // Added because of b10267814 where mako is restarting. - Log.e(TAG, "PacProxyInstaller: no proxy service"); + Log.e(TAG, "PacProxyService: no proxy service"); } mDefaultList = Lists.newArrayList(java.net.Proxy.NO_PROXY); } diff --git a/core/java/android/net/vcn/VcnManager.java b/core/java/android/net/vcn/VcnManager.java index 8ebf757760c3..062438c6e5db 100644 --- a/core/java/android/net/vcn/VcnManager.java +++ b/core/java/android/net/vcn/VcnManager.java @@ -73,7 +73,8 @@ import java.util.concurrent.Executor; public class VcnManager { @NonNull private static final String TAG = VcnManager.class.getSimpleName(); - private static final Map<VcnNetworkPolicyListener, VcnUnderlyingNetworkPolicyListenerBinder> + private static final Map< + VcnNetworkPolicyChangeListener, VcnUnderlyingNetworkPolicyListenerBinder> REGISTERED_POLICY_LISTENERS = new ConcurrentHashMap<>(); @NonNull private final Context mContext; @@ -93,13 +94,13 @@ public class VcnManager { } /** - * Get all currently registered VcnNetworkPolicyListeners for testing purposes. + * Get all currently registered VcnNetworkPolicyChangeListeners for testing purposes. * * @hide */ @VisibleForTesting(visibility = Visibility.PRIVATE) @NonNull - public static Map<VcnNetworkPolicyListener, VcnUnderlyingNetworkPolicyListenerBinder> + public static Map<VcnNetworkPolicyChangeListener, VcnUnderlyingNetworkPolicyListenerBinder> getAllPolicyListeners() { return Collections.unmodifiableMap(REGISTERED_POLICY_LISTENERS); } @@ -162,14 +163,14 @@ public class VcnManager { } // TODO(b/180537630): remove all VcnUnderlyingNetworkPolicyListener refs once Telephony is using - // the new VcnNetworkPolicyListener API + // the new VcnNetworkPolicyChangeListener API /** * VcnUnderlyingNetworkPolicyListener is the interface through which internal system components * can register to receive updates for VCN-underlying Network policies from the System Server. * * @hide */ - public interface VcnUnderlyingNetworkPolicyListener extends VcnNetworkPolicyListener {} + public interface VcnUnderlyingNetworkPolicyListener extends VcnNetworkPolicyChangeListener {} /** * Add a listener for VCN-underlying network policy updates. @@ -185,7 +186,7 @@ public class VcnManager { @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void addVcnUnderlyingNetworkPolicyListener( @NonNull Executor executor, @NonNull VcnUnderlyingNetworkPolicyListener listener) { - addVcnNetworkPolicyListener(executor, listener); + addVcnNetworkPolicyChangeListener(executor, listener); } /** @@ -198,7 +199,7 @@ public class VcnManager { */ public void removeVcnUnderlyingNetworkPolicyListener( @NonNull VcnUnderlyingNetworkPolicyListener listener) { - removeVcnNetworkPolicyListener(listener); + removeVcnNetworkPolicyChangeListener(listener); } /** @@ -233,20 +234,20 @@ public class VcnManager { } /** - * VcnNetworkPolicyListener is the interface through which internal system components (e.g. - * Network Factories) can register to receive updates for VCN-underlying Network policies from - * the System Server. + * VcnNetworkPolicyChangeListener is the interface through which internal system components + * (e.g. Network Factories) can register to receive updates for VCN-underlying Network policies + * from the System Server. * * <p>Any Network Factory that brings up Networks capable of being VCN-underlying Networks - * should register a VcnNetworkPolicyListener. VcnManager will then use this listener to notify - * the registrant when VCN Network policies change. Upon receiving this signal, the listener - * must check {@link VcnManager} for the current Network policy result for each of its Networks - * via {@link #applyVcnNetworkPolicy(NetworkCapabilities, LinkProperties)}. + * should register a VcnNetworkPolicyChangeListener. VcnManager will then use this listener to + * notify the registrant when VCN Network policies change. Upon receiving this signal, the + * listener must check {@link VcnManager} for the current Network policy result for each of its + * Networks via {@link #applyVcnNetworkPolicy(NetworkCapabilities, LinkProperties)}. * * @hide */ @SystemApi - public interface VcnNetworkPolicyListener { + public interface VcnNetworkPolicyChangeListener { /** * Notifies the implementation that the VCN's underlying Network policy has changed. * @@ -260,20 +261,21 @@ public class VcnManager { /** * Add a listener for VCN-underlying Network policy updates. * - * <p>A {@link VcnNetworkPolicyListener} is eligible to begin receiving callbacks once it is - * registered. No callbacks are guaranteed upon registration. + * <p>A {@link VcnNetworkPolicyChangeListener} is eligible to begin receiving callbacks once it + * is registered. No callbacks are guaranteed upon registration. * * @param executor the Executor that will be used for invoking all calls to the specified * Listener - * @param listener the VcnNetworkPolicyListener to be added + * @param listener the VcnNetworkPolicyChangeListener to be added * @throws SecurityException if the caller does not have permission NETWORK_FACTORY - * @throws IllegalStateException if the specified VcnNetworkPolicyListener is already registered + * @throws IllegalStateException if the specified VcnNetworkPolicyChangeListener is already + * registered * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) - public void addVcnNetworkPolicyListener( - @NonNull Executor executor, @NonNull VcnNetworkPolicyListener listener) { + public void addVcnNetworkPolicyChangeListener( + @NonNull Executor executor, @NonNull VcnNetworkPolicyChangeListener listener) { requireNonNull(executor, "executor must not be null"); requireNonNull(listener, "listener must not be null"); @@ -292,15 +294,18 @@ public class VcnManager { } /** - * Remove the specified VcnNetworkPolicyListener from VcnManager. + * Remove the specified VcnNetworkPolicyChangeListener from VcnManager. * * <p>If the specified listener is not currently registered, this is a no-op. * - * @param listener the VcnNetworkPolicyListener that will be removed + * @param listener the VcnNetworkPolicyChangeListener that will be removed + * @throws SecurityException if the caller does not have permission NETWORK_FACTORY * @hide */ @SystemApi - public void removeVcnNetworkPolicyListener(@NonNull VcnNetworkPolicyListener listener) { + @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) + public void removeVcnNetworkPolicyChangeListener( + @NonNull VcnNetworkPolicyChangeListener listener) { requireNonNull(listener, "listener must not be null"); VcnUnderlyingNetworkPolicyListenerBinder binder = @@ -320,8 +325,9 @@ public class VcnManager { * Applies the network policy for a {@link android.net.Network} with the given parameters. * * <p>Prior to a new NetworkAgent being registered, or upon notification that Carrier VCN policy - * may have changed via {@link VcnNetworkPolicyListener#onPolicyChanged()}, a Network Provider - * MUST poll for the updated Network policy based on that Network's capabilities and properties. + * may have changed via {@link VcnNetworkPolicyChangeListener#onPolicyChanged()}, a Network + * Provider MUST poll for the updated Network policy based on that Network's capabilities and + * properties. * * @param networkCapabilities the NetworkCapabilities to be used in determining the Network * policy result for this Network. @@ -532,17 +538,18 @@ public class VcnManager { } /** - * Binder wrapper for added VcnNetworkPolicyListeners to receive signals from System Server. + * Binder wrapper for added VcnNetworkPolicyChangeListeners to receive signals from System + * Server. * * @hide */ private static class VcnUnderlyingNetworkPolicyListenerBinder extends IVcnUnderlyingNetworkPolicyListener.Stub { @NonNull private final Executor mExecutor; - @NonNull private final VcnNetworkPolicyListener mListener; + @NonNull private final VcnNetworkPolicyChangeListener mListener; private VcnUnderlyingNetworkPolicyListenerBinder( - Executor executor, VcnNetworkPolicyListener listener) { + Executor executor, VcnNetworkPolicyChangeListener listener) { mExecutor = executor; mListener = listener; } diff --git a/core/java/android/uwb/AngleMeasurement.java b/core/java/android/uwb/AngleMeasurement.java index 9df213b2092f..8c771baaea37 100644 --- a/core/java/android/uwb/AngleMeasurement.java +++ b/core/java/android/uwb/AngleMeasurement.java @@ -38,9 +38,30 @@ public final class AngleMeasurement implements Parcelable { private final double mErrorRadians; private final double mConfidenceLevel; - private AngleMeasurement(double radians, double errorRadians, double confidenceLevel) { + /** + * Constructs a new {@link AngleMeasurement} object + * + * @param radians the angle in radians + * @param errorRadians the error of the angle measurement in radians + * @param confidenceLevel confidence level of the angle measurement + * + * @throws IllegalArgumentException if the radians, errorRadians, or confidenceLevel is out of + * allowed range + */ + public AngleMeasurement(double radians, double errorRadians, double confidenceLevel) { + if (radians < -Math.PI || radians > Math.PI) { + throw new IllegalArgumentException("Invalid radians: " + radians); + } mRadians = radians; + + if (errorRadians < 0.0 || errorRadians > Math.PI) { + throw new IllegalArgumentException("Invalid error radians: " + errorRadians); + } mErrorRadians = errorRadians; + + if (confidenceLevel < 0.0 || confidenceLevel > 1.0) { + throw new IllegalArgumentException("Invalid confidence level: " + confidenceLevel); + } mConfidenceLevel = confidenceLevel; } @@ -122,11 +143,7 @@ public final class AngleMeasurement implements Parcelable { new Creator<AngleMeasurement>() { @Override public AngleMeasurement createFromParcel(Parcel in) { - Builder builder = new Builder(); - builder.setRadians(in.readDouble()); - builder.setErrorRadians(in.readDouble()); - builder.setConfidenceLevel(in.readDouble()); - return builder.build(); + return new AngleMeasurement(in.readDouble(), in.readDouble(), in.readDouble()); } @Override @@ -134,82 +151,4 @@ public final class AngleMeasurement implements Parcelable { return new AngleMeasurement[size]; } }; - - /** - * Builder class for {@link AngleMeasurement}. - */ - public static final class Builder { - private double mRadians = Double.NaN; - private double mErrorRadians = Double.NaN; - private double mConfidenceLevel = Double.NaN; - - /** - * Set the angle in radians - * - * @param radians angle in radians - * @throws IllegalArgumentException if angle exceeds allowed limits of [-Math.PI, +Math.PI] - */ - @NonNull - public Builder setRadians(double radians) { - if (radians < -Math.PI || radians > Math.PI) { - throw new IllegalArgumentException("Invalid radians: " + radians); - } - mRadians = radians; - return this; - } - - /** - * Set the angle error in radians - * - * @param errorRadians error of the angle in radians - * @throws IllegalArgumentException if the error exceeds the allowed limits of [0, +Math.PI] - */ - @NonNull - public Builder setErrorRadians(double errorRadians) { - if (errorRadians < 0.0 || errorRadians > Math.PI) { - throw new IllegalArgumentException( - "Invalid error radians: " + errorRadians); - } - mErrorRadians = errorRadians; - return this; - } - - /** - * Set the angle confidence level - * - * @param confidenceLevel level of confidence of the angle measurement - * @throws IllegalArgumentException if the error exceeds the allowed limits of [0.0, 1.0] - */ - @NonNull - public Builder setConfidenceLevel(double confidenceLevel) { - if (confidenceLevel < 0.0 || confidenceLevel > 1.0) { - throw new IllegalArgumentException( - "Invalid confidence level: " + confidenceLevel); - } - mConfidenceLevel = confidenceLevel; - return this; - } - - /** - * Build the {@link AngleMeasurement} object - * - * @throws IllegalStateException if angle, error, or confidence values are missing - */ - @NonNull - public AngleMeasurement build() { - if (Double.isNaN(mRadians)) { - throw new IllegalStateException("Angle is not set"); - } - - if (Double.isNaN(mErrorRadians)) { - throw new IllegalStateException("Angle error is not set"); - } - - if (Double.isNaN(mConfidenceLevel)) { - throw new IllegalStateException("Angle confidence level is not set"); - } - - return new AngleMeasurement(mRadians, mErrorRadians, mConfidenceLevel); - } - } } diff --git a/core/java/android/uwb/AngleOfArrivalMeasurement.java b/core/java/android/uwb/AngleOfArrivalMeasurement.java index 3d8626b98bed..db04ad16c191 100644 --- a/core/java/android/uwb/AngleOfArrivalMeasurement.java +++ b/core/java/android/uwb/AngleOfArrivalMeasurement.java @@ -116,9 +116,8 @@ public final class AngleOfArrivalMeasurement implements Parcelable { new Creator<AngleOfArrivalMeasurement>() { @Override public AngleOfArrivalMeasurement createFromParcel(Parcel in) { - Builder builder = new Builder(); - - builder.setAzimuth(in.readParcelable(AngleMeasurement.class.getClassLoader())); + Builder builder = + new Builder(in.readParcelable(AngleMeasurement.class.getClassLoader())); builder.setAltitude(in.readParcelable(AngleMeasurement.class.getClassLoader())); @@ -135,18 +134,16 @@ public final class AngleOfArrivalMeasurement implements Parcelable { * Builder class for {@link AngleOfArrivalMeasurement}. */ public static final class Builder { - private AngleMeasurement mAzimuthAngleMeasurement = null; + private final AngleMeasurement mAzimuthAngleMeasurement; private AngleMeasurement mAltitudeAngleMeasurement = null; /** - * Set the azimuth angle + * Constructs an {@link AngleOfArrivalMeasurement} object * - * @param azimuthAngle azimuth angle + * @param azimuthAngle the azimuth angle of the measurement */ - @NonNull - public Builder setAzimuth(@NonNull AngleMeasurement azimuthAngle) { + public Builder(@NonNull AngleMeasurement azimuthAngle) { mAzimuthAngleMeasurement = azimuthAngle; - return this; } /** @@ -162,15 +159,9 @@ public final class AngleOfArrivalMeasurement implements Parcelable { /** * Build the {@link AngleOfArrivalMeasurement} object - * - * @throws IllegalStateException if the required azimuth angle is not provided */ @NonNull public AngleOfArrivalMeasurement build() { - if (mAzimuthAngleMeasurement == null) { - throw new IllegalStateException("Azimuth angle measurement is not set"); - } - return new AngleOfArrivalMeasurement(mAzimuthAngleMeasurement, mAltitudeAngleMeasurement); } diff --git a/core/java/android/uwb/IUwbAdapter.aidl b/core/java/android/uwb/IUwbAdapter.aidl index 468a69c7bddb..4036892fb9e7 100644 --- a/core/java/android/uwb/IUwbAdapter.aidl +++ b/core/java/android/uwb/IUwbAdapter.aidl @@ -62,9 +62,6 @@ interface IUwbAdapter { /** * Request to open a new ranging session * - * This function must return before calling any functions in - * IUwbAdapterCallbacks. - * * This function does not start the ranging session, but all necessary * components must be initialized and ready to start a new ranging * session prior to calling IUwbAdapterCallback#onRangingOpened. @@ -77,12 +74,16 @@ interface IUwbAdapter { * RANGING_SESSION_OPEN_THRESHOLD_MS milliseconds of #openRanging being called * if the ranging session fails to be opened. * + * If the provided sessionHandle is already open for the calling client, then + * #onRangingOpenFailed must be called and the new session must not be opened. + * + * @param sessionHandle the session handle to open ranging for * @param rangingCallbacks the callbacks used to deliver ranging information * @param parameters the configuration to use for ranging - * @return a SessionHandle used to identify this ranging request */ - SessionHandle openRanging(in IUwbRangingCallbacks rangingCallbacks, - in PersistableBundle parameters); + void openRanging(in SessionHandle sessionHandle, + in IUwbRangingCallbacks rangingCallbacks, + in PersistableBundle parameters); /** * Request to start ranging diff --git a/core/java/android/uwb/RangingManager.java b/core/java/android/uwb/RangingManager.java index c0d818774ba0..85f2c1ccc180 100644 --- a/core/java/android/uwb/RangingManager.java +++ b/core/java/android/uwb/RangingManager.java @@ -17,6 +17,7 @@ package android.uwb; import android.annotation.NonNull; +import android.os.CancellationSignal; import android.os.PersistableBundle; import android.os.RemoteException; import android.util.Log; @@ -32,6 +33,7 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub { private final IUwbAdapter mAdapter; private final Hashtable<SessionHandle, RangingSession> mRangingSessionTable = new Hashtable<>(); + private int mNextSessionId = 1; public RangingManager(IUwbAdapter adapter) { mAdapter = adapter; @@ -44,29 +46,26 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub { * @param executor {@link Executor} to run callbacks * @param callbacks {@link RangingSession.Callback} to associate with the {@link RangingSession} * that is being opened. - * @return a new {@link RangingSession} + * @return a {@link CancellationSignal} that may be used to cancel the opening of the + * {@link RangingSession}. */ - public RangingSession openSession(@NonNull PersistableBundle params, @NonNull Executor executor, + public CancellationSignal openSession(@NonNull PersistableBundle params, + @NonNull Executor executor, @NonNull RangingSession.Callback callbacks) { - SessionHandle sessionHandle; - try { - sessionHandle = mAdapter.openRanging(this, params); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - synchronized (this) { - if (hasSession(sessionHandle)) { - Log.w(TAG, "Newly created session unexpectedly reuses an active SessionHandle"); - executor.execute(() -> callbacks.onClosed( - RangingSession.Callback.REASON_GENERIC_ERROR, - new PersistableBundle())); - } - + SessionHandle sessionHandle = new SessionHandle(mNextSessionId++); RangingSession session = new RangingSession(executor, callbacks, mAdapter, sessionHandle); mRangingSessionTable.put(sessionHandle, session); - return session; + try { + mAdapter.openRanging(sessionHandle, this, params); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + + CancellationSignal cancellationSignal = new CancellationSignal(); + cancellationSignal.setOnCancelListener(() -> session.close()); + return cancellationSignal; } } diff --git a/core/java/android/uwb/UwbManager.java b/core/java/android/uwb/UwbManager.java index 63a6d058f358..844bbbe7970b 100644 --- a/core/java/android/uwb/UwbManager.java +++ b/core/java/android/uwb/UwbManager.java @@ -25,6 +25,7 @@ import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.content.Context; +import android.os.CancellationSignal; import android.os.IBinder; import android.os.PersistableBundle; import android.os.RemoteException; @@ -228,14 +229,14 @@ public final class UwbManager { * @param callbacks {@link RangingSession.Callback} to associate with the * {@link RangingSession} that is being opened. * - * @return an {@link AutoCloseable} that is able to be used to close or cancel the opening of a + * @return an {@link CancellationSignal} that is able to be used to cancel the opening of a * {@link RangingSession} that has been requested through {@link #openRangingSession} * but has not yet been made available by * {@link RangingSession.Callback#onOpened(RangingSession)}. */ @NonNull @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) - public AutoCloseable openRangingSession(@NonNull PersistableBundle parameters, + public CancellationSignal openRangingSession(@NonNull PersistableBundle parameters, @NonNull @CallbackExecutor Executor executor, @NonNull RangingSession.Callback callbacks) { return mRangingManager.openSession(parameters, executor, callbacks); diff --git a/core/java/com/android/internal/view/inline/OWNERS b/core/java/com/android/internal/view/inline/OWNERS new file mode 100644 index 000000000000..edfb2112198a --- /dev/null +++ b/core/java/com/android/internal/view/inline/OWNERS @@ -0,0 +1 @@ +include /core/java/android/view/autofill/OWNERS diff --git a/core/jni/android_net_NetworkUtils.cpp b/core/jni/android_net_NetworkUtils.cpp index 750810840bde..a781a377694b 100644 --- a/core/jni/android_net_NetworkUtils.cpp +++ b/core/jni/android_net_NetworkUtils.cpp @@ -52,27 +52,6 @@ constexpr int MAXPACKETSIZE = 8 * 1024; // FrameworkListener limits the size of commands to 4096 bytes. constexpr int MAXCMDSIZE = 4096; -static void throwErrnoException(JNIEnv* env, const char* functionName, int error) { - ScopedLocalRef<jstring> detailMessage(env, env->NewStringUTF(functionName)); - if (detailMessage.get() == NULL) { - // Not really much we can do here. We're probably dead in the water, - // but let's try to stumble on... - env->ExceptionClear(); - } - static jclass errnoExceptionClass = - MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/system/ErrnoException")); - - static jmethodID errnoExceptionCtor = - GetMethodIDOrDie(env, errnoExceptionClass, - "<init>", "(Ljava/lang/String;I)V"); - - jobject exception = env->NewObject(errnoExceptionClass, - errnoExceptionCtor, - detailMessage.get(), - error); - env->Throw(reinterpret_cast<jthrowable>(exception)); -} - static void android_net_utils_attachDropAllBPFFilter(JNIEnv *env, jobject clazz, jobject javaFd) { struct sock_filter filter_code[] = { @@ -150,7 +129,7 @@ static jobject android_net_utils_resNetworkQuery(JNIEnv *env, jobject thiz, jint int fd = resNetworkQuery(netId, queryname.data(), ns_class, ns_type, flags); if (fd < 0) { - throwErrnoException(env, "resNetworkQuery", -fd); + jniThrowErrnoException(env, "resNetworkQuery", -fd); return nullptr; } @@ -165,7 +144,7 @@ static jobject android_net_utils_resNetworkSend(JNIEnv *env, jobject thiz, jint int fd = resNetworkSend(netId, data, msgLen, flags); if (fd < 0) { - throwErrnoException(env, "resNetworkSend", -fd); + jniThrowErrnoException(env, "resNetworkSend", -fd); return nullptr; } @@ -180,13 +159,13 @@ static jobject android_net_utils_resNetworkResult(JNIEnv *env, jobject thiz, job int res = resNetworkResult(fd, &rcode, buf.data(), MAXPACKETSIZE); jniSetFileDescriptorOfFD(env, javaFd, -1); if (res < 0) { - throwErrnoException(env, "resNetworkResult", -res); + jniThrowErrnoException(env, "resNetworkResult", -res); return nullptr; } jbyteArray answer = env->NewByteArray(res); if (answer == nullptr) { - throwErrnoException(env, "resNetworkResult", ENOMEM); + jniThrowErrnoException(env, "resNetworkResult", ENOMEM); return nullptr; } else { env->SetByteArrayRegion(answer, 0, res, @@ -208,7 +187,7 @@ static void android_net_utils_resNetworkCancel(JNIEnv *env, jobject thiz, jobjec static jobject android_net_utils_getDnsNetwork(JNIEnv *env, jobject thiz) { unsigned dnsNetId = 0; if (int res = getNetworkForDns(&dnsNetId) < 0) { - throwErrnoException(env, "getDnsNetId", -res); + jniThrowErrnoException(env, "getDnsNetId", -res); return nullptr; } bool privateDnsBypass = dnsNetId & NETID_USE_LOCAL_NAMESERVERS; @@ -233,8 +212,8 @@ static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, j // Obtain the parameters of the TCP repair window. int rc = getsockopt(fd, IPPROTO_TCP, TCP_REPAIR_WINDOW, &trw, &size); if (rc == -1) { - throwErrnoException(env, "getsockopt : TCP_REPAIR_WINDOW", errno); - return NULL; + jniThrowErrnoException(env, "getsockopt : TCP_REPAIR_WINDOW", errno); + return NULL; } struct tcp_info tcpinfo = {}; @@ -244,8 +223,8 @@ static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, j // should be applied to the window size. rc = getsockopt(fd, IPPROTO_TCP, TCP_INFO, &tcpinfo, &tcpinfo_size); if (rc == -1) { - throwErrnoException(env, "getsockopt : TCP_INFO", errno); - return NULL; + jniThrowErrnoException(env, "getsockopt : TCP_INFO", errno); + return NULL; } jclass class_TcpRepairWindow = env->FindClass("android/net/TcpRepairWindow"); diff --git a/core/jni/android_os_SharedMemory.cpp b/core/jni/android_os_SharedMemory.cpp index dc86187d8fea..fe375f4fa359 100644 --- a/core/jni/android_os_SharedMemory.cpp +++ b/core/jni/android_os_SharedMemory.cpp @@ -35,21 +35,6 @@ namespace { jclass errnoExceptionClass; jmethodID errnoExceptionCtor; // MethodID for ErrnoException.<init>(String,I) -void throwErrnoException(JNIEnv* env, const char* functionName, int error) { - ScopedLocalRef<jstring> detailMessage(env, env->NewStringUTF(functionName)); - if (detailMessage.get() == NULL) { - // Not really much we can do here. We're probably dead in the water, - // but let's try to stumble on... - env->ExceptionClear(); - } - - jobject exception = env->NewObject(errnoExceptionClass, - errnoExceptionCtor, - detailMessage.get(), - error); - env->Throw(reinterpret_cast<jthrowable>(exception)); -} - jobject SharedMemory_nCreate(JNIEnv* env, jobject, jstring jname, jint size) { // Name is optional so we can't use ScopedUtfChars for this as it throws NPE on null @@ -65,7 +50,7 @@ jobject SharedMemory_nCreate(JNIEnv* env, jobject, jstring jname, jint size) { } if (fd < 0) { - throwErrnoException(env, "SharedMemory_create", err); + jniThrowErrnoException(env, "SharedMemory_create", err); return nullptr; } diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index f71b42c4793f..249950419441 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -1516,7 +1516,9 @@ static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj, res = JNI_TRUE; } else { jniThrowException(env, "java/util/NoSuchElementException", - "Death link does not exist"); + base::StringPrintf("Death link does not exist (%s)", + statusToString(err).c_str()) + .c_str()); } } diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index 6becb07d02a4..04faebc7beff 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -1290,24 +1290,6 @@ void android_os_Process_removeAllProcessGroups(JNIEnv* env, jobject clazz) return removeAllProcessGroups(); } -static void throwErrnoException(JNIEnv* env, const char* functionName, int error) { - ScopedLocalRef<jstring> detailMessage(env, env->NewStringUTF(functionName)); - if (detailMessage.get() == NULL) { - // Not really much we can do here. We're probably dead in the water, - // but let's try to stumble on... - env->ExceptionClear(); - } - static jclass errnoExceptionClass = - MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/system/ErrnoException")); - - static jmethodID errnoExceptionCtor = - GetMethodIDOrDie(env, errnoExceptionClass, "<init>", "(Ljava/lang/String;I)V"); - - jobject exception = - env->NewObject(errnoExceptionClass, errnoExceptionCtor, detailMessage.get(), error); - env->Throw(reinterpret_cast<jthrowable>(exception)); -} - // Wrapper function to the syscall pidfd_open, which creates a file // descriptor that refers to the process whose PID is specified in pid. static inline int sys_pidfd_open(pid_t pid, unsigned int flags) { @@ -1317,7 +1299,7 @@ static inline int sys_pidfd_open(pid_t pid, unsigned int flags) { static jint android_os_Process_nativePidFdOpen(JNIEnv* env, jobject, jint pid, jint flags) { int fd = sys_pidfd_open(pid, flags); if (fd < 0) { - throwErrnoException(env, "nativePidFdOpen", errno); + jniThrowErrnoException(env, "nativePidFdOpen", errno); return -1; } return fd; diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 22a79ed12c24..0f6f15de6458 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -327,9 +327,6 @@ <item>"0,1"</item> </string-array> - <!-- The maximum duration (in milliseconds) we expect a network transition to take --> - <integer name="config_networkTransitionTimeout">60000</integer> - <!-- Whether/how to notify the user on network switches. See LingerMonitor.java. --> <integer translatable="false" name="config_networkNotifySwitchType">0</integer> @@ -342,16 +339,6 @@ Settings.Global.NETWORK_AVOID_BAD_WIFI. This is the default value of that setting. --> <integer translatable="false" name="config_networkAvoidBadWifi">1</integer> - <!-- Configuration hook for the URL returned by ConnectivityManager#getCaptivePortalServerUrl. - If empty, the returned value is controlled by Settings.Global.CAPTIVE_PORTAL_HTTP_URL, - and if that value is empty, the framework will use a hard-coded default. - This is *NOT* a URL that will always be used by the system network validation to detect - captive portals: NetworkMonitor may use different strategies and will not necessarily use - this URL. NetworkMonitor behaviour should be configured with NetworkStack resource overlays - instead. --> - <!--suppress CheckTagEmptyBody --> - <string translatable="false" name="config_networkCaptivePortalServerUrl"></string> - <!-- If the hardware supports specially marking packets that caused a wakeup of the main CPU, set this value to the mark used. --> <integer name="config_networkWakeupPacketMark">0</integer> @@ -459,14 +446,6 @@ apps requested it. --> <bool name="config_vehicleInternalNetworkAlwaysRequested">false</bool> - <!-- Configuration of network interfaces that support WakeOnLAN --> - <string-array translatable="false" name="config_wakeonlan_supported_interfaces"> - <!-- - <item>wlan0</item> - <item>eth0</item> - --> - </string-array> - <!-- This setting is deprecated, please use com.android.networkstack.tethering.R.array.config_mobile_hotspot_provision_app instead. --> <string-array translatable="false" name="config_mobile_hotspot_provision_app"> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index fc75463a44fa..ad24b79779d4 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -685,7 +685,6 @@ <java-symbol type="string" name="not_checked" /> <java-symbol type="array" name="config_ethernet_interfaces" /> <java-symbol type="bool" name="config_vehicleInternalNetworkAlwaysRequested" /> - <java-symbol type="array" name="config_wakeonlan_supported_interfaces" /> <java-symbol type="string" name="config_forceVoiceInteractionServicePackage" /> <java-symbol type="string" name="config_mms_user_agent" /> <java-symbol type="string" name="config_mms_user_agent_profile_url" /> @@ -1951,11 +1950,9 @@ <java-symbol type="integer" name="config_lowBatteryCloseWarningBump" /> <java-symbol type="integer" name="config_lowBatteryWarningLevel" /> <java-symbol type="integer" name="config_networkPolicyDefaultWarning" /> - <java-symbol type="integer" name="config_networkTransitionTimeout" /> <java-symbol type="integer" name="config_networkNotifySwitchType" /> <java-symbol type="array" name="config_networkNotifySwitches" /> <java-symbol type="integer" name="config_networkAvoidBadWifi" /> - <java-symbol type="string" name="config_networkCaptivePortalServerUrl" /> <java-symbol type="integer" name="config_networkWakeupPacketMark" /> <java-symbol type="integer" name="config_networkWakeupPacketMask" /> <java-symbol type="bool" name="config_apfDrop802_3Frames" /> diff --git a/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java index c01bb75c32aa..e41805dd3a59 100644 --- a/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java +++ b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java @@ -22,7 +22,6 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import android.os.PersistableBundle; import android.os.RemoteException; @@ -32,6 +31,7 @@ import androidx.test.filters.SmallTest; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import java.util.concurrent.Executor; @@ -42,51 +42,23 @@ import java.util.concurrent.Executor; @RunWith(AndroidJUnit4.class) public class RangingManagerTest { - private static final IUwbAdapter ADAPTER = mock(IUwbAdapter.class); private static final Executor EXECUTOR = UwbTestUtils.getExecutor(); private static final PersistableBundle PARAMS = new PersistableBundle(); private static final @RangingChangeReason int REASON = RangingChangeReason.UNKNOWN; @Test public void testOpenSession_OpenRangingInvoked() throws RemoteException { - RangingManager rangingManager = new RangingManager(ADAPTER); + IUwbAdapter adapter = mock(IUwbAdapter.class); + RangingManager rangingManager = new RangingManager(adapter); RangingSession.Callback callback = mock(RangingSession.Callback.class); rangingManager.openSession(PARAMS, EXECUTOR, callback); - verify(ADAPTER, times(1)).openRanging(eq(rangingManager), eq(PARAMS)); - } - - @Test - public void testOpenSession_ErrorIfSameSessionHandleReturned() throws RemoteException { - RangingManager rangingManager = new RangingManager(ADAPTER); - RangingSession.Callback callback = mock(RangingSession.Callback.class); - SessionHandle handle = new SessionHandle(1); - when(ADAPTER.openRanging(any(), any())).thenReturn(handle); - - rangingManager.openSession(PARAMS, EXECUTOR, callback); - - // Calling openSession will cause the same session handle to be returned. The onClosed - // callback should be invoked - RangingSession.Callback callback2 = mock(RangingSession.Callback.class); - rangingManager.openSession(PARAMS, EXECUTOR, callback2); - verify(callback, times(0)).onClosed(anyInt(), any()); - verify(callback2, times(1)).onClosed(anyInt(), any()); - } - - @Test - public void testOnRangingOpened_ValidSessionHandle() throws RemoteException { - RangingManager rangingManager = new RangingManager(ADAPTER); - RangingSession.Callback callback = mock(RangingSession.Callback.class); - SessionHandle handle = new SessionHandle(1); - when(ADAPTER.openRanging(any(), any())).thenReturn(handle); - - rangingManager.openSession(PARAMS, EXECUTOR, callback); - rangingManager.onRangingOpened(handle); - verify(callback, times(1)).onOpened(any()); + verify(adapter, times(1)).openRanging(any(), eq(rangingManager), eq(PARAMS)); } @Test public void testOnRangingOpened_InvalidSessionHandle() throws RemoteException { - RangingManager rangingManager = new RangingManager(ADAPTER); + IUwbAdapter adapter = mock(IUwbAdapter.class); + RangingManager rangingManager = new RangingManager(adapter); RangingSession.Callback callback = mock(RangingSession.Callback.class); rangingManager.onRangingOpened(new SessionHandle(2)); @@ -95,18 +67,20 @@ public class RangingManagerTest { @Test public void testOnRangingOpened_MultipleSessionsRegistered() throws RemoteException { - SessionHandle sessionHandle1 = new SessionHandle(1); - SessionHandle sessionHandle2 = new SessionHandle(2); + IUwbAdapter adapter = mock(IUwbAdapter.class); RangingSession.Callback callback1 = mock(RangingSession.Callback.class); RangingSession.Callback callback2 = mock(RangingSession.Callback.class); + ArgumentCaptor<SessionHandle> sessionHandleCaptor = + ArgumentCaptor.forClass(SessionHandle.class); - when(ADAPTER.openRanging(any(), any())) - .thenReturn(sessionHandle1) - .thenReturn(sessionHandle2); - - RangingManager rangingManager = new RangingManager(ADAPTER); + RangingManager rangingManager = new RangingManager(adapter); rangingManager.openSession(PARAMS, EXECUTOR, callback1); + verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any()); + SessionHandle sessionHandle1 = sessionHandleCaptor.getValue(); + rangingManager.openSession(PARAMS, EXECUTOR, callback2); + verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any()); + SessionHandle sessionHandle2 = sessionHandleCaptor.getValue(); rangingManager.onRangingOpened(sessionHandle1); verify(callback1, times(1)).onOpened(any()); @@ -119,12 +93,17 @@ public class RangingManagerTest { @Test public void testCorrectCallbackInvoked() throws RemoteException { - RangingManager rangingManager = new RangingManager(ADAPTER); + IUwbAdapter adapter = mock(IUwbAdapter.class); + RangingManager rangingManager = new RangingManager(adapter); RangingSession.Callback callback = mock(RangingSession.Callback.class); - SessionHandle handle = new SessionHandle(1); - when(ADAPTER.openRanging(any(), any())).thenReturn(handle); + + ArgumentCaptor<SessionHandle> sessionHandleCaptor = + ArgumentCaptor.forClass(SessionHandle.class); rangingManager.openSession(PARAMS, EXECUTOR, callback); + verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any()); + SessionHandle handle = sessionHandleCaptor.getValue(); + rangingManager.onRangingOpened(handle); verify(callback, times(1)).onOpened(any()); @@ -156,20 +135,23 @@ public class RangingManagerTest { @Test public void testOnRangingClosed_MultipleSessionsRegistered() throws RemoteException { + IUwbAdapter adapter = mock(IUwbAdapter.class); // Verify that if multiple sessions are registered, only the session that is // requested to close receives the associated callbacks - SessionHandle sessionHandle1 = new SessionHandle(1); - SessionHandle sessionHandle2 = new SessionHandle(2); RangingSession.Callback callback1 = mock(RangingSession.Callback.class); RangingSession.Callback callback2 = mock(RangingSession.Callback.class); - when(ADAPTER.openRanging(any(), any())) - .thenReturn(sessionHandle1) - .thenReturn(sessionHandle2); + RangingManager rangingManager = new RangingManager(adapter); + ArgumentCaptor<SessionHandle> sessionHandleCaptor = + ArgumentCaptor.forClass(SessionHandle.class); - RangingManager rangingManager = new RangingManager(ADAPTER); rangingManager.openSession(PARAMS, EXECUTOR, callback1); + verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any()); + SessionHandle sessionHandle1 = sessionHandleCaptor.getValue(); + rangingManager.openSession(PARAMS, EXECUTOR, callback2); + verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any()); + SessionHandle sessionHandle2 = sessionHandleCaptor.getValue(); rangingManager.onRangingClosed(sessionHandle1, REASON, PARAMS); verify(callback1, times(1)).onClosed(anyInt(), any()); @@ -182,19 +164,22 @@ public class RangingManagerTest { @Test public void testOnRangingReport_MultipleSessionsRegistered() throws RemoteException { - SessionHandle sessionHandle1 = new SessionHandle(1); - SessionHandle sessionHandle2 = new SessionHandle(2); + IUwbAdapter adapter = mock(IUwbAdapter.class); RangingSession.Callback callback1 = mock(RangingSession.Callback.class); RangingSession.Callback callback2 = mock(RangingSession.Callback.class); - when(ADAPTER.openRanging(any(), any())) - .thenReturn(sessionHandle1) - .thenReturn(sessionHandle2); + ArgumentCaptor<SessionHandle> sessionHandleCaptor = + ArgumentCaptor.forClass(SessionHandle.class); - RangingManager rangingManager = new RangingManager(ADAPTER); + RangingManager rangingManager = new RangingManager(adapter); rangingManager.openSession(PARAMS, EXECUTOR, callback1); + verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any()); + SessionHandle sessionHandle1 = sessionHandleCaptor.getValue(); + rangingManager.onRangingStarted(sessionHandle1, PARAMS); rangingManager.openSession(PARAMS, EXECUTOR, callback2); + verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any()); + SessionHandle sessionHandle2 = sessionHandleCaptor.getValue(); rangingManager.onRangingStarted(sessionHandle2, PARAMS); rangingManager.onRangingResult(sessionHandle1, UwbTestUtils.getRangingReports(1)); @@ -232,17 +217,24 @@ public class RangingManagerTest { private void runReason(@RangingChangeReason int reasonIn, @RangingSession.Callback.Reason int reasonOut) throws RemoteException { - RangingManager rangingManager = new RangingManager(ADAPTER); + IUwbAdapter adapter = mock(IUwbAdapter.class); + RangingManager rangingManager = new RangingManager(adapter); RangingSession.Callback callback = mock(RangingSession.Callback.class); - SessionHandle handle = new SessionHandle(1); - when(ADAPTER.openRanging(any(), any())).thenReturn(handle); + + ArgumentCaptor<SessionHandle> sessionHandleCaptor = + ArgumentCaptor.forClass(SessionHandle.class); + rangingManager.openSession(PARAMS, EXECUTOR, callback); + verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any()); + SessionHandle handle = sessionHandleCaptor.getValue(); rangingManager.onRangingOpenFailed(handle, reasonIn, PARAMS); verify(callback, times(1)).onOpenFailed(eq(reasonOut), eq(PARAMS)); // Open a new session rangingManager.openSession(PARAMS, EXECUTOR, callback); + verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any()); + handle = sessionHandleCaptor.getValue(); rangingManager.onRangingOpened(handle); rangingManager.onRangingStartFailed(handle, reasonIn, PARAMS); diff --git a/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java b/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java index 8e7f7c562ade..75c6924a1939 100644 --- a/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java +++ b/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java @@ -16,34 +16,23 @@ package android.uwb; -import android.content.Context; -import android.content.pm.PackageManager; import android.os.SystemClock; -import java.util.ArrayList; -import java.util.List; import java.util.concurrent.Executor; public class UwbTestUtils { private UwbTestUtils() {} - public static boolean isUwbSupported(Context context) { - PackageManager packageManager = context.getPackageManager(); - return packageManager.hasSystemFeature(PackageManager.FEATURE_UWB); - } - public static AngleMeasurement getAngleMeasurement() { - return new AngleMeasurement.Builder() - .setRadians(getDoubleInRange(-Math.PI, Math.PI)) - .setErrorRadians(getDoubleInRange(0, Math.PI)) - .setConfidenceLevel(getDoubleInRange(0, 1)) - .build(); + return new AngleMeasurement( + getDoubleInRange(-Math.PI, Math.PI), + getDoubleInRange(0, Math.PI), + getDoubleInRange(0, 1)); } public static AngleOfArrivalMeasurement getAngleOfArrivalMeasurement() { - return new AngleOfArrivalMeasurement.Builder() + return new AngleOfArrivalMeasurement.Builder(getAngleMeasurement()) .setAltitude(getAngleMeasurement()) - .setAzimuth(getAngleMeasurement()) .build(); } @@ -69,14 +58,6 @@ public class UwbTestUtils { .build(); } - public static List<RangingMeasurement> getRangingMeasurements(int num) { - List<RangingMeasurement> result = new ArrayList<>(); - for (int i = 0; i < num; i++) { - result.add(getRangingMeasurement()); - } - return result; - } - public static RangingReport getRangingReports(int numMeasurements) { RangingReport.Builder builder = new RangingReport.Builder(); for (int i = 0; i < numMeasurements; i++) { diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt index 4b3336644ef9..c3b1800af2aa 100644 --- a/packages/Connectivity/framework/api/module-lib-current.txt +++ b/packages/Connectivity/framework/api/module-lib-current.txt @@ -8,9 +8,13 @@ package android.net { public class ConnectivityManager { method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public java.util.List<android.net.NetworkStateSnapshot> getAllNetworkStateSnapshot(); method @NonNull public static android.util.Range<java.lang.Integer> getIpSecNetIdRange(); + method @NonNull public static String getPrivateDnsMode(@NonNull android.content.ContentResolver); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @NonNull android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback); method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle); + field public static final String PRIVATE_DNS_MODE_OFF = "off"; + field public static final String PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic"; + field public static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = "hostname"; } public final class NetworkAgentConfig implements android.os.Parcelable { @@ -25,6 +29,11 @@ package android.net { field public static final int TRANSPORT_TEST = 7; // 0x7 } + public class ParseException extends java.lang.RuntimeException { + ctor public ParseException(@NonNull String); + ctor public ParseException(@NonNull String, @NonNull Throwable); + } + public final class TcpRepairWindow { ctor public TcpRepairWindow(int, int, int, int, int, int); field public final int maxWindow; diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java index 8c66db9a205a..8b669284adc1 100644 --- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java +++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java @@ -23,6 +23,8 @@ import static android.net.NetworkRequest.Type.TRACK_BEST; import static android.net.NetworkRequest.Type.TRACK_DEFAULT; import static android.net.NetworkRequest.Type.TRACK_SYSTEM_DEFAULT; import static android.net.QosCallback.QosCallbackRegistrationException; +import static android.provider.Settings.Global.PRIVATE_DNS_DEFAULT_MODE; +import static android.provider.Settings.Global.PRIVATE_DNS_MODE; import android.annotation.CallbackExecutor; import android.annotation.IntDef; @@ -31,11 +33,13 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.annotation.StringDef; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.app.PendingIntent; import android.compat.annotation.UnsupportedAppUsage; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.net.IpSecManager.UdpEncapsulationSocket; @@ -63,6 +67,7 @@ import android.os.ServiceSpecificException; import android.provider.Settings; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; +import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; import android.util.Range; @@ -802,24 +807,27 @@ public class ConnectivityManager { /** * @hide */ + @SystemApi(client = MODULE_LIBRARIES) public static final String PRIVATE_DNS_MODE_OFF = "off"; /** * @hide */ + @SystemApi(client = MODULE_LIBRARIES) public static final String PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic"; /** * @hide */ + @SystemApi(client = MODULE_LIBRARIES) public static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = "hostname"; - /** - * The default Private DNS mode. - * - * This may change from release to release or may become dependent upon - * the capabilities of the underlying platform. - * - * @hide - */ - public static final String PRIVATE_DNS_DEFAULT_MODE_FALLBACK = PRIVATE_DNS_MODE_OPPORTUNISTIC; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @StringDef(value = { + PRIVATE_DNS_MODE_OFF, + PRIVATE_DNS_MODE_OPPORTUNISTIC, + PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, + }) + public @interface PrivateDnsMode {} @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562) private final IConnectivityManager mService; @@ -3205,23 +3213,6 @@ public class ConnectivityManager { } } - // TODO : remove this method. It is a stopgap measure to help sheperding a number - // of dependent changes that would conflict throughout the automerger graph. Having this - // temporarily helps with the process of going through with all these dependent changes across - // the entire tree. - /** - * @hide - * Register a NetworkAgent with ConnectivityService. - * @return Network corresponding to NetworkAgent. - */ - @RequiresPermission(anyOf = { - NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, - android.Manifest.permission.NETWORK_FACTORY}) - public Network registerNetworkAgent(INetworkAgent na, NetworkInfo ni, LinkProperties lp, - NetworkCapabilities nc, int score, NetworkAgentConfig config) { - return registerNetworkAgent(na, ni, lp, nc, score, config, NetworkProvider.ID_NONE); - } - /** * @hide * Register a NetworkAgent with ConnectivityService. @@ -3231,7 +3222,8 @@ public class ConnectivityManager { NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_FACTORY}) public Network registerNetworkAgent(INetworkAgent na, NetworkInfo ni, LinkProperties lp, - NetworkCapabilities nc, int score, NetworkAgentConfig config, int providerId) { + NetworkCapabilities nc, @NonNull NetworkScore score, NetworkAgentConfig config, + int providerId) { try { return mService.registerNetworkAgent(na, ni, lp, nc, score, config, providerId); } catch (RemoteException e) { @@ -5113,9 +5105,9 @@ public class ConnectivityManager { } // The first network ID of IPSec tunnel interface. - private static final int TUN_INTF_NETID_START = 0xFC00; + private static final int TUN_INTF_NETID_START = 0xFC00; // 0xFC00 = 64512 // The network ID range of IPSec tunnel interface. - private static final int TUN_INTF_NETID_RANGE = 0x0400; + private static final int TUN_INTF_NETID_RANGE = 0x0400; // 0x0400 = 1024 /** * Get the network ID range reserved for IPSec tunnel interfaces. @@ -5128,4 +5120,24 @@ public class ConnectivityManager { public static Range<Integer> getIpSecNetIdRange() { return new Range(TUN_INTF_NETID_START, TUN_INTF_NETID_START + TUN_INTF_NETID_RANGE - 1); } + + /** + * Get private DNS mode from settings. + * + * @param cr The ContentResolver to query private DNS mode from settings. + * @return A string of private DNS mode as one of the PRIVATE_DNS_MODE_* constants. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + @NonNull + @PrivateDnsMode + public static String getPrivateDnsMode(@NonNull ContentResolver cr) { + String mode = Settings.Global.getString(cr, PRIVATE_DNS_MODE); + if (TextUtils.isEmpty(mode)) mode = Settings.Global.getString(cr, PRIVATE_DNS_DEFAULT_MODE); + // If both PRIVATE_DNS_MODE and PRIVATE_DNS_DEFAULT_MODE are not set, choose + // PRIVATE_DNS_MODE_OPPORTUNISTIC as default mode. + if (TextUtils.isEmpty(mode)) mode = PRIVATE_DNS_MODE_OPPORTUNISTIC; + return mode; + } } diff --git a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl index f9393e315b83..1bbf1a95fcca 100644 --- a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl +++ b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl @@ -30,6 +30,7 @@ import android.net.NetworkAgentConfig; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkRequest; +import android.net.NetworkScore; import android.net.NetworkState; import android.net.NetworkStateSnapshot; import android.net.OemNetworkPreferences; @@ -138,7 +139,7 @@ interface IConnectivityManager void declareNetworkRequestUnfulfillable(in NetworkRequest request); Network registerNetworkAgent(in INetworkAgent na, in NetworkInfo ni, in LinkProperties lp, - in NetworkCapabilities nc, int score, in NetworkAgentConfig config, + in NetworkCapabilities nc, in NetworkScore score, in NetworkAgentConfig config, in int factorySerialNumber); NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities, int reqType, diff --git a/packages/Connectivity/framework/src/android/net/IpPrefix.java b/packages/Connectivity/framework/src/android/net/IpPrefix.java index d2ee7d13b05f..bf4481afc53d 100644 --- a/packages/Connectivity/framework/src/android/net/IpPrefix.java +++ b/packages/Connectivity/framework/src/android/net/IpPrefix.java @@ -113,7 +113,7 @@ public final class IpPrefix implements Parcelable { // first statement in constructor". We could factor out setting the member variables to an // init() method, but if we did, then we'd have to make the members non-final, or "error: // cannot assign a value to final variable address". So we just duplicate the code here. - Pair<InetAddress, Integer> ipAndMask = NetworkUtils.parseIpAndMask(prefix); + Pair<InetAddress, Integer> ipAndMask = NetworkUtils.legacyParseIpAndMask(prefix); this.address = ipAndMask.first.getAddress(); this.prefixLength = ipAndMask.second; checkAndMaskAddressAndPrefixLength(); diff --git a/packages/Connectivity/framework/src/android/net/LinkAddress.java b/packages/Connectivity/framework/src/android/net/LinkAddress.java index d1bdaa078cdc..d48b8c71f495 100644 --- a/packages/Connectivity/framework/src/android/net/LinkAddress.java +++ b/packages/Connectivity/framework/src/android/net/LinkAddress.java @@ -325,7 +325,7 @@ public class LinkAddress implements Parcelable { public LinkAddress(@NonNull String address, int flags, int scope) { // This may throw an IllegalArgumentException; catching it is the caller's responsibility. // TODO: consider rejecting mapped IPv4 addresses such as "::ffff:192.0.2.5/24". - Pair<InetAddress, Integer> ipAndMask = NetworkUtils.parseIpAndMask(address); + Pair<InetAddress, Integer> ipAndMask = NetworkUtils.legacyParseIpAndMask(address); init(ipAndMask.first, ipAndMask.second, flags, scope, LIFETIME_UNKNOWN, LIFETIME_UNKNOWN); } diff --git a/packages/Connectivity/framework/src/android/net/Network.java b/packages/Connectivity/framework/src/android/net/Network.java index 46141e0d0c1e..7245db3b17db 100644 --- a/packages/Connectivity/framework/src/android/net/Network.java +++ b/packages/Connectivity/framework/src/android/net/Network.java @@ -30,10 +30,10 @@ import android.system.OsConstants; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; -import com.android.okhttp.internalandroidapi.Dns; -import com.android.okhttp.internalandroidapi.HttpURLConnectionFactory; import libcore.io.IoUtils; +import libcore.net.http.Dns; +import libcore.net.http.HttpURLConnectionFactory; import java.io.FileDescriptor; import java.io.IOException; @@ -299,7 +299,7 @@ public class Network implements Parcelable { // Set configuration on the HttpURLConnectionFactory that will be good for all // connections created by this Network. Configuration that might vary is left // until openConnection() and passed as arguments. - HttpURLConnectionFactory urlConnectionFactory = new HttpURLConnectionFactory(); + HttpURLConnectionFactory urlConnectionFactory = HttpURLConnectionFactory.createInstance(); urlConnectionFactory.setDns(dnsLookup); // Let traffic go via dnsLookup // A private connection pool just for this Network. urlConnectionFactory.setNewConnectionPool(httpMaxConnections, diff --git a/packages/Connectivity/framework/src/android/net/NetworkAgent.java b/packages/Connectivity/framework/src/android/net/NetworkAgent.java index 27aa15d1e1e4..b3ab0ee8bd3c 100644 --- a/packages/Connectivity/framework/src/android/net/NetworkAgent.java +++ b/packages/Connectivity/framework/src/android/net/NetworkAgent.java @@ -371,6 +371,14 @@ public abstract class NetworkAgent { return ni; } + // Temporary backward compatibility constructor + public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag, + @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score, + @NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider) { + this(context, looper, logTag, nc, lp, + new NetworkScore.Builder().setLegacyInt(score).build(), config, provider); + } + /** * Create a new network agent. * @param context a {@link Context} to get system services from. @@ -382,10 +390,12 @@ public abstract class NetworkAgent { * @param score the initial score of this network. Update with sendNetworkScore. * @param config an immutable {@link NetworkAgentConfig} for this agent. * @param provider the {@link NetworkProvider} managing this agent. + * @hide TODO : unhide when impl is complete */ public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag, - @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score, - @NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider) { + @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, + @NonNull NetworkScore score, @NonNull NetworkAgentConfig config, + @Nullable NetworkProvider provider) { this(looper, context, logTag, nc, lp, score, config, provider == null ? NetworkProvider.ID_NONE : provider.getProviderId(), getLegacyNetworkInfo(config)); @@ -395,12 +405,12 @@ public abstract class NetworkAgent { public final Context context; public final NetworkCapabilities capabilities; public final LinkProperties properties; - public final int score; + public final NetworkScore score; public final NetworkAgentConfig config; public final NetworkInfo info; InitialConfiguration(@NonNull Context context, @NonNull NetworkCapabilities capabilities, - @NonNull LinkProperties properties, int score, @NonNull NetworkAgentConfig config, - @NonNull NetworkInfo info) { + @NonNull LinkProperties properties, @NonNull NetworkScore score, + @NonNull NetworkAgentConfig config, @NonNull NetworkInfo info) { this.context = context; this.capabilities = capabilities; this.properties = properties; @@ -412,8 +422,9 @@ public abstract class NetworkAgent { private volatile InitialConfiguration mInitialConfiguration; private NetworkAgent(@NonNull Looper looper, @NonNull Context context, @NonNull String logTag, - @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score, - @NonNull NetworkAgentConfig config, int providerId, @NonNull NetworkInfo ni) { + @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, + @NonNull NetworkScore score, @NonNull NetworkAgentConfig config, int providerId, + @NonNull NetworkInfo ni) { mHandler = new NetworkAgentHandler(looper); LOG_TAG = logTag; mNetworkInfo = new NetworkInfo(ni); @@ -875,13 +886,22 @@ public abstract class NetworkAgent { /** * Must be called by the agent to update the score of this network. * + * @param score the new score. + * @hide TODO : unhide when impl is complete + */ + public final void sendNetworkScore(@NonNull NetworkScore score) { + Objects.requireNonNull(score); + queueOrSendMessage(reg -> reg.sendScore(score)); + } + + /** + * Must be called by the agent to update the score of this network. + * * @param score the new score, between 0 and 99. + * deprecated use sendNetworkScore(NetworkScore) TODO : remove in S. */ public final void sendNetworkScore(@IntRange(from = 0, to = 99) int score) { - if (score < 0) { - throw new IllegalArgumentException("Score must be >= 0"); - } - queueOrSendMessage(reg -> reg.sendScore(score)); + sendNetworkScore(new NetworkScore.Builder().setLegacyInt(score).build()); } /** diff --git a/packages/Connectivity/framework/src/android/net/NetworkUtils.java b/packages/Connectivity/framework/src/android/net/NetworkUtils.java index 9e42bbecbe9d..c0f262815b0c 100644 --- a/packages/Connectivity/framework/src/android/net/NetworkUtils.java +++ b/packages/Connectivity/framework/src/android/net/NetworkUtils.java @@ -27,8 +27,10 @@ import com.android.net.module.util.Inet4AddressUtils; import java.io.FileDescriptor; import java.math.BigInteger; import java.net.Inet4Address; +import java.net.Inet6Address; import java.net.InetAddress; import java.net.SocketException; +import java.net.UnknownHostException; import java.util.Locale; import java.util.TreeSet; @@ -212,7 +214,7 @@ public class NetworkUtils { @Deprecated public static InetAddress numericToInetAddress(String addrString) throws IllegalArgumentException { - return InetAddress.parseNumericAddress(addrString); + return InetAddresses.parseNumericAddress(addrString); } /** @@ -234,7 +236,7 @@ public class NetworkUtils { try { String[] pieces = ipAndMaskString.split("/", 2); prefixLength = Integer.parseInt(pieces[1]); - address = InetAddress.parseNumericAddress(pieces[0]); + address = InetAddresses.parseNumericAddress(pieces[0]); } catch (NullPointerException e) { // Null string. } catch (ArrayIndexOutOfBoundsException e) { // No prefix length. } catch (NumberFormatException e) { // Non-numeric prefix. @@ -249,6 +251,47 @@ public class NetworkUtils { } /** + * Utility method to parse strings such as "192.0.2.5/24" or "2001:db8::cafe:d00d/64". + * @hide + * + * @deprecated This method is used only for IpPrefix and LinkAddress. Since Android S, use + * {@link #parseIpAndMask(String)}, if possible. + */ + @Deprecated + public static Pair<InetAddress, Integer> legacyParseIpAndMask(String ipAndMaskString) { + InetAddress address = null; + int prefixLength = -1; + try { + String[] pieces = ipAndMaskString.split("/", 2); + prefixLength = Integer.parseInt(pieces[1]); + if (pieces[0] == null || pieces[0].isEmpty()) { + final byte[] bytes = new byte[16]; + bytes[15] = 1; + return new Pair<InetAddress, Integer>(Inet6Address.getByAddress( + "ip6-localhost"/* host */, bytes, 0 /* scope_id */), prefixLength); + } + + if (pieces[0].startsWith("[") + && pieces[0].endsWith("]") + && pieces[0].indexOf(':') != -1) { + pieces[0] = pieces[0].substring(1, pieces[0].length() - 1); + } + address = InetAddresses.parseNumericAddress(pieces[0]); + } catch (NullPointerException e) { // Null string. + } catch (ArrayIndexOutOfBoundsException e) { // No prefix length. + } catch (NumberFormatException e) { // Non-numeric prefix. + } catch (IllegalArgumentException e) { // Invalid IP address. + } catch (UnknownHostException e) { // IP address length is illegal + } + + if (address == null || prefixLength == -1) { + throw new IllegalArgumentException("Invalid IP address and mask " + ipAndMaskString); + } + + return new Pair<InetAddress, Integer>(address, prefixLength); + } + + /** * Convert a 32 char hex string into a Inet6Address. * throws a runtime exception if the string isn't 32 chars, isn't hex or can't be * made into an Inet6Address diff --git a/packages/Connectivity/framework/src/android/net/ParseException.java b/packages/Connectivity/framework/src/android/net/ParseException.java index bcfdd7ef09cc..ca6d012dfe7c 100644 --- a/packages/Connectivity/framework/src/android/net/ParseException.java +++ b/packages/Connectivity/framework/src/android/net/ParseException.java @@ -17,6 +17,7 @@ package android.net; import android.annotation.NonNull; +import android.annotation.SystemApi; /** * Thrown when parsing failed. @@ -25,12 +26,16 @@ import android.annotation.NonNull; public class ParseException extends RuntimeException { public String response; - ParseException(@NonNull String response) { + /** @hide */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public ParseException(@NonNull String response) { super(response); this.response = response; } - ParseException(@NonNull String response, @NonNull Throwable cause) { + /** @hide */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public ParseException(@NonNull String response, @NonNull Throwable cause) { super(response, cause); this.response = response; } diff --git a/packages/Connectivity/framework/src/android/net/ProxyInfo.java b/packages/Connectivity/framework/src/android/net/ProxyInfo.java index 229db0d717cd..745e20f1542e 100644 --- a/packages/Connectivity/framework/src/android/net/ProxyInfo.java +++ b/packages/Connectivity/framework/src/android/net/ProxyInfo.java @@ -129,7 +129,7 @@ public class ProxyInfo implements Parcelable { } /** - * Only used in PacProxyInstaller after Local Proxy is bound. + * Only used in PacProxyService after Local Proxy is bound. * @hide */ public ProxyInfo(@NonNull Uri pacFileUrl, int localProxyPort) { diff --git a/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java b/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java index 340141b78aa5..c5100794899a 100644 --- a/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java +++ b/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java @@ -42,9 +42,9 @@ public final class VpnTransportInfo implements TransportInfo, Parcelable { MessageUtils.findMessageNames(new Class[]{VpnManager.class}, new String[]{"TYPE_VPN_"}); /** Type of this VPN. */ - @VpnManager.VpnType public final int type; + public final int type; - public VpnTransportInfo(@VpnManager.VpnType int type) { + public VpnTransportInfo(int type) { this.type = type; } diff --git a/packages/Connectivity/framework/src/com/android/connectivity/aidl/INetworkAgentRegistry.aidl b/packages/Connectivity/framework/src/com/android/connectivity/aidl/INetworkAgentRegistry.aidl index f0193db5c2e2..18d26a7e4baf 100644 --- a/packages/Connectivity/framework/src/com/android/connectivity/aidl/INetworkAgentRegistry.aidl +++ b/packages/Connectivity/framework/src/com/android/connectivity/aidl/INetworkAgentRegistry.aidl @@ -19,11 +19,12 @@ import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkInfo; +import android.net.NetworkScore; import android.net.QosSession; import android.telephony.data.EpsBearerQosSessionAttributes; /** - * Interface for NetworkAgents to send network network properties. + * Interface for NetworkAgents to send network properties. * @hide */ oneway interface INetworkAgentRegistry { @@ -31,7 +32,7 @@ oneway interface INetworkAgentRegistry { void sendLinkProperties(in LinkProperties lp); // TODO: consider replacing this by "markConnected()" and removing void sendNetworkInfo(in NetworkInfo info); - void sendScore(int score); + void sendScore(in NetworkScore score); void sendExplicitlySelected(boolean explicitlySelected, boolean acceptPartial); void sendSocketKeepaliveEvent(int slot, int reason); void sendUnderlyingNetworks(in @nullable List<Network> networks); diff --git a/packages/Connectivity/service/Android.bp b/packages/Connectivity/service/Android.bp index e65b7b423bdc..f630ceac3662 100644 --- a/packages/Connectivity/service/Android.bp +++ b/packages/Connectivity/service/Android.bp @@ -50,24 +50,38 @@ cc_library_shared { } java_library { - name: "service-connectivity", + name: "service-connectivity-pre-jarjar", srcs: [ + ":framework-connectivity-shared-srcs", ":connectivity-service-srcs", ], - installable: true, - jarjar_rules: "jarjar-rules.txt", libs: [ "android.net.ipsec.ike", "services.core", "services.net", "unsupportedappusage", + "ServiceConnectivityResources", ], static_libs: [ "modules-utils-os", "net-utils-device-common", "net-utils-framework-common", "netd-client", + "PlatformProperties", + ], + apex_available: [ + "//apex_available:platform", + "com.android.tethering", ], +} + +java_library { + name: "service-connectivity", + installable: true, + static_libs: [ + "service-connectivity-pre-jarjar", + ], + jarjar_rules: "jarjar-rules.txt", apex_available: [ "//apex_available:platform", "com.android.tethering", diff --git a/packages/Connectivity/service/ServiceConnectivityResources/Android.bp b/packages/Connectivity/service/ServiceConnectivityResources/Android.bp new file mode 100644 index 000000000000..f2446b7f7eb8 --- /dev/null +++ b/packages/Connectivity/service/ServiceConnectivityResources/Android.bp @@ -0,0 +1,35 @@ +// +// Copyright (C) 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// APK to hold all the wifi overlayable resources. +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +android_app { + name: "ServiceConnectivityResources", + sdk_version: "system_current", + resource_dirs: [ + "res", + ], + privileged: true, + export_package_resources: true, + apex_available: [ + "com.android.tethering", + ], + // TODO: use a dedicated cert once generated + certificate: "platform", +} diff --git a/packages/Connectivity/service/ServiceConnectivityResources/AndroidManifest.xml b/packages/Connectivity/service/ServiceConnectivityResources/AndroidManifest.xml new file mode 100644 index 000000000000..2c303026158e --- /dev/null +++ b/packages/Connectivity/service/ServiceConnectivityResources/AndroidManifest.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<!-- Manifest for connectivity resources APK --> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.connectivity.resources" + coreApp="true" + android:versionCode="1" + android:versionName="S-initial"> + <application + android:label="@string/connectivityResourcesAppLabel" + android:defaultToDeviceProtectedStorage="true" + android:directBootAware="true"> + <!-- This is only used to identify this app by resolving the action. + The activity is never actually triggered. --> + <activity android:name="android.app.Activity" android:exported="true" android:enabled="true"> + <intent-filter> + <action android:name="com.android.server.connectivity.intent.action.SERVICE_CONNECTIVITY_RESOURCES_APK" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values/config.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values/config.xml new file mode 100644 index 000000000000..7d98c76a40ba --- /dev/null +++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values/config.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2021 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT 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 values for ConnectivityService + DO NOT EDIT THIS FILE for specific device configuration; instead, use a Runtime Resources + Overlay package following the overlayable.xml configuration in the same directory: + https://source.android.com/devices/architecture/rros --> +<resources> + + <!-- Configuration hook for the URL returned by ConnectivityManager#getCaptivePortalServerUrl. + If empty, the returned value is controlled by Settings.Global.CAPTIVE_PORTAL_HTTP_URL, + and if that value is empty, the framework will use a hard-coded default. + This is *NOT* a URL that will always be used by the system network validation to detect + captive portals: NetworkMonitor may use different strategies and will not necessarily use + this URL. NetworkMonitor behaviour should be configured with NetworkStack resource overlays + instead. --> + <!--suppress CheckTagEmptyBody --> + <string translatable="false" name="config_networkCaptivePortalServerUrl"></string> + + <!-- The maximum duration (in milliseconds) we expect a network transition to take --> + <integer name="config_networkTransitionTimeout">60000</integer> + + <!-- Configuration of network interfaces that support WakeOnLAN --> + <string-array translatable="false" name="config_wakeonlan_supported_interfaces"> + <!-- + <item>wlan0</item> + <item>eth0</item> + --> + </string-array> + +</resources>
\ No newline at end of file diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values/overlayable.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values/overlayable.xml new file mode 100644 index 000000000000..00ec2df0e6f1 --- /dev/null +++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values/overlayable.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- Copyright (C) 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android"> + <overlayable name="ServiceConnectivityResourcesConfig"> + <policy type="product|system|vendor"> + <!-- Configuration values for ConnectivityService --> + <item type="string" name="config_networkCaptivePortalServerUrl"/> + <item type="integer" name="config_networkTransitionTimeout"/> + <item type="array" name="config_wakeonlan_supported_interfaces"/> + + + </policy> + </overlayable> +</resources> diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values/strings.xml new file mode 100644 index 000000000000..2c7b99265019 --- /dev/null +++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2021 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<resources> + <!-- The System Connectivity Resources package is an internal system package that provides + configuration values for system networking that were pre-configured in the device. This + is the name of the package to display in the list of system apps. [CHAR LIMIT=40] --> + <string name="connectivityResourcesAppLabel">System Connectivity Resources</string> +</resources>
\ No newline at end of file diff --git a/packages/Connectivity/service/jarjar-rules.txt b/packages/Connectivity/service/jarjar-rules.txt index d8205bf780fd..a7b419b020b5 100644 --- a/packages/Connectivity/service/jarjar-rules.txt +++ b/packages/Connectivity/service/jarjar-rules.txt @@ -1,2 +1,14 @@ +rule android.sysprop.** com.android.connectivity.sysprop.@1 rule com.android.net.module.util.** com.android.connectivity.net-utils.@1 -rule com.android.modules.utils.** com.android.connectivity.modules-utils.@1
\ No newline at end of file +rule com.android.modules.utils.** com.android.connectivity.modules-utils.@1 + +# internal util classes +# Exclude AsyncChannel. TODO: remove AsyncChannel usage in ConnectivityService +rule com.android.internal.util.AsyncChannel* @0 +# Exclude LocationPermissionChecker. This is going to be moved to libs/net +rule com.android.internal.util.LocationPermissionChecker* @0 +rule android.util.LocalLog* com.android.connectivity.util.LocalLog@1 +# android.util.IndentingPrintWriter* should use a different package name from +# the one in com.android.internal.util +rule android.util.IndentingPrintWriter* android.connectivity.util.IndentingPrintWriter@1 +rule com.android.internal.util.** com.android.connectivity.util.@1 diff --git a/packages/CtsShim/apk/arm/CtsShim.apk b/packages/CtsShim/apk/arm/CtsShim.apk Binary files differindex 180dfb672c7f..784a74701b4f 100644 --- a/packages/CtsShim/apk/arm/CtsShim.apk +++ b/packages/CtsShim/apk/arm/CtsShim.apk diff --git a/packages/CtsShim/apk/arm/CtsShimPriv.apk b/packages/CtsShim/apk/arm/CtsShimPriv.apk Binary files differindex d87ea7fcef89..5b7bda4d4f84 100644 --- a/packages/CtsShim/apk/arm/CtsShimPriv.apk +++ b/packages/CtsShim/apk/arm/CtsShimPriv.apk diff --git a/packages/CtsShim/apk/x86/CtsShim.apk b/packages/CtsShim/apk/x86/CtsShim.apk Binary files differindex 180dfb672c7f..784a74701b4f 100644 --- a/packages/CtsShim/apk/x86/CtsShim.apk +++ b/packages/CtsShim/apk/x86/CtsShim.apk diff --git a/packages/CtsShim/apk/x86/CtsShimPriv.apk b/packages/CtsShim/apk/x86/CtsShimPriv.apk Binary files differindex 3124651fe425..780cb8a72526 100644 --- a/packages/CtsShim/apk/x86/CtsShimPriv.apk +++ b/packages/CtsShim/apk/x86/CtsShimPriv.apk diff --git a/packages/CtsShim/build/shim/AndroidManifest.xml b/packages/CtsShim/build/shim/AndroidManifest.xml index 3e546f1e02db..58e85220fefe 100644 --- a/packages/CtsShim/build/shim/AndroidManifest.xml +++ b/packages/CtsShim/build/shim/AndroidManifest.xml @@ -52,6 +52,9 @@ </intent-filter> </activity> + <!-- The stub shared library for package visibility test --> + <library android:name="com.android.cts.ctsshim.shared_library" /> + </application> </manifest> diff --git a/packages/SettingsLib/src/com/android/settingslib/connectivity/OWNERS b/packages/SettingsLib/src/com/android/settingslib/connectivity/OWNERS index e7a20b3f73a4..c88ed8e96f99 100644 --- a/packages/SettingsLib/src/com/android/settingslib/connectivity/OWNERS +++ b/packages/SettingsLib/src/com/android/settingslib/connectivity/OWNERS @@ -1,6 +1,7 @@ # Default reviewers for this and subdirectories. andychou@google.com arcwang@google.com +changbetty@google.com goldmanj@google.com qal@google.com wengsu@google.com diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS b/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS index 0bde5c030eb0..f3b600c8e9c1 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS @@ -2,6 +2,7 @@ andychou@google.com arcwang@google.com asapperstein@google.com +changbetty@google.com goldmanj@google.com qal@google.com wengsu@google.com diff --git a/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java b/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java index f8b9309f9a7f..f0de81183919 100644 --- a/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java +++ b/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java @@ -360,7 +360,7 @@ public class ProxyServer extends Thread { try { mCallback.setProxyPort(port); } catch (RemoteException e) { - Log.w(TAG, "Proxy failed to report port to PacProxyInstaller", e); + Log.w(TAG, "Proxy failed to report port to PacProxyService", e); } } mPort = port; @@ -371,7 +371,7 @@ public class ProxyServer extends Thread { try { callback.setProxyPort(mPort); } catch (RemoteException e) { - Log.w(TAG, "Proxy failed to report port to PacProxyInstaller", e); + Log.w(TAG, "Proxy failed to report port to PacProxyService", e); } } mCallback = callback; diff --git a/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java b/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java index bdf478d36c8c..a8e26221a7ab 100644 --- a/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java +++ b/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java @@ -30,7 +30,7 @@ public class ProxyService extends Service { private static ProxyServer server = null; - /** Keep these values up-to-date with PacProxyInstaller.java */ + /** Keep these values up-to-date with PacProxyService.java */ public static final String KEY_PROXY = "keyProxy"; public static final String HOST = "localhost"; public static final String EXCL_LIST = ""; diff --git a/services/core/Android.bp b/services/core/Android.bp index f1ab2aa8b5ec..f91e69240605 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -81,9 +81,18 @@ genrule { out: ["services.core.protolog.json"], } +genrule { + name: "statslog-art-java-gen", + tools: ["stats-log-api-gen"], + cmd: "$(location stats-log-api-gen) --java $(out) --module art" + + " --javaPackage com.android.internal.art --javaClass ArtStatsLog --worksource", + out: ["com/android/internal/art/ArtStatsLog.java"], +} + java_library_static { name: "services.core.unboosted", srcs: [ + ":statslog-art-java-gen", ":services.core.protologsrc", ":dumpstate_aidl", ":framework_native_aidl", @@ -200,6 +209,7 @@ filegroup { "java/com/android/server/TestNetworkService.java", "java/com/android/server/connectivity/AutodestructReference.java", "java/com/android/server/connectivity/ConnectivityConstants.java", + "java/com/android/server/connectivity/ConnectivityResources.java", "java/com/android/server/connectivity/DnsManager.java", "java/com/android/server/connectivity/KeepaliveTracker.java", "java/com/android/server/connectivity/LingerMonitor.java", diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index afa3bd1da6e7..92d9b08ed29d 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -117,6 +117,7 @@ import android.net.NetworkMonitorManager; import android.net.NetworkPolicyManager; import android.net.NetworkProvider; import android.net.NetworkRequest; +import android.net.NetworkScore; import android.net.NetworkSpecifier; import android.net.NetworkStack; import android.net.NetworkStackClient; @@ -188,7 +189,6 @@ import android.util.SparseArray; import android.util.SparseIntArray; import com.android.connectivity.aidl.INetworkAgent; -import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.IndentingPrintWriter; @@ -202,6 +202,7 @@ import com.android.net.module.util.LinkPropertiesUtils.CompareResult; import com.android.net.module.util.NetworkCapabilitiesUtils; import com.android.net.module.util.PermissionUtils; import com.android.server.connectivity.AutodestructReference; +import com.android.server.connectivity.ConnectivityResources; import com.android.server.connectivity.DnsManager; import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate; import com.android.server.connectivity.KeepaliveTracker; @@ -317,6 +318,7 @@ public class ConnectivityService extends IConnectivityManager.Stub private boolean mRestrictBackground; private final Context mContext; + private final ConnectivityResources mResources; // The Context is created for UserHandle.ALL. private final Context mUserAllContext; private final Dependencies mDeps; @@ -604,7 +606,6 @@ public class ConnectivityService extends IConnectivityManager.Stub private Intent mInitialBroadcast; private PowerManager.WakeLock mNetTransitionWakeLock; - private int mNetTransitionWakeLockTimeout; private final PowerManager.WakeLock mPendingIntentWakeLock; // A helper object to track the current default HTTP proxy. ConnectivityService needs to tell @@ -1012,6 +1013,13 @@ public class ConnectivityService extends IConnectivityManager.Stub } /** + * Get the {@link ConnectivityResources} to use in ConnectivityService. + */ + public ConnectivityResources getResources(@NonNull Context ctx) { + return new ConnectivityResources(ctx); + } + + /** * Create a HandlerThread to use in ConnectivityService. */ public HandlerThread makeHandlerThread() { @@ -1093,6 +1101,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mSystemProperties = mDeps.getSystemProperties(); mNetIdManager = mDeps.makeNetIdManager(); mContext = Objects.requireNonNull(context, "missing Context"); + mResources = deps.getResources(mContext); mNetworkRequestCounter = new PerUidCounter(MAX_NETWORK_REQUESTS_PER_UID); mMetricsLog = logger; @@ -1154,8 +1163,6 @@ public class ConnectivityService extends IConnectivityManager.Stub final PowerManager powerManager = (PowerManager) context.getSystemService( Context.POWER_SERVICE); mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); - mNetTransitionWakeLockTimeout = mContext.getResources().getInteger( - com.android.internal.R.integer.config_networkTransitionTimeout); mPendingIntentWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1]; @@ -1222,10 +1229,6 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - mWolSupportedInterfaces = new ArraySet( - mContext.getResources().getStringArray( - com.android.internal.R.array.config_wakeonlan_supported_interfaces)); - mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); mPermissionMonitor = new PermissionMonitor(mContext, mNetd); @@ -1271,12 +1274,18 @@ public class ConnectivityService extends IConnectivityManager.Stub mDnsManager = new DnsManager(mContext, mDnsResolver); registerPrivateDnsSettingsCallbacks(); + // This NAI is a sentinel used to offer no service to apps that are on a multi-layer + // request that doesn't allow fallback to the default network. It should never be visible + // to apps. As such, it's not in the list of NAIs and doesn't need many of the normal + // arguments like the handler or the DnsResolver. + // TODO : remove this ; it is probably better handled with a sentinel request. mNoServiceNetwork = new NetworkAgentInfo(null, new Network(NO_SERVICE_NET_ID), new NetworkInfo(TYPE_NONE, 0, "", ""), - new LinkProperties(), new NetworkCapabilities(), 0, mContext, - null, new NetworkAgentConfig(), this, null, - null, 0, INVALID_UID, mQosCallbackTracker, mDeps); + new LinkProperties(), new NetworkCapabilities(), + new NetworkScore.Builder().setLegacyInt(0).build(), mContext, null, + new NetworkAgentConfig(), this, null, null, 0, INVALID_UID, mQosCallbackTracker, + mDeps); } private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) { @@ -2947,7 +2956,7 @@ public class ConnectivityService extends IConnectivityManager.Stub break; } case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: { - updateNetworkScore(nai, msg.arg1); + updateNetworkScore(nai, (NetworkScore) arg.second); break; } case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: { @@ -3797,8 +3806,7 @@ public class ConnectivityService extends IConnectivityManager.Stub ? mNetworkRequests.get(request) : getNriForAppRequest(request); if (nri != null) { - if (Process.SYSTEM_UID != callingUid && Process.NETWORK_STACK_UID != callingUid - && nri.mUid != callingUid) { + if (Process.SYSTEM_UID != callingUid && nri.mUid != callingUid) { log(String.format("UID %d attempted to %s for unowned request %s", callingUid, requestedOperation, nri)); return null; @@ -4423,7 +4431,8 @@ public class ConnectivityService extends IConnectivityManager.Stub break; } case EVENT_PROXY_HAS_CHANGED: { - handleApplyDefaultProxy((ProxyInfo)msg.obj); + final Pair<Network, ProxyInfo> arg = (Pair<Network, ProxyInfo>) msg.obj; + handleApplyDefaultProxy(arg.second); break; } case EVENT_REGISTER_NETWORK_PROVIDER: { @@ -4600,7 +4609,9 @@ public class ConnectivityService extends IConnectivityManager.Stub } mWakelockLogs.log("ACQUIRE for " + forWhom); Message msg = mHandler.obtainMessage(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK); - mHandler.sendMessageDelayed(msg, mNetTransitionWakeLockTimeout); + final int lockTimeout = mResources.get().getInteger( + com.android.connectivity.resources.R.integer.config_networkTransitionTimeout); + mHandler.sendMessageDelayed(msg, lockTimeout); } // Called when we gain a new default network to release the network transition wakelock in a @@ -6078,20 +6089,6 @@ public class ConnectivityService extends IConnectivityManager.Stub return nai == getDefaultNetwork(); } - // TODO : remove this method. It's a stopgap measure to help sheperding a number of dependent - // changes that would conflict throughout the automerger graph. Having this method temporarily - // helps with the process of going through with all these dependent changes across the entire - // tree. - /** - * Register a new agent. {@see #registerNetworkAgent} below. - */ - public Network registerNetworkAgent(INetworkAgent na, NetworkInfo networkInfo, - LinkProperties linkProperties, NetworkCapabilities networkCapabilities, - int currentScore, NetworkAgentConfig networkAgentConfig) { - return registerNetworkAgent(na, networkInfo, linkProperties, networkCapabilities, - currentScore, networkAgentConfig, NetworkProvider.ID_NONE); - } - /** * Register a new agent with ConnectivityService to handle a network. * @@ -6102,7 +6099,7 @@ public class ConnectivityService extends IConnectivityManager.Stub * later : see {@link #updateLinkProperties}. * @param networkCapabilities the initial capabilites of this network. They can be updated * later : see {@link #updateCapabilities}. - * @param currentScore the initial score of the network. See + * @param initialScore the initial score of the network. See * {@link NetworkAgentInfo#getCurrentScore}. * @param networkAgentConfig metadata about the network. This is never updated. * @param providerId the ID of the provider owning this NetworkAgent. @@ -6110,10 +6107,12 @@ public class ConnectivityService extends IConnectivityManager.Stub */ public Network registerNetworkAgent(INetworkAgent na, NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, - int currentScore, NetworkAgentConfig networkAgentConfig, int providerId) { + @NonNull NetworkScore initialScore, NetworkAgentConfig networkAgentConfig, + int providerId) { Objects.requireNonNull(networkInfo, "networkInfo must not be null"); Objects.requireNonNull(linkProperties, "linkProperties must not be null"); Objects.requireNonNull(networkCapabilities, "networkCapabilities must not be null"); + Objects.requireNonNull(initialScore, "initialScore must not be null"); Objects.requireNonNull(networkAgentConfig, "networkAgentConfig must not be null"); if (networkCapabilities.hasTransport(TRANSPORT_TEST)) { enforceAnyPermissionOf(Manifest.permission.MANAGE_TEST_NETWORKS); @@ -6125,7 +6124,7 @@ public class ConnectivityService extends IConnectivityManager.Stub final long token = Binder.clearCallingIdentity(); try { return registerNetworkAgentInternal(na, networkInfo, linkProperties, - networkCapabilities, currentScore, networkAgentConfig, providerId, uid); + networkCapabilities, initialScore, networkAgentConfig, providerId, uid); } finally { Binder.restoreCallingIdentity(token); } @@ -6133,7 +6132,8 @@ public class ConnectivityService extends IConnectivityManager.Stub private Network registerNetworkAgentInternal(INetworkAgent na, NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, - int currentScore, NetworkAgentConfig networkAgentConfig, int providerId, int uid) { + NetworkScore currentScore, NetworkAgentConfig networkAgentConfig, int providerId, + int uid) { if (networkCapabilities.hasTransport(TRANSPORT_TEST)) { // Strictly, sanitizing here is unnecessary as the capabilities will be sanitized in // the call to mixInCapabilities below anyway, but sanitizing here means the NAI never @@ -6514,6 +6514,11 @@ public class ConnectivityService extends IConnectivityManager.Stub } private void updateWakeOnLan(@NonNull LinkProperties lp) { + if (mWolSupportedInterfaces == null) { + mWolSupportedInterfaces = new ArraySet<>(mResources.get().getStringArray( + com.android.connectivity.resources.R.array + .config_wakeonlan_supported_interfaces)); + } lp.setWakeOnLanSupported(mWolSupportedInterfaces.contains(lp.getInterfaceName())); } @@ -7852,7 +7857,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - private void updateNetworkScore(@NonNull final NetworkAgentInfo nai, final int score) { + private void updateNetworkScore(@NonNull final NetworkAgentInfo nai, final NetworkScore score) { if (VDBG || DDBG) log("updateNetworkScore for " + nai.toShortString() + " to " + score); nai.setScore(score); rematchAllNetworksAndRequests(); @@ -8075,8 +8080,8 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public String getCaptivePortalServerUrl() { enforceNetworkStackOrSettingsPermission(); - String settingUrl = mContext.getResources().getString( - R.string.config_networkCaptivePortalServerUrl); + String settingUrl = mResources.get().getString( + com.android.connectivity.resources.R.string.config_networkCaptivePortalServerUrl); if (!TextUtils.isEmpty(settingUrl)) { return settingUrl; diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS index 222c96f2496b..3bcde1204079 100644 --- a/services/core/java/com/android/server/OWNERS +++ b/services/core/java/com/android/server/OWNERS @@ -19,6 +19,7 @@ per-file ServiceWatcher.java = sooniln@google.com per-file *Alarm* = file:/apex/jobscheduler/OWNERS per-file *AppOp* = file:/core/java/android/permission/OWNERS +per-file *Battery* = file:/BATTERY_STATS_OWNERS per-file *Bluetooth* = file:/core/java/android/bluetooth/OWNERS per-file *Gnss* = file:/services/core/java/com/android/server/location/OWNERS per-file *Location* = file:/services/core/java/com/android/server/location/OWNERS diff --git a/services/core/java/com/android/server/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java index ee610671ff23..f5662772f59f 100644 --- a/services/core/java/com/android/server/TestNetworkService.java +++ b/services/core/java/com/android/server/TestNetworkService.java @@ -90,7 +90,12 @@ class TestNetworkService extends ITestNetworkManager.Stub { mCm = mContext.getSystemService(ConnectivityManager.class); mNetworkProvider = new NetworkProvider(mContext, mHandler.getLooper(), TEST_NETWORK_PROVIDER_NAME); - mCm.registerNetworkProvider(mNetworkProvider); + final long token = Binder.clearCallingIdentity(); + try { + mCm.registerNetworkProvider(mNetworkProvider); + } finally { + Binder.restoreCallingIdentity(token); + } } /** diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java index 502e74a4cc6a..1ef93f4da255 100644 --- a/services/core/java/com/android/server/VcnManagementService.java +++ b/services/core/java/com/android/server/VcnManagementService.java @@ -667,6 +667,10 @@ public class VcnManagementService extends IVcnManagementService.Stub { @NonNull IVcnUnderlyingNetworkPolicyListener listener) { requireNonNull(listener, "listener was null"); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.NETWORK_FACTORY, + "Must have permission NETWORK_FACTORY to unregister a policy listener"); + Binder.withCleanCallingIdentity(() -> { synchronized (mLock) { PolicyListenerBinderDeath listenerBinderDeath = diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java index ed3a223b5dd7..d2b642c21713 100644 --- a/services/core/java/com/android/server/clipboard/ClipboardService.java +++ b/services/core/java/com/android/server/clipboard/ClipboardService.java @@ -65,6 +65,7 @@ import com.android.server.wm.WindowManagerInternal; import java.io.IOException; import java.io.RandomAccessFile; +import java.util.Arrays; import java.util.HashSet; import java.util.List; @@ -80,21 +81,20 @@ class HostClipboardMonitor implements Runnable { private static final String PIPE_NAME = "pipe:clipboard"; private static final String PIPE_DEVICE = "/dev/qemu_pipe"; + private static byte[] createOpenHandshake() { + // String.getBytes doesn't include the null terminator, + // but the QEMU pipe device requires the pipe service name + // to be null-terminated. + + final byte[] bits = Arrays.copyOf(PIPE_NAME.getBytes(), PIPE_NAME.length() + 1); + bits[PIPE_NAME.length()] = 0; + return bits; + } + private void openPipe() { try { - // String.getBytes doesn't include the null terminator, - // but the QEMU pipe device requires the pipe service name - // to be null-terminated. - byte[] b = new byte[PIPE_NAME.length() + 1]; - b[PIPE_NAME.length()] = 0; - System.arraycopy( - PIPE_NAME.getBytes(), - 0, - b, - 0, - PIPE_NAME.length()); mPipe = new RandomAccessFile(PIPE_DEVICE, "rw"); - mPipe.write(b); + mPipe.write(createOpenHandshake()); } catch (IOException e) { try { if (mPipe != null) mPipe.close(); diff --git a/services/core/java/com/android/server/connectivity/ConnectivityResources.java b/services/core/java/com/android/server/connectivity/ConnectivityResources.java new file mode 100644 index 000000000000..45cf21e035ca --- /dev/null +++ b/services/core/java/com/android/server/connectivity/ConnectivityResources.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.connectivity; + +import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.res.Resources; +import android.util.Log; + +import com.android.server.ConnectivityService; + +import java.util.List; + +/** + * Utility to obtain the {@link ConnectivityService} {@link Resources}, in the + * ServiceConnectivityResources APK. + */ +public class ConnectivityResources { + private static final String RESOURCES_APK_INTENT = + "com.android.server.connectivity.intent.action.SERVICE_CONNECTIVITY_RESOURCES_APK"; + private static final String RES_PKG_DIR = "/apex/com.android.tethering/"; + + @NonNull + private final Context mContext; + + @Nullable + private Resources mResources = null; + + public ConnectivityResources(Context context) { + mContext = context; + } + + /** + * Get the {@link Resources} of the ServiceConnectivityResources APK. + */ + public synchronized Resources get() { + if (mResources != null) { + return mResources; + } + + final List<ResolveInfo> pkgs = mContext.getPackageManager() + .queryIntentActivities(new Intent(RESOURCES_APK_INTENT), MATCH_SYSTEM_ONLY); + pkgs.removeIf(pkg -> !pkg.activityInfo.applicationInfo.sourceDir.startsWith(RES_PKG_DIR)); + if (pkgs.size() > 1) { + Log.wtf(ConnectivityResources.class.getSimpleName(), + "More than one package found: " + pkgs); + } + if (pkgs.isEmpty()) { + throw new IllegalStateException("No connectivity resource package found"); + } + + final Context pkgContext; + try { + pkgContext = mContext.createPackageContext( + pkgs.get(0).activityInfo.applicationInfo.packageName, 0 /* flags */); + } catch (PackageManager.NameNotFoundException e) { + throw new IllegalStateException("Resolved package not found", e); + } + + mResources = pkgContext.getResources(); + return mResources; + } +} diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java index 4f6b5301e56f..7a5abf807fbb 100644 --- a/services/core/java/com/android/server/connectivity/DnsManager.java +++ b/services/core/java/com/android/server/connectivity/DnsManager.java @@ -16,7 +16,6 @@ package com.android.server.connectivity; -import static android.net.ConnectivityManager.PRIVATE_DNS_DEFAULT_MODE_FALLBACK; import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF; import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE; @@ -33,6 +32,7 @@ import android.annotation.NonNull; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.net.ConnectivityManager; import android.net.IDnsResolver; import android.net.InetAddresses; import android.net.LinkProperties; @@ -128,7 +128,7 @@ public class DnsManager { private static final int DNS_RESOLVER_DEFAULT_MAX_SAMPLES = 64; public static PrivateDnsConfig getPrivateDnsConfig(ContentResolver cr) { - final String mode = getPrivateDnsMode(cr); + final String mode = ConnectivityManager.getPrivateDnsMode(cr); final boolean useTls = !TextUtils.isEmpty(mode) && !PRIVATE_DNS_MODE_OFF.equals(mode); @@ -479,13 +479,6 @@ public class DnsManager { return result; } - private static String getPrivateDnsMode(ContentResolver cr) { - String mode = getStringSetting(cr, PRIVATE_DNS_MODE); - if (TextUtils.isEmpty(mode)) mode = getStringSetting(cr, PRIVATE_DNS_DEFAULT_MODE); - if (TextUtils.isEmpty(mode)) mode = PRIVATE_DNS_DEFAULT_MODE_FALLBACK; - return mode; - } - private static String getStringSetting(ContentResolver cr, String which) { return Settings.Global.getString(cr, which); } diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java index 803cc9d31c35..9dcc55b81a58 100644 --- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java @@ -35,6 +35,7 @@ import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkMonitorManager; import android.net.NetworkRequest; +import android.net.NetworkScore; import android.net.NetworkStateSnapshot; import android.net.QosCallbackException; import android.net.QosFilter; @@ -302,8 +303,8 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { // validated). private boolean mInactive; - // This represents the quality of the network with no clear scale. - private int mScore; + // This represents the quality of the network. + private NetworkScore mScore; // The list of NetworkRequests being satisfied by this Network. private final SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>(); @@ -338,7 +339,8 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { private final QosCallbackTracker mQosCallbackTracker; public NetworkAgentInfo(INetworkAgent na, Network net, NetworkInfo info, - @NonNull LinkProperties lp, @NonNull NetworkCapabilities nc, int score, Context context, + @NonNull LinkProperties lp, @NonNull NetworkCapabilities nc, + @NonNull NetworkScore score, Context context, Handler handler, NetworkAgentConfig config, ConnectivityService connService, INetd netd, IDnsResolver dnsResolver, int factorySerialNumber, int creatorUid, QosCallbackTracker qosCallbackTracker, ConnectivityService.Dependencies deps) { @@ -603,9 +605,9 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { } @Override - public void sendScore(int score) { - mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_SCORE_CHANGED, score, 0, - new Pair<>(NetworkAgentInfo.this, null)).sendToTarget(); + public void sendScore(@NonNull final NetworkScore score) { + mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_SCORE_CHANGED, + new Pair<>(NetworkAgentInfo.this, score)).sendToTarget(); } @Override @@ -857,7 +859,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { return ConnectivityConstants.EXPLICITLY_SELECTED_NETWORK_SCORE; } - int score = mScore; + int score = mScore.getLegacyInt(); if (!lastValidated && !pretendValidated && !ignoreWifiUnvalidationPenalty() && !isVPN()) { score -= ConnectivityConstants.UNVALIDATED_SCORE_PENALTY; } @@ -886,7 +888,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { return getCurrentScore(true); } - public void setScore(final int score) { + public void setScore(final NetworkScore score) { mScore = score; } diff --git a/services/core/java/com/android/server/connectivity/PacProxyInstaller.java b/services/core/java/com/android/server/connectivity/PacProxyService.java index aadaf4d9584f..d23b488f3054 100644 --- a/services/core/java/com/android/server/connectivity/PacProxyInstaller.java +++ b/services/core/java/com/android/server/connectivity/PacProxyService.java @@ -16,6 +16,8 @@ package com.android.server.connectivity; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.WorkerThread; import android.app.AlarmManager; import android.app.PendingIntent; @@ -26,12 +28,16 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; +import android.net.IPacProxyInstalledListener; +import android.net.IPacProxyManager; import android.net.ProxyInfo; import android.net.TrafficStats; import android.net.Uri; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.HandlerThread; import android.os.IBinder; +import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; @@ -44,6 +50,7 @@ import com.android.internal.util.TrafficStatsConstants; import com.android.net.IProxyCallback; import com.android.net.IProxyPortListener; import com.android.net.IProxyService; +import com.android.net.module.util.PermissionUtils; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -53,7 +60,7 @@ import java.net.URLConnection; /** * @hide */ -public class PacProxyInstaller { +public class PacProxyService extends IPacProxyManager.Stub { private static final String PAC_PACKAGE = "com.android.pacprocessor"; private static final String PAC_SERVICE = "com.android.pacprocessor.PacService"; private static final String PAC_SERVICE_NAME = "com.android.net.IProxyService"; @@ -61,7 +68,7 @@ public class PacProxyInstaller { private static final String PROXY_PACKAGE = "com.android.proxyhandler"; private static final String PROXY_SERVICE = "com.android.proxyhandler.ProxyService"; - private static final String TAG = "PacProxyInstaller"; + private static final String TAG = "PacProxyService"; private static final String ACTION_PAC_REFRESH = "android.net.proxy.PAC_REFRESH"; @@ -71,10 +78,6 @@ public class PacProxyInstaller { private static final int DELAY_LONG = 4; private static final long MAX_PAC_SIZE = 20 * 1000 * 1000; - // Return values for #setCurrentProxyScriptUrl - public static final boolean DONT_SEND_BROADCAST = false; - public static final boolean DO_SEND_BROADCAST = true; - private String mCurrentPac; @GuardedBy("mProxyLock") private volatile Uri mPacUrl = Uri.EMPTY; @@ -93,8 +96,8 @@ public class PacProxyInstaller { private volatile boolean mHasSentBroadcast; private volatile boolean mHasDownloaded; - private Handler mConnectivityHandler; - private final int mProxyMessage; + private final RemoteCallbackList<IPacProxyInstalledListener> + mCallbacks = new RemoteCallbackList<>(); /** * Used for locking when setting mProxyService and all references to mCurrentPac. @@ -102,6 +105,13 @@ public class PacProxyInstaller { private final Object mProxyLock = new Object(); /** + * Lock ensuring consistency between the values of mHasSentBroadcast, mHasDownloaded, the + * last URL and port, and the broadcast message being sent with the correct arguments. + * TODO : this should probably protect all instances of these variables + */ + private final Object mBroadcastStateLock = new Object(); + + /** * Runnable to download PAC script. * The behavior relies on the assumption it always runs on mNetThread to guarantee that the * latest data fetched from mPacUrl is stored in mProxyService. @@ -146,10 +156,10 @@ public class PacProxyInstaller { } } - public PacProxyInstaller(Context context, Handler handler, int proxyMessage) { + public PacProxyService(@NonNull Context context) { mContext = context; mLastPort = -1; - final HandlerThread netThread = new HandlerThread("android.pacproxyinstaller", + final HandlerThread netThread = new HandlerThread("android.pacproxyservice", android.os.Process.THREAD_PRIORITY_DEFAULT); netThread.start(); mNetThreadHandler = new Handler(netThread.getLooper()); @@ -158,8 +168,6 @@ public class PacProxyInstaller { context, 0, new Intent(ACTION_PAC_REFRESH), PendingIntent.FLAG_IMMUTABLE); context.registerReceiver(new PacRefreshIntentReceiver(), new IntentFilter(ACTION_PAC_REFRESH)); - mConnectivityHandler = handler; - mProxyMessage = proxyMessage; } private AlarmManager getAlarmManager() { @@ -169,38 +177,52 @@ public class PacProxyInstaller { return mAlarmManager; } + @Override + public void addListener(IPacProxyInstalledListener listener) { + PermissionUtils.enforceNetworkStackPermissionOr(mContext, + android.Manifest.permission.NETWORK_SETTINGS); + mCallbacks.register(listener); + } + + @Override + public void removeListener(IPacProxyInstalledListener listener) { + PermissionUtils.enforceNetworkStackPermissionOr(mContext, + android.Manifest.permission.NETWORK_SETTINGS); + mCallbacks.unregister(listener); + } + /** * Updates the PAC Proxy Installer with current Proxy information. This is called by - * the ProxyTracker directly before a broadcast takes place to allow - * the PacProxyInstaller to indicate that the broadcast should not be sent and the - * PacProxyInstaller will trigger a new broadcast when it is ready. + * the ProxyTracker through PacProxyManager before a broadcast takes place to allow + * the PacProxyService to indicate that the broadcast should not be sent and the + * PacProxyService will trigger a new broadcast when it is ready. * * @param proxy Proxy information that is about to be broadcast. - * @return Returns whether the broadcast should be sent : either DO_ or DONT_SEND_BROADCAST */ - public synchronized boolean setCurrentProxyScriptUrl(ProxyInfo proxy) { - if (!Uri.EMPTY.equals(proxy.getPacFileUrl())) { - if (proxy.getPacFileUrl().equals(mPacUrl) && (proxy.getPort() > 0)) { - // Allow to send broadcast, nothing to do. - return DO_SEND_BROADCAST; - } - mPacUrl = proxy.getPacFileUrl(); - mCurrentDelay = DELAY_1; - mHasSentBroadcast = false; - mHasDownloaded = false; - getAlarmManager().cancel(mPacRefreshIntent); - bind(); - return DONT_SEND_BROADCAST; - } else { - getAlarmManager().cancel(mPacRefreshIntent); - synchronized (mProxyLock) { - mPacUrl = Uri.EMPTY; - mCurrentPac = null; - if (mProxyService != null) { - unbind(); + @Override + public void setCurrentProxyScriptUrl(@Nullable ProxyInfo proxy) { + PermissionUtils.enforceNetworkStackPermissionOr(mContext, + android.Manifest.permission.NETWORK_SETTINGS); + + synchronized (mBroadcastStateLock) { + if (proxy != null && !Uri.EMPTY.equals(proxy.getPacFileUrl())) { + if (proxy.getPacFileUrl().equals(mPacUrl) && (proxy.getPort() > 0)) return; + mPacUrl = proxy.getPacFileUrl(); + mCurrentDelay = DELAY_1; + mHasSentBroadcast = false; + mHasDownloaded = false; + getAlarmManager().cancel(mPacRefreshIntent); + bind(); + } else { + getAlarmManager().cancel(mPacRefreshIntent); + synchronized (mProxyLock) { + mPacUrl = Uri.EMPTY; + mCurrentPac = null; + if (mProxyService != null) { + unbind(); + } } } - return DO_SEND_BROADCAST; } } @@ -275,6 +297,7 @@ public class PacProxyInstaller { getAlarmManager().set(AlarmManager.ELAPSED_REALTIME, timeTillTrigger, mPacRefreshIntent); } + @GuardedBy("mProxyLock") private void setCurrentProxyScript(String script) { if (mProxyService == null) { Log.e(TAG, "setCurrentProxyScript: no proxy service"); @@ -347,6 +370,9 @@ public class PacProxyInstaller { public void setProxyPort(int port) { if (mLastPort != -1) { // Always need to send if port changed + // TODO: Here lacks synchronization because this write cannot + // guarantee that it's visible from sendProxyIfNeeded() when + // it's called by a Runnable which is post by mNetThread. mHasSentBroadcast = false; } mLastPort = port; @@ -365,8 +391,9 @@ public class PacProxyInstaller { } } }; - mContext.bindService(intent, mProxyConnection, - Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND | Context.BIND_NOT_VISIBLE); + mContext.bindService(intent, + Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND | Context.BIND_NOT_VISIBLE, + new HandlerExecutor(mNetThreadHandler), mProxyConnection); } private void unbind() { @@ -383,16 +410,28 @@ public class PacProxyInstaller { } private void sendPacBroadcast(ProxyInfo proxy) { - mConnectivityHandler.sendMessage(mConnectivityHandler.obtainMessage(mProxyMessage, proxy)); + final int length = mCallbacks.beginBroadcast(); + for (int i = 0; i < length; i++) { + final IPacProxyInstalledListener listener = mCallbacks.getBroadcastItem(i); + if (listener != null) { + try { + listener.onPacProxyInstalled(null /* network */, proxy); + } catch (RemoteException ignored) { } + } + } + mCallbacks.finishBroadcast(); } - private synchronized void sendProxyIfNeeded() { - if (!mHasDownloaded || (mLastPort == -1)) { - return; - } - if (!mHasSentBroadcast) { - sendPacBroadcast(ProxyInfo.buildPacProxy(mPacUrl, mLastPort)); - mHasSentBroadcast = true; + // This method must be called on mNetThreadHandler. + private void sendProxyIfNeeded() { + synchronized (mBroadcastStateLock) { + if (!mHasDownloaded || (mLastPort == -1)) { + return; + } + if (!mHasSentBroadcast) { + sendPacBroadcast(ProxyInfo.buildPacProxy(mPacUrl, mLastPort)); + mHasSentBroadcast = true; + } } } } diff --git a/services/core/java/com/android/server/connectivity/ProxyTracker.java b/services/core/java/com/android/server/connectivity/ProxyTracker.java index d83ff837d9be..8b9c83678777 100644 --- a/services/core/java/com/android/server/connectivity/ProxyTracker.java +++ b/services/core/java/com/android/server/connectivity/ProxyTracker.java @@ -27,15 +27,19 @@ import android.annotation.Nullable; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.net.Network; +import android.net.PacProxyManager; import android.net.Proxy; import android.net.ProxyInfo; import android.net.Uri; import android.os.Binder; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; +import android.util.Pair; import com.android.internal.annotations.GuardedBy; import com.android.net.module.util.ProxyUtils; @@ -67,7 +71,7 @@ public class ProxyTracker { // is not set. Individual networks have their own settings that override this. This member // is set through setDefaultProxy, which is called when the default network changes proxies // in its LinkProperties, or when ConnectivityService switches to a new default network, or - // when PacProxyInstaller resolves the proxy. + // when PacProxyService resolves the proxy. @Nullable @GuardedBy("mProxyLock") private volatile ProxyInfo mDefaultProxy = null; @@ -77,16 +81,31 @@ public class ProxyTracker { private final Handler mConnectivityServiceHandler; - // The object responsible for Proxy Auto Configuration (PAC). - @NonNull - private final PacProxyInstaller mPacProxyInstaller; + private final PacProxyManager mPacProxyManager; + + private class PacProxyInstalledListener implements PacProxyManager.PacProxyInstalledListener { + private final int mEvent; + + PacProxyInstalledListener(int event) { + mEvent = event; + } + + public void onPacProxyInstalled(@Nullable Network network, @NonNull ProxyInfo proxy) { + mConnectivityServiceHandler + .sendMessage(mConnectivityServiceHandler + .obtainMessage(mEvent, new Pair<>(network, proxy))); + } + } public ProxyTracker(@NonNull final Context context, @NonNull final Handler connectivityServiceInternalHandler, final int pacChangedEvent) { mContext = context; mConnectivityServiceHandler = connectivityServiceInternalHandler; - mPacProxyInstaller = new PacProxyInstaller( - context, connectivityServiceInternalHandler, pacChangedEvent); + mPacProxyManager = context.getSystemService(PacProxyManager.class); + + PacProxyInstalledListener listener = new PacProxyInstalledListener(pacChangedEvent); + mPacProxyManager.addPacProxyInstalledListener( + new HandlerExecutor(mConnectivityServiceHandler), listener); } // Convert empty ProxyInfo's to null as null-checks are used to determine if proxies are present @@ -182,7 +201,7 @@ public class ProxyTracker { if (!TextUtils.isEmpty(pacFileUrl)) { mConnectivityServiceHandler.post( - () -> mPacProxyInstaller.setCurrentProxyScriptUrl(proxyProperties)); + () -> mPacProxyManager.setCurrentProxyScriptUrl(proxyProperties)); } } } @@ -226,9 +245,9 @@ public class ProxyTracker { final ProxyInfo defaultProxy = getDefaultProxy(); final ProxyInfo proxyInfo = null != defaultProxy ? defaultProxy : ProxyInfo.buildDirectProxy("", 0, Collections.emptyList()); + mPacProxyManager.setCurrentProxyScriptUrl(proxyInfo); - if (mPacProxyInstaller.setCurrentProxyScriptUrl(proxyInfo) - == PacProxyInstaller.DONT_SEND_BROADCAST) { + if (!shouldSendBroadcast(proxyInfo)) { return; } if (DBG) Log.d(TAG, "sending Proxy Broadcast for " + proxyInfo); @@ -244,6 +263,10 @@ public class ProxyTracker { } } + private boolean shouldSendBroadcast(ProxyInfo proxy) { + return Uri.EMPTY.equals(proxy.getPacFileUrl()) || proxy.getPort() > 0; + } + /** * Sets the global proxy in memory. Also writes the values to the global settings of the device. * @@ -308,10 +331,10 @@ public class ProxyTracker { return; } - // This call could be coming from the PacProxyInstaller, containing the port of the + // This call could be coming from the PacProxyService, containing the port of the // local proxy. If this new proxy matches the global proxy then copy this proxy to the // global (to get the correct local port), and send a broadcast. - // TODO: Switch PacProxyInstaller to have its own message to send back rather than + // TODO: Switch PacProxyService to have its own message to send back rather than // reusing EVENT_HAS_CHANGED_PROXY and this call to handleApplyDefaultProxy. if ((mGlobalProxy != null) && (proxyInfo != null) && (!Uri.EMPTY.equals(proxyInfo.getPacFileUrl())) diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java index b39a6b4f4658..5d8b75d2af4e 100644 --- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java +++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java @@ -52,6 +52,7 @@ import android.os.PowerManager; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; +import android.os.Trace; import android.os.WorkSource; import android.os.storage.StorageManager; import android.util.Log; @@ -62,6 +63,8 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; import com.android.server.pm.Installer.InstallerException; import com.android.server.pm.dex.ArtManagerService; +import com.android.server.pm.dex.ArtStatsLogUtils; +import com.android.server.pm.dex.ArtStatsLogUtils.ArtStatsLogger; import com.android.server.pm.dex.DexManager; import com.android.server.pm.dex.DexoptOptions; import com.android.server.pm.dex.DexoptUtils; @@ -99,6 +102,8 @@ public class PackageDexOptimizer { private final PowerManager.WakeLock mDexoptWakeLock; private volatile boolean mSystemReady; + private final ArtStatsLogger mArtStatsLogger = new ArtStatsLogger(); + PackageDexOptimizer(Installer installer, Object installLock, Context context, String wakeLockTag) { this.mInstaller = installer; @@ -252,6 +257,28 @@ public class PackageDexOptimizer { profileUpdated, classLoaderContexts[i], dexoptFlags, sharedGid, packageStats, options.isDowngrade(), profileName, dexMetadataPath, options.getCompilationReason()); + + // Only report metrics for base apk for now. + // TODO: add ISA and APK type to metrics. + if (pkg.getBaseCodePath().equals(path)) { + Trace.traceBegin(Trace.TRACE_TAG_PACKAGE_MANAGER, "dex2oat-metrics"); + try { + long sessionId = Math.randomLongInternal(); + ArtStatsLogUtils.writeStatsLog( + mArtStatsLogger, + sessionId, + path, + compilerFilter, + sharedGid, + packageStats.getCompileTime(path), + dexMetadataPath, + options.getCompilationReason(), + newResult); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_PACKAGE_MANAGER); + } + } + // The end result is: // - FAILED if any path failed, // - PERFORMED if at least one path needed compilation, diff --git a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java new file mode 100644 index 000000000000..3b77c39cc31b --- /dev/null +++ b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.pm.dex; + +import static com.android.internal.art.ArtStatsLog.ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_BULK_DOWNGRADED; +import static com.android.internal.art.ArtStatsLog.ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_BULK_SECONDARY; +import static com.android.internal.art.ArtStatsLog.ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_BULK_SECONDARY_DOWNGRADED; +import static com.android.internal.art.ArtStatsLog.ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_FAKE_RUN_FROM_APK_FALLBACK; +import static com.android.internal.art.ArtStatsLog.ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_FAKE_RUN_FROM_VDEX_FALLBACK; + +import android.util.jar.StrictJarFile; +import android.util.Slog; + +import com.android.internal.art.ArtStatsLog; +import com.android.server.pm.PackageManagerService; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.zip.ZipEntry; + +/** Utils class to report ART metrics to statsd. */ +public class ArtStatsLogUtils { + private static final String TAG = ArtStatsLogUtils.class.getSimpleName(); + private static final String PROFILE_DEX_METADATA = "primary.prof"; + private static final String VDEX_DEX_METADATA = "primary.vdex"; + + + private static final int ART_COMPILATION_REASON_INSTALL_BULK_SECONDARY = + ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_BULK_SECONDARY; + private static final int ART_COMPILATION_REASON_INSTALL_BULK_DOWNGRADED = + ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_BULK_DOWNGRADED; + private static final int ART_COMPILATION_REASON_INSTALL_BULK_SECONDARY_DOWNGRADED = + ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_BULK_SECONDARY_DOWNGRADED; + + private static final int ART_COMPILATION_FILTER_FAKE_RUN_FROM_APK_FALLBACK = + ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_FAKE_RUN_FROM_APK_FALLBACK; + private static final int ART_COMPILATION_FILTER_FAKE_RUN_FROM_VDEX_FALLBACK = + ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_FAKE_RUN_FROM_VDEX_FALLBACK; + + private static final Map<Integer, Integer> COMPILATION_REASON_MAP = new HashMap(); + + static { + COMPILATION_REASON_MAP.put(PackageManagerService.REASON_UNKNOWN, ArtStatsLog. + ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_UNKNOWN); + COMPILATION_REASON_MAP.put(PackageManagerService.REASON_FIRST_BOOT, ArtStatsLog. + ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_FIRST_BOOT); + COMPILATION_REASON_MAP.put(PackageManagerService.REASON_BOOT_AFTER_OTA, ArtStatsLog. + ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_BOOT); + COMPILATION_REASON_MAP.put(PackageManagerService.REASON_POST_BOOT, ArtStatsLog. + ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_POST_BOOT); + COMPILATION_REASON_MAP.put(PackageManagerService.REASON_INSTALL, ArtStatsLog. + ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL); + COMPILATION_REASON_MAP.put(PackageManagerService.REASON_INSTALL_FAST, ArtStatsLog. + ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_FAST); + COMPILATION_REASON_MAP.put(PackageManagerService.REASON_INSTALL_BULK, ArtStatsLog. + ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INSTALL_BULK); + COMPILATION_REASON_MAP.put(PackageManagerService.REASON_INSTALL_BULK_SECONDARY, + ART_COMPILATION_REASON_INSTALL_BULK_SECONDARY); + COMPILATION_REASON_MAP.put(PackageManagerService.REASON_INSTALL_BULK_DOWNGRADED, + ART_COMPILATION_REASON_INSTALL_BULK_DOWNGRADED); + COMPILATION_REASON_MAP.put(PackageManagerService.REASON_INSTALL_BULK_SECONDARY_DOWNGRADED, + ART_COMPILATION_REASON_INSTALL_BULK_SECONDARY_DOWNGRADED); + COMPILATION_REASON_MAP.put(PackageManagerService.REASON_BACKGROUND_DEXOPT, ArtStatsLog. + ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_BG_DEXOPT); + COMPILATION_REASON_MAP.put(PackageManagerService.REASON_AB_OTA, ArtStatsLog. + ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_AB_OTA); + COMPILATION_REASON_MAP.put(PackageManagerService.REASON_INACTIVE_PACKAGE_DOWNGRADE, + ArtStatsLog. + ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_INACTIVE); + COMPILATION_REASON_MAP.put(PackageManagerService.REASON_SHARED, + ArtStatsLog.ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_SHARED); + } + + private static final Map<String, Integer> COMPILE_FILTER_MAP = new HashMap(); + + static { + COMPILE_FILTER_MAP.put("error", ArtStatsLog. + ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_ERROR); + COMPILE_FILTER_MAP.put("unknown", ArtStatsLog. + ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_UNKNOWN); + COMPILE_FILTER_MAP.put("assume-verified", ArtStatsLog. + ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_ASSUMED_VERIFIED); + COMPILE_FILTER_MAP.put("extract", ArtStatsLog. + ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_EXTRACT); + COMPILE_FILTER_MAP.put("verify", ArtStatsLog. + ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_VERIFY); + COMPILE_FILTER_MAP.put("quicken", ArtStatsLog. + ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_QUICKEN); + COMPILE_FILTER_MAP.put("space-profile", ArtStatsLog. + ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_SPACE_PROFILE); + COMPILE_FILTER_MAP.put("space", ArtStatsLog. + ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_SPACE); + COMPILE_FILTER_MAP.put("speed-profile", ArtStatsLog. + ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_SPEED_PROFILE); + COMPILE_FILTER_MAP.put("speed", ArtStatsLog. + ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_SPEED); + COMPILE_FILTER_MAP.put("everything-profile", ArtStatsLog. + ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_EVERYTHING_PROFILE); + COMPILE_FILTER_MAP.put("everything", ArtStatsLog. + ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_EVERYTHING); + COMPILE_FILTER_MAP.put("run-from-apk", ArtStatsLog. + ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_FAKE_RUN_FROM_APK); + COMPILE_FILTER_MAP.put("run-from-apk-fallback", + ART_COMPILATION_FILTER_FAKE_RUN_FROM_APK_FALLBACK); + COMPILE_FILTER_MAP.put("run-from-vdex-fallback", + ART_COMPILATION_FILTER_FAKE_RUN_FROM_VDEX_FALLBACK); + } + + public static void writeStatsLog( + ArtStatsLogger logger, + long sessionId, + String path, + String compilerFilter, + int uid, + long compileTime, + String dexMetadataPath, + int compilationReason, + int result) { + int dexMetadataType = getDexMetadataType(dexMetadataPath); + logger.write( + sessionId, + uid, + compilationReason, + compilerFilter, + ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_RESULT_CODE, + result, + dexMetadataType); + logger.write( + sessionId, + uid, + compilationReason, + compilerFilter, + ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_DEX_CODE_BYTES, + getDexBytes(path), + dexMetadataType); + logger.write( + sessionId, + uid, + compilationReason, + compilerFilter, + ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_TOTAL_TIME, + compileTime, + dexMetadataType); + } + + private static long getDexBytes(String apkPath) { + StrictJarFile jarFile = null; + long dexBytes = 0; + try { + jarFile = new StrictJarFile(apkPath, + /*verify=*/ false, + /*signatureSchemeRollbackProtectionsEnforced=*/ false); + Iterator<ZipEntry> it = jarFile.iterator(); + while (it.hasNext()) { + ZipEntry entry = it.next(); + if (entry.getName().matches("classes(\\d)*[.]dex")) { + dexBytes += entry.getSize(); + } + } + return dexBytes; + } catch (IOException ignore) { + Slog.e(TAG, "Error when parsing APK " + apkPath); + return -1L; + } finally { + try { + if (jarFile != null) { + jarFile.close(); + } + } catch (IOException ignore) { + } + } + } + + private static int getDexMetadataType(String dexMetadataPath) { + if (dexMetadataPath == null) { + return ArtStatsLog.ART_DATUM_REPORTED__DEX_METADATA_TYPE__NONE_DEX_METADATA; + } + StrictJarFile jarFile = null; + try { + jarFile = new StrictJarFile(dexMetadataPath, + /*verify=*/ false, + /*signatureSchemeRollbackProtectionsEnforced=*/false); + boolean hasProfile = findFileName(jarFile, PROFILE_DEX_METADATA); + boolean hasVdex = findFileName(jarFile, VDEX_DEX_METADATA); + if (hasProfile && hasVdex) { + return ArtStatsLog.ART_DATUM_REPORTED__DEX_METADATA_TYPE__PROFILE_AND_VDEX; + } else if (hasProfile) { + return ArtStatsLog.ART_DATUM_REPORTED__DEX_METADATA_TYPE__PROFILE; + } else if (hasVdex) { + return ArtStatsLog.ART_DATUM_REPORTED__DEX_METADATA_TYPE__VDEX; + } else { + return ArtStatsLog.ART_DATUM_REPORTED__DEX_METADATA_TYPE__UNKNOWN_DEX_METADATA; + } + } catch (IOException ignore) { + Slog.e(TAG, "Error when parsing dex metadata " + dexMetadataPath); + return ArtStatsLog.ART_DATUM_REPORTED__DEX_METADATA_TYPE__ERROR_DEX_METADATA; + } finally { + try { + if (jarFile != null) { + jarFile.close(); + } + } catch (IOException ignore) { + } + } + } + + private static boolean findFileName(StrictJarFile jarFile, String filename) throws IOException { + Iterator<ZipEntry> it = jarFile.iterator(); + while (it.hasNext()) { + ZipEntry entry = it.next(); + if (entry.getName().equals(filename)) { + return true; + } + } + return false; + } + + public static class ArtStatsLogger { + public void write( + long sessionId, + int uid, + int compilationReason, + String compilerFilter, + int kind, + long value, + int dexMetadataType) { + ArtStatsLog.write( + ArtStatsLog.ART_DATUM_REPORTED, + sessionId, + uid, + COMPILE_FILTER_MAP.getOrDefault(compilerFilter, ArtStatsLog. + ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_UNKNOWN), + COMPILATION_REASON_MAP.getOrDefault(compilationReason, ArtStatsLog. + ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_UNKNOWN), + /*timestamp_millis=*/ 0L, + ArtStatsLog.ART_DATUM_REPORTED__THREAD_TYPE__ART_THREAD_MAIN, + kind, + value, + dexMetadataType); + } + } +} diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index d858ae41cee8..61bd5dfd3878 100755 --- a/services/core/java/com/android/server/tv/TvInputManagerService.java +++ b/services/core/java/com/android/server/tv/TvInputManagerService.java @@ -2934,7 +2934,11 @@ public final class TvInputManagerService extends SystemService { values.put(TvContract.WatchedPrograms.COLUMN_INTERNAL_SESSION_TOKEN, sessionToken.toString()); - mContentResolver.insert(TvContract.WatchedPrograms.CONTENT_URI, values); + try{ + mContentResolver.insert(TvContract.WatchedPrograms.CONTENT_URI, values); + }catch(IllegalArgumentException ex){ + Slog.w(TAG, "error in insert db for MSG_LOG_WATCH_START", ex); + } args.recycle(); break; } @@ -2949,7 +2953,11 @@ public final class TvInputManagerService extends SystemService { values.put(TvContract.WatchedPrograms.COLUMN_INTERNAL_SESSION_TOKEN, sessionToken.toString()); - mContentResolver.insert(TvContract.WatchedPrograms.CONTENT_URI, values); + try{ + mContentResolver.insert(TvContract.WatchedPrograms.CONTENT_URI, values); + }catch(IllegalArgumentException ex){ + Slog.w(TAG, "error in insert db for MSG_LOG_WATCH_END", ex); + } args.recycle(); break; } diff --git a/services/core/jni/com_android_server_SystemServer.cpp b/services/core/jni/com_android_server_SystemServer.cpp index 729fa71af169..d18043f6b3e9 100644 --- a/services/core/jni/com_android_server_SystemServer.cpp +++ b/services/core/jni/com_android_server_SystemServer.cpp @@ -100,16 +100,9 @@ static void android_server_SystemServer_initZygoteChildHeapProfiling(JNIEnv* /* } static void android_server_SystemServer_fdtrackAbort(JNIEnv*, jobject) { - raise(BIONIC_SIGNAL_FDTRACK); - - // Wait for a bit to allow fdtrack to dump backtraces to logcat. - std::this_thread::sleep_for(5s); - - // Abort on a different thread to avoid ART dumping runtime stacks. - std::thread([]() { - LOG_ALWAYS_FATAL("b/140703823: aborting due to fd leak: check logs for fd " - "backtraces"); - }).join(); + sigval val; + val.sival_int = 1; + sigqueue(getpid(), BIONIC_SIGNAL_FDTRACK, val); } static jlong android_server_SystemServer_startIncrementalService(JNIEnv* env, jclass klass, diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 6badafa34dfd..374abd6a6f85 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -15621,10 +15621,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Objects.requireNonNull(who, "ComponentName is null"); enforceDeviceOwner(who); - String currentMode = mInjector.settingsGlobalGetString(PRIVATE_DNS_MODE); - if (currentMode == null) { - currentMode = ConnectivityManager.PRIVATE_DNS_DEFAULT_MODE_FALLBACK; - } + final String currentMode = + ConnectivityManager.getPrivateDnsMode(mContext.getContentResolver()); switch (currentMode) { case ConnectivityManager.PRIVATE_DNS_MODE_OFF: return PRIVATE_DNS_MODE_OFF; diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index a6a99f232ef4..7bde760191b5 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -108,6 +108,7 @@ import com.android.server.camera.CameraServiceProxy; import com.android.server.clipboard.ClipboardService; import com.android.server.compat.PlatformCompat; import com.android.server.compat.PlatformCompatNative; +import com.android.server.connectivity.PacProxyService; import com.android.server.contentcapture.ContentCaptureManagerInternal; import com.android.server.coverage.CoverageService; import com.android.server.devicepolicy.DevicePolicyManagerService; @@ -1115,6 +1116,7 @@ public final class SystemServer { ConsumerIrService consumerIr = null; MmsServiceBroker mmsService = null; HardwarePropertiesManagerService hardwarePropertiesService = null; + PacProxyService pacProxyService = null; boolean disableSystemTextClassifier = SystemProperties.getBoolean( "config.disable_systemtextclassifier", false); @@ -1623,6 +1625,15 @@ public final class SystemServer { t.traceEnd(); } + t.traceBegin("StartPacProxyService"); + try { + pacProxyService = new PacProxyService(context); + ServiceManager.addService(Context.PAC_PROXY_SERVICE, pacProxyService); + } catch (Throwable e) { + reportWtf("starting PacProxyService", e); + } + t.traceEnd(); + t.traceBegin("StartConnectivityService"); // This has to be called after NetworkManagementService, NetworkStatsService // and NetworkPolicyManager because ConnectivityService needs to take these diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java new file mode 100644 index 000000000000..3ab34484ce25 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java @@ -0,0 +1,295 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.pm.dex; + +import static org.mockito.Mockito.inOrder; + +import com.android.internal.art.ArtStatsLog; +import com.android.server.pm.dex.ArtStatsLogUtils.ArtStatsLogger; + +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.InOrder; +import org.mockito.MockitoAnnotations; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +/** + * Unit tests for {@link com.android.server.pm.dex.ArtStatsLogUtils}. + * + * Run with "atest ArtStatsLogUtilsTest". + */ +@RunWith(JUnit4.class) +public final class ArtStatsLogUtilsTest { + private static final String TAG = ArtStatsLogUtilsTest.class.getSimpleName(); + private static final String COMPILER_FILTER = "space-profile"; + private static final String PROFILE_DEX_METADATA = "primary.prof"; + private static final String VDEX_DEX_METADATA = "primary.vdex"; + private static final byte[] DEX_CONTENT = "dexData".getBytes(); + private static final int COMPILATION_REASON = 1; + private static final int RESULT_CODE = 222; + private static final int UID = 111; + private static final long COMPILE_TIME = 333L; + private static final long SESSION_ID = 444L; + + @Mock + ArtStatsLogger mockLogger; + + private static Path TEST_DIR; + private static Path DEX; + private static Path NON_DEX; + + @BeforeClass + public static void setUpAll() throws IOException { + TEST_DIR = Files.createTempDirectory(null); + DEX = Files.createFile(TEST_DIR.resolve("classes.dex")); + NON_DEX = Files.createFile(TEST_DIR.resolve("test.dex")); + Files.write(DEX, DEX_CONTENT); + Files.write(NON_DEX, "empty".getBytes()); + } + + @AfterClass + public static void tearnDownAll() { + deleteSliently(DEX); + deleteSliently(NON_DEX); + deleteSliently(TEST_DIR); + } + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void testProfileAndVdexDexMetadata() throws IOException { + // Setup + Path dexMetadataPath = null; + Path apk = null; + try { + dexMetadataPath = createDexMetadata(PROFILE_DEX_METADATA, VDEX_DEX_METADATA); + apk = zipFiles(".apk", DEX, NON_DEX, dexMetadataPath); + + // Act + ArtStatsLogUtils.writeStatsLog( + mockLogger, + SESSION_ID, + apk.toString(), + COMPILER_FILTER, + UID, + COMPILE_TIME, + dexMetadataPath.toString(), + COMPILATION_REASON, + RESULT_CODE); + + // Assert + verifyWrites(ArtStatsLog.ART_DATUM_REPORTED__DEX_METADATA_TYPE__PROFILE_AND_VDEX); + } finally { + deleteSliently(dexMetadataPath); + deleteSliently(apk); + } + } + + @Test + public void testProfileOnlyDexMetadata() throws IOException { + // Setup + Path dexMetadataPath = null; + Path apk = null; + try { + dexMetadataPath = createDexMetadata(PROFILE_DEX_METADATA); + apk = zipFiles(".apk", DEX, NON_DEX, dexMetadataPath); + + // Act + ArtStatsLogUtils.writeStatsLog( + mockLogger, + SESSION_ID, + apk.toString(), + COMPILER_FILTER, + UID, + COMPILE_TIME, + dexMetadataPath.toString(), + COMPILATION_REASON, + RESULT_CODE); + + // Assert + verifyWrites(ArtStatsLog.ART_DATUM_REPORTED__DEX_METADATA_TYPE__PROFILE); + } finally { + deleteSliently(dexMetadataPath); + deleteSliently(apk); + } + } + + @Test + public void testVdexOnlyDexMetadata() throws IOException { + // Setup + Path dexMetadataPath = null; + Path apk = null; + try { + dexMetadataPath = createDexMetadata(VDEX_DEX_METADATA); + apk = zipFiles(".apk", DEX, NON_DEX, dexMetadataPath); + + // Act + ArtStatsLogUtils.writeStatsLog( + mockLogger, + SESSION_ID, + apk.toString(), + COMPILER_FILTER, + UID, + COMPILE_TIME, + dexMetadataPath.toString(), + COMPILATION_REASON, + RESULT_CODE); + + // Assert + verifyWrites(ArtStatsLog.ART_DATUM_REPORTED__DEX_METADATA_TYPE__VDEX); + } finally { + deleteSliently(dexMetadataPath); + deleteSliently(apk); + } + } + + @Test + public void testNoneDexMetadata() throws IOException { + // Setup + Path apk = null; + try { + apk = zipFiles(".apk", DEX, NON_DEX); + + // Act + ArtStatsLogUtils.writeStatsLog( + mockLogger, + SESSION_ID, + apk.toString(), + COMPILER_FILTER, + UID, + COMPILE_TIME, + /*dexMetadataPath=*/ null, + COMPILATION_REASON, + RESULT_CODE); + + // Assert + verifyWrites(ArtStatsLog.ART_DATUM_REPORTED__DEX_METADATA_TYPE__NONE_DEX_METADATA); + } finally { + deleteSliently(apk); + } + } + + @Test + public void testUnKnownDexMetadata() throws IOException { + // Setup + Path dexMetadataPath = null; + Path apk = null; + try { + dexMetadataPath = createDexMetadata("unknown"); + apk = zipFiles(".apk", DEX, NON_DEX, dexMetadataPath); + + // Act + ArtStatsLogUtils.writeStatsLog( + mockLogger, + SESSION_ID, + apk.toString(), + COMPILER_FILTER, + UID, + COMPILE_TIME, + dexMetadataPath.toString(), + COMPILATION_REASON, + RESULT_CODE); + + // Assert + verifyWrites(ArtStatsLog.ART_DATUM_REPORTED__DEX_METADATA_TYPE__UNKNOWN_DEX_METADATA); + } finally { + deleteSliently(dexMetadataPath); + deleteSliently(apk); + } + } + + private void verifyWrites(int dexMetadataType) { + InOrder inorder = inOrder(mockLogger); + inorder.verify(mockLogger).write( + SESSION_ID, UID, + COMPILATION_REASON, + COMPILER_FILTER, + ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_RESULT_CODE, + RESULT_CODE, + dexMetadataType); + inorder.verify(mockLogger).write( + SESSION_ID, + UID, + COMPILATION_REASON, + COMPILER_FILTER, + ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_DEX_CODE_BYTES, + DEX_CONTENT.length, + dexMetadataType); + inorder.verify(mockLogger).write( + SESSION_ID, + UID, + COMPILATION_REASON, + COMPILER_FILTER, + ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_TOTAL_TIME, + COMPILE_TIME, + dexMetadataType); + } + + private Path zipFiles(String suffix, Path... files) throws IOException { + Path zipFile = Files.createTempFile(null, suffix); + try (final OutputStream os = Files.newOutputStream(zipFile)) { + try (final ZipOutputStream zos = new ZipOutputStream(os)) { + for (Path file : files) { + ZipEntry zipEntry = new ZipEntry(file.getFileName().toString()); + zos.putNextEntry(zipEntry); + zos.write(Files.readAllBytes(file)); + zos.closeEntry(); + } + } + } + return zipFile; + } + + private Path createDexMetadata(String... entryNames) throws IOException { + Path zipFile = Files.createTempFile(null, ".dm"); + try (final OutputStream os = Files.newOutputStream(zipFile)) { + try (final ZipOutputStream zos = new ZipOutputStream(os)) { + for (String entryName : entryNames) { + ZipEntry zipEntry = new ZipEntry(entryName); + zos.putNextEntry(zipEntry); + zos.write(entryName.getBytes()); + zos.closeEntry(); + } + } + } + return zipFile; + } + + private static void deleteSliently(Path file) { + if (file != null) { + try { + Files.deleteIfExists(file); + } catch (IOException e) { + // ignore + } + } + } +} diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 6902550ddfd6..e77ee365b4d3 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -14111,6 +14111,10 @@ public class TelephonyManager { /** * Enable/Disable E-UTRA-NR Dual Connectivity. * + * This api is supported only if + * {@link android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported} + * ({@link TelephonyManager#CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE}) + * returns true. * @param nrDualConnectivityState expected NR dual connectivity state * This can be passed following states * <ol> @@ -14125,6 +14129,9 @@ public class TelephonyManager { */ @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + @RequiresFeature( + enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported", + value = TelephonyManager.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE) public @EnableNrDualConnectivityResult int setNrDualConnectivityState( @NrDualConnectivityState int nrDualConnectivityState) { try { @@ -14144,15 +14151,21 @@ public class TelephonyManager { /** * Is E-UTRA-NR Dual Connectivity enabled. + * This api is supported only if + * {@link android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported} + * ({@link TelephonyManager#CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE}) + * returns true. * @return true if dual connectivity is enabled else false. Enabled state does not mean dual * connectivity is active. It means the device is allowed to connect to both primary and * secondary cell. - * <p>Requires Permission: - * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE} * @throws IllegalStateException if the Telephony process is not currently available. * @hide */ @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @RequiresFeature( + enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported", + value = TelephonyManager.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE) public boolean isNrDualConnectivityEnabled() { try { ITelephony telephony = getITelephony(); @@ -14404,11 +14417,23 @@ public class TelephonyManager { public static final String CAPABILITY_ALLOWED_NETWORK_TYPES_USED = "CAPABILITY_ALLOWED_NETWORK_TYPES_USED"; + /** + * Indicates whether {@link #setNrDualConnectivityState()} and + * {@link #isNrDualConnectivityEnabled()} ()} are available. See comments + * on respective methods for more information. + * + * @hide + */ + @SystemApi + public static final String CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE = + "CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE"; + /** @hide */ @Retention(RetentionPolicy.SOURCE) @StringDef(prefix = "CAPABILITY_", value = { CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE, CAPABILITY_ALLOWED_NETWORK_TYPES_USED, + CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE }) public @interface RadioInterfaceCapability {} diff --git a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java index cedf48b0b8e1..9c28c36521f5 100644 --- a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java +++ b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java @@ -25,7 +25,6 @@ import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; -import android.util.Log; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -389,22 +388,6 @@ public final class RcsContactPresenceTuple implements Parcelable { * The optional timestamp indicating the data and time of the status change of this tuple. * Per RFC3863 section 4.1.7, the timestamp is formatted as an IMPP datetime format * string per RFC3339. - * @hide - */ - public @NonNull Builder setTimestamp(@NonNull String timestamp) { - try { - mPresenceTuple.mTimestamp = - DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(timestamp, Instant::from); - } catch (DateTimeParseException e) { - Log.d(LOG_TAG, "Parse timestamp failed " + e); - } - return this; - } - - /** - * The optional timestamp indicating the data and time of the status change of this tuple. - * Per RFC3863 section 4.1.7, the timestamp is formatted as an IMPP datetime format - * string per RFC3339. */ public @NonNull Builder setTime(@NonNull Instant timestamp) { mPresenceTuple.mTimestamp = timestamp; @@ -534,14 +517,6 @@ public final class RcsContactPresenceTuple implements Parcelable { return mContactUri; } - /** - * @return the timestamp element contained in the tuple if it exists - * @hide - */ - public @Nullable String getTimestamp() { - return (mTimestamp == null) ? null : mTimestamp.toString(); - } - /** @return the timestamp element contained in the tuple if it exists */ public @Nullable Instant getTime() { return mTimestamp; diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java index 815c08d120c2..dd9102699529 100644 --- a/telephony/java/android/telephony/ims/RcsUceAdapter.java +++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java @@ -439,8 +439,7 @@ public class RcsUceAdapter { /** * The pending request has resulted in an error and may need to be retried, depending on the - * error code. The callback {@link #onCapabilitiesReceived(List)} - * for each contacts is required to be called before {@link #onError} is called. + * error code. * @param errorCode The reason for the framework being unable to process the request. * @param retryIntervalMillis The time in milliseconds the requesting application should * wait before retrying, if non-zero. @@ -487,93 +486,6 @@ public class RcsUceAdapter { * becomes inactive. See {@link ImsException#getCode()} for more information on the error codes. * @hide */ - @RequiresPermission(allOf = {Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE, - Manifest.permission.READ_CONTACTS}) - public void requestCapabilities(@NonNull List<Uri> contactNumbers, - @NonNull @CallbackExecutor Executor executor, - @NonNull CapabilitiesCallback c) throws ImsException { - if (c == null) { - throw new IllegalArgumentException("Must include a non-null CapabilitiesCallback."); - } - if (executor == null) { - throw new IllegalArgumentException("Must include a non-null Executor."); - } - if (contactNumbers == null) { - throw new IllegalArgumentException("Must include non-null contact number list."); - } - - IImsRcsController imsRcsController = getIImsRcsController(); - if (imsRcsController == null) { - Log.e(TAG, "requestCapabilities: IImsRcsController is null"); - throw new ImsException("Can not find remote IMS service", - ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); - } - - IRcsUceControllerCallback internalCallback = new IRcsUceControllerCallback.Stub() { - @Override - public void onCapabilitiesReceived(List<RcsContactUceCapability> contactCapabilities) { - final long callingIdentity = Binder.clearCallingIdentity(); - try { - executor.execute(() -> c.onCapabilitiesReceived(contactCapabilities)); - } finally { - restoreCallingIdentity(callingIdentity); - } - } - @Override - public void onComplete() { - final long callingIdentity = Binder.clearCallingIdentity(); - try { - executor.execute(() -> c.onComplete()); - } finally { - restoreCallingIdentity(callingIdentity); - } - } - @Override - public void onError(int errorCode, long retryAfterMilliseconds) { - final long callingIdentity = Binder.clearCallingIdentity(); - try { - executor.execute(() -> c.onError(errorCode, retryAfterMilliseconds)); - } finally { - restoreCallingIdentity(callingIdentity); - } - } - }; - - try { - imsRcsController.requestCapabilities(mSubId, mContext.getOpPackageName(), - mContext.getAttributionTag(), contactNumbers, internalCallback); - } catch (ServiceSpecificException e) { - throw new ImsException(e.toString(), e.errorCode); - } catch (RemoteException e) { - Log.e(TAG, "Error calling IImsRcsController#requestCapabilities", e); - throw new ImsException("Remote IMS Service is not available", - ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); - } - } - - /** - * Request the User Capability Exchange capabilities for one or more contacts. - * <p> - * This will return the cached capabilities of the contact and will not perform a capability - * poll on the network unless there are contacts being queried with stale information. - * <p> - * Be sure to check the availability of this feature using - * {@link ImsRcsManager#isAvailable(int, int)} and ensuring - * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or - * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE} is enabled or else - * this operation will fail with {@link #ERROR_NOT_AVAILABLE} or {@link #ERROR_NOT_ENABLED}. - * - * @param contactNumbers A list of numbers that the capabilities are being requested for. - * @param executor The executor that will be used when the request is completed and the - * {@link CapabilitiesCallback} is called. - * @param c A one-time callback for when the request for capabilities completes or there is an - * error processing the request. - * @throws ImsException if the subscription associated with this instance of - * {@link RcsUceAdapter} is valid, but the ImsService associated with the subscription is not - * available. This can happen if the ImsService has crashed, for example, or if the subscription - * becomes inactive. See {@link ImsException#getCode()} for more information on the error codes. - * @hide - */ @SystemApi @RequiresPermission(allOf = {Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE, Manifest.permission.READ_CONTACTS}) diff --git a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java index 00c91681d9ea..03e17fbc2c0d 100644 --- a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java +++ b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java @@ -386,41 +386,6 @@ public class RcsCapabilityExchangeImplBase { * {@link SubscribeResponseCallback#onTerminated(String, long)} must be called for the * framework to finish listening for NOTIFY responses. * - * @param uris A {@link List} of the {@link Uri}s that the framework is requesting the UCE - * capabilities for. - * @param cb The callback of the subscribe request. - * @hide - */ - // executor used is defined in the constructor. - @SuppressLint("ExecutorRegistration") - public void subscribeForCapabilities(@NonNull List<Uri> uris, - @NonNull SubscribeResponseCallback cb) { - // Stub - to be implemented by service - Log.w(LOG_TAG, "subscribeForCapabilities called with no implementation."); - try { - cb.onCommandError(COMMAND_CODE_NOT_SUPPORTED); - } catch (ImsException e) { - // Do not do anything, this is a stub implementation. - } - } - - /** - * The user capabilities of one or multiple contacts have been requested by the framework. - * <p> - * The implementer must follow up this call with an - * {@link SubscribeResponseCallback#onCommandError} call to indicate this operation has failed. - * The response from the network to the SUBSCRIBE request must be sent back to the framework - * using {@link SubscribeResponseCallback#onNetworkResponse(int, String)}. - * As NOTIFY requests come in from the network, the requested contact’s capabilities should be - * sent back to the framework using - * {@link SubscribeResponseCallback#onNotifyCapabilitiesUpdate(List<String>}) and - * {@link SubscribeResponseCallback#onResourceTerminated(List<Pair<Uri, String>>)} - * should be called with the presence information for the contacts specified. - * <p> - * Once the subscription is terminated, - * {@link SubscribeResponseCallback#onTerminated(String, long)} must be called for the - * framework to finish listening for NOTIFY responses. - * * @param uris A {@link Collection} of the {@link Uri}s that the framework is requesting the * UCE capabilities for. * @param cb The callback of the subscribe request. diff --git a/tests/net/Android.bp b/tests/net/Android.bp index 81224957b2c7..e1a424f214a5 100644 --- a/tests/net/Android.bp +++ b/tests/net/Android.bp @@ -70,7 +70,7 @@ android_test { "mockito-target-minus-junit4", "net-tests-utils", "platform-test-annotations", - "service-connectivity", + "service-connectivity-pre-jarjar", "services.core", "services.net", ], @@ -79,6 +79,7 @@ android_test { "android.test.runner", "android.test.base", "android.test.mock", + "ServiceConnectivityResources", ], jni_libs: [ "libservice-connectivity", diff --git a/tests/net/common/java/android/net/IpPrefixTest.java b/tests/net/common/java/android/net/IpPrefixTest.java index 9c0fc7ce7881..50ecb428359e 100644 --- a/tests/net/common/java/android/net/IpPrefixTest.java +++ b/tests/net/common/java/android/net/IpPrefixTest.java @@ -113,6 +113,15 @@ public class IpPrefixTest { p = new IpPrefix("f00:::/32"); fail("Expected IllegalArgumentException: invalid IPv6 address"); } catch (IllegalArgumentException expected) { } + + p = new IpPrefix("/64"); + assertEquals("::/64", p.toString()); + + p = new IpPrefix("/128"); + assertEquals("::1/128", p.toString()); + + p = new IpPrefix("[2001:db8::123]/64"); + assertEquals("2001:db8::/64", p.toString()); } @Test diff --git a/tests/net/common/java/android/net/LinkAddressTest.java b/tests/net/common/java/android/net/LinkAddressTest.java index 1eaf30c5e068..2cf3cf9c11da 100644 --- a/tests/net/common/java/android/net/LinkAddressTest.java +++ b/tests/net/common/java/android/net/LinkAddressTest.java @@ -53,6 +53,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import java.net.Inet4Address; +import java.net.Inet6Address; import java.net.InetAddress; import java.net.InterfaceAddress; import java.net.NetworkInterface; @@ -117,6 +118,20 @@ public class LinkAddressTest { assertEquals(456, address.getScope()); assertTrue(address.isIpv4()); + address = new LinkAddress("/64", 1 /* flags */, 2 /* scope */); + assertEquals(Inet6Address.LOOPBACK, address.getAddress()); + assertEquals(64, address.getPrefixLength()); + assertEquals(1, address.getFlags()); + assertEquals(2, address.getScope()); + assertTrue(address.isIpv6()); + + address = new LinkAddress("[2001:db8::123]/64", 3 /* flags */, 4 /* scope */); + assertEquals(InetAddresses.parseNumericAddress("2001:db8::123"), address.getAddress()); + assertEquals(64, address.getPrefixLength()); + assertEquals(3, address.getFlags()); + assertEquals(4, address.getScope()); + assertTrue(address.isIpv6()); + // InterfaceAddress doesn't have a constructor. Fetch some from an interface. List<InterfaceAddress> addrs = NetworkInterface.getByName("lo").getInterfaceAddresses(); diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 2c8c8a6409ea..cc58edf80e88 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -202,6 +202,7 @@ import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkPolicyManager; import android.net.NetworkRequest; +import android.net.NetworkScore; import android.net.NetworkSpecifier; import android.net.NetworkStack; import android.net.NetworkStackClient; @@ -275,6 +276,7 @@ import com.android.internal.util.test.FakeSettingsProvider; import com.android.net.module.util.ArrayTrackRecord; import com.android.server.ConnectivityService.ConnectivityDiagnosticsCallbackInfo; import com.android.server.connectivity.ConnectivityConstants; +import com.android.server.connectivity.ConnectivityResources; import com.android.server.connectivity.MockableSystemProperties; import com.android.server.connectivity.Nat464Xlat; import com.android.server.connectivity.NetworkAgentInfo; @@ -444,6 +446,7 @@ public class ConnectivityServiceTest { @Mock NetworkPolicyManager mNetworkPolicyManager; @Mock VpnProfileStore mVpnProfileStore; @Mock SystemConfigManager mSystemConfigManager; + @Mock Resources mResources; private ArgumentCaptor<ResolverParamsParcel> mResolverParamsParcelCaptor = ArgumentCaptor.forClass(ResolverParamsParcel.class); @@ -471,7 +474,7 @@ public class ConnectivityServiceTest { private class MockContext extends BroadcastInterceptingContext { private final MockContentResolver mContentResolver; - @Spy private Resources mResources; + @Spy private Resources mInternalResources; private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>(); // Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant @@ -480,21 +483,15 @@ public class ConnectivityServiceTest { MockContext(Context base, ContentProvider settingsProvider) { super(base); - mResources = spy(base.getResources()); - when(mResources.getStringArray(com.android.internal.R.array.networkAttributes)). - thenReturn(new String[] { + mInternalResources = spy(base.getResources()); + when(mInternalResources.getStringArray(com.android.internal.R.array.networkAttributes)) + .thenReturn(new String[] { "wifi,1,1,1,-1,true", "mobile,0,0,0,-1,true", "mobile_mms,2,0,2,60000,true", "mobile_supl,3,0,2,60000,true", }); - when(mResources.getStringArray( - com.android.internal.R.array.config_wakeonlan_supported_interfaces)) - .thenReturn(new String[]{ - WIFI_WOL_IFNAME, - }); - mContentResolver = new MockContentResolver(); mContentResolver.addProvider(Settings.AUTHORITY, settingsProvider); } @@ -559,7 +556,7 @@ public class ConnectivityServiceTest { @Override public Resources getResources() { - return mResources; + return mInternalResources; } @Override @@ -1534,6 +1531,17 @@ public class ConnectivityServiceTest { }).when(deps).makeMultinetworkPolicyTracker(any(), any(), any()); doReturn(true).when(deps).getCellular464XlatEnabled(); + doReturn(60000).when(mResources).getInteger( + com.android.connectivity.resources.R.integer.config_networkTransitionTimeout); + doReturn("").when(mResources).getString( + com.android.connectivity.resources.R.string.config_networkCaptivePortalServerUrl); + doReturn(new String[]{ WIFI_WOL_IFNAME }).when(mResources).getStringArray( + com.android.connectivity.resources.R.array.config_wakeonlan_supported_interfaces); + final com.android.server.connectivity.ConnectivityResources connRes = mock( + ConnectivityResources.class); + doReturn(mResources).when(connRes).get(); + doReturn(connRes).when(deps).getResources(any()); + return deps; } @@ -9153,7 +9161,8 @@ public class ConnectivityServiceTest { ConnectivityManager.getNetworkTypeName(TYPE_MOBILE), TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_LTE)); return new NetworkAgentInfo(null, new Network(NET_ID), info, new LinkProperties(), - nc, 0, mServiceContext, null, new NetworkAgentConfig(), mService, null, null, 0, + nc, new NetworkScore.Builder().setLegacyInt(0).build(), + mServiceContext, null, new NetworkAgentConfig(), mService, null, null, 0, INVALID_UID, mQosCallbackTracker, new ConnectivityService.Dependencies()); } diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java index 1c0ba4f8d8f5..ea2b362c537a 100644 --- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java +++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java @@ -40,6 +40,7 @@ import android.net.NetworkAgentConfig; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkProvider; +import android.net.NetworkScore; import android.os.Binder; import android.text.format.DateUtils; @@ -355,8 +356,9 @@ public class LingerMonitorTest { caps.addCapability(0); caps.addTransportType(transport); NetworkAgentInfo nai = new NetworkAgentInfo(null, new Network(netId), info, - new LinkProperties(), caps, 50, mCtx, null, new NetworkAgentConfig() /* config */, - mConnService, mNetd, mDnsResolver, NetworkProvider.ID_NONE, Binder.getCallingUid(), + new LinkProperties(), caps, new NetworkScore.Builder().setLegacyInt(50).build(), + mCtx, null, new NetworkAgentConfig() /* config */, mConnService, mNetd, + mDnsResolver, NetworkProvider.ID_NONE, Binder.getCallingUid(), mQosCallbackTracker, new ConnectivityService.Dependencies()); nai.everValidated = true; return nai; diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java index b8f7fbca3983..11fcea60d98d 100644 --- a/tests/net/java/com/android/server/connectivity/VpnTest.java +++ b/tests/net/java/com/android/server/connectivity/VpnTest.java @@ -1026,7 +1026,11 @@ public class VpnTest { .thenReturn(new Network[] { new Network(101) }); when(mConnectivityManager.registerNetworkAgent(any(), any(), any(), any(), - anyInt(), any(), anyInt())).thenReturn(new Network(102)); + any(), any(), anyInt())).thenAnswer(invocation -> { + // The runner has registered an agent and is now ready. + legacyRunnerReady.open(); + return new Network(102); + }); final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), profile); final TestDeps deps = (TestDeps) vpn.mDeps; try { @@ -1048,7 +1052,7 @@ public class VpnTest { ArgumentCaptor<NetworkCapabilities> ncCaptor = ArgumentCaptor.forClass(NetworkCapabilities.class); verify(mConnectivityManager, timeout(10_000)).registerNetworkAgent(any(), any(), - lpCaptor.capture(), ncCaptor.capture(), anyInt(), any(), anyInt()); + lpCaptor.capture(), ncCaptor.capture(), any(), any(), anyInt()); // In this test the expected address is always v4 so /32. // Note that the interface needs to be specified because RouteInfo objects stored in diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java index 11498dec8165..a02002752c38 100644 --- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java +++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java @@ -593,6 +593,16 @@ public class VcnManagementServiceTest { mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener); } + @Test(expected = SecurityException.class) + public void testRemoveVcnUnderlyingNetworkPolicyListenerInvalidPermission() { + doThrow(new SecurityException()) + .when(mMockContext) + .enforceCallingOrSelfPermission( + eq(android.Manifest.permission.NETWORK_FACTORY), any()); + + mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener); + } + @Test public void testRemoveVcnUnderlyingNetworkPolicyListenerNeverRegistered() { mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener); diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java index 0e5f5e43f282..ca6448ca9b8c 100644 --- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java +++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java @@ -188,7 +188,7 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection any(), lpCaptor.capture(), ncCaptor.capture(), - anyInt(), + any(), any(), anyInt()); verify(mIpSecSvc) |