Merge "Move netd.c to Tethering module"
diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp
index 9363c29..4c64e98 100644
--- a/Tethering/apex/Android.bp
+++ b/Tethering/apex/Android.bp
@@ -96,6 +96,7 @@
name: "com.android.tethering-bootclasspath-fragment",
contents: [
"framework-connectivity",
+ "framework-connectivity-tiramisu",
"framework-tethering",
],
apex_available: ["com.android.tethering"],
@@ -117,7 +118,13 @@
// Additional hidden API flag files to override the defaults. This must only be
// modified by the Soong or platform compat team.
hidden_api: {
- max_target_o_low_priority: ["hiddenapi/hiddenapi-max-target-o-low-priority.txt"],
+ max_target_r_low_priority: [
+ "hiddenapi/hiddenapi-max-target-r-loprio.txt",
+ ],
+ max_target_o_low_priority: [
+ "hiddenapi/hiddenapi-max-target-o-low-priority.txt",
+ "hiddenapi/hiddenapi-max-target-o-low-priority-tiramisu.txt",
+ ],
unsupported: ["hiddenapi/hiddenapi-unsupported.txt"],
},
}
diff --git a/Tethering/apex/hiddenapi/hiddenapi-max-target-o-low-priority-tiramisu.txt b/Tethering/apex/hiddenapi/hiddenapi-max-target-o-low-priority-tiramisu.txt
new file mode 100644
index 0000000..88c77f2
--- /dev/null
+++ b/Tethering/apex/hiddenapi/hiddenapi-max-target-o-low-priority-tiramisu.txt
@@ -0,0 +1,87 @@
+Landroid/net/nsd/DnsSdTxtRecord;-><init>()V
+Landroid/net/nsd/DnsSdTxtRecord;-><init>(Landroid/net/nsd/DnsSdTxtRecord;)V
+Landroid/net/nsd/DnsSdTxtRecord;-><init>([B)V
+Landroid/net/nsd/DnsSdTxtRecord;->contains(Ljava/lang/String;)Z
+Landroid/net/nsd/DnsSdTxtRecord;->CREATOR:Landroid/os/Parcelable$Creator;
+Landroid/net/nsd/DnsSdTxtRecord;->get(Ljava/lang/String;)Ljava/lang/String;
+Landroid/net/nsd/DnsSdTxtRecord;->getKey(I)Ljava/lang/String;
+Landroid/net/nsd/DnsSdTxtRecord;->getRawData()[B
+Landroid/net/nsd/DnsSdTxtRecord;->getValue(I)[B
+Landroid/net/nsd/DnsSdTxtRecord;->getValue(Ljava/lang/String;)[B
+Landroid/net/nsd/DnsSdTxtRecord;->getValueAsString(I)Ljava/lang/String;
+Landroid/net/nsd/DnsSdTxtRecord;->insert([B[BI)V
+Landroid/net/nsd/DnsSdTxtRecord;->keyCount()I
+Landroid/net/nsd/DnsSdTxtRecord;->mData:[B
+Landroid/net/nsd/DnsSdTxtRecord;->mSeperator:B
+Landroid/net/nsd/DnsSdTxtRecord;->remove(Ljava/lang/String;)I
+Landroid/net/nsd/DnsSdTxtRecord;->set(Ljava/lang/String;Ljava/lang/String;)V
+Landroid/net/nsd/DnsSdTxtRecord;->size()I
+Landroid/net/nsd/INsdManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/net/nsd/INsdManager$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
+Landroid/net/nsd/INsdManager$Stub$Proxy;->getMessenger()Landroid/os/Messenger;
+Landroid/net/nsd/INsdManager$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/net/nsd/INsdManager$Stub$Proxy;->setEnabled(Z)V
+Landroid/net/nsd/INsdManager$Stub;-><init>()V
+Landroid/net/nsd/INsdManager$Stub;->DESCRIPTOR:Ljava/lang/String;
+Landroid/net/nsd/INsdManager$Stub;->TRANSACTION_getMessenger:I
+Landroid/net/nsd/INsdManager$Stub;->TRANSACTION_setEnabled:I
+Landroid/net/nsd/INsdManager;->setEnabled(Z)V
+Landroid/net/nsd/NsdManager;-><init>(Landroid/content/Context;Landroid/net/nsd/INsdManager;)V
+Landroid/net/nsd/NsdManager;->BASE:I
+Landroid/net/nsd/NsdManager;->checkListener(Ljava/lang/Object;)V
+Landroid/net/nsd/NsdManager;->checkProtocol(I)V
+Landroid/net/nsd/NsdManager;->checkServiceInfo(Landroid/net/nsd/NsdServiceInfo;)V
+Landroid/net/nsd/NsdManager;->DBG:Z
+Landroid/net/nsd/NsdManager;->DISABLE:I
+Landroid/net/nsd/NsdManager;->disconnect()V
+Landroid/net/nsd/NsdManager;->DISCOVER_SERVICES:I
+Landroid/net/nsd/NsdManager;->DISCOVER_SERVICES_FAILED:I
+Landroid/net/nsd/NsdManager;->DISCOVER_SERVICES_STARTED:I
+Landroid/net/nsd/NsdManager;->ENABLE:I
+Landroid/net/nsd/NsdManager;->EVENT_NAMES:Landroid/util/SparseArray;
+Landroid/net/nsd/NsdManager;->fatal(Ljava/lang/String;)V
+Landroid/net/nsd/NsdManager;->FIRST_LISTENER_KEY:I
+Landroid/net/nsd/NsdManager;->getListenerKey(Ljava/lang/Object;)I
+Landroid/net/nsd/NsdManager;->getMessenger()Landroid/os/Messenger;
+Landroid/net/nsd/NsdManager;->getNsdServiceInfoType(Landroid/net/nsd/NsdServiceInfo;)Ljava/lang/String;
+Landroid/net/nsd/NsdManager;->init()V
+Landroid/net/nsd/NsdManager;->mAsyncChannel:Lcom/android/internal/util/AsyncChannel;
+Landroid/net/nsd/NsdManager;->mConnected:Ljava/util/concurrent/CountDownLatch;
+Landroid/net/nsd/NsdManager;->mContext:Landroid/content/Context;
+Landroid/net/nsd/NsdManager;->mHandler:Landroid/net/nsd/NsdManager$ServiceHandler;
+Landroid/net/nsd/NsdManager;->mListenerKey:I
+Landroid/net/nsd/NsdManager;->mListenerMap:Landroid/util/SparseArray;
+Landroid/net/nsd/NsdManager;->mMapLock:Ljava/lang/Object;
+Landroid/net/nsd/NsdManager;->mService:Landroid/net/nsd/INsdManager;
+Landroid/net/nsd/NsdManager;->mServiceMap:Landroid/util/SparseArray;
+Landroid/net/nsd/NsdManager;->nameOf(I)Ljava/lang/String;
+Landroid/net/nsd/NsdManager;->NATIVE_DAEMON_EVENT:I
+Landroid/net/nsd/NsdManager;->nextListenerKey()I
+Landroid/net/nsd/NsdManager;->putListener(Ljava/lang/Object;Landroid/net/nsd/NsdServiceInfo;)I
+Landroid/net/nsd/NsdManager;->REGISTER_SERVICE:I
+Landroid/net/nsd/NsdManager;->REGISTER_SERVICE_FAILED:I
+Landroid/net/nsd/NsdManager;->REGISTER_SERVICE_SUCCEEDED:I
+Landroid/net/nsd/NsdManager;->removeListener(I)V
+Landroid/net/nsd/NsdManager;->RESOLVE_SERVICE:I
+Landroid/net/nsd/NsdManager;->RESOLVE_SERVICE_FAILED:I
+Landroid/net/nsd/NsdManager;->RESOLVE_SERVICE_SUCCEEDED:I
+Landroid/net/nsd/NsdManager;->SERVICE_FOUND:I
+Landroid/net/nsd/NsdManager;->SERVICE_LOST:I
+Landroid/net/nsd/NsdManager;->setEnabled(Z)V
+Landroid/net/nsd/NsdManager;->STOP_DISCOVERY:I
+Landroid/net/nsd/NsdManager;->STOP_DISCOVERY_FAILED:I
+Landroid/net/nsd/NsdManager;->STOP_DISCOVERY_SUCCEEDED:I
+Landroid/net/nsd/NsdManager;->TAG:Ljava/lang/String;
+Landroid/net/nsd/NsdManager;->UNREGISTER_SERVICE:I
+Landroid/net/nsd/NsdManager;->UNREGISTER_SERVICE_FAILED:I
+Landroid/net/nsd/NsdManager;->UNREGISTER_SERVICE_SUCCEEDED:I
+Landroid/net/nsd/NsdServiceInfo;-><init>(Ljava/lang/String;Ljava/lang/String;)V
+Landroid/net/nsd/NsdServiceInfo;->getTxtRecord()[B
+Landroid/net/nsd/NsdServiceInfo;->getTxtRecordSize()I
+Landroid/net/nsd/NsdServiceInfo;->mHost:Ljava/net/InetAddress;
+Landroid/net/nsd/NsdServiceInfo;->mPort:I
+Landroid/net/nsd/NsdServiceInfo;->mServiceName:Ljava/lang/String;
+Landroid/net/nsd/NsdServiceInfo;->mServiceType:Ljava/lang/String;
+Landroid/net/nsd/NsdServiceInfo;->mTxtRecord:Landroid/util/ArrayMap;
+Landroid/net/nsd/NsdServiceInfo;->setTxtRecords(Ljava/lang/String;)V
+Landroid/net/nsd/NsdServiceInfo;->TAG:Ljava/lang/String;
diff --git a/Tethering/apex/hiddenapi/hiddenapi-max-target-r-loprio.txt b/Tethering/apex/hiddenapi/hiddenapi-max-target-r-loprio.txt
new file mode 100644
index 0000000..211b847
--- /dev/null
+++ b/Tethering/apex/hiddenapi/hiddenapi-max-target-r-loprio.txt
@@ -0,0 +1 @@
+Landroid/net/nsd/INsdManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/nsd/INsdManager;
diff --git a/Tethering/proguard.flags b/Tethering/proguard.flags
index f62df7f..6735317 100644
--- a/Tethering/proguard.flags
+++ b/Tethering/proguard.flags
@@ -8,6 +8,10 @@
native <methods>;
}
+-keep class com.android.networkstack.tethering.util.TcUtils {
+ native <methods>;
+}
+
-keepclassmembers public class * extends com.android.networkstack.tethering.util.Struct {
*;
}
diff --git a/framework-t/Android.bp b/framework-t/Android.bp
new file mode 100644
index 0000000..abcfbeb
--- /dev/null
+++ b/framework-t/Android.bp
@@ -0,0 +1,71 @@
+//
+// 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 {
+ // See: http://go/android-license-faq
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_defaults {
+ name: "enable-framework-connectivity-t-targets",
+ enabled: true,
+}
+// The above defaults can be used to disable framework-connectivity t
+// targets while minimizing merge conflicts in the build rules.
+
+
+java_sdk_library {
+ name: "framework-connectivity-tiramisu",
+ sdk_version: "module_current",
+ min_sdk_version: "Tiramisu",
+ defaults: [
+ "framework-module-defaults",
+ "enable-framework-connectivity-t-targets",
+ ],
+ srcs: [
+ ":framework-connectivity-tiramisu-updatable-sources",
+ ],
+ libs: [
+ "unsupportedappusage",
+ "app-compat-annotations",
+ ],
+ permitted_packages: [
+ "android.net",
+ "android.net.nsd",
+ ],
+ apex_available: [
+ "com.android.tethering",
+ ],
+ impl_library_visibility: [
+ "//packages/modules/Connectivity/Tethering/apex",
+ // In preparation for future move
+ "//packages/modules/Connectivity/apex",
+ "//packages/modules/Connectivity/service-t",
+ "//frameworks/base",
+
+ // Tests using hidden APIs
+ "//cts/tests/netlegacy22.api",
+ "//external/sl4a:__subpackages__",
+ "//frameworks/libs/net/common/testutils",
+ "//frameworks/libs/net/common/tests:__subpackages__",
+ "//frameworks/opt/telephony/tests/telephonytests",
+ "//packages/modules/CaptivePortalLogin/tests",
+ "//packages/modules/Connectivity/Tethering/tests:__subpackages__",
+ "//packages/modules/Connectivity/tests:__subpackages__",
+ "//packages/modules/NetworkStack/tests:__subpackages__",
+ "//packages/modules/Wifi/service/tests/wifitests",
+ ],
+}
diff --git a/framework-t/api/current.txt b/framework-t/api/current.txt
new file mode 100644
index 0000000..0443456
--- /dev/null
+++ b/framework-t/api/current.txt
@@ -0,0 +1,60 @@
+// Signature format: 2.0
+package android.net.nsd {
+
+ public final class NsdManager {
+ method public void discoverServices(String, int, android.net.nsd.NsdManager.DiscoveryListener);
+ method public void registerService(android.net.nsd.NsdServiceInfo, int, android.net.nsd.NsdManager.RegistrationListener);
+ method public void resolveService(android.net.nsd.NsdServiceInfo, android.net.nsd.NsdManager.ResolveListener);
+ method public void stopServiceDiscovery(android.net.nsd.NsdManager.DiscoveryListener);
+ method public void unregisterService(android.net.nsd.NsdManager.RegistrationListener);
+ field public static final String ACTION_NSD_STATE_CHANGED = "android.net.nsd.STATE_CHANGED";
+ field public static final String EXTRA_NSD_STATE = "nsd_state";
+ field public static final int FAILURE_ALREADY_ACTIVE = 3; // 0x3
+ field public static final int FAILURE_INTERNAL_ERROR = 0; // 0x0
+ field public static final int FAILURE_MAX_LIMIT = 4; // 0x4
+ field public static final int NSD_STATE_DISABLED = 1; // 0x1
+ field public static final int NSD_STATE_ENABLED = 2; // 0x2
+ field public static final int PROTOCOL_DNS_SD = 1; // 0x1
+ }
+
+ public static interface NsdManager.DiscoveryListener {
+ method public void onDiscoveryStarted(String);
+ method public void onDiscoveryStopped(String);
+ method public void onServiceFound(android.net.nsd.NsdServiceInfo);
+ method public void onServiceLost(android.net.nsd.NsdServiceInfo);
+ method public void onStartDiscoveryFailed(String, int);
+ method public void onStopDiscoveryFailed(String, int);
+ }
+
+ public static interface NsdManager.RegistrationListener {
+ method public void onRegistrationFailed(android.net.nsd.NsdServiceInfo, int);
+ method public void onServiceRegistered(android.net.nsd.NsdServiceInfo);
+ method public void onServiceUnregistered(android.net.nsd.NsdServiceInfo);
+ method public void onUnregistrationFailed(android.net.nsd.NsdServiceInfo, int);
+ }
+
+ public static interface NsdManager.ResolveListener {
+ method public void onResolveFailed(android.net.nsd.NsdServiceInfo, int);
+ method public void onServiceResolved(android.net.nsd.NsdServiceInfo);
+ }
+
+ public final class NsdServiceInfo implements android.os.Parcelable {
+ ctor public NsdServiceInfo();
+ method public int describeContents();
+ method public java.util.Map<java.lang.String,byte[]> getAttributes();
+ method public java.net.InetAddress getHost();
+ method public int getPort();
+ method public String getServiceName();
+ method public String getServiceType();
+ method public void removeAttribute(String);
+ method public void setAttribute(String, String);
+ method public void setHost(java.net.InetAddress);
+ method public void setPort(int);
+ method public void setServiceName(String);
+ method public void setServiceType(String);
+ method public void writeToParcel(android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.nsd.NsdServiceInfo> CREATOR;
+ }
+
+}
+
diff --git a/framework-t/api/module-lib-current.txt b/framework-t/api/module-lib-current.txt
new file mode 100644
index 0000000..81d89c6
--- /dev/null
+++ b/framework-t/api/module-lib-current.txt
@@ -0,0 +1,9 @@
+// Signature format: 2.0
+package android.net {
+
+ public final class ConnectivityFrameworkInitializerTiramisu {
+ method public static void registerServiceWrappers();
+ }
+
+}
+
diff --git a/framework-t/api/module-lib-removed.txt b/framework-t/api/module-lib-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/framework-t/api/module-lib-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/framework-t/api/removed.txt b/framework-t/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/framework-t/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/framework-t/api/system-current.txt b/framework-t/api/system-current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/framework-t/api/system-current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/framework-t/api/system-removed.txt b/framework-t/api/system-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/framework-t/api/system-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/framework/Android.bp b/framework/Android.bp
index 028701a..de505c7 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -94,6 +94,7 @@
// In preparation for future move
"//packages/modules/Connectivity/apex",
"//packages/modules/Connectivity/service",
+ "//packages/modules/Connectivity/service-t",
"//frameworks/base/packages/Connectivity/service",
"//frameworks/base",
diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java
index 7d65f8c..009890c 100644
--- a/framework/src/android/net/ConnectivityManager.java
+++ b/framework/src/android/net/ConnectivityManager.java
@@ -5612,7 +5612,7 @@
* background data is restricted.
*
* @param uid uid of target app
- * @throws IllegalStateException if update allow list failed.
+ * @throws IllegalStateException if updating allow list failed.
* @hide
*/
@SystemApi(client = MODULE_LIBRARIES)
@@ -5634,7 +5634,7 @@
* Takes precedence over {@link #updateMeteredNetworkAllowList}.
*
* @param uid uid of target app
- * @throws IllegalStateException if update deny list failed.
+ * @throws IllegalStateException if updating deny list failed.
* @hide
*/
@SystemApi(client = MODULE_LIBRARIES)
@@ -5656,8 +5656,8 @@
*
* @param chain target chain.
* @param uid uid to allow/deny.
- * @param allow either add or remove rule.
- * @throws IllegalStateException if update firewall rule failed.
+ * @param allow whether networking is allowed or denied.
+ * @throws IllegalStateException if updating firewall rule failed.
* @hide
*/
@SystemApi(client = MODULE_LIBRARIES)
@@ -5680,7 +5680,7 @@
*
* @param chain target chain.
* @param enable whether the chain should be enabled.
- * @throws IllegalStateException if set firewall chain failed.
+ * @throws IllegalStateException if enabling or disabling the firewall chain failed.
* @hide
*/
@SystemApi(client = MODULE_LIBRARIES)
@@ -5702,7 +5702,7 @@
*
* @param chain target chain to replace.
* @param uids The list of UIDs to be placed into chain.
- * @throws IllegalStateException if replace firewall chain failed.
+ * @throws IllegalStateException if replacing the firewall chain failed.
* @throws IllegalArgumentException if {@code chain} is not a valid chain.
* @hide
*/
@@ -5727,7 +5727,7 @@
* NetworkStatsFactory which is platform code but will be moved into connectivity (tethering)
* mainline module.
*
- * @throws IllegalStateException if swap active stats map failed.
+ * @throws IllegalStateException if swapping active stats map failed.
* @hide
*/
@SystemApi(client = MODULE_LIBRARIES)
diff --git a/service-t/Android.bp b/service-t/Android.bp
new file mode 100644
index 0000000..48c74c6
--- /dev/null
+++ b/service-t/Android.bp
@@ -0,0 +1,56 @@
+//
+// 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 {
+ // See: http://go/android-license-faq
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+// This builds T+ services depending on framework-connectivity-tiramisu
+// hidden symbols separately from the S+ services, to ensure that S+
+// services cannot accidentally depend on T+ hidden symbols from
+// framework-connectivity-tiramisu.
+java_library {
+ name: "service-connectivity-tiramisu-pre-jarjar",
+ sdk_version: "system_server_current",
+ // TODO(b/210962470): Bump this to at least S, and then T.
+ min_sdk_version: "30",
+ srcs: [
+ "src/**/*.java",
+ // TODO: This is necessary just for LocalLog, remove after removing NativeDaemonConnector.
+ ":framework-connectivity-shared-srcs",
+ ":services.connectivity-tiramisu-updatable-sources",
+ ],
+ libs: [
+ "framework-annotations-lib",
+ "framework-connectivity.impl",
+ "framework-connectivity-tiramisu.impl",
+ "service-connectivity-pre-jarjar",
+ "unsupportedappusage",
+ ],
+ static_libs: [
+ "modules-utils-build",
+ "modules-utils-statemachine",
+ "net-utils-framework-common",
+ ],
+ apex_available: [
+ "com.android.tethering",
+ ],
+ visibility: [
+ "//packages/modules/Connectivity/service",
+ "//packages/modules/Connectivity/tests:__subpackages__",
+ ],
+}
diff --git a/service/src/com/android/server/ConnectivityServiceInitializer.java b/service-t/src/com/android/server/ConnectivityServiceInitializer.java
similarity index 68%
rename from service/src/com/android/server/ConnectivityServiceInitializer.java
rename to service-t/src/com/android/server/ConnectivityServiceInitializer.java
index b1a56ae..23d8bdc 100644
--- a/service/src/com/android/server/ConnectivityServiceInitializer.java
+++ b/service-t/src/com/android/server/ConnectivityServiceInitializer.java
@@ -19,6 +19,8 @@
import android.content.Context;
import android.util.Log;
+import com.android.modules.utils.build.SdkLevel;
+
/**
* Connectivity service initializer for core networking. This is called by system server to create
* a new instance of ConnectivityService.
@@ -26,12 +28,14 @@
public final class ConnectivityServiceInitializer extends SystemService {
private static final String TAG = ConnectivityServiceInitializer.class.getSimpleName();
private final ConnectivityService mConnectivity;
+ private final NsdService mNsdService;
public ConnectivityServiceInitializer(Context context) {
super(context);
// Load JNI libraries used by ConnectivityService and its dependencies
System.loadLibrary("service-connectivity");
mConnectivity = new ConnectivityService(context);
+ mNsdService = createNsdService(context);
}
@Override
@@ -39,5 +43,20 @@
Log.i(TAG, "Registering " + Context.CONNECTIVITY_SERVICE);
publishBinderService(Context.CONNECTIVITY_SERVICE, mConnectivity,
/* allowIsolated= */ false);
+ if (mNsdService != null) {
+ Log.i(TAG, "Registering " + Context.NSD_SERVICE);
+ publishBinderService(Context.NSD_SERVICE, mNsdService, /* allowIsolated= */ false);
+ }
+ }
+
+ /** Return NsdService instance or null if current SDK is lower than T */
+ private NsdService createNsdService(final Context context) {
+ if (!SdkLevel.isAtLeastT()) return null;
+ try {
+ return NsdService.create(context);
+ } catch (InterruptedException e) {
+ Log.d(TAG, "Unable to get NSD service", e);
+ return null;
+ }
}
}
diff --git a/service/Android.bp b/service/Android.bp
index 1ec7daa..76f9153 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -108,6 +108,10 @@
"com.android.tethering",
],
lint: { strict_updatability_linting: true },
+ visibility: [
+ "//packages/modules/Connectivity/service-t",
+ "//packages/modules/Connectivity/tests:__subpackages__",
+ ],
}
java_library {
@@ -132,8 +136,13 @@
sdk_version: "system_server_current",
min_sdk_version: "30",
installable: true,
+ // This library combines system server jars that have access to different bootclasspath jars.
+ // Lower SDK service jars must not depend on higher SDK jars as that would let them
+ // transitively depend on the wrong bootclasspath jars. Sources also cannot be added here as
+ // they would transitively depend on bootclasspath jars that may not be available.
static_libs: [
"service-connectivity-pre-jarjar",
+ "service-connectivity-tiramisu-pre-jarjar",
],
jarjar_rules: "jarjar-rules.txt",
apex_available: [
diff --git a/tests/common/Android.bp b/tests/common/Android.bp
index c533dab..f1897f5 100644
--- a/tests/common/Android.bp
+++ b/tests/common/Android.bp
@@ -114,6 +114,7 @@
// meaning @hide APIs in framework-connectivity are resolved before @SystemApi
// stubs in framework
"framework-connectivity.impl",
+ "framework-connectivity-tiramisu.impl",
"framework-tethering.impl",
"framework",
diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java
deleted file mode 100644
index 6e61705..0000000
--- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java
+++ /dev/null
@@ -1,470 +0,0 @@
-/*
- * Copyright (C) 2008 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.cts;
-
-import junit.framework.TestCase;
-
-import android.net.Credentials;
-import android.net.LocalServerSocket;
-import android.net.LocalSocket;
-import android.net.LocalSocketAddress;
-import android.system.Os;
-import android.system.OsConstants;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-public class LocalSocketTest extends TestCase {
- private final static String ADDRESS_PREFIX = "com.android.net.LocalSocketTest";
-
- public void testLocalConnections() throws IOException {
- String address = ADDRESS_PREFIX + "_testLocalConnections";
- // create client and server socket
- LocalServerSocket localServerSocket = new LocalServerSocket(address);
- LocalSocket clientSocket = new LocalSocket();
-
- // establish connection between client and server
- LocalSocketAddress locSockAddr = new LocalSocketAddress(address);
- assertFalse(clientSocket.isConnected());
- clientSocket.connect(locSockAddr);
- assertTrue(clientSocket.isConnected());
-
- LocalSocket serverSocket = localServerSocket.accept();
- assertTrue(serverSocket.isConnected());
- assertTrue(serverSocket.isBound());
- try {
- serverSocket.bind(localServerSocket.getLocalSocketAddress());
- fail("Cannot bind a LocalSocket from accept()");
- } catch (IOException expected) {
- }
- try {
- serverSocket.connect(locSockAddr);
- fail("Cannot connect a LocalSocket from accept()");
- } catch (IOException expected) {
- }
-
- Credentials credent = clientSocket.getPeerCredentials();
- assertTrue(0 != credent.getPid());
-
- // send data from client to server
- OutputStream clientOutStream = clientSocket.getOutputStream();
- clientOutStream.write(12);
- InputStream serverInStream = serverSocket.getInputStream();
- assertEquals(12, serverInStream.read());
-
- //send data from server to client
- OutputStream serverOutStream = serverSocket.getOutputStream();
- serverOutStream.write(3);
- InputStream clientInStream = clientSocket.getInputStream();
- assertEquals(3, clientInStream.read());
-
- // Test sending and receiving file descriptors
- clientSocket.setFileDescriptorsForSend(new FileDescriptor[]{FileDescriptor.in});
- clientOutStream.write(32);
- assertEquals(32, serverInStream.read());
-
- FileDescriptor[] out = serverSocket.getAncillaryFileDescriptors();
- assertEquals(1, out.length);
- FileDescriptor fd = clientSocket.getFileDescriptor();
- assertTrue(fd.valid());
-
- //shutdown input stream of client
- clientSocket.shutdownInput();
- assertEquals(-1, clientInStream.read());
-
- //shutdown output stream of client
- clientSocket.shutdownOutput();
- try {
- clientOutStream.write(10);
- fail("testLocalSocket shouldn't come to here");
- } catch (IOException e) {
- // expected
- }
-
- //shutdown input stream of server
- serverSocket.shutdownInput();
- assertEquals(-1, serverInStream.read());
-
- //shutdown output stream of server
- serverSocket.shutdownOutput();
- try {
- serverOutStream.write(10);
- fail("testLocalSocket shouldn't come to here");
- } catch (IOException e) {
- // expected
- }
-
- //close client socket
- clientSocket.close();
- try {
- clientInStream.read();
- fail("testLocalSocket shouldn't come to here");
- } catch (IOException e) {
- // expected
- }
-
- //close server socket
- serverSocket.close();
- try {
- serverInStream.read();
- fail("testLocalSocket shouldn't come to here");
- } catch (IOException e) {
- // expected
- }
- }
-
- public void testAccessors() throws IOException {
- String address = ADDRESS_PREFIX + "_testAccessors";
- LocalSocket socket = new LocalSocket();
- LocalSocketAddress addr = new LocalSocketAddress(address);
-
- assertFalse(socket.isBound());
- socket.bind(addr);
- assertTrue(socket.isBound());
- assertEquals(addr, socket.getLocalSocketAddress());
-
- String str = socket.toString();
- assertTrue(str.contains("impl:android.net.LocalSocketImpl"));
-
- socket.setReceiveBufferSize(1999);
- assertEquals(1999 << 1, socket.getReceiveBufferSize());
-
- socket.setSendBufferSize(3998);
- assertEquals(3998 << 1, socket.getSendBufferSize());
-
- assertEquals(0, socket.getSoTimeout());
- socket.setSoTimeout(1996);
- assertTrue(socket.getSoTimeout() > 0);
-
- try {
- socket.getRemoteSocketAddress();
- fail("testLocalSocketSecondary shouldn't come to here");
- } catch (UnsupportedOperationException e) {
- // expected
- }
-
- try {
- socket.isClosed();
- fail("testLocalSocketSecondary shouldn't come to here");
- } catch (UnsupportedOperationException e) {
- // expected
- }
-
- try {
- socket.isInputShutdown();
- fail("testLocalSocketSecondary shouldn't come to here");
- } catch (UnsupportedOperationException e) {
- // expected
- }
-
- try {
- socket.isOutputShutdown();
- fail("testLocalSocketSecondary shouldn't come to here");
- } catch (UnsupportedOperationException e) {
- // expected
- }
-
- try {
- socket.connect(addr, 2005);
- fail("testLocalSocketSecondary shouldn't come to here");
- } catch (UnsupportedOperationException e) {
- // expected
- }
-
- socket.close();
- }
-
- // http://b/31205169
- public void testSetSoTimeout_readTimeout() throws Exception {
- String address = ADDRESS_PREFIX + "_testSetSoTimeout_readTimeout";
-
- try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
- final LocalSocket clientSocket = socketPair.clientSocket;
-
- // Set the timeout in millis.
- int timeoutMillis = 1000;
- clientSocket.setSoTimeout(timeoutMillis);
-
- // Avoid blocking the test run if timeout doesn't happen by using a separate thread.
- Callable<Result> reader = () -> {
- try {
- clientSocket.getInputStream().read();
- return Result.noException("Did not block");
- } catch (IOException e) {
- return Result.exception(e);
- }
- };
- // Allow the configured timeout, plus some slop.
- int allowedTime = timeoutMillis + 2000;
- Result result = runInSeparateThread(allowedTime, reader);
-
- // Check the message was a timeout, it's all we have to go on.
- String expectedMessage = Os.strerror(OsConstants.EAGAIN);
- result.assertThrewIOException(expectedMessage);
- }
- }
-
- // http://b/31205169
- public void testSetSoTimeout_writeTimeout() throws Exception {
- String address = ADDRESS_PREFIX + "_testSetSoTimeout_writeTimeout";
-
- try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
- final LocalSocket clientSocket = socketPair.clientSocket;
-
- // Set the timeout in millis.
- int timeoutMillis = 1000;
- clientSocket.setSoTimeout(timeoutMillis);
-
- // Set a small buffer size so we know we can flood it.
- clientSocket.setSendBufferSize(100);
- final int bufferSize = clientSocket.getSendBufferSize();
-
- // Avoid blocking the test run if timeout doesn't happen by using a separate thread.
- Callable<Result> writer = () -> {
- try {
- byte[] toWrite = new byte[bufferSize * 2];
- clientSocket.getOutputStream().write(toWrite);
- return Result.noException("Did not block");
- } catch (IOException e) {
- return Result.exception(e);
- }
- };
- // Allow the configured timeout, plus some slop.
- int allowedTime = timeoutMillis + 2000;
-
- Result result = runInSeparateThread(allowedTime, writer);
-
- // Check the message was a timeout, it's all we have to go on.
- String expectedMessage = Os.strerror(OsConstants.EAGAIN);
- result.assertThrewIOException(expectedMessage);
- }
- }
-
- public void testAvailable() throws Exception {
- String address = ADDRESS_PREFIX + "_testAvailable";
-
- try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
- LocalSocket clientSocket = socketPair.clientSocket;
- LocalSocket serverSocket = socketPair.serverSocket.accept();
-
- OutputStream clientOutputStream = clientSocket.getOutputStream();
- InputStream serverInputStream = serverSocket.getInputStream();
- assertEquals(0, serverInputStream.available());
-
- byte[] buffer = new byte[50];
- clientOutputStream.write(buffer);
- assertEquals(50, serverInputStream.available());
-
- InputStream clientInputStream = clientSocket.getInputStream();
- OutputStream serverOutputStream = serverSocket.getOutputStream();
- assertEquals(0, clientInputStream.available());
- serverOutputStream.write(buffer);
- assertEquals(50, serverInputStream.available());
-
- serverSocket.close();
- }
- }
-
- // http://b/34095140
- public void testLocalSocketCreatedFromFileDescriptor() throws Exception {
- String address = ADDRESS_PREFIX + "_testLocalSocketCreatedFromFileDescriptor";
-
- // Establish connection between a local client and server to get a valid client socket file
- // descriptor.
- try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
- // Extract the client FileDescriptor we can use.
- FileDescriptor fileDescriptor = socketPair.clientSocket.getFileDescriptor();
- assertTrue(fileDescriptor.valid());
-
- // Create the LocalSocket we want to test.
- LocalSocket clientSocketCreatedFromFileDescriptor =
- LocalSocket.createConnectedLocalSocket(fileDescriptor);
- assertTrue(clientSocketCreatedFromFileDescriptor.isConnected());
- assertTrue(clientSocketCreatedFromFileDescriptor.isBound());
-
- // Test the LocalSocket can be used for communication.
- LocalSocket serverSocket = socketPair.serverSocket.accept();
- OutputStream clientOutputStream =
- clientSocketCreatedFromFileDescriptor.getOutputStream();
- InputStream serverInputStream = serverSocket.getInputStream();
-
- clientOutputStream.write(12);
- assertEquals(12, serverInputStream.read());
-
- // Closing clientSocketCreatedFromFileDescriptor does not close the file descriptor.
- clientSocketCreatedFromFileDescriptor.close();
- assertTrue(fileDescriptor.valid());
-
- // .. while closing the LocalSocket that owned the file descriptor does.
- socketPair.clientSocket.close();
- assertFalse(fileDescriptor.valid());
- }
- }
-
- public void testFlush() throws Exception {
- String address = ADDRESS_PREFIX + "_testFlush";
-
- try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
- LocalSocket clientSocket = socketPair.clientSocket;
- LocalSocket serverSocket = socketPair.serverSocket.accept();
-
- OutputStream clientOutputStream = clientSocket.getOutputStream();
- InputStream serverInputStream = serverSocket.getInputStream();
- testFlushWorks(clientOutputStream, serverInputStream);
-
- OutputStream serverOutputStream = serverSocket.getOutputStream();
- InputStream clientInputStream = clientSocket.getInputStream();
- testFlushWorks(serverOutputStream, clientInputStream);
-
- serverSocket.close();
- }
- }
-
- private void testFlushWorks(OutputStream outputStream, InputStream inputStream)
- throws Exception {
- final int bytesToTransfer = 50;
- StreamReader inputStreamReader = new StreamReader(inputStream, bytesToTransfer);
-
- byte[] buffer = new byte[bytesToTransfer];
- outputStream.write(buffer);
- assertEquals(bytesToTransfer, inputStream.available());
-
- // Start consuming the data.
- inputStreamReader.start();
-
- // This doesn't actually flush any buffers, it just polls until the reader has read all the
- // bytes.
- outputStream.flush();
-
- inputStreamReader.waitForCompletion(5000);
- inputStreamReader.assertBytesRead(bytesToTransfer);
- assertEquals(0, inputStream.available());
- }
-
- private static class StreamReader extends Thread {
- private final InputStream is;
- private final int expectedByteCount;
- private final CountDownLatch completeLatch = new CountDownLatch(1);
-
- private volatile Exception exception;
- private int bytesRead;
-
- private StreamReader(InputStream is, int expectedByteCount) {
- this.is = is;
- this.expectedByteCount = expectedByteCount;
- }
-
- @Override
- public void run() {
- try {
- byte[] buffer = new byte[10];
- int readCount;
- while ((readCount = is.read(buffer)) >= 0) {
- bytesRead += readCount;
- if (bytesRead >= expectedByteCount) {
- break;
- }
- }
- } catch (IOException e) {
- exception = e;
- } finally {
- completeLatch.countDown();
- }
- }
-
- public void waitForCompletion(long waitMillis) throws Exception {
- if (!completeLatch.await(waitMillis, TimeUnit.MILLISECONDS)) {
- fail("Timeout waiting for completion");
- }
- if (exception != null) {
- throw new Exception("Read failed", exception);
- }
- }
-
- public void assertBytesRead(int expected) {
- assertEquals(expected, bytesRead);
- }
- }
-
- private static class Result {
- private final String type;
- private final Exception e;
-
- private Result(String type, Exception e) {
- this.type = type;
- this.e = e;
- }
-
- static Result noException(String description) {
- return new Result(description, null);
- }
-
- static Result exception(Exception e) {
- return new Result(e.getClass().getName(), e);
- }
-
- void assertThrewIOException(String expectedMessage) {
- assertEquals("Unexpected result type", IOException.class.getName(), type);
- assertEquals("Unexpected exception message", expectedMessage, e.getMessage());
- }
- }
-
- private static Result runInSeparateThread(int allowedTime, final Callable<Result> callable)
- throws Exception {
- ExecutorService service = Executors.newSingleThreadScheduledExecutor();
- Future<Result> future = service.submit(callable);
- Result result = future.get(allowedTime, TimeUnit.MILLISECONDS);
- if (!future.isDone()) {
- fail("Worker thread appears blocked");
- }
- return result;
- }
-
- private static class LocalSocketPair implements AutoCloseable {
- static LocalSocketPair createConnectedSocketPair(String address) throws Exception {
- LocalServerSocket localServerSocket = new LocalServerSocket(address);
- final LocalSocket clientSocket = new LocalSocket();
-
- // Establish connection between client and server
- LocalSocketAddress locSockAddr = new LocalSocketAddress(address);
- clientSocket.connect(locSockAddr);
- assertTrue(clientSocket.isConnected());
- return new LocalSocketPair(localServerSocket, clientSocket);
- }
-
- final LocalServerSocket serverSocket;
- final LocalSocket clientSocket;
-
- LocalSocketPair(LocalServerSocket serverSocket, LocalSocket clientSocket) {
- this.serverSocket = serverSocket;
- this.clientSocket = clientSocket;
- }
-
- public void close() throws Exception {
- serverSocket.close();
- clientSocket.close();
- }
- }
-}
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index 3735ca4..48751f4 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -130,6 +130,7 @@
"platform-compat-test-rules",
"platform-test-annotations",
"service-connectivity-pre-jarjar",
+ "service-connectivity-tiramisu-pre-jarjar",
"services.core-vpn",
],
libs: [
diff --git a/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java b/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java
index 6e51069..561e621 100644
--- a/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java
+++ b/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java
@@ -240,6 +240,27 @@
assertFalse(stats.hasNextBucket());
}
+
+ @Test
+ public void testQueryDetailsForDevice() throws Exception {
+ final long startTime = 1;
+ final long endTime = 100;
+
+ reset(mStatsSession);
+ when(mService.openSessionForUsageStats(anyInt(), anyString())).thenReturn(mStatsSession);
+ when(mStatsSession.getHistoryIntervalForNetwork(any(NetworkTemplate.class),
+ anyInt(), anyLong(), anyLong()))
+ .thenReturn(new NetworkStatsHistory(10, 0));
+ final NetworkTemplate template = new NetworkTemplate.Builder(NetworkTemplate.MATCH_MOBILE)
+ .setMeteredness(NetworkStats.Bucket.METERED_YES).build();
+ NetworkStats stats = mManager.queryDetailsForDevice(template, startTime, endTime);
+
+ verify(mStatsSession, times(1)).getHistoryIntervalForNetwork(
+ eq(template), eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime));
+
+ assertFalse(stats.hasNextBucket());
+ }
+
private void assertBucketMatches(Entry expected, NetworkStats.Bucket actual) {
assertEquals(expected.uid, actual.getUid());
assertEquals(expected.rxBytes, actual.getRxBytes());
diff --git a/tests/unit/java/android/net/NetworkStatsTest.java b/tests/unit/java/android/net/NetworkStatsTest.java
index be2857e..b0cc16c 100644
--- a/tests/unit/java/android/net/NetworkStatsTest.java
+++ b/tests/unit/java/android/net/NetworkStatsTest.java
@@ -37,6 +37,7 @@
import static android.net.NetworkStats.UID_ALL;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.os.Build;
@@ -53,8 +54,10 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
+import java.util.Iterator;
@RunWith(DevSdkIgnoreRunner.class)
@SmallTest
@@ -1037,6 +1040,29 @@
assertEquals(secondEntry, stats.getValues(1, null));
}
+ @Test
+ public void testIterator() {
+ final NetworkStats emptyStats = new NetworkStats(0, 0);
+ final Iterator emptyIterator = emptyStats.iterator();
+ assertFalse(emptyIterator.hasNext());
+
+ final int numEntries = 10;
+ final ArrayList<NetworkStats.Entry> entries = new ArrayList<>();
+ final NetworkStats stats = new NetworkStats(TEST_START, 1);
+ for (int i = 0; i < numEntries; ++i) {
+ NetworkStats.Entry entry = new NetworkStats.Entry("test1", 10100, SET_DEFAULT,
+ TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO,
+ i * 10L /* rxBytes */, i * 3L /* rxPackets */,
+ i * 15L /* txBytes */, i * 2L /* txPackets */, 0L /* operations */);
+ stats.insertEntry(entry);
+ entries.add(entry);
+ }
+
+ for (NetworkStats.Entry e : stats) {
+ assertEquals(e, entries.remove(0));
+ }
+ }
+
private static void assertContains(NetworkStats stats, String iface, int uid, int set,
int tag, int metered, int roaming, int defaultNetwork, long rxBytes, long rxPackets,
long txBytes, long txPackets, long operations) {
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
index 40587c5..3765bf0 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -66,8 +66,10 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
@@ -119,6 +121,7 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.test.BroadcastInterceptingContext;
+import com.android.net.module.util.LocationPermissionChecker;
import com.android.server.net.NetworkStatsService.AlertObserver;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
@@ -193,6 +196,8 @@
@Mock
private NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor;
private HandlerThread mHandlerThread;
+ @Mock
+ private LocationPermissionChecker mLocationPermissionChecker;
private NetworkStatsService mService;
private INetworkStatsSession mSession;
@@ -262,6 +267,8 @@
MockitoAnnotations.initMocks(this);
final Context context = InstrumentationRegistry.getContext();
mServiceContext = new MockContext(context);
+ when(mLocationPermissionChecker.checkCallersLocationPermission(
+ any(), any(), anyInt(), anyBoolean(), any())).thenReturn(true);
when(sWifiInfo.getCurrentNetworkKey()).thenReturn(TEST_WIFI_NETWORK_KEY);
mStatsDir = TestIoUtils.createTemporaryDirectory(getClass().getSimpleName());
@@ -334,6 +341,10 @@
return mContentObserver = super.makeContentObserver(handler, settings, monitor);
}
+ @Override
+ public LocationPermissionChecker makeLocationPermissionChecker(final Context context) {
+ return mLocationPermissionChecker;
+ }
};
}
@@ -1688,6 +1699,28 @@
provider.expectOnRequestStatsUpdate(0 /* unused */);
}
+ /**
+ * Verify the service will throw exceptions if the template is location sensitive but
+ * the permission is not granted.
+ */
+ @Test
+ public void testEnforceTemplateLocationPermission() throws Exception {
+ when(mLocationPermissionChecker.checkCallersLocationPermission(
+ any(), any(), anyInt(), anyBoolean(), any())).thenReturn(false);
+ initWifiStats(buildWifiState(true, TEST_IFACE, IMSI_1));
+ assertThrows(SecurityException.class, () ->
+ assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0));
+ // Templates w/o wifi network keys can query stats as usual.
+ assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
+ assertNetworkTotal(sTemplateImsi1, 0L, 0L, 0L, 0L, 0);
+
+ when(mLocationPermissionChecker.checkCallersLocationPermission(
+ any(), any(), anyInt(), anyBoolean(), any())).thenReturn(true);
+ assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
+ assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
+ assertNetworkTotal(sTemplateImsi1, 0L, 0L, 0L, 0L, 0);
+ }
+
private static File getBaseDir(File statsDir) {
File baseDir = new File(statsDir, "netstats");
baseDir.mkdirs();
@@ -1703,7 +1736,8 @@
private void assertNetworkTotal(NetworkTemplate template, long start, long end, long rxBytes,
long rxPackets, long txBytes, long txPackets, int operations) throws Exception {
// verify history API
- final NetworkStatsHistory history = mSession.getHistoryForNetwork(template, FIELD_ALL);
+ final NetworkStatsHistory history =
+ mSession.getHistoryIntervalForNetwork(template, FIELD_ALL, start, end);
assertValues(history, start, end, rxBytes, rxPackets, txBytes, txPackets, operations);
// verify summary API