Merge "Move to android_mallopt for malloc debug calls."
diff --git a/Android.mk b/Android.mk
index c58f7af..9bda2dc 100644
--- a/Android.mk
+++ b/Android.mk
@@ -32,27 +32,6 @@
# ============================================================
include $(CLEAR_VARS)
-aidl_parcelables :=
-define stubs-to-aidl-parcelables
- gen := $(TARGET_OUT_COMMON_INTERMEDIATES)/$1.aidl
- aidl_parcelables += $$(gen)
- $$(gen): $(call java-lib-header-files,$1) $(HOST_OUT_EXECUTABLES)/sdkparcelables
- @echo Extract SDK parcelables: $$@
- rm -f $$@
- $(HOST_OUT_EXECUTABLES)/sdkparcelables $$< $$@
-endef
-
-$(foreach stubs,android_stubs_current android_test_stubs_current android_system_stubs_current,\
- $(eval $(call stubs-to-aidl-parcelables,$(stubs))))
-
-gen := $(TARGET_OUT_COMMON_INTERMEDIATES)/framework.aidl
-.KATI_RESTAT: $(gen)
-$(gen): $(aidl_parcelables)
- @echo Combining SDK parcelables: $@
- rm -f $@.tmp
- cat $^ | sort -u > $@.tmp
- $(call commit-change-for-toc,$@)
-
# This is used by ide.mk as the list of source files that are
# always included.
INTERNAL_SDK_SOURCE_DIRS := $(addprefix $(LOCAL_PATH)/,$(dirs_to_document))
diff --git a/api/current.txt b/api/current.txt
index 4dcba83..2417d8e 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -8734,8 +8734,8 @@
method public android.bluetooth.le.ScanFilter.Builder setManufacturerData(int, byte[], byte[]);
method public android.bluetooth.le.ScanFilter.Builder setServiceData(android.os.ParcelUuid, byte[]);
method public android.bluetooth.le.ScanFilter.Builder setServiceData(android.os.ParcelUuid, byte[], byte[]);
- method public android.bluetooth.le.ScanFilter.Builder setServiceSolicitationUuid(android.os.ParcelUuid);
- method public android.bluetooth.le.ScanFilter.Builder setServiceSolicitationUuid(android.os.ParcelUuid, android.os.ParcelUuid);
+ method @NonNull public android.bluetooth.le.ScanFilter.Builder setServiceSolicitationUuid(@Nullable android.os.ParcelUuid);
+ method @NonNull public android.bluetooth.le.ScanFilter.Builder setServiceSolicitationUuid(@Nullable android.os.ParcelUuid, @Nullable android.os.ParcelUuid);
method public android.bluetooth.le.ScanFilter.Builder setServiceUuid(android.os.ParcelUuid);
method public android.bluetooth.le.ScanFilter.Builder setServiceUuid(android.os.ParcelUuid, android.os.ParcelUuid);
}
diff --git a/api/test-current.txt b/api/test-current.txt
index dc5ff8f..cb9ff493 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -923,6 +923,7 @@
package android.os {
public static class Build.VERSION {
+ field public static final String[] ACTIVE_CODENAMES;
field public static final int FIRST_SDK_INT;
field public static final int RESOURCES_SDK_INT;
}
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 1e12801..34c7372 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -56,7 +56,8 @@
* returned by {@link BluetoothAdapter#getBondedDevices()
* BluetoothAdapter.getBondedDevices()}. You can then open a
* {@link BluetoothSocket} for communication with the remote device, using
- * {@link #createRfcommSocketToServiceRecord(UUID)}.
+ * {@link #createRfcommSocketToServiceRecord(UUID)} over Bluetooth BR/EDR or using
+ * {@link #createL2capChannel(int)} over Bluetooth LE.
*
* <p class="note"><strong>Note:</strong>
* Requires the {@link android.Manifest.permission#BLUETOOTH} permission.
diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java
index 4e88625..c06b837 100644
--- a/core/java/android/bluetooth/BluetoothServerSocket.java
+++ b/core/java/android/bluetooth/BluetoothServerSocket.java
@@ -35,21 +35,28 @@
* On the client side, use a single {@link BluetoothSocket} to both initiate
* an outgoing connection and to manage the connection.
*
- * <p>The most common type of Bluetooth socket is RFCOMM, which is the type
- * supported by the Android APIs. RFCOMM is a connection-oriented, streaming
- * transport over Bluetooth. It is also known as the Serial Port Profile (SPP).
+ * <p>For Bluetooth BR/EDR, the most common type of socket is RFCOMM, which is the type supported by
+ * the Android APIs. RFCOMM is a connection-oriented, streaming transport over Bluetooth BR/EDR. It
+ * is also known as the Serial Port Profile (SPP). To create a listening
+ * {@link BluetoothServerSocket} that's ready for incoming Bluetooth BR/EDR connections, use {@link
+ * BluetoothAdapter#listenUsingRfcommWithServiceRecord
+ * BluetoothAdapter.listenUsingRfcommWithServiceRecord()}.
*
- * <p>To create a listening {@link BluetoothServerSocket} that's ready for
- * incoming connections, use
- * {@link BluetoothAdapter#listenUsingRfcommWithServiceRecord
- * BluetoothAdapter.listenUsingRfcommWithServiceRecord()}. Then call
- * {@link #accept()} to listen for incoming connection requests. This call
- * will block until a connection is established, at which point, it will return
- * a {@link BluetoothSocket} to manage the connection. Once the {@link
- * BluetoothSocket} is acquired, it's a good idea to call {@link #close()} on
- * the {@link BluetoothServerSocket} when it's no longer needed for accepting
- * connections. Closing the {@link BluetoothServerSocket} will <em>not</em>
- * close the returned {@link BluetoothSocket}.
+ * <p>For Bluetooth LE, the socket uses LE Connection-oriented Channel (CoC). LE CoC is a
+ * connection-oriented, streaming transport over Bluetooth LE and has a credit-based flow control.
+ * Correspondingly, use {@link BluetoothAdapter#listenUsingL2capChannel
+ * BluetoothAdapter.listenUsingL2capChannel()} to create a listening {@link BluetoothServerSocket}
+ * that's ready for incoming Bluetooth LE CoC connections. For LE CoC, you can use {@link #getPsm()}
+ * to get the protocol/service multiplexer (PSM) value that the peer needs to use to connect to your
+ * socket.
+ *
+ * <p> After the listening {@link BluetoothServerSocket} is created, call {@link #accept()} to
+ * listen for incoming connection requests. This call will block until a connection is established,
+ * at which point, it will return a {@link BluetoothSocket} to manage the connection. Once the
+ * {@link BluetoothSocket} is acquired, it's a good idea to call {@link #close()} on the {@link
+ * BluetoothServerSocket} when it's no longer needed for accepting
+ * connections. Closing the {@link BluetoothServerSocket} will <em>not</em> close the returned
+ * {@link BluetoothSocket}.
*
* <p>{@link BluetoothServerSocket} is thread
* safe. In particular, {@link #close} will always immediately abort ongoing
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
index c5d435b..66d1da8 100644
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ b/core/java/android/bluetooth/le/ScanFilter.java
@@ -16,6 +16,7 @@
package android.bluetooth.le;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
@@ -586,7 +587,8 @@
/**
* Set filter on service solicitation uuid.
*/
- public Builder setServiceSolicitationUuid(ParcelUuid serviceSolicitationUuid) {
+ public @NonNull Builder setServiceSolicitationUuid(
+ @Nullable ParcelUuid serviceSolicitationUuid) {
mServiceSolicitationUuid = serviceSolicitationUuid;
return this;
}
@@ -601,8 +603,9 @@
* @throws IllegalArgumentException If {@code serviceSolicitationUuid} is {@code null} but
* {@code serviceSolicitationUuidMask} is not {@code null}.
*/
- public Builder setServiceSolicitationUuid(ParcelUuid serviceSolicitationUuid,
- ParcelUuid solicitationUuidMask) {
+ public @NonNull Builder setServiceSolicitationUuid(
+ @Nullable ParcelUuid serviceSolicitationUuid,
+ @Nullable ParcelUuid solicitationUuidMask) {
if (mServiceSolicitationUuidMask != null && mServiceSolicitationUuid == null) {
throw new IllegalArgumentException(
"SolicitationUuid is null while SolicitationUuidMask is not null!");
diff --git a/core/java/android/net/IIpSecService.aidl b/core/java/android/net/IIpSecService.aidl
index d6774d4..b5a2a16 100644
--- a/core/java/android/net/IIpSecService.aidl
+++ b/core/java/android/net/IIpSecService.aidl
@@ -72,4 +72,8 @@
int tunnelResourceId, int direction, int transformResourceId, in String callingPackage);
void removeTransportModeTransforms(in ParcelFileDescriptor socket);
+
+ int lockEncapSocketForNattKeepalive(int encapSocketResourceId, int requesterUid);
+
+ void releaseNattKeepalive(int nattKeepaliveResourceId, int ownerUid);
}
diff --git a/core/java/android/net/ITestNetworkManager.aidl b/core/java/android/net/ITestNetworkManager.aidl
index bab6ae8..d586038 100644
--- a/core/java/android/net/ITestNetworkManager.aidl
+++ b/core/java/android/net/ITestNetworkManager.aidl
@@ -17,6 +17,7 @@
package android.net;
import android.net.LinkAddress;
+import android.net.LinkProperties;
import android.net.TestNetworkInterface;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
@@ -31,7 +32,8 @@
TestNetworkInterface createTunInterface(in LinkAddress[] linkAddrs);
TestNetworkInterface createTapInterface();
- void setupTestNetwork(in String iface, in IBinder binder);
+ void setupTestNetwork(in String iface, in LinkProperties lp, in boolean isMetered,
+ in IBinder binder);
void teardownTestNetwork(int netId);
}
diff --git a/core/java/android/net/TestNetworkManager.java b/core/java/android/net/TestNetworkManager.java
index e274005..4ac4a69 100644
--- a/core/java/android/net/TestNetworkManager.java
+++ b/core/java/android/net/TestNetworkManager.java
@@ -56,6 +56,26 @@
/**
* Sets up a capability-limited, testing-only network for a given interface
*
+ * @param lp The LinkProperties for the TestNetworkService to use for this test network. Note
+ * that the interface name and link addresses will be overwritten, and the passed-in values
+ * discarded.
+ * @param isMetered Whether or not the network should be considered metered.
+ * @param binder A binder object guarding the lifecycle of this test network.
+ * @hide
+ */
+ public void setupTestNetwork(
+ @NonNull LinkProperties lp, boolean isMetered, @NonNull IBinder binder) {
+ Preconditions.checkNotNull(lp, "Invalid LinkProperties");
+ try {
+ mService.setupTestNetwork(lp.getInterfaceName(), lp, isMetered, binder);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Sets up a capability-limited, testing-only network for a given interface
+ *
* @param iface the name of the interface to be used for the Network LinkProperties.
* @param binder A binder object guarding the lifecycle of this test network.
* @hide
@@ -63,7 +83,7 @@
@TestApi
public void setupTestNetwork(@NonNull String iface, @NonNull IBinder binder) {
try {
- mService.setupTestNetwork(iface, binder);
+ mService.setupTestNetwork(iface, null, true, binder);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/net/UrlQuerySanitizer.java b/core/java/android/net/UrlQuerySanitizer.java
index 5b67406..cf08b65 100644
--- a/core/java/android/net/UrlQuerySanitizer.java
+++ b/core/java/android/net/UrlQuerySanitizer.java
@@ -22,6 +22,8 @@
import java.util.Locale;
import java.util.Set;
import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
*
@@ -837,15 +839,11 @@
* @param string the escaped string
* @return the unescaped string.
*/
+ private static final Pattern plusOrPercent = Pattern.compile("[+%]");
public String unescape(String string) {
- // Early exit if no escaped characters.
- int firstEscape = string.indexOf('%');
- if ( firstEscape < 0) {
- firstEscape = string.indexOf('+');
- if (firstEscape < 0) {
- return string;
- }
- }
+ final Matcher matcher = plusOrPercent.matcher(string);
+ if (!matcher.find()) return string;
+ final int firstEscape = matcher.start();
int length = string.length();
@@ -855,8 +853,7 @@
char c = string.charAt(i);
if (c == '+') {
c = ' ';
- }
- else if ( c == '%' && i + 2 < length) {
+ } else if (c == '%' && i + 2 < length) {
char c1 = string.charAt(i + 1);
char c2 = string.charAt(i + 2);
if (isHexDigit(c1) && isHexDigit(c2)) {
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 1c319fb..d3bed02 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -287,6 +287,7 @@
/**
* @hide
*/
+ @TestApi
@UnsupportedAppUsage
public static final String[] ACTIVE_CODENAMES = "REL".equals(ALL_CODENAMES[0])
? new String[0] : ALL_CODENAMES;
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index d46cf3c..1aaee18 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -20,24 +20,16 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
-import android.gamedriver.GameDriverProto.Blacklist;
-import android.gamedriver.GameDriverProto.Blacklists;
import android.opengl.EGL14;
import android.os.Build;
import android.os.SystemProperties;
import android.provider.Settings;
-import android.util.Base64;
import android.util.Log;
-import com.android.framework.protobuf.InvalidProtocolBufferException;
-
import dalvik.system.VMRuntime;
-import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -57,9 +49,7 @@
private static final boolean DEBUG = false;
private static final String TAG = "GraphicsEnvironment";
private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
- private static final String GAME_DRIVER_WHITELIST_FILENAME = "whitelist.txt";
- private static final String GAME_DRIVER_BLACKLIST_FLAG = "blacklist";
- private static final int BASE64_FLAGS = Base64.NO_PADDING | Base64.NO_WRAP;
+ private static final String GAME_DRIVER_WHITELIST_ALL = "*";
private ClassLoader mClassLoader;
private String mLayerPath;
@@ -108,15 +98,15 @@
if (isDebuggable(context)) {
- int enable = Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.ENABLE_GPU_DEBUG_LAYERS, 0);
+ final int enable = Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.ENABLE_GPU_DEBUG_LAYERS, 0);
if (enable != 0) {
- String gpuDebugApp = Settings.Global.getString(context.getContentResolver(),
- Settings.Global.GPU_DEBUG_APP);
+ final String gpuDebugApp = Settings.Global.getString(context.getContentResolver(),
+ Settings.Global.GPU_DEBUG_APP);
- String packageName = context.getPackageName();
+ final String packageName = context.getPackageName();
if ((gpuDebugApp != null && packageName != null)
&& (!gpuDebugApp.isEmpty() && !packageName.isEmpty())
@@ -148,7 +138,7 @@
private static List<String> getGlobalSettingsString(Bundle bundle, String globalSetting) {
List<String> valueList = null;
- String settingsValue = bundle.getString(globalSetting);
+ final String settingsValue = bundle.getString(globalSetting);
if (settingsValue != null) {
valueList = new ArrayList<>(Arrays.asList(settingsValue.split(",")));
@@ -163,12 +153,12 @@
* Choose whether the current process should use the builtin or an updated driver.
*/
private static void chooseDriver(Context context, Bundle coreSettings) {
- String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
+ final String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
if (driverPackageName == null || driverPackageName.isEmpty()) {
return;
}
- ApplicationInfo driverInfo;
+ final ApplicationInfo driverInfo;
try {
driverInfo = context.getPackageManager().getApplicationInfo(driverPackageName,
PackageManager.MATCH_SYSTEM_ONLY);
@@ -189,7 +179,7 @@
// To minimize risk of driver updates crippling the device beyond user repair, never use an
// updated driver for privileged or non-updated system apps. Presumably pre-installed apps
// were tested thoroughly with the pre-installed driver.
- ApplicationInfo ai = context.getApplicationInfo();
+ final ApplicationInfo ai = context.getApplicationInfo();
if (ai.isPrivilegedApp() || (ai.isSystemApp() && !ai.isUpdatedSystemApp())) {
if (DEBUG) Log.v(TAG, "ignoring driver package for privileged/non-updated system app");
return;
@@ -199,7 +189,7 @@
// 0: Default (Invalid values fallback to default as well)
// 1: All apps use Game Driver
// 2: All apps use system graphics driver
- int gameDriverAllApps = coreSettings.getInt(Settings.Global.GAME_DRIVER_ALL_APPS, 0);
+ final int gameDriverAllApps = coreSettings.getInt(Settings.Global.GAME_DRIVER_ALL_APPS, 0);
if (gameDriverAllApps == 2) {
if (DEBUG) {
Log.w(TAG, "Game Driver is turned off on this device");
@@ -216,49 +206,29 @@
}
return;
}
- boolean isOptIn =
+ final boolean isOptIn =
getGlobalSettingsString(coreSettings, Settings.Global.GAME_DRIVER_OPT_IN_APPS)
.contains(ai.packageName);
-
- if (!isOptIn && !onWhitelist(context, driverPackageName, ai.packageName)) {
+ final List<String> whitelist = getGlobalSettingsString(coreSettings,
+ Settings.Global.GAME_DRIVER_WHITELIST);
+ if (!isOptIn && whitelist.indexOf(GAME_DRIVER_WHITELIST_ALL) != 0
+ && !whitelist.contains(ai.packageName)) {
if (DEBUG) {
Log.w(TAG, ai.packageName + " is not on the whitelist.");
}
return;
}
- if (!isOptIn) {
- // At this point, the application is on the whitelist only, check whether it's
- // on the blacklist, terminate early when it's on the blacklist.
- try {
- // TODO(b/121350991) Switch to DeviceConfig with property listener.
- String base64String =
- coreSettings.getString(Settings.Global.GAME_DRIVER_BLACKLIST);
- if (base64String != null && !base64String.isEmpty()) {
- Blacklists blacklistsProto = Blacklists.parseFrom(
- Base64.decode(base64String, BASE64_FLAGS));
- List<Blacklist> blacklists = blacklistsProto.getBlacklistsList();
- long driverVersionCode = driverInfo.longVersionCode;
- for (Blacklist blacklist : blacklists) {
- if (blacklist.getVersionCode() == driverVersionCode) {
- for (String packageName : blacklist.getPackageNamesList()) {
- if (packageName == ai.packageName) {
- return;
- }
- }
- break;
- }
- }
- }
- } catch (InvalidProtocolBufferException e) {
- if (DEBUG) {
- Log.w(TAG, "Can't parse blacklist, skip and continue...");
- }
- }
+ // If the application is not opted-in and check whether it's on the blacklist,
+ // terminate early if it's on the blacklist and fallback to system driver.
+ if (!isOptIn
+ && getGlobalSettingsString(coreSettings, Settings.Global.GAME_DRIVER_BLACKLIST)
+ .contains(ai.packageName)) {
+ return;
}
}
- String abi = chooseAbi(driverInfo);
+ final String abi = chooseAbi(driverInfo);
if (abi == null) {
if (DEBUG) {
// This is the normal case for the pre-installed empty driver package, don't spam
@@ -269,16 +239,23 @@
return;
}
- StringBuilder sb = new StringBuilder();
+ final StringBuilder sb = new StringBuilder();
sb.append(driverInfo.nativeLibraryDir)
.append(File.pathSeparator);
sb.append(driverInfo.sourceDir)
.append("!/lib/")
.append(abi);
- String paths = sb.toString();
+ final String paths = sb.toString();
- if (DEBUG) Log.v(TAG, "gfx driver package libs: " + paths);
- setDriverPath(paths);
+ final String sphalLibraries =
+ coreSettings.getString(Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES);
+
+ if (DEBUG) {
+ Log.v(TAG,
+ "gfx driver package search path: " + paths
+ + ", required sphal libraries: " + sphalLibraries);
+ }
+ setDriverPathAndSphalLibraries(paths, sphalLibraries);
}
/**
@@ -292,7 +269,7 @@
* Should only be called after chooseDriver().
*/
public static void earlyInitEGL() {
- Thread eglInitThread = new Thread(
+ final Thread eglInitThread = new Thread(
() -> {
EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
},
@@ -301,7 +278,7 @@
}
private static String chooseAbi(ApplicationInfo ai) {
- String isa = VMRuntime.getCurrentInstructionSet();
+ final String isa = VMRuntime.getCurrentInstructionSet();
if (ai.primaryCpuAbi != null &&
isa.equals(VMRuntime.getInstructionSet(ai.primaryCpuAbi))) {
return ai.primaryCpuAbi;
@@ -313,32 +290,7 @@
return null;
}
- private static boolean onWhitelist(Context context, String driverPackageName,
- String applicationPackageName) {
- try {
- Context driverContext = context.createPackageContext(driverPackageName,
- Context.CONTEXT_RESTRICTED);
- AssetManager assets = driverContext.getAssets();
- InputStream stream = assets.open(GAME_DRIVER_WHITELIST_FILENAME);
- BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
- for (String packageName; (packageName = reader.readLine()) != null; ) {
- if (packageName.equals(applicationPackageName)) {
- return true;
- }
- }
- } catch (PackageManager.NameNotFoundException e) {
- if (DEBUG) {
- Log.w(TAG, "driver package '" + driverPackageName + "' not installed");
- }
- } catch (IOException e) {
- if (DEBUG) {
- Log.w(TAG, "Failed to load whitelist driver package, abort.");
- }
- }
- return false;
- }
-
private static native void setLayerPaths(ClassLoader classLoader, String layerPaths);
private static native void setDebugLayers(String layers);
- private static native void setDriverPath(String path);
+ private static native void setDriverPathAndSphalLibraries(String path, String sphalLibraries);
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a0e4d0d..f98641d 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -11475,6 +11475,12 @@
public static final String GAME_DRIVER_BLACKLIST = "game_driver_blacklist";
/**
+ * List of blacklists, each blacklist is a blacklist for a specific version of Game Driver.
+ * @hide
+ */
+ public static final String GAME_DRIVER_BLACKLISTS = "game_driver_blacklists";
+
+ /**
* Apps on the whitelist that are allowed to use Game Driver.
* The string is a list of application package names, seperated by comma.
* i.e. <apk1>,<apk2>,...,<apkN>
@@ -11483,6 +11489,14 @@
public static final String GAME_DRIVER_WHITELIST = "game_driver_whitelist";
/**
+ * List of libraries in sphal accessible by Game Driver
+ * The string is a list of library names, separated by colon.
+ * i.e. <lib1>:<lib2>:...:<libN>
+ * @hide
+ */
+ public static final String GAME_DRIVER_SPHAL_LIBRARIES = "game_driver_sphal_libraries";
+
+ /**
* Ordered GPU debug layer list
* i.e. <layer1>:<layer2>:...:<layerN>
* @hide
diff --git a/core/jni/android_os_GraphicsEnvironment.cpp b/core/jni/android_os_GraphicsEnvironment.cpp
index dfa5de6..b95d500 100644
--- a/core/jni/android_os_GraphicsEnvironment.cpp
+++ b/core/jni/android_os_GraphicsEnvironment.cpp
@@ -23,9 +23,12 @@
namespace {
-void setDriverPath(JNIEnv* env, jobject clazz, jstring path) {
+void setDriverPathAndSphalLibraries_native(JNIEnv* env, jobject clazz, jstring path,
+ jstring sphalLibraries) {
ScopedUtfChars pathChars(env, path);
- android::GraphicsEnv::getInstance().setDriverPath(pathChars.c_str());
+ ScopedUtfChars sphalLibrariesChars(env, sphalLibraries);
+ android::GraphicsEnv::getInstance().setDriverPathAndSphalLibraries(pathChars.c_str(),
+ sphalLibrariesChars.c_str());
}
void setLayerPaths_native(JNIEnv* env, jobject clazz, jobject classLoader, jstring layerPaths) {
@@ -43,7 +46,7 @@
}
const JNINativeMethod g_methods[] = {
- { "setDriverPath", "(Ljava/lang/String;)V", reinterpret_cast<void*>(setDriverPath) },
+ { "setDriverPathAndSphalLibraries", "(Ljava/lang/String;Ljava/lang/String;)V", reinterpret_cast<void*>(setDriverPathAndSphalLibraries_native) },
{ "setLayerPaths", "(Ljava/lang/ClassLoader;Ljava/lang/String;)V", reinterpret_cast<void*>(setLayerPaths_native) },
{ "setDebugLayers", "(Ljava/lang/String;)V", reinterpret_cast<void*>(setDebugLayers_native) },
};
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index 5aa3992..a44ec9a 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -399,6 +399,11 @@
optional SettingProto game_driver_blacklist = 11;
// Game Driver - List of Apps that are allowed to use Game Driver
optional SettingProto game_driver_whitelist = 12;
+ // Game Driver - List of blacklists, each blacklist is a blacklist for
+ // a specific Game Driver version
+ optional SettingProto game_driver_blacklists = 14;
+ // Game Driver - List of libraries in sphal accessible by Game Driver
+ optional SettingProto game_driver_sphal_libraries = 16;
}
optional Gpu gpu = 59;
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index c166408..76356ed 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -447,8 +447,10 @@
Settings.Global.GAME_DRIVER_ALL_APPS,
Settings.Global.GAME_DRIVER_OPT_IN_APPS,
Settings.Global.GAME_DRIVER_OPT_OUT_APPS,
+ Settings.Global.GAME_DRIVER_BLACKLISTS,
Settings.Global.GAME_DRIVER_BLACKLIST,
Settings.Global.GAME_DRIVER_WHITELIST,
+ Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES,
Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING,
Settings.Global.INSTALL_CARRIER_APP_NOTIFICATION_PERSISTENT,
Settings.Global.INSTALL_CARRIER_APP_NOTIFICATION_SLEEP_MILLIS,
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 28099a1..875f2c0 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -39,6 +39,7 @@
<permission name="android.permission.MODIFY_PHONE_STATE"/>
<permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
<permission name="android.permission.RECEIVE_EMERGENCY_BROADCAST"/>
+ <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
</privapp-permissions>
<privapp-permissions package="com.android.defcontainer">
diff --git a/packages/NetworkStack/res/values/config.xml b/packages/NetworkStack/res/values/config.xml
index 704788d..478ed6b 100644
--- a/packages/NetworkStack/res/values/config.xml
+++ b/packages/NetworkStack/res/values/config.xml
@@ -7,6 +7,9 @@
values are meant to be the default when no other configuration is specified.
-->
+ <!-- DNS probe timeout for network validation. Enough for 3 DNS queries 5 seconds apart. -->
+ <integer name="default_captive_portal_dns_probe_timeout">12500</integer>
+
<!-- HTTP URL for network validation, to use for detecting captive portals. -->
<string name="default_captive_portal_http_url" translatable="false">http://connectivitycheck.gstatic.com/generate_204</string>
@@ -27,6 +30,7 @@
<!-- Configuration hooks for the above settings.
Empty by default but may be overridden by RROs. -->
+ <integer name="config_captive_portal_dns_probe_timeout"></integer>
<!--suppress CheckTagEmptyBody: overlayable resource to use as configuration hook -->
<string name="config_captive_portal_http_url" translatable="false"></string>
<!--suppress CheckTagEmptyBody: overlayable resource to use as configuration hook -->
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java b/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java
index d21b5f7..b8ab94c 100644
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java
+++ b/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java
@@ -647,4 +647,9 @@
}
}
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
}
diff --git a/packages/NetworkStack/src/android/net/ip/IpClient.java b/packages/NetworkStack/src/android/net/ip/IpClient.java
index 80d139c..96e09fa 100644
--- a/packages/NetworkStack/src/android/net/ip/IpClient.java
+++ b/packages/NetworkStack/src/android/net/ip/IpClient.java
@@ -557,6 +557,11 @@
checkNetworkStackCallingPermission();
IpClient.this.removeKeepalivePacketFilter(slot);
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
}
public String getInterfaceName() {
diff --git a/packages/NetworkStack/src/com/android/server/NetworkStackService.java b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
index a0a90fd..a6d7484 100644
--- a/packages/NetworkStack/src/com/android/server/NetworkStackService.java
+++ b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
@@ -251,6 +251,11 @@
}
}
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
}
private static class NetworkMonitorImpl extends INetworkMonitor.Stub {
@@ -325,5 +330,10 @@
checkNetworkStackCallingPermission();
mNm.notifyNetworkCapabilitiesChanged(nc);
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
}
}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
index 093235e..50eb5d4 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
@@ -59,6 +59,7 @@
import android.content.IntentFilter;
import android.content.res.Resources;
import android.net.ConnectivityManager;
+import android.net.DnsResolver;
import android.net.INetworkMonitor;
import android.net.INetworkMonitorCallbacks;
import android.net.LinkProperties;
@@ -122,6 +123,7 @@
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
/**
@@ -136,8 +138,16 @@
+ "AppleWebKit/537.36 (KHTML, like Gecko) "
+ "Chrome/60.0.3112.32 Safari/537.36";
+ @VisibleForTesting
+ static final String CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT =
+ "captive_portal_dns_probe_timeout";
+
private static final int SOCKET_TIMEOUT_MS = 10000;
private static final int PROBE_TIMEOUT_MS = 3000;
+ // Enough for 3 DNS queries 5 seconds apart.
+ // TODO: get this from resources and DeviceConfig instead.
+ private static final int DNS_TIMEOUT_MS = 12500;
+
enum EvaluationResult {
VALIDATED(true),
CAPTIVE_PORTAL(false);
@@ -1185,6 +1195,33 @@
Settings.Global.CAPTIVE_PORTAL_HTTPS_URL);
}
+ private int getDnsProbeTimeout() {
+ return getIntSetting(mContext, R.integer.config_captive_portal_dns_probe_timeout,
+ CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
+ R.integer.default_captive_portal_dns_probe_timeout);
+ }
+
+ /**
+ * Gets an integer setting from resources or device config
+ *
+ * configResource is used if set, followed by device config if set, followed by defaultResource.
+ * If none of these are set then an exception is thrown.
+ *
+ * TODO: move to a common location such as a ConfigUtils class.
+ * TODO(b/130324939): test that the resources can be overlayed by an RRO package.
+ */
+ @VisibleForTesting
+ int getIntSetting(@NonNull final Context context, @StringRes int configResource,
+ @NonNull String symbol, @StringRes int defaultResource) {
+ final Resources res = context.getResources();
+ try {
+ return res.getInteger(configResource);
+ } catch (Resources.NotFoundException e) {
+ return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
+ symbol, res.getInteger(defaultResource));
+ }
+ }
+
/**
* Get the captive portal server HTTP URL that is configured on the device.
*
@@ -1446,6 +1483,45 @@
return sendHttpProbe(url, probeType, null);
}
+ /** Do a DNS lookup for the given server, or throw UnknownHostException after timeoutMs */
+ @VisibleForTesting
+ protected InetAddress[] sendDnsProbeWithTimeout(String host, int timeoutMs)
+ throws UnknownHostException {
+ final CountDownLatch latch = new CountDownLatch(1);
+ final AtomicReference<List<InetAddress>> resultRef = new AtomicReference<>();
+ final DnsResolver.Callback<List<InetAddress>> callback =
+ new DnsResolver.Callback<List<InetAddress>>() {
+ public void onAnswer(List<InetAddress> answer, int rcode) {
+ if (rcode == 0) {
+ resultRef.set(answer);
+ }
+ latch.countDown();
+ }
+ public void onError(@NonNull DnsResolver.DnsException e) {
+ validationLog("DNS error resolving " + host + ": " + e.getMessage());
+ latch.countDown();
+ }
+ };
+
+ final int oldTag = TrafficStats.getAndSetThreadStatsTag(
+ TrafficStatsConstants.TAG_SYSTEM_PROBE);
+ mDependencies.getDnsResolver().query(mNetwork, host, DnsResolver.FLAG_EMPTY,
+ r -> r.run() /* executor */, null /* cancellationSignal */, callback);
+ TrafficStats.setThreadStatsTag(oldTag);
+
+ try {
+ latch.await(timeoutMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ }
+
+ List<InetAddress> result = resultRef.get();
+ if (result == null || result.size() == 0) {
+ throw new UnknownHostException(host);
+ }
+
+ return result.toArray(new InetAddress[0]);
+ }
+
/** Do a DNS resolution of the given server. */
private void sendDnsProbe(String host) {
if (TextUtils.isEmpty(host)) {
@@ -1457,7 +1533,7 @@
int result;
String connectInfo;
try {
- InetAddress[] addresses = mNetwork.getAllByName(host);
+ InetAddress[] addresses = sendDnsProbeWithTimeout(host, getDnsProbeTimeout());
StringBuffer buffer = new StringBuffer();
for (InetAddress address : addresses) {
buffer.append(',').append(address.getHostAddress());
@@ -1782,6 +1858,10 @@
return new OneAddressPerFamilyNetwork(network);
}
+ public DnsResolver getDnsResolver() {
+ return DnsResolver.getInstance();
+ }
+
public Random getRandom() {
return new Random();
}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java
index 5650f21..6a6bf83 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java
@@ -33,8 +33,8 @@
import android.net.ipmemorystore.Blob;
import android.net.ipmemorystore.IOnBlobRetrievedListener;
import android.net.ipmemorystore.IOnL2KeyResponseListener;
-import android.net.ipmemorystore.IOnNetworkAttributesRetrieved;
-import android.net.ipmemorystore.IOnSameNetworkResponseListener;
+import android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener;
+import android.net.ipmemorystore.IOnSameL3NetworkResponseListener;
import android.net.ipmemorystore.IOnStatusListener;
import android.net.ipmemorystore.NetworkAttributes;
import android.net.ipmemorystore.NetworkAttributesParcelable;
@@ -297,16 +297,16 @@
*/
@Override
public void isSameNetwork(@Nullable final String l2Key1, @Nullable final String l2Key2,
- @Nullable final IOnSameNetworkResponseListener listener) {
+ @Nullable final IOnSameL3NetworkResponseListener listener) {
if (null == listener) return;
mExecutor.execute(() -> {
try {
if (null == l2Key1 || null == l2Key2) {
- listener.onSameNetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
+ listener.onSameL3NetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
return;
}
if (null == mDb) {
- listener.onSameNetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
+ listener.onSameL3NetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
return;
}
try {
@@ -315,16 +315,16 @@
final NetworkAttributes attr2 =
IpMemoryStoreDatabase.retrieveNetworkAttributes(mDb, l2Key2);
if (null == attr1 || null == attr2) {
- listener.onSameNetworkResponse(makeStatus(SUCCESS),
+ listener.onSameL3NetworkResponse(makeStatus(SUCCESS),
new SameL3NetworkResponse(l2Key1, l2Key2,
-1f /* never connected */).toParcelable());
return;
}
final float confidence = attr1.getNetworkGroupSamenessConfidence(attr2);
- listener.onSameNetworkResponse(makeStatus(SUCCESS),
+ listener.onSameL3NetworkResponse(makeStatus(SUCCESS),
new SameL3NetworkResponse(l2Key1, l2Key2, confidence).toParcelable());
} catch (Exception e) {
- listener.onSameNetworkResponse(makeStatus(ERROR_GENERIC), null);
+ listener.onSameL3NetworkResponse(makeStatus(ERROR_GENERIC), null);
}
} catch (final RemoteException e) {
// Client at the other end died
@@ -343,7 +343,7 @@
*/
@Override
public void retrieveNetworkAttributes(@Nullable final String l2Key,
- @Nullable final IOnNetworkAttributesRetrieved listener) {
+ @Nullable final IOnNetworkAttributesRetrievedListener listener) {
if (null == listener) return;
mExecutor.execute(() -> {
try {
@@ -494,4 +494,9 @@
listener.onComplete(makeStatus(ERROR_INTERNAL_INTERRUPTED));
return true;
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java
index 2775fde..bea7052 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java
@@ -91,6 +91,11 @@
}
@Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
+
+ @Override
public IBinder asBinder() {
return null;
}
diff --git a/packages/NetworkStack/tests/src/android/net/dhcp/DhcpServerTest.java b/packages/NetworkStack/tests/src/android/net/dhcp/DhcpServerTest.java
index 7d5e9e3..f0e2f1b 100644
--- a/packages/NetworkStack/tests/src/android/net/dhcp/DhcpServerTest.java
+++ b/packages/NetworkStack/tests/src/android/net/dhcp/DhcpServerTest.java
@@ -133,6 +133,11 @@
public void onStatusAvailable(int statusCode) {
assertEquals(STATUS_SUCCESS, statusCode);
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
};
@Before
diff --git a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
index 594f2ca..0dc1cbf 100644
--- a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -33,6 +33,7 @@
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -41,6 +42,7 @@
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
@@ -55,6 +57,7 @@
import android.content.Intent;
import android.content.res.Resources;
import android.net.ConnectivityManager;
+import android.net.DnsResolver;
import android.net.INetworkMonitorCallbacks;
import android.net.InetAddresses;
import android.net.LinkProperties;
@@ -69,6 +72,7 @@
import android.os.Bundle;
import android.os.ConditionVariable;
import android.os.Handler;
+import android.os.Looper;
import android.os.RemoteException;
import android.os.SystemClock;
import android.provider.Settings;
@@ -79,6 +83,7 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.networkstack.R;
import com.android.networkstack.metrics.DataStallDetectionStats;
import com.android.networkstack.metrics.DataStallStatsUtils;
@@ -96,8 +101,12 @@
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
import java.util.Random;
+import java.util.concurrent.Executor;
import javax.net.ssl.SSLHandshakeException;
@@ -111,6 +120,7 @@
private @Mock IpConnectivityLog mLogger;
private @Mock SharedLog mValidationLogger;
private @Mock NetworkInfo mNetworkInfo;
+ private @Mock DnsResolver mDnsResolver;
private @Mock ConnectivityManager mCm;
private @Mock TelephonyManager mTelephony;
private @Mock WifiManager mWifi;
@@ -156,10 +166,36 @@
private static final NetworkCapabilities NO_INTERNET_CAPABILITIES = new NetworkCapabilities()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+ private void setDnsAnswers(String[] answers) throws UnknownHostException {
+ if (answers == null) {
+ doThrow(new UnknownHostException()).when(mNetwork).getAllByName(any());
+ doNothing().when(mDnsResolver).query(any(), any(), anyInt(), any(), any(), any());
+ return;
+ }
+
+ List<InetAddress> answerList = new ArrayList<>();
+ for (String answer : answers) {
+ answerList.add(InetAddresses.parseNumericAddress(answer));
+ }
+ InetAddress[] answerArray = answerList.toArray(new InetAddress[0]);
+
+ doReturn(answerArray).when(mNetwork).getAllByName(any());
+
+ doAnswer((invocation) -> {
+ Executor executor = (Executor) invocation.getArgument(3);
+ DnsResolver.Callback<List<InetAddress>> callback = invocation.getArgument(5);
+ new Handler(Looper.getMainLooper()).post(() -> {
+ executor.execute(() -> callback.onAnswer(answerList, 0));
+ });
+ return null;
+ }).when(mDnsResolver).query(eq(mNetwork), any(), anyInt(), any(), any(), any());
+ }
+
@Before
public void setUp() throws IOException {
MockitoAnnotations.initMocks(this);
when(mDependencies.getPrivateDnsBypassNetwork(any())).thenReturn(mNetwork);
+ when(mDependencies.getDnsResolver()).thenReturn(mDnsResolver);
when(mDependencies.getRandom()).thenReturn(mRandom);
when(mDependencies.getSetting(any(), eq(Settings.Global.CAPTIVE_PORTAL_MODE), anyInt()))
.thenReturn(Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT);
@@ -204,9 +240,8 @@
}).when(mNetwork).openConnection(any());
when(mHttpConnection.getRequestProperties()).thenReturn(new ArrayMap<>());
when(mHttpsConnection.getRequestProperties()).thenReturn(new ArrayMap<>());
- doReturn(new InetAddress[] {
- InetAddresses.parseNumericAddress("192.168.0.0")
- }).when(mNetwork).getAllByName(any());
+
+ setDnsAnswers(new String[]{"2001:db8::1", "192.0.2.2"});
when(mContext.registerReceiver(any(BroadcastReceiver.class), any())).then((invocation) -> {
mRegisteredReceivers.add(invocation.getArgument(0));
@@ -313,6 +348,44 @@
}
@Test
+ public void testGetIntSetting() throws Exception {
+ WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
+
+ // No config resource, no device config. Expect to get default resource.
+ doThrow(new Resources.NotFoundException())
+ .when(mResources).getInteger(eq(R.integer.config_captive_portal_dns_probe_timeout));
+ doAnswer(invocation -> {
+ int defaultValue = invocation.getArgument(2);
+ return defaultValue;
+ }).when(mDependencies).getDeviceConfigPropertyInt(any(),
+ eq(NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT),
+ anyInt());
+ when(mResources.getInteger(eq(R.integer.default_captive_portal_dns_probe_timeout)))
+ .thenReturn(42);
+ assertEquals(42, wnm.getIntSetting(mContext,
+ R.integer.config_captive_portal_dns_probe_timeout,
+ NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
+ R.integer.default_captive_portal_dns_probe_timeout));
+
+ // Set device config. Expect to get device config.
+ when(mDependencies.getDeviceConfigPropertyInt(any(),
+ eq(NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT), anyInt()))
+ .thenReturn(1234);
+ assertEquals(1234, wnm.getIntSetting(mContext,
+ R.integer.config_captive_portal_dns_probe_timeout,
+ NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
+ R.integer.default_captive_portal_dns_probe_timeout));
+
+ // Set config resource. Expect to get config resource.
+ when(mResources.getInteger(eq(R.integer.config_captive_portal_dns_probe_timeout)))
+ .thenReturn(5678);
+ assertEquals(5678, wnm.getIntSetting(mContext,
+ R.integer.config_captive_portal_dns_probe_timeout,
+ NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
+ R.integer.default_captive_portal_dns_probe_timeout));
+ }
+
+ @Test
public void testIsCaptivePortal_HttpProbeIsPortal() throws IOException {
setSslException(mHttpsConnection);
setPortal302(mHttpConnection);
@@ -642,6 +715,45 @@
runPartialConnectivityNetworkTest();
}
+ private void assertIpAddressArrayEquals(String[] expected, InetAddress[] actual) {
+ String[] actualStrings = new String[actual.length];
+ for (int i = 0; i < actual.length; i++) {
+ actualStrings[i] = actual[i].getHostAddress();
+ }
+ assertArrayEquals("Array of IP addresses differs", expected, actualStrings);
+ }
+
+ @Test
+ public void testSendDnsProbeWithTimeout() throws Exception {
+ WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
+ final int shortTimeoutMs = 200;
+
+ String[] expected = new String[]{"2001:db8::"};
+ setDnsAnswers(expected);
+ InetAddress[] actual = wnm.sendDnsProbeWithTimeout("www.google.com", shortTimeoutMs);
+ assertIpAddressArrayEquals(expected, actual);
+
+ expected = new String[]{"2001:db8::", "192.0.2.1"};
+ setDnsAnswers(expected);
+ actual = wnm.sendDnsProbeWithTimeout("www.google.com", shortTimeoutMs);
+ assertIpAddressArrayEquals(expected, actual);
+
+ expected = new String[0];
+ setDnsAnswers(expected);
+ try {
+ wnm.sendDnsProbeWithTimeout("www.google.com", shortTimeoutMs);
+ fail("No DNS results, expected UnknownHostException");
+ } catch (UnknownHostException e) {
+ }
+
+ setDnsAnswers(null);
+ try {
+ wnm.sendDnsProbeWithTimeout("www.google.com", shortTimeoutMs);
+ fail("DNS query timed out, expected UnknownHostException");
+ } catch (UnknownHostException e) {
+ }
+ }
+
private void makeDnsTimeoutEvent(WrappedNetworkMonitor wrappedMonitor, int count) {
for (int i = 0; i < count; i++) {
wrappedMonitor.getDnsStallDetector().accumulateConsecutiveDnsTimeoutCount(
diff --git a/packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java b/packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
index 94cc589..87346e5 100644
--- a/packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
+++ b/packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
@@ -31,8 +31,8 @@
import android.net.ipmemorystore.Blob;
import android.net.ipmemorystore.IOnBlobRetrievedListener;
import android.net.ipmemorystore.IOnL2KeyResponseListener;
-import android.net.ipmemorystore.IOnNetworkAttributesRetrieved;
-import android.net.ipmemorystore.IOnSameNetworkResponseListener;
+import android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener;
+import android.net.ipmemorystore.IOnSameL3NetworkResponseListener;
import android.net.ipmemorystore.IOnStatusListener;
import android.net.ipmemorystore.NetworkAttributes;
import android.net.ipmemorystore.NetworkAttributesParcelable;
@@ -136,6 +136,11 @@
public IBinder asBinder() {
return null;
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
};
}
@@ -156,6 +161,11 @@
public IBinder asBinder() {
return null;
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
};
}
@@ -163,9 +173,9 @@
private interface OnNetworkAttributesRetrievedListener {
void onNetworkAttributesRetrieved(Status status, String l2Key, NetworkAttributes attr);
}
- private IOnNetworkAttributesRetrieved onNetworkAttributesRetrieved(
+ private IOnNetworkAttributesRetrievedListener onNetworkAttributesRetrieved(
final OnNetworkAttributesRetrievedListener functor) {
- return new IOnNetworkAttributesRetrieved() {
+ return new IOnNetworkAttributesRetrievedListener() {
@Override
public void onNetworkAttributesRetrieved(final StatusParcelable status,
final String l2Key, final NetworkAttributesParcelable attributes)
@@ -178,21 +188,26 @@
public IBinder asBinder() {
return null;
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
};
}
/** Helper method to make an IOnSameNetworkResponseListener */
- private interface OnSameNetworkResponseListener {
- void onSameNetworkResponse(Status status, SameL3NetworkResponse answer);
+ private interface OnSameL3NetworkResponseListener {
+ void onSameL3NetworkResponse(Status status, SameL3NetworkResponse answer);
}
- private IOnSameNetworkResponseListener onSameResponse(
- final OnSameNetworkResponseListener functor) {
- return new IOnSameNetworkResponseListener() {
+ private IOnSameL3NetworkResponseListener onSameResponse(
+ final OnSameL3NetworkResponseListener functor) {
+ return new IOnSameL3NetworkResponseListener() {
@Override
- public void onSameNetworkResponse(final StatusParcelable status,
+ public void onSameL3NetworkResponse(final StatusParcelable status,
final SameL3NetworkResponseParcelable sameL3Network)
throws RemoteException {
- functor.onSameNetworkResponse(new Status(status),
+ functor.onSameL3NetworkResponse(new Status(status),
null == sameL3Network ? null : new SameL3NetworkResponse(sameL3Network));
}
@@ -200,6 +215,11 @@
public IBinder asBinder() {
return null;
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
};
}
@@ -219,6 +239,11 @@
public IBinder asBinder() {
return null;
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
};
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 43c1a26..c60e352 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -662,6 +662,12 @@
dumpSetting(s, p,
Settings.Global.GAME_DRIVER_WHITELIST,
GlobalSettingsProto.Gpu.GAME_DRIVER_WHITELIST);
+ dumpSetting(s, p,
+ Settings.Global.GAME_DRIVER_BLACKLISTS,
+ GlobalSettingsProto.Gpu.GAME_DRIVER_BLACKLISTS);
+ dumpSetting(s, p,
+ Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES,
+ GlobalSettingsProto.Gpu.GAME_DRIVER_SPHAL_LIBRARIES);
p.end(gpuToken);
final long hdmiToken = p.start(GlobalSettingsProto.HDMI);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index c1aff75..90c86c7 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -27,6 +27,7 @@
import static android.net.ConnectivityManager.isNetworkTypeValid;
import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY;
import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_VALID;
+import static android.net.IpSecManager.INVALID_RESOURCE_ID;
import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
@@ -634,7 +635,8 @@
* the first network for a given type changes, or if the default network
* changes.
*/
- private class LegacyTypeTracker {
+ @VisibleForTesting
+ static class LegacyTypeTracker {
private static final boolean DBG = true;
private static final boolean VDBG = false;
@@ -660,10 +662,12 @@
* - dump is thread-safe with respect to concurrent add and remove calls.
*/
private final ArrayList<NetworkAgentInfo> mTypeLists[];
+ @NonNull
+ private final ConnectivityService mService;
- public LegacyTypeTracker() {
- mTypeLists = (ArrayList<NetworkAgentInfo>[])
- new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1];
+ LegacyTypeTracker(@NonNull ConnectivityService service) {
+ mService = service;
+ mTypeLists = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1];
}
public void addSupportedType(int type) {
@@ -712,10 +716,10 @@
}
// Send a broadcast if this is the first network of its type or if it's the default.
- final boolean isDefaultNetwork = isDefaultNetwork(nai);
+ final boolean isDefaultNetwork = mService.isDefaultNetwork(nai);
if ((list.size() == 1) || isDefaultNetwork) {
maybeLogBroadcast(nai, DetailedState.CONNECTED, type, isDefaultNetwork);
- sendLegacyNetworkBroadcast(nai, DetailedState.CONNECTED, type);
+ mService.sendLegacyNetworkBroadcast(nai, DetailedState.CONNECTED, type);
}
}
@@ -733,19 +737,18 @@
}
}
- final DetailedState state = DetailedState.DISCONNECTED;
-
if (wasFirstNetwork || wasDefault) {
- maybeLogBroadcast(nai, state, type, wasDefault);
- sendLegacyNetworkBroadcast(nai, state, type);
+ maybeLogBroadcast(nai, DetailedState.DISCONNECTED, type, wasDefault);
+ mService.sendLegacyNetworkBroadcast(nai, DetailedState.DISCONNECTED, type);
}
if (!list.isEmpty() && wasFirstNetwork) {
if (DBG) log("Other network available for type " + type +
", sending connected broadcast");
final NetworkAgentInfo replacement = list.get(0);
- maybeLogBroadcast(replacement, state, type, isDefaultNetwork(replacement));
- sendLegacyNetworkBroadcast(replacement, state, type);
+ maybeLogBroadcast(replacement, DetailedState.CONNECTED, type,
+ mService.isDefaultNetwork(replacement));
+ mService.sendLegacyNetworkBroadcast(replacement, DetailedState.CONNECTED, type);
}
}
@@ -760,7 +763,7 @@
// send out another legacy broadcast - currently only used for suspend/unsuspend
// toggle
public void update(NetworkAgentInfo nai) {
- final boolean isDefault = isDefaultNetwork(nai);
+ final boolean isDefault = mService.isDefaultNetwork(nai);
final DetailedState state = nai.networkInfo.getDetailedState();
for (int type = 0; type < mTypeLists.length; type++) {
final ArrayList<NetworkAgentInfo> list = mTypeLists[type];
@@ -768,7 +771,7 @@
final boolean isFirst = contains && (nai == list.get(0));
if (isFirst || contains && isDefault) {
maybeLogBroadcast(nai, state, type, isDefault);
- sendLegacyNetworkBroadcast(nai, state, type);
+ mService.sendLegacyNetworkBroadcast(nai, state, type);
}
}
}
@@ -804,7 +807,7 @@
pw.println();
}
}
- private LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker();
+ private final LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(this);
/**
* Helper class which parses out priority arguments and dumps sections according to their
@@ -2815,6 +2818,11 @@
EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_HIDE,
mNai.network.netId));
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
}
private boolean networkRequiresValidation(NetworkAgentInfo nai) {
@@ -5371,7 +5379,8 @@
}
}
- private boolean isDefaultNetwork(NetworkAgentInfo nai) {
+ @VisibleForTesting
+ protected boolean isDefaultNetwork(NetworkAgentInfo nai) {
return nai == getDefaultNetwork();
}
@@ -6671,7 +6680,8 @@
}
}
- private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
+ @VisibleForTesting
+ protected void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
// The NetworkInfo we actually send out has no bearing on the real
// state of affairs. For example, if the default connection is mobile,
// and a request for HIPRI has just gone away, we need to pretend that
@@ -6838,6 +6848,7 @@
enforceKeepalivePermission();
mKeepaliveTracker.startNattKeepalive(
getNetworkAgentInfoForNetwork(network), null /* fd */,
+ INVALID_RESOURCE_ID /* Unused */,
intervalSeconds, cb,
srcAddr, srcPort, dstAddr, NattSocketKeepalive.NATT_PORT);
}
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index 2055b64..c1f5255 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -28,8 +28,10 @@
import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.net.IIpSecService;
import android.net.INetd;
import android.net.IpSecAlgorithm;
@@ -42,6 +44,7 @@
import android.net.IpSecUdpEncapResponse;
import android.net.LinkAddress;
import android.net.Network;
+import android.net.NetworkStack;
import android.net.NetworkUtils;
import android.net.TrafficStats;
import android.net.util.NetdService;
@@ -74,6 +77,8 @@
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
/**
@@ -175,6 +180,14 @@
}
/**
+ * Sentinel value placeholder for a real binder in RefcountedResources.
+ *
+ * <p>Used for cases where there the allocating party is a system service, and thus is expected
+ * to track the resource lifecycles instead of IpSecService.
+ */
+ private static final Binder DUMMY_BINDER = new Binder();
+
+ /**
* RefcountedResource manages references and dependencies in an exclusively acyclic graph.
*
* <p>RefcountedResource implements both explicit and implicit resource management. Creating a
@@ -188,24 +201,42 @@
*/
@VisibleForTesting
public class RefcountedResource<T extends IResource> implements IBinder.DeathRecipient {
- private final T mResource;
- private final List<RefcountedResource> mChildren;
- int mRefCount = 1; // starts at 1 for user's reference.
- IBinder mBinder;
- RefcountedResource(T resource, IBinder binder, RefcountedResource... children) {
+ @NonNull private final T mResource;
+ @NonNull private final List<RefcountedResource> mChildren;
+ int mRefCount = 1; // starts at 1 for user's reference.
+
+ /*
+ * This field can take one of three states:
+ * 1. null, when the object has been released by the user (or the user's binder dies)
+ * 2. DUMMY_BINDER, when the refcounted resource is allocated from another system service
+ * and the other system service manages the lifecycle of the resource instead of
+ * IpSecService.
+ * 3. an actual binder, to ensure IpSecService can cleanup after users that forget to close
+ * their resources.
+ */
+ @Nullable IBinder mBinder;
+
+ RefcountedResource(@NonNull T resource, @NonNull RefcountedResource... children) {
+ this(resource, DUMMY_BINDER, children);
+ }
+
+ RefcountedResource(
+ @NonNull T resource,
+ @NonNull IBinder binder,
+ @NonNull RefcountedResource... children) {
synchronized (IpSecService.this) {
this.mResource = resource;
- this.mChildren = new ArrayList<>(children.length);
this.mBinder = binder;
-
+ this.mChildren = Collections.unmodifiableList(Arrays.asList(children));
for (RefcountedResource child : children) {
- mChildren.add(child);
child.mRefCount++;
}
try {
- mBinder.linkToDeath(this, 0);
+ if (mBinder != DUMMY_BINDER) {
+ mBinder.linkToDeath(this, 0);
+ }
} catch (RemoteException e) {
binderDied();
e.rethrowFromSystemServer();
@@ -252,11 +283,12 @@
return;
}
- mBinder.unlinkToDeath(this, 0);
+ if (mBinder != DUMMY_BINDER) {
+ mBinder.unlinkToDeath(this, 0);
+ }
mBinder = null;
mResource.invalidate();
-
releaseReference();
}
@@ -381,6 +413,8 @@
new RefcountedResourceArray<>(EncapSocketRecord.class.getSimpleName());
final RefcountedResourceArray<TunnelInterfaceRecord> mTunnelInterfaceRecords =
new RefcountedResourceArray<>(TunnelInterfaceRecord.class.getSimpleName());
+ final RefcountedResourceArray<NattKeepaliveRecord> mNattKeepaliveRecords =
+ new RefcountedResourceArray<>(NattKeepaliveRecord.class.getSimpleName());
/**
* Trackers for quotas for each of the OwnedResource types.
@@ -394,6 +428,8 @@
final ResourceTracker mSpiQuotaTracker = new ResourceTracker(MAX_NUM_SPIS);
final ResourceTracker mTransformQuotaTracker = new ResourceTracker(MAX_NUM_TRANSFORMS);
final ResourceTracker mSocketQuotaTracker = new ResourceTracker(MAX_NUM_ENCAP_SOCKETS);
+ final ResourceTracker mNattKeepaliveQuotaTracker =
+ new ResourceTracker(MAX_NUM_ENCAP_SOCKETS); // Max 1 NATT keepalive per encap socket
final ResourceTracker mTunnelQuotaTracker = new ResourceTracker(MAX_NUM_TUNNEL_INTERFACES);
void removeSpiRecord(int resourceId) {
@@ -412,6 +448,10 @@
mEncapSocketRecords.remove(resourceId);
}
+ void removeNattKeepaliveRecord(int resourceId) {
+ mNattKeepaliveRecords.remove(resourceId);
+ }
+
@Override
public String toString() {
return new StringBuilder()
@@ -421,6 +461,8 @@
.append(mTransformQuotaTracker)
.append(", mSocketQuotaTracker=")
.append(mSocketQuotaTracker)
+ .append(", mNattKeepaliveQuotaTracker=")
+ .append(mNattKeepaliveQuotaTracker)
.append(", mTunnelQuotaTracker=")
.append(mTunnelQuotaTracker)
.append(", mSpiRecords=")
@@ -429,6 +471,8 @@
.append(mTransformRecords)
.append(", mEncapSocketRecords=")
.append(mEncapSocketRecords)
+ .append(", mNattKeepaliveRecords=")
+ .append(mNattKeepaliveRecords)
.append(", mTunnelInterfaceRecords=")
.append(mTunnelInterfaceRecords)
.append("}")
@@ -573,6 +617,11 @@
mArray.remove(key);
}
+ @VisibleForTesting
+ int size() {
+ return mArray.size();
+ }
+
@Override
public String toString() {
return mArray.toString();
@@ -984,6 +1033,50 @@
}
/**
+ * Tracks a NATT-keepalive instance
+ *
+ * <p>This class ensures that while a NATT-keepalive is active, the UDP encap socket that it is
+ * supporting will stay open until the NATT-keepalive is finished. NATT-keepalive offload
+ * lifecycles will be managed by ConnectivityService, which will validate that the UDP Encap
+ * socket is owned by the requester, and take a reference to it via this NattKeepaliveRecord
+ *
+ * <p>It shall be the responsibility of the caller to ensure that instances of an EncapSocket do
+ * not spawn multiple instances of NATT keepalives (and thereby register duplicate records)
+ */
+ private final class NattKeepaliveRecord extends OwnedResourceRecord {
+ NattKeepaliveRecord(int resourceId) {
+ super(resourceId);
+ }
+
+ @Override
+ @GuardedBy("IpSecService.this")
+ public void freeUnderlyingResources() {
+ Log.d(TAG, "Natt Keepalive released: " + mResourceId);
+
+ getResourceTracker().give();
+ }
+
+ @Override
+ protected ResourceTracker getResourceTracker() {
+ return getUserRecord().mNattKeepaliveQuotaTracker;
+ }
+
+ @Override
+ public void invalidate() {
+ getUserRecord().removeNattKeepaliveRecord(mResourceId);
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder()
+ .append("{super=")
+ .append(super.toString())
+ .append("}")
+ .toString();
+ }
+ }
+
+ /**
* Constructs a new IpSecService instance
*
* @param context Binder context for this service
@@ -1818,6 +1911,57 @@
}
}
+ private void verifyNetworkStackCaller() {
+ if (mContext.checkCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
+ != PackageManager.PERMISSION_GRANTED
+ && mContext.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_STACK)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException(
+ "Requires permission NETWORK_STACK or MAINLINE_NETWORK_STACK");
+ }
+ }
+
+ /**
+ * Validates that a provided UID owns the encapSocket, and creates a NATT keepalive record
+ *
+ * <p>For system server use only. Caller must have NETWORK_STACK permission
+ *
+ * @param encapSocketResourceId resource identifier of the encap socket record
+ * @param ownerUid the UID of the caller. Used to verify ownership.
+ * @return
+ */
+ public synchronized int lockEncapSocketForNattKeepalive(
+ int encapSocketResourceId, int ownerUid) {
+ verifyNetworkStackCaller();
+
+ // Verify ownership. Will throw IllegalArgumentException if the UID specified does not
+ // own the specified UDP encapsulation socket
+ UserRecord userRecord = mUserResourceTracker.getUserRecord(ownerUid);
+ RefcountedResource<EncapSocketRecord> refcountedSocketRecord =
+ userRecord.mEncapSocketRecords.getRefcountedResourceOrThrow(encapSocketResourceId);
+
+ // Build NattKeepaliveRecord
+ final int resourceId = mNextResourceId++;
+ userRecord.mNattKeepaliveRecords.put(
+ resourceId,
+ new RefcountedResource<NattKeepaliveRecord>(
+ new NattKeepaliveRecord(resourceId), refcountedSocketRecord));
+
+ return resourceId;
+ }
+
+ /**
+ * Release a previously allocated NattKeepalive that has been registered with the system server
+ */
+ @Override
+ public synchronized void releaseNattKeepalive(int nattKeepaliveResourceId, int ownerUid)
+ throws RemoteException {
+ verifyNetworkStackCaller();
+
+ UserRecord userRecord = mUserResourceTracker.getUserRecord(ownerUid);
+ releaseResource(userRecord.mNattKeepaliveRecords, nattKeepaliveResourceId);
+ }
+
@Override
protected synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
mContext.enforceCallingOrSelfPermission(DUMP, TAG);
diff --git a/services/core/java/com/android/server/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java
index 40bf7bc..d19d2dd 100644
--- a/services/core/java/com/android/server/TestNetworkService.java
+++ b/services/core/java/com/android/server/TestNetworkService.java
@@ -19,6 +19,7 @@
import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.INetd;
@@ -53,6 +54,7 @@
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
+import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
/** @hide */
@@ -226,6 +228,8 @@
@NonNull Looper looper,
@NonNull Context context,
@NonNull String iface,
+ @Nullable LinkProperties lp,
+ boolean isMetered,
int callingUid,
@NonNull IBinder binder)
throws RemoteException, SocketException {
@@ -245,9 +249,19 @@
nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED);
nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
nc.setNetworkSpecifier(new StringNetworkSpecifier(iface));
+ if (!isMetered) {
+ nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+ }
// Build LinkProperties
- LinkProperties lp = new LinkProperties();
+ if (lp == null) {
+ lp = new LinkProperties();
+ } else {
+ lp = new LinkProperties(lp);
+ // Use LinkAddress(es) from the interface itself to minimize how much the caller
+ // is trusted.
+ lp.setLinkAddresses(new ArrayList<>());
+ }
lp.setInterfaceName(iface);
// Find the currently assigned addresses, and add them to LinkProperties
@@ -284,7 +298,11 @@
* <p>This method provides a Network that is useful only for testing.
*/
@Override
- public void setupTestNetwork(@NonNull String iface, @NonNull IBinder binder) {
+ public void setupTestNetwork(
+ @NonNull String iface,
+ @Nullable LinkProperties lp,
+ boolean isMetered,
+ @NonNull IBinder binder) {
enforceTestNetworkPermissions(mContext);
checkNotNull(iface, "missing Iface");
@@ -315,6 +333,8 @@
mHandler.getLooper(),
mContext,
iface,
+ lp,
+ isMetered,
callingUid,
binder);
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index 75da9b5..9ff47e0 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -60,6 +60,8 @@
sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_OPT_OUT_APPS, String.class);
sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_BLACKLIST, String.class);
sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_WHITELIST, String.class);
+ sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_BLACKLISTS, String.class);
+ sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, String.class);
// add other global settings here...
}
diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
index 77a18e2..bde430c 100644
--- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
+++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
@@ -17,6 +17,7 @@
package com.android.server.connectivity;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.net.IpSecManager.INVALID_RESOURCE_ID;
import static android.net.NattSocketKeepalive.NATT_PORT;
import static android.net.NetworkAgent.CMD_ADD_KEEPALIVE_PACKET_FILTER;
import static android.net.NetworkAgent.CMD_REMOVE_KEEPALIVE_PACKET_FILTER;
@@ -37,6 +38,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.net.IIpSecService;
import android.net.ISocketKeepaliveCallback;
import android.net.KeepalivePacketData;
import android.net.NattKeepalivePacketData;
@@ -52,6 +54,7 @@
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.system.ErrnoException;
import android.system.Os;
import android.util.Log;
@@ -89,11 +92,14 @@
private final TcpKeepaliveController mTcpController;
@NonNull
private final Context mContext;
+ @NonNull
+ private final IIpSecService mIpSec;
public KeepaliveTracker(Context context, Handler handler) {
mConnectivityServiceHandler = handler;
mTcpController = new TcpKeepaliveController(handler);
mContext = context;
+ mIpSec = IIpSecService.Stub.asInterface(ServiceManager.getService(Context.IPSEC_SERVICE));
}
/**
@@ -112,6 +118,10 @@
private final int mType;
private final FileDescriptor mFd;
+ private final int mEncapSocketResourceId;
+ // Stores the NATT keepalive resource ID returned by IpSecService.
+ private int mNattIpsecResourceId = INVALID_RESOURCE_ID;
+
public static final int TYPE_NATT = 1;
public static final int TYPE_TCP = 2;
@@ -140,7 +150,8 @@
@NonNull KeepalivePacketData packet,
int interval,
int type,
- @Nullable FileDescriptor fd) throws InvalidSocketException {
+ @Nullable FileDescriptor fd,
+ int encapSocketResourceId) throws InvalidSocketException {
mCallback = callback;
mPid = Binder.getCallingPid();
mUid = Binder.getCallingUid();
@@ -151,6 +162,9 @@
mInterval = interval;
mType = type;
+ mEncapSocketResourceId = encapSocketResourceId;
+ mNattIpsecResourceId = INVALID_RESOURCE_ID;
+
// For SocketKeepalive, a dup of fd is kept in mFd so the source port from which the
// keepalives are sent cannot be reused by another app even if the fd gets closed by
// the user. A null is acceptable here for backward compatibility of PacketKeepalive
@@ -158,7 +172,7 @@
try {
if (fd != null) {
mFd = Os.dup(fd);
- } else {
+ } else {
Log.d(TAG, toString() + " calls with null fd");
if (!mPrivileged) {
throw new SecurityException(
@@ -206,6 +220,8 @@
+ IpUtils.addressAndPortToString(mPacket.dstAddress, mPacket.dstPort)
+ " interval=" + mInterval
+ " uid=" + mUid + " pid=" + mPid + " privileged=" + mPrivileged
+ + " nattIpsecRId=" + mNattIpsecResourceId
+ + " encapSocketRId=" + mEncapSocketResourceId
+ " packetData=" + HexDump.toHexString(mPacket.getPacket())
+ " ]";
}
@@ -262,6 +278,51 @@
return SUCCESS;
}
+ private int checkAndLockNattKeepaliveResource() {
+ // Check that apps should be either privileged or fill in an ipsec encapsulated socket
+ // resource id.
+ if (mEncapSocketResourceId == INVALID_RESOURCE_ID) {
+ if (mPrivileged) {
+ return SUCCESS;
+ } else {
+ // Invalid access.
+ return ERROR_INVALID_SOCKET;
+ }
+ }
+
+ // Check if the ipsec encapsulated socket resource id is registered.
+ final HashMap<Integer, KeepaliveInfo> networkKeepalives = mKeepalives.get(mNai);
+ if (networkKeepalives == null) {
+ return ERROR_INVALID_NETWORK;
+ }
+ for (KeepaliveInfo ki : networkKeepalives.values()) {
+ if (ki.mEncapSocketResourceId == mEncapSocketResourceId
+ && ki.mNattIpsecResourceId != INVALID_RESOURCE_ID) {
+ Log.d(TAG, "Registered resource found on keepalive " + mSlot
+ + " when verify NATT socket with uid=" + mUid + " rid="
+ + mEncapSocketResourceId);
+ return ERROR_INVALID_SOCKET;
+ }
+ }
+
+ // Ensure that the socket is created by IpSecService, and lock the resource that is
+ // preserved by IpSecService. If succeed, a resource id is stored to keep tracking
+ // the resource preserved by IpSecServce and must be released when stopping keepalive.
+ try {
+ mNattIpsecResourceId =
+ mIpSec.lockEncapSocketForNattKeepalive(mEncapSocketResourceId, mUid);
+ return SUCCESS;
+ } catch (IllegalArgumentException e) {
+ // The UID specified does not own the specified UDP encapsulation socket.
+ Log.d(TAG, "Failed to verify NATT socket with uid=" + mUid + " rid="
+ + mEncapSocketResourceId + ": " + e);
+ } catch (RemoteException e) {
+ Log.wtf(TAG, "Error calling lockEncapSocketForNattKeepalive with "
+ + this.toString(), e);
+ }
+ return ERROR_INVALID_SOCKET;
+ }
+
private int isValid() {
synchronized (mNai) {
int error = checkInterval();
@@ -275,6 +336,13 @@
void start(int slot) {
mSlot = slot;
int error = isValid();
+
+ // Check and lock ipsec resource needed by natt kepalive. This should be only called
+ // once per keepalive.
+ if (error == SUCCESS && mType == TYPE_NATT) {
+ error = checkAndLockNattKeepaliveResource();
+ }
+
if (error == SUCCESS) {
Log.d(TAG, "Starting keepalive " + mSlot + " on " + mNai.name());
switch (mType) {
@@ -350,6 +418,20 @@
}
}
+ // Release the resource held by keepalive in IpSecService.
+ if (mNattIpsecResourceId != INVALID_RESOURCE_ID) {
+ if (mType != TYPE_NATT) {
+ Log.wtf(TAG, "natt ipsec resource held by incorrect keepalive "
+ + this.toString());
+ }
+ try {
+ mIpSec.releaseNattKeepalive(mNattIpsecResourceId, mUid);
+ } catch (RemoteException e) {
+ Log.wtf(TAG, "error calling releaseNattKeepalive with " + this.toString(), e);
+ }
+ mNattIpsecResourceId = INVALID_RESOURCE_ID;
+ }
+
if (reason == SUCCESS) {
try {
mCallback.onStopped();
@@ -538,6 +620,7 @@
**/
public void startNattKeepalive(@Nullable NetworkAgentInfo nai,
@Nullable FileDescriptor fd,
+ int encapSocketResourceId,
int intervalSeconds,
@NonNull ISocketKeepaliveCallback cb,
@NonNull String srcAddrString,
@@ -569,7 +652,7 @@
KeepaliveInfo ki = null;
try {
ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds,
- KeepaliveInfo.TYPE_NATT, fd);
+ KeepaliveInfo.TYPE_NATT, fd, encapSocketResourceId);
} catch (InvalidSocketException | IllegalArgumentException | SecurityException e) {
Log.e(TAG, "Fail to construct keepalive", e);
notifyErrorCallback(cb, ERROR_INVALID_SOCKET);
@@ -609,7 +692,7 @@
KeepaliveInfo ki = null;
try {
ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds,
- KeepaliveInfo.TYPE_TCP, fd);
+ KeepaliveInfo.TYPE_TCP, fd, INVALID_RESOURCE_ID /* Unused */);
} catch (InvalidSocketException | IllegalArgumentException | SecurityException e) {
Log.e(TAG, "Fail to construct keepalive e=" + e);
notifyErrorCallback(cb, ERROR_INVALID_SOCKET);
@@ -628,17 +711,12 @@
**/
public void startNattKeepalive(@Nullable NetworkAgentInfo nai,
@Nullable FileDescriptor fd,
- int resourceId,
+ int encapSocketResourceId,
int intervalSeconds,
@NonNull ISocketKeepaliveCallback cb,
@NonNull String srcAddrString,
@NonNull String dstAddrString,
int dstPort) {
- // Ensure that the socket is created by IpSecService.
- if (!isNattKeepaliveSocketValid(fd, resourceId)) {
- notifyErrorCallback(cb, ERROR_INVALID_SOCKET);
- }
-
// Get src port to adopt old API.
int srcPort = 0;
try {
@@ -649,23 +727,8 @@
}
// Forward request to old API.
- startNattKeepalive(nai, fd, intervalSeconds, cb, srcAddrString, srcPort,
- dstAddrString, dstPort);
- }
-
- /**
- * Verify if the IPsec NAT-T file descriptor and resource Id hold for IPsec keepalive is valid.
- **/
- public static boolean isNattKeepaliveSocketValid(@Nullable FileDescriptor fd, int resourceId) {
- // TODO: 1. confirm whether the fd is called from system api or created by IpSecService.
- // 2. If the fd is created from the system api, check that it's bounded. And
- // call dup to keep the fd open.
- // 3. If the fd is created from IpSecService, check if the resource ID is valid. And
- // hold the resource needed in IpSecService.
- if (null == fd) {
- return false;
- }
- return true;
+ startNattKeepalive(nai, fd, encapSocketResourceId, intervalSeconds, cb, srcAddrString,
+ srcPort, dstAddrString, dstPort);
}
public void dump(IndentingPrintWriter pw) {
diff --git a/services/core/java/com/android/server/gpu/GpuService.java b/services/core/java/com/android/server/gpu/GpuService.java
new file mode 100644
index 0000000..647727f
--- /dev/null
+++ b/services/core/java/com/android/server/gpu/GpuService.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.gpu;
+
+import static android.content.Intent.ACTION_PACKAGE_ADDED;
+import static android.content.Intent.ACTION_PACKAGE_CHANGED;
+import static android.content.Intent.ACTION_PACKAGE_REMOVED;
+
+import android.annotation.NonNull;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.database.ContentObserver;
+import android.gamedriver.GameDriverProto.Blacklist;
+import android.gamedriver.GameDriverProto.Blacklists;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Handler;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Base64;
+import android.util.Slog;
+
+import com.android.framework.protobuf.InvalidProtocolBufferException;
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.SystemService;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Service to manage GPU related features.
+ *
+ * <p>GPU service is a core service that monitors, coordinates all GPU related features,
+ * as well as collect metrics about the GPU and GPU driver.</p>
+ */
+public class GpuService extends SystemService {
+ public static final String TAG = "GpuService";
+ public static final boolean DEBUG = false;
+
+ private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
+ private static final String GAME_DRIVER_WHITELIST_FILENAME = "whitelist.txt";
+ private static final String GAME_DRIVER_SPHAL_LIBRARIES_FILENAME = "sphal_libraries.txt";
+ private static final int BASE64_FLAGS = Base64.NO_PADDING | Base64.NO_WRAP;
+
+ private final Context mContext;
+ private final String mDriverPackageName;
+ private final PackageManager mPackageManager;
+ private final Object mLock = new Object();
+ private ContentResolver mContentResolver;
+ private long mGameDriverVersionCode;
+ private SettingsObserver mSettingsObserver;
+ @GuardedBy("mLock")
+ private Blacklists mBlacklists;
+
+ public GpuService(Context context) {
+ super(context);
+
+ mContext = context;
+ mDriverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
+ mGameDriverVersionCode = -1;
+ mPackageManager = context.getPackageManager();
+ if (mDriverPackageName != null && !mDriverPackageName.isEmpty()) {
+ final IntentFilter packageFilter = new IntentFilter();
+ packageFilter.addAction(ACTION_PACKAGE_ADDED);
+ packageFilter.addAction(ACTION_PACKAGE_CHANGED);
+ packageFilter.addAction(ACTION_PACKAGE_REMOVED);
+ packageFilter.addDataScheme("package");
+ getContext().registerReceiverAsUser(new PackageReceiver(), UserHandle.ALL,
+ packageFilter, null, null);
+ }
+ }
+
+ @Override
+ public void onStart() {
+ }
+
+ @Override
+ public void onBootPhase(int phase) {
+ if (phase == PHASE_BOOT_COMPLETED) {
+ mContentResolver = mContext.getContentResolver();
+ mSettingsObserver = new SettingsObserver();
+ if (mDriverPackageName == null || mDriverPackageName.isEmpty()) {
+ return;
+ }
+ fetchGameDriverPackageProperties();
+ processBlacklists();
+ setBlacklist();
+ }
+ }
+
+ private final class SettingsObserver extends ContentObserver {
+ private final Uri mGameDriverBlackUri =
+ Settings.Global.getUriFor(Settings.Global.GAME_DRIVER_BLACKLISTS);
+
+ SettingsObserver() {
+ super(new Handler());
+ mContentResolver.registerContentObserver(mGameDriverBlackUri, false, this,
+ UserHandle.USER_ALL);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ if (uri == null) {
+ return;
+ }
+
+ if (mGameDriverBlackUri.equals(uri)) {
+ processBlacklists();
+ setBlacklist();
+ }
+ }
+ }
+
+ private final class PackageReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(@NonNull final Context context, @NonNull final Intent intent) {
+ final Uri data = intent.getData();
+ if (data == null && DEBUG) {
+ Slog.e(TAG, "Cannot handle package broadcast with null data");
+ return;
+ }
+ final String packageName = data.getSchemeSpecificPart();
+ if (!packageName.equals(mDriverPackageName)) {
+ return;
+ }
+
+ final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
+
+ switch (intent.getAction()) {
+ case ACTION_PACKAGE_ADDED:
+ case ACTION_PACKAGE_CHANGED:
+ case ACTION_PACKAGE_REMOVED:
+ fetchGameDriverPackageProperties();
+ setBlacklist();
+ break;
+ default:
+ // do nothing
+ break;
+ }
+ }
+ }
+
+ private static void assetToSettingsGlobal(Context context, Context driverContext,
+ String fileName, String settingsGlobal, CharSequence delimiter) {
+ try {
+ final BufferedReader reader = new BufferedReader(
+ new InputStreamReader(driverContext.getAssets().open(fileName)));
+ final ArrayList<String> assetStrings = new ArrayList<>();
+ for (String assetString; (assetString = reader.readLine()) != null; ) {
+ assetStrings.add(assetString);
+ }
+ Settings.Global.putString(context.getContentResolver(),
+ settingsGlobal,
+ String.join(delimiter, assetStrings));
+ } catch (IOException e) {
+ if (DEBUG) {
+ Slog.w(TAG, "Failed to load " + fileName + ", abort.");
+ }
+ }
+ }
+
+ private void fetchGameDriverPackageProperties() {
+ final ApplicationInfo driverInfo;
+ try {
+ driverInfo = mPackageManager.getApplicationInfo(mDriverPackageName,
+ PackageManager.MATCH_SYSTEM_ONLY);
+ } catch (PackageManager.NameNotFoundException e) {
+ if (DEBUG) {
+ Slog.e(TAG, "driver package '" + mDriverPackageName + "' not installed");
+ }
+ return;
+ }
+
+ // O drivers are restricted to the sphal linker namespace, so don't try to use
+ // packages unless they declare they're compatible with that restriction.
+ if (driverInfo.targetSdkVersion < Build.VERSION_CODES.O) {
+ if (DEBUG) {
+ Slog.w(TAG, "Driver package is not known to be compatible with O");
+ }
+ return;
+ }
+
+ // Reset the whitelist.
+ Settings.Global.putString(mContentResolver,
+ Settings.Global.GAME_DRIVER_WHITELIST, "");
+ // Reset the sphal libraries
+ Settings.Global.putString(mContentResolver,
+ Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, "");
+ mGameDriverVersionCode = driverInfo.longVersionCode;
+
+ try {
+ final Context driverContext = mContext.createPackageContext(mDriverPackageName,
+ Context.CONTEXT_RESTRICTED);
+
+ assetToSettingsGlobal(mContext, driverContext, GAME_DRIVER_WHITELIST_FILENAME,
+ Settings.Global.GAME_DRIVER_WHITELIST, ",");
+
+ assetToSettingsGlobal(mContext, driverContext, GAME_DRIVER_SPHAL_LIBRARIES_FILENAME,
+ Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, ":");
+
+ } catch (PackageManager.NameNotFoundException e) {
+ if (DEBUG) {
+ Slog.w(TAG, "driver package '" + mDriverPackageName + "' not installed");
+ }
+ }
+ }
+
+ private void processBlacklists() {
+ // TODO(b/121350991) Switch to DeviceConfig with property listener.
+ String base64String =
+ Settings.Global.getString(mContentResolver, Settings.Global.GAME_DRIVER_BLACKLISTS);
+ if (base64String == null || base64String.isEmpty()) {
+ return;
+ }
+
+ synchronized (mLock) {
+ // Reset all blacklists
+ mBlacklists = null;
+ try {
+ mBlacklists = Blacklists.parseFrom(Base64.decode(base64String, BASE64_FLAGS));
+ } catch (IllegalArgumentException e) {
+ if (DEBUG) {
+ Slog.w(TAG, "Can't parse blacklist, skip and continue...");
+ }
+ } catch (InvalidProtocolBufferException e) {
+ if (DEBUG) {
+ Slog.w(TAG, "Can't parse blacklist, skip and continue...");
+ }
+ }
+ }
+ }
+
+ private void setBlacklist() {
+ Settings.Global.putString(mContentResolver,
+ Settings.Global.GAME_DRIVER_BLACKLIST, "");
+ synchronized (mLock) {
+ if (mBlacklists == null) {
+ return;
+ }
+ List<Blacklist> blacklists = mBlacklists.getBlacklistsList();
+ for (Blacklist blacklist : blacklists) {
+ if (blacklist.getVersionCode() == mGameDriverVersionCode) {
+ Settings.Global.putString(mContentResolver,
+ Settings.Global.GAME_DRIVER_BLACKLIST,
+ String.join(",", blacklist.getPackageNamesList()));
+ return;
+ }
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index 4baf70b..62ea95b 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -34,10 +34,10 @@
per-file UserRestrictionsUtils.java = omakoto@google.com, rubinxu@google.com, sandness@google.com, yamasani@google.com
# security
-per-file KeySetHandle.java = cbrubaker@google.com
-per-file KeySetManagerService.java = cbrubaker@google.com
-per-file PackageKeySetData.java = cbrubaker@google.com
-per-file PackageSignatures.java = cbrubaker@google.com
+per-file KeySetHandle.java = cbrubaker@google.com, nnk@google.com
+per-file KeySetManagerService.java = cbrubaker@google.com, nnk@google.com
+per-file PackageKeySetData.java = cbrubaker@google.com, nnk@google.com
+per-file PackageSignatures.java = cbrubaker@google.com, nnk@google.com
per-file SELinuxMMAC.java = cbrubaker@google.com, jeffv@google.com, jgalenson@google.com, nnk@google.com
# shortcuts
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 7be7ab2..f0292aa 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -87,6 +87,7 @@
import com.android.server.dreams.DreamManagerService;
import com.android.server.emergency.EmergencyAffordanceService;
import com.android.server.fingerprint.FingerprintService;
+import com.android.server.gpu.GpuService;
import com.android.server.hdmi.HdmiControlService;
import com.android.server.input.InputManagerService;
import com.android.server.job.JobSchedulerService;
@@ -747,6 +748,11 @@
traceBeginAndSlog("StartBugreportManagerService");
mSystemServiceManager.startService(BugreportManagerService.class);
traceEnd();
+
+ // Serivce for GPU and GPU driver.
+ traceBeginAndSlog("GpuService");
+ mSystemServiceManager.startService(GpuService.class);
+ traceEnd();
}
/**
diff --git a/services/net/Android.bp b/services/net/Android.bp
index 8f48f5b..d72f1cf 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -3,8 +3,6 @@
name: "ipmemorystore-aidl-interfaces",
local_include_dir: "java",
srcs: [
- // TODO: Define and use a filegroup for these files, since they're also used in
- // networkstack-aidl-interfaces. This does not appear to work at the moment.
"java/android/net/IIpMemoryStore.aidl",
"java/android/net/IIpMemoryStoreCallbacks.aidl",
"java/android/net/ipmemorystore/**/*.aidl",
@@ -17,17 +15,16 @@
enabled: false,
},
},
- api_dir: "aidl/networkstack",
+ api_dir: "aidl/ipmemorystore",
+ versions: ["1"],
}
aidl_interface {
name: "networkstack-aidl-interfaces",
local_include_dir: "java",
- include_dirs: ["frameworks/base/core/java"], // For framework parcelables.
+ include_dirs: ["frameworks/base/core/java"], // For framework parcelables.
srcs: [
"java/android/net/DhcpResultsParcelable.aidl",
- "java/android/net/IIpMemoryStore.aidl",
- "java/android/net/IIpMemoryStoreCallbacks.aidl",
"java/android/net/INetworkMonitor.aidl",
"java/android/net/INetworkMonitorCallbacks.aidl",
"java/android/net/INetworkStackConnector.aidl",
@@ -41,7 +38,6 @@
"java/android/net/dhcp/IDhcpServerCallbacks.aidl",
"java/android/net/ip/IIpClient.aidl",
"java/android/net/ip/IIpClientCallbacks.aidl",
- "java/android/net/ipmemorystore/**/*.aidl",
],
backend: {
ndk: {
@@ -52,6 +48,8 @@
},
},
api_dir: "aidl/networkstack",
+ imports: ["ipmemorystore-aidl-interfaces"],
+ versions: ["1"],
}
java_library_static {
@@ -59,9 +57,10 @@
srcs: ["java/**/*.java"],
static_libs: [
"dnsresolver_aidl_interface-java",
+ "ipmemorystore-client",
"netd_aidl_interface-java",
"networkstack-aidl-interfaces-java",
- ]
+ ],
}
java_library_static {
@@ -74,7 +73,7 @@
],
static_libs: [
"ipmemorystore-aidl-interfaces-java",
- ]
+ ],
}
filegroup {
diff --git a/services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStore.aidl b/services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStore.aidl
new file mode 100644
index 0000000..a8cbab2
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStore.aidl
@@ -0,0 +1,9 @@
+package android.net;
+interface IIpMemoryStore {
+ oneway void storeNetworkAttributes(String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes, android.net.ipmemorystore.IOnStatusListener listener);
+ oneway void storeBlob(String l2Key, String clientId, String name, in android.net.ipmemorystore.Blob data, android.net.ipmemorystore.IOnStatusListener listener);
+ oneway void findL2Key(in android.net.ipmemorystore.NetworkAttributesParcelable attributes, android.net.ipmemorystore.IOnL2KeyResponseListener listener);
+ oneway void isSameNetwork(String l2Key1, String l2Key2, android.net.ipmemorystore.IOnSameL3NetworkResponseListener listener);
+ oneway void retrieveNetworkAttributes(String l2Key, android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener listener);
+ oneway void retrieveBlob(String l2Key, String clientId, String name, android.net.ipmemorystore.IOnBlobRetrievedListener listener);
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStoreCallbacks.aidl b/services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStoreCallbacks.aidl
new file mode 100644
index 0000000..cf02c26
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStoreCallbacks.aidl
@@ -0,0 +1,4 @@
+package android.net;
+interface IIpMemoryStoreCallbacks {
+ oneway void onIpMemoryStoreFetched(in android.net.IIpMemoryStore ipMemoryStore);
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/Blob.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/Blob.aidl
new file mode 100644
index 0000000..291dbef
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/Blob.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+parcelable Blob {
+ byte[] data;
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
new file mode 100644
index 0000000..52f40d4
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+interface IOnBlobRetrievedListener {
+ oneway void onBlobRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in String name, in android.net.ipmemorystore.Blob data);
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
new file mode 100644
index 0000000..7853514
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+interface IOnL2KeyResponseListener {
+ oneway void onL2KeyResponse(in android.net.ipmemorystore.StatusParcelable status, in String l2Key);
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
new file mode 100644
index 0000000..3dd2ae6
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+interface IOnNetworkAttributesRetrievedListener {
+ oneway void onNetworkAttributesRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes);
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
new file mode 100644
index 0000000..46d4ecb
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+interface IOnSameL3NetworkResponseListener {
+ oneway void onSameL3NetworkResponse(in android.net.ipmemorystore.StatusParcelable status, in android.net.ipmemorystore.SameL3NetworkResponseParcelable response);
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnStatusListener.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnStatusListener.aidl
new file mode 100644
index 0000000..54e654b
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnStatusListener.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+interface IOnStatusListener {
+ oneway void onComplete(in android.net.ipmemorystore.StatusParcelable status);
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/NetworkAttributesParcelable.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
new file mode 100644
index 0000000..9531ea3
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
@@ -0,0 +1,8 @@
+package android.net.ipmemorystore;
+parcelable NetworkAttributesParcelable {
+ byte[] assignedV4Address;
+ long assignedV4AddressExpiry;
+ String groupHint;
+ android.net.ipmemorystore.Blob[] dnsAddresses;
+ int mtu;
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
new file mode 100644
index 0000000..414272b
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
@@ -0,0 +1,6 @@
+package android.net.ipmemorystore;
+parcelable SameL3NetworkResponseParcelable {
+ String l2Key1;
+ String l2Key2;
+ float confidence;
+}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/StatusParcelable.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/StatusParcelable.aidl
new file mode 100644
index 0000000..92c6779
--- /dev/null
+++ b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/StatusParcelable.aidl
@@ -0,0 +1,4 @@
+package android.net.ipmemorystore;
+parcelable StatusParcelable {
+ int resultCode;
+}
diff --git a/services/net/aidl/networkstack/1/android/net/DhcpResultsParcelable.aidl b/services/net/aidl/networkstack/1/android/net/DhcpResultsParcelable.aidl
new file mode 100644
index 0000000..92b5345
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/DhcpResultsParcelable.aidl
@@ -0,0 +1,8 @@
+package android.net;
+parcelable DhcpResultsParcelable {
+ android.net.StaticIpConfiguration baseConfiguration;
+ int leaseDuration;
+ int mtu;
+ String serverAddress;
+ String vendorInfo;
+}
diff --git a/services/net/aidl/networkstack/1/android/net/INetworkMonitor.aidl b/services/net/aidl/networkstack/1/android/net/INetworkMonitor.aidl
new file mode 100644
index 0000000..b19f522
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/INetworkMonitor.aidl
@@ -0,0 +1,17 @@
+package android.net;
+interface INetworkMonitor {
+ oneway void start();
+ oneway void launchCaptivePortalApp();
+ oneway void notifyCaptivePortalAppFinished(int response);
+ oneway void setAcceptPartialConnectivity();
+ oneway void forceReevaluation(int uid);
+ oneway void notifyPrivateDnsChanged(in android.net.PrivateDnsConfigParcel config);
+ oneway void notifyDnsResponse(int returnCode);
+ oneway void notifyNetworkConnected(in android.net.LinkProperties lp, in android.net.NetworkCapabilities nc);
+ oneway void notifyNetworkDisconnected();
+ oneway void notifyLinkPropertiesChanged(in android.net.LinkProperties lp);
+ oneway void notifyNetworkCapabilitiesChanged(in android.net.NetworkCapabilities nc);
+ const int NETWORK_TEST_RESULT_VALID = 0;
+ const int NETWORK_TEST_RESULT_INVALID = 1;
+ const int NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY = 2;
+}
diff --git a/services/net/aidl/networkstack/1/android/net/INetworkMonitorCallbacks.aidl b/services/net/aidl/networkstack/1/android/net/INetworkMonitorCallbacks.aidl
new file mode 100644
index 0000000..ee9871d
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/INetworkMonitorCallbacks.aidl
@@ -0,0 +1,8 @@
+package android.net;
+interface INetworkMonitorCallbacks {
+ oneway void onNetworkMonitorCreated(in android.net.INetworkMonitor networkMonitor);
+ oneway void notifyNetworkTested(int testResult, @nullable String redirectUrl);
+ oneway void notifyPrivateDnsConfigResolved(in android.net.PrivateDnsConfigParcel config);
+ oneway void showProvisioningNotification(String action, String packageName);
+ oneway void hideProvisioningNotification();
+}
diff --git a/services/net/aidl/networkstack/1/android/net/INetworkStackConnector.aidl b/services/net/aidl/networkstack/1/android/net/INetworkStackConnector.aidl
new file mode 100644
index 0000000..7da11e4
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/INetworkStackConnector.aidl
@@ -0,0 +1,7 @@
+package android.net;
+interface INetworkStackConnector {
+ oneway void makeDhcpServer(in String ifName, in android.net.dhcp.DhcpServingParamsParcel params, in android.net.dhcp.IDhcpServerCallbacks cb);
+ oneway void makeNetworkMonitor(in android.net.Network network, String name, in android.net.INetworkMonitorCallbacks cb);
+ oneway void makeIpClient(in String ifName, in android.net.ip.IIpClientCallbacks callbacks);
+ oneway void fetchIpMemoryStore(in android.net.IIpMemoryStoreCallbacks cb);
+}
diff --git a/services/net/aidl/networkstack/1/android/net/INetworkStackStatusCallback.aidl b/services/net/aidl/networkstack/1/android/net/INetworkStackStatusCallback.aidl
new file mode 100644
index 0000000..f6ca6f7
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/INetworkStackStatusCallback.aidl
@@ -0,0 +1,4 @@
+package android.net;
+interface INetworkStackStatusCallback {
+ oneway void onStatusAvailable(int statusCode);
+}
diff --git a/services/net/aidl/networkstack/1/android/net/InitialConfigurationParcelable.aidl b/services/net/aidl/networkstack/1/android/net/InitialConfigurationParcelable.aidl
new file mode 100644
index 0000000..c80a787
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/InitialConfigurationParcelable.aidl
@@ -0,0 +1,7 @@
+package android.net;
+parcelable InitialConfigurationParcelable {
+ android.net.LinkAddress[] ipAddresses;
+ android.net.IpPrefix[] directlyConnectedRoutes;
+ String[] dnsServers;
+ String gateway;
+}
diff --git a/services/net/aidl/networkstack/1/android/net/PrivateDnsConfigParcel.aidl b/services/net/aidl/networkstack/1/android/net/PrivateDnsConfigParcel.aidl
new file mode 100644
index 0000000..2de790b
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/PrivateDnsConfigParcel.aidl
@@ -0,0 +1,5 @@
+package android.net;
+parcelable PrivateDnsConfigParcel {
+ String hostname;
+ String[] ips;
+}
diff --git a/services/net/aidl/networkstack/1/android/net/ProvisioningConfigurationParcelable.aidl b/services/net/aidl/networkstack/1/android/net/ProvisioningConfigurationParcelable.aidl
new file mode 100644
index 0000000..3a6c304
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/ProvisioningConfigurationParcelable.aidl
@@ -0,0 +1,15 @@
+package android.net;
+parcelable ProvisioningConfigurationParcelable {
+ boolean enableIPv4;
+ boolean enableIPv6;
+ boolean usingMultinetworkPolicyTracker;
+ boolean usingIpReachabilityMonitor;
+ int requestedPreDhcpActionMs;
+ android.net.InitialConfigurationParcelable initialConfig;
+ android.net.StaticIpConfiguration staticIpConfig;
+ android.net.apf.ApfCapabilities apfCapabilities;
+ int provisioningTimeoutMs;
+ int ipv6AddrGenMode;
+ android.net.Network network;
+ String displayName;
+}
diff --git a/services/net/aidl/networkstack/1/android/net/TcpKeepalivePacketDataParcelable.aidl b/services/net/aidl/networkstack/1/android/net/TcpKeepalivePacketDataParcelable.aidl
new file mode 100644
index 0000000..e121c06
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/TcpKeepalivePacketDataParcelable.aidl
@@ -0,0 +1,13 @@
+package android.net;
+parcelable TcpKeepalivePacketDataParcelable {
+ byte[] srcAddress;
+ int srcPort;
+ byte[] dstAddress;
+ int dstPort;
+ int seq;
+ int ack;
+ int rcvWnd;
+ int rcvWndScale;
+ int tos;
+ int ttl;
+}
diff --git a/services/net/aidl/networkstack/1/android/net/dhcp/DhcpServingParamsParcel.aidl b/services/net/aidl/networkstack/1/android/net/dhcp/DhcpServingParamsParcel.aidl
new file mode 100644
index 0000000..67193ae
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/dhcp/DhcpServingParamsParcel.aidl
@@ -0,0 +1,11 @@
+package android.net.dhcp;
+parcelable DhcpServingParamsParcel {
+ int serverAddr;
+ int serverAddrPrefixLength;
+ int[] defaultRouters;
+ int[] dnsServers;
+ int[] excludedAddrs;
+ long dhcpLeaseTimeSecs;
+ int linkMtu;
+ boolean metered;
+}
diff --git a/services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServer.aidl b/services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServer.aidl
new file mode 100644
index 0000000..9143158
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServer.aidl
@@ -0,0 +1,10 @@
+package android.net.dhcp;
+interface IDhcpServer {
+ oneway void start(in android.net.INetworkStackStatusCallback cb);
+ oneway void updateParams(in android.net.dhcp.DhcpServingParamsParcel params, in android.net.INetworkStackStatusCallback cb);
+ oneway void stop(in android.net.INetworkStackStatusCallback cb);
+ const int STATUS_UNKNOWN = 0;
+ const int STATUS_SUCCESS = 1;
+ const int STATUS_INVALID_ARGUMENT = 2;
+ const int STATUS_UNKNOWN_ERROR = 3;
+}
diff --git a/services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServerCallbacks.aidl b/services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServerCallbacks.aidl
new file mode 100644
index 0000000..dcc4489
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServerCallbacks.aidl
@@ -0,0 +1,4 @@
+package android.net.dhcp;
+interface IDhcpServerCallbacks {
+ oneway void onDhcpServerCreated(int statusCode, in android.net.dhcp.IDhcpServer server);
+}
diff --git a/services/net/aidl/networkstack/1/android/net/ip/IIpClient.aidl b/services/net/aidl/networkstack/1/android/net/ip/IIpClient.aidl
new file mode 100644
index 0000000..95a1574
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/ip/IIpClient.aidl
@@ -0,0 +1,14 @@
+package android.net.ip;
+interface IIpClient {
+ oneway void completedPreDhcpAction();
+ oneway void confirmConfiguration();
+ oneway void readPacketFilterComplete(in byte[] data);
+ oneway void shutdown();
+ oneway void startProvisioning(in android.net.ProvisioningConfigurationParcelable req);
+ oneway void stop();
+ oneway void setTcpBufferSizes(in String tcpBufferSizes);
+ oneway void setHttpProxy(in android.net.ProxyInfo proxyInfo);
+ oneway void setMulticastFilter(boolean enabled);
+ oneway void addKeepalivePacketFilter(int slot, in android.net.TcpKeepalivePacketDataParcelable pkt);
+ oneway void removeKeepalivePacketFilter(int slot);
+}
diff --git a/services/net/aidl/networkstack/1/android/net/ip/IIpClientCallbacks.aidl b/services/net/aidl/networkstack/1/android/net/ip/IIpClientCallbacks.aidl
new file mode 100644
index 0000000..d6bc808
--- /dev/null
+++ b/services/net/aidl/networkstack/1/android/net/ip/IIpClientCallbacks.aidl
@@ -0,0 +1,16 @@
+package android.net.ip;
+interface IIpClientCallbacks {
+ oneway void onIpClientCreated(in android.net.ip.IIpClient ipClient);
+ oneway void onPreDhcpAction();
+ oneway void onPostDhcpAction();
+ oneway void onNewDhcpResults(in android.net.DhcpResultsParcelable dhcpResults);
+ oneway void onProvisioningSuccess(in android.net.LinkProperties newLp);
+ oneway void onProvisioningFailure(in android.net.LinkProperties newLp);
+ oneway void onLinkPropertiesChange(in android.net.LinkProperties newLp);
+ oneway void onReachabilityLost(in String logMsg);
+ oneway void onQuit();
+ oneway void installPacketFilter(in byte[] filter);
+ oneway void startReadPacketFilter();
+ oneway void setFallbackMulticastFilter(boolean enabled);
+ oneway void setNeighborDiscoveryOffload(boolean enable);
+}
diff --git a/services/net/java/android/net/IIpMemoryStore.aidl b/services/net/java/android/net/IIpMemoryStore.aidl
index 6f88dec..63feae6 100644
--- a/services/net/java/android/net/IIpMemoryStore.aidl
+++ b/services/net/java/android/net/IIpMemoryStore.aidl
@@ -20,8 +20,8 @@
import android.net.ipmemorystore.NetworkAttributesParcelable;
import android.net.ipmemorystore.IOnBlobRetrievedListener;
import android.net.ipmemorystore.IOnL2KeyResponseListener;
-import android.net.ipmemorystore.IOnNetworkAttributesRetrieved;
-import android.net.ipmemorystore.IOnSameNetworkResponseListener;
+import android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener;
+import android.net.ipmemorystore.IOnSameL3NetworkResponseListener;
import android.net.ipmemorystore.IOnStatusListener;
/** {@hide} */
@@ -84,7 +84,7 @@
* @param listener The listener that will be invoked to return the answer.
* @return (through the listener) A SameL3NetworkResponse containing the answer and confidence.
*/
- void isSameNetwork(String l2Key1, String l2Key2, IOnSameNetworkResponseListener listener);
+ void isSameNetwork(String l2Key1, String l2Key2, IOnSameL3NetworkResponseListener listener);
/**
* Retrieve the network attributes for a key.
@@ -95,7 +95,7 @@
* @return (through the listener) The network attributes and the L2 key associated with
* the query.
*/
- void retrieveNetworkAttributes(String l2Key, IOnNetworkAttributesRetrieved listener);
+ void retrieveNetworkAttributes(String l2Key, IOnNetworkAttributesRetrievedListener listener);
/**
* Retrieve previously stored private data.
diff --git a/services/net/java/android/net/IpMemoryStore.java b/services/net/java/android/net/IpMemoryStore.java
index 9248299..4a115e6 100644
--- a/services/net/java/android/net/IpMemoryStore.java
+++ b/services/net/java/android/net/IpMemoryStore.java
@@ -41,6 +41,11 @@
public void onIpMemoryStoreFetched(final IIpMemoryStore memoryStore) {
mService.complete(memoryStore);
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
});
}
diff --git a/services/net/java/android/net/IpMemoryStoreClient.java b/services/net/java/android/net/IpMemoryStoreClient.java
index 2f4fdbd..379c017 100644
--- a/services/net/java/android/net/IpMemoryStoreClient.java
+++ b/services/net/java/android/net/IpMemoryStoreClient.java
@@ -20,14 +20,13 @@
import android.annotation.Nullable;
import android.content.Context;
import android.net.ipmemorystore.Blob;
-import android.net.ipmemorystore.IOnBlobRetrievedListener;
-import android.net.ipmemorystore.IOnL2KeyResponseListener;
-import android.net.ipmemorystore.IOnNetworkAttributesRetrieved;
-import android.net.ipmemorystore.IOnSameNetworkResponseListener;
-import android.net.ipmemorystore.IOnStatusListener;
import android.net.ipmemorystore.NetworkAttributes;
+import android.net.ipmemorystore.OnBlobRetrievedListener;
+import android.net.ipmemorystore.OnL2KeyResponseListener;
+import android.net.ipmemorystore.OnNetworkAttributesRetrievedListener;
+import android.net.ipmemorystore.OnSameL3NetworkResponseListener;
+import android.net.ipmemorystore.OnStatusListener;
import android.net.ipmemorystore.Status;
-import android.net.ipmemorystore.StatusParcelable;
import android.os.RemoteException;
import android.util.Log;
@@ -50,12 +49,6 @@
@NonNull
protected abstract IIpMemoryStore getService() throws InterruptedException, ExecutionException;
- protected StatusParcelable internalErrorStatus() {
- final StatusParcelable error = new StatusParcelable();
- error.resultCode = Status.ERROR_UNKNOWN;
- return error;
- }
-
/**
* Store network attributes for a given L2 key.
* If L2Key is null, choose automatically from the attributes ; passing null is equivalent to
@@ -74,12 +67,13 @@
*/
public void storeNetworkAttributes(@NonNull final String l2Key,
@NonNull final NetworkAttributes attributes,
- @Nullable final IOnStatusListener listener) {
+ @Nullable final OnStatusListener listener) {
try {
try {
- getService().storeNetworkAttributes(l2Key, attributes.toParcelable(), listener);
+ getService().storeNetworkAttributes(l2Key, attributes.toParcelable(),
+ OnStatusListener.toAIDL(listener));
} catch (InterruptedException | ExecutionException m) {
- listener.onComplete(internalErrorStatus());
+ listener.onComplete(new Status(Status.ERROR_UNKNOWN));
}
} catch (RemoteException e) {
Log.e(TAG, "Error storing network attributes", e);
@@ -99,12 +93,13 @@
*/
public void storeBlob(@NonNull final String l2Key, @NonNull final String clientId,
@NonNull final String name, @NonNull final Blob data,
- @Nullable final IOnStatusListener listener) {
+ @Nullable final OnStatusListener listener) {
try {
try {
- getService().storeBlob(l2Key, clientId, name, data, listener);
+ getService().storeBlob(l2Key, clientId, name, data,
+ OnStatusListener.toAIDL(listener));
} catch (InterruptedException | ExecutionException m) {
- listener.onComplete(internalErrorStatus());
+ listener.onComplete(new Status(Status.ERROR_UNKNOWN));
}
} catch (RemoteException e) {
Log.e(TAG, "Error storing blob", e);
@@ -126,12 +121,13 @@
* Through the listener, returns the L2 key if one matched, or null.
*/
public void findL2Key(@NonNull final NetworkAttributes attributes,
- @NonNull final IOnL2KeyResponseListener listener) {
+ @NonNull final OnL2KeyResponseListener listener) {
try {
try {
- getService().findL2Key(attributes.toParcelable(), listener);
+ getService().findL2Key(attributes.toParcelable(),
+ OnL2KeyResponseListener.toAIDL(listener));
} catch (InterruptedException | ExecutionException m) {
- listener.onL2KeyResponse(internalErrorStatus(), null);
+ listener.onL2KeyResponse(new Status(Status.ERROR_UNKNOWN), null);
}
} catch (RemoteException e) {
Log.e(TAG, "Error finding L2 Key", e);
@@ -148,12 +144,13 @@
* Through the listener, a SameL3NetworkResponse containing the answer and confidence.
*/
public void isSameNetwork(@NonNull final String l2Key1, @NonNull final String l2Key2,
- @NonNull final IOnSameNetworkResponseListener listener) {
+ @NonNull final OnSameL3NetworkResponseListener listener) {
try {
try {
- getService().isSameNetwork(l2Key1, l2Key2, listener);
+ getService().isSameNetwork(l2Key1, l2Key2,
+ OnSameL3NetworkResponseListener.toAIDL(listener));
} catch (InterruptedException | ExecutionException m) {
- listener.onSameNetworkResponse(internalErrorStatus(), null);
+ listener.onSameL3NetworkResponse(new Status(Status.ERROR_UNKNOWN), null);
}
} catch (RemoteException e) {
Log.e(TAG, "Error checking for network sameness", e);
@@ -170,12 +167,13 @@
* the query.
*/
public void retrieveNetworkAttributes(@NonNull final String l2Key,
- @NonNull final IOnNetworkAttributesRetrieved listener) {
+ @NonNull final OnNetworkAttributesRetrievedListener listener) {
try {
try {
- getService().retrieveNetworkAttributes(l2Key, listener);
+ getService().retrieveNetworkAttributes(l2Key,
+ OnNetworkAttributesRetrievedListener.toAIDL(listener));
} catch (InterruptedException | ExecutionException m) {
- listener.onNetworkAttributesRetrieved(internalErrorStatus(), null, null);
+ listener.onNetworkAttributesRetrieved(new Status(Status.ERROR_UNKNOWN), null, null);
}
} catch (RemoteException e) {
Log.e(TAG, "Error retrieving network attributes", e);
@@ -194,12 +192,13 @@
* and the name of the data associated with the query.
*/
public void retrieveBlob(@NonNull final String l2Key, @NonNull final String clientId,
- @NonNull final String name, @NonNull final IOnBlobRetrievedListener listener) {
+ @NonNull final String name, @NonNull final OnBlobRetrievedListener listener) {
try {
try {
- getService().retrieveBlob(l2Key, clientId, name, listener);
+ getService().retrieveBlob(l2Key, clientId, name,
+ OnBlobRetrievedListener.toAIDL(listener));
} catch (InterruptedException | ExecutionException m) {
- listener.onBlobRetrieved(internalErrorStatus(), null, null, null);
+ listener.onBlobRetrieved(new Status(Status.ERROR_UNKNOWN), null, null, null);
}
} catch (RemoteException e) {
Log.e(TAG, "Error retrieving blob", e);
diff --git a/services/net/java/android/net/ip/IpClientUtil.java b/services/net/java/android/net/ip/IpClientUtil.java
index 90624e0..714ade1 100644
--- a/services/net/java/android/net/ip/IpClientUtil.java
+++ b/services/net/java/android/net/ip/IpClientUtil.java
@@ -175,6 +175,11 @@
public void setNeighborDiscoveryOffload(boolean enable) {
mCb.setNeighborDiscoveryOffload(enable);
}
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
}
/**
diff --git a/services/net/java/android/net/ip/IpServer.java b/services/net/java/android/net/ip/IpServer.java
index fc1128b..66884c6 100644
--- a/services/net/java/android/net/ip/IpServer.java
+++ b/services/net/java/android/net/ip/IpServer.java
@@ -277,6 +277,11 @@
}
public abstract void callback(int statusCode);
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
}
private class DhcpServerCallbacksImpl extends DhcpServerCallbacks {
diff --git a/services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrieved.aidl b/services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
similarity index 94%
rename from services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrieved.aidl
rename to services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
index fb4ca3b..870e217 100644
--- a/services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrieved.aidl
+++ b/services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
@@ -20,7 +20,7 @@
import android.net.ipmemorystore.StatusParcelable;
/** {@hide} */
-oneway interface IOnNetworkAttributesRetrieved {
+oneway interface IOnNetworkAttributesRetrievedListener {
/**
* Network attributes were fetched for the specified L2 key. While the L2 key will never
* be null, the attributes may be if no data is stored about this L2 key.
diff --git a/services/net/java/android/net/ipmemorystore/IOnSameNetworkResponseListener.aidl b/services/net/java/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
similarity index 89%
rename from services/net/java/android/net/ipmemorystore/IOnSameNetworkResponseListener.aidl
rename to services/net/java/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
index 294bd3b..b8ccfb9 100644
--- a/services/net/java/android/net/ipmemorystore/IOnSameNetworkResponseListener.aidl
+++ b/services/net/java/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
@@ -20,10 +20,10 @@
import android.net.ipmemorystore.StatusParcelable;
/** {@hide} */
-oneway interface IOnSameNetworkResponseListener {
+oneway interface IOnSameL3NetworkResponseListener {
/**
* The memory store has come up with the answer to a query that was sent.
*/
- void onSameNetworkResponse(in StatusParcelable status,
+ void onSameL3NetworkResponse(in StatusParcelable status,
in SameL3NetworkResponseParcelable response);
}
diff --git a/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java b/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java
new file mode 100644
index 0000000..a17483a
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ipmemorystore;
+
+import android.annotation.NonNull;
+
+/**
+ * A listener for the IpMemoryStore to return a blob.
+ * @hide
+ */
+public interface OnBlobRetrievedListener {
+ /**
+ * The memory store has come up with the answer to a query that was sent.
+ */
+ void onBlobRetrieved(Status status, String l2Key, String name, Blob blob);
+
+ /** Converts this OnBlobRetrievedListener to a parcelable object */
+ @NonNull
+ static IOnBlobRetrievedListener toAIDL(@NonNull final OnBlobRetrievedListener listener) {
+ return new IOnBlobRetrievedListener.Stub() {
+ @Override
+ public void onBlobRetrieved(final StatusParcelable statusParcelable, final String l2Key,
+ final String name, final Blob blob) {
+ // NonNull, but still don't crash the system server if null
+ if (null != listener) {
+ listener.onBlobRetrieved(new Status(statusParcelable), l2Key, name, blob);
+ }
+ }
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
+ };
+ }
+}
diff --git a/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java b/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java
new file mode 100644
index 0000000..e608aec
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ipmemorystore;
+
+import android.annotation.NonNull;
+
+/**
+ * A listener for the IpMemoryStore to return a L2 key.
+ * @hide
+ */
+public interface OnL2KeyResponseListener {
+ /**
+ * The operation has completed with the specified status.
+ */
+ void onL2KeyResponse(Status status, String l2Key);
+
+ /** Converts this OnL2KeyResponseListener to a parcelable object */
+ @NonNull
+ static IOnL2KeyResponseListener toAIDL(@NonNull final OnL2KeyResponseListener listener) {
+ return new IOnL2KeyResponseListener.Stub() {
+ @Override
+ public void onL2KeyResponse(final StatusParcelable statusParcelable,
+ final String l2Key) {
+ // NonNull, but still don't crash the system server if null
+ if (null != listener) {
+ listener.onL2KeyResponse(new Status(statusParcelable), l2Key);
+ }
+ }
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
+ };
+ }
+}
diff --git a/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java b/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
new file mode 100644
index 0000000..ca6f302
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ipmemorystore;
+
+import android.annotation.NonNull;
+
+/**
+ * A listener for the IpMemoryStore to return network attributes.
+ * @hide
+ */
+public interface OnNetworkAttributesRetrievedListener {
+ /**
+ * The memory store has come up with the answer to a query that was sent.
+ */
+ void onNetworkAttributesRetrieved(Status status, String l2Key, NetworkAttributes attributes);
+
+ /** Converts this OnNetworkAttributesRetrievedListener to a parcelable object */
+ @NonNull
+ static IOnNetworkAttributesRetrievedListener toAIDL(
+ @NonNull final OnNetworkAttributesRetrievedListener listener) {
+ return new IOnNetworkAttributesRetrievedListener.Stub() {
+ @Override
+ public void onNetworkAttributesRetrieved(final StatusParcelable statusParcelable,
+ final String l2Key,
+ final NetworkAttributesParcelable networkAttributesParcelable) {
+ // NonNull, but still don't crash the system server if null
+ if (null != listener) {
+ listener.onNetworkAttributesRetrieved(
+ new Status(statusParcelable), l2Key,
+ new NetworkAttributes(networkAttributesParcelable));
+ }
+ }
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
+ };
+ }
+}
diff --git a/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java b/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java
new file mode 100644
index 0000000..67f8da8
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ipmemorystore;
+
+import android.annotation.NonNull;
+
+/**
+ * A listener for the IpMemoryStore to return a response about network sameness.
+ * @hide
+ */
+public interface OnSameL3NetworkResponseListener {
+ /**
+ * The memory store has come up with the answer to a query that was sent.
+ */
+ void onSameL3NetworkResponse(Status status, SameL3NetworkResponse response);
+
+ /** Converts this OnSameL3NetworkResponseListener to a parcelable object */
+ @NonNull
+ static IOnSameL3NetworkResponseListener toAIDL(
+ @NonNull final OnSameL3NetworkResponseListener listener) {
+ return new IOnSameL3NetworkResponseListener.Stub() {
+ @Override
+ public void onSameL3NetworkResponse(final StatusParcelable statusParcelable,
+ final SameL3NetworkResponseParcelable sameL3NetworkResponseParcelable) {
+ // NonNull, but still don't crash the system server if null
+ if (null != listener) {
+ listener.onSameL3NetworkResponse(
+ new Status(statusParcelable),
+ new SameL3NetworkResponse(sameL3NetworkResponseParcelable));
+ }
+ }
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
+ };
+ }
+}
diff --git a/services/net/java/android/net/ipmemorystore/OnStatusListener.java b/services/net/java/android/net/ipmemorystore/OnStatusListener.java
new file mode 100644
index 0000000..4262efd
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnStatusListener.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ipmemorystore;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+/**
+ * A listener for the IpMemoryStore to return a status to a client.
+ * @hide
+ */
+public interface OnStatusListener {
+ /**
+ * The operation has completed with the specified status.
+ */
+ void onComplete(Status status);
+
+ /** Converts this OnStatusListener to a parcelable object */
+ @NonNull
+ static IOnStatusListener toAIDL(@Nullable final OnStatusListener listener) {
+ return new IOnStatusListener.Stub() {
+ @Override
+ public void onComplete(final StatusParcelable statusParcelable) {
+ if (null != listener) {
+ listener.onComplete(new Status(statusParcelable));
+ }
+ }
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
+ };
+ }
+}
diff --git a/startop/iorap/TEST_MAPPING b/startop/iorap/DISABLED_TEST_MAPPING
similarity index 100%
rename from startop/iorap/TEST_MAPPING
rename to startop/iorap/DISABLED_TEST_MAPPING
diff --git a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
index 2cb369d..3dd9318 100644
--- a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
+++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
@@ -95,6 +95,21 @@
this.mIsUsingCarrierAggregation = isUsingCarrierAggregation;
}
+ /**
+ * Constructor from another data specific registration info
+ *
+ * @param dsri another data specific registration info
+ * @hide
+ */
+ DataSpecificRegistrationInfo(DataSpecificRegistrationInfo dsri) {
+ maxDataCalls = dsri.maxDataCalls;
+ isDcNrRestricted = dsri.isDcNrRestricted;
+ isNrAvailable = dsri.isNrAvailable;
+ isEnDcAvailable = dsri.isEnDcAvailable;
+ mLteVopsSupportInfo = dsri.mLteVopsSupportInfo;
+ mIsUsingCarrierAggregation = dsri.mIsUsingCarrierAggregation;
+ }
+
private DataSpecificRegistrationInfo(Parcel source) {
maxDataCalls = source.readInt();
isDcNrRestricted = source.readBoolean();
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 7b9f6d5..2fae949 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -280,6 +280,39 @@
}
/**
+ * Constructor from another network registration info
+ *
+ * @param nri Another network registration info
+ * @hide
+ */
+ public NetworkRegistrationInfo(NetworkRegistrationInfo nri) {
+ mDomain = nri.mDomain;
+ mTransportType = nri.mTransportType;
+ mRegistrationState = nri.mRegistrationState;
+ mRoamingType = nri.mRoamingType;
+ mAccessNetworkTechnology = nri.mAccessNetworkTechnology;
+ mRejectCause = nri.mRejectCause;
+ mEmergencyOnly = nri.mEmergencyOnly;
+ mAvailableServices = new ArrayList<>(nri.mAvailableServices);
+ if (nri.mCellIdentity != null) {
+ Parcel p = Parcel.obtain();
+ nri.mCellIdentity.writeToParcel(p, 0);
+ p.setDataPosition(0);
+ // TODO: Instead of doing this, we should create a formal way for cloning cell identity.
+ // Cell identity is not an immutable object so we have to deep copy it.
+ mCellIdentity = CellIdentity.CREATOR.createFromParcel(p);
+ }
+
+ if (nri.mVoiceSpecificInfo != null) {
+ mVoiceSpecificInfo = new VoiceSpecificRegistrationInfo(nri.mVoiceSpecificInfo);
+ }
+ if (nri.mDataSpecificInfo != null) {
+ mDataSpecificInfo = new DataSpecificRegistrationInfo(nri.mDataSpecificInfo);
+ }
+ mNrState = nri.mNrState;
+ }
+
+ /**
* @return The transport type.
*/
public @TransportType int getTransportType() { return mTransportType; }
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index f4a6984..86cdce1 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -418,7 +418,7 @@
Arrays.copyOf(s.mCellBandwidths, s.mCellBandwidths.length);
mLteEarfcnRsrpBoost = s.mLteEarfcnRsrpBoost;
mNetworkRegistrationInfos = s.mNetworkRegistrationInfos == null ? null :
- new ArrayList<>(s.mNetworkRegistrationInfos);
+ s.getNetworkRegistrationInfoList();
mNrFrequencyRange = s.mNrFrequencyRange;
}
@@ -1113,16 +1113,16 @@
/** @hide */
@TestApi
public void setVoiceRoamingType(@RoamingType int type) {
- NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+ NetworkRegistrationInfo regInfo = getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- if (regState == null) {
- regState = new NetworkRegistrationInfo.Builder()
+ if (regInfo == null) {
+ regInfo = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.build();
- addNetworkRegistrationInfo(regState);
}
- regState.setRoamingType(type);
+ regInfo.setRoamingType(type);
+ addNetworkRegistrationInfo(regInfo);
}
/** @hide */
@@ -1134,16 +1134,16 @@
/** @hide */
@TestApi
public void setDataRoamingType(@RoamingType int type) {
- NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+ NetworkRegistrationInfo regInfo = getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- if (regState == null) {
- regState = new NetworkRegistrationInfo.Builder()
+ if (regInfo == null) {
+ regInfo = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.build();
- addNetworkRegistrationInfo(regState);
}
- regState.setRoamingType(type);
+ regInfo.setRoamingType(type);
+ addNetworkRegistrationInfo(regInfo);
}
/**
@@ -1305,16 +1305,16 @@
Rlog.e(LOG_TAG, "ServiceState.setRilVoiceRadioTechnology() called. It's encouraged to "
+ "use addNetworkRegistrationInfo() instead *******");
// Sync to network registration state
- NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+ NetworkRegistrationInfo regInfo = getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- if (regState == null) {
- regState = new NetworkRegistrationInfo.Builder()
+ if (regInfo == null) {
+ regInfo = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.build();
- addNetworkRegistrationInfo(regState);
}
- regState.setAccessNetworkTechnology(rilRadioTechnologyToNetworkType(rt));
+ regInfo.setAccessNetworkTechnology(rilRadioTechnologyToNetworkType(rt));
+ addNetworkRegistrationInfo(regInfo);
}
@@ -1326,17 +1326,17 @@
// Sync to network registration state. Always write down the WWAN transport. For AP-assisted
// mode device, use addNetworkRegistrationInfo() to set the correct transport if RAT
// is IWLAN.
- NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+ NetworkRegistrationInfo regInfo = getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- if (regState == null) {
- regState = new NetworkRegistrationInfo.Builder()
+ if (regInfo == null) {
+ regInfo = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.build();
- addNetworkRegistrationInfo(regState);
}
- regState.setAccessNetworkTechnology(rilRadioTechnologyToNetworkType(rt));
+ regInfo.setAccessNetworkTechnology(rilRadioTechnologyToNetworkType(rt));
+ addNetworkRegistrationInfo(regInfo);
}
/** @hide */
@@ -1378,10 +1378,10 @@
* @hide
*/
public @NRState int getNrState() {
- final NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
+ final NetworkRegistrationInfo regInfo = getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- if (regState == null) return NetworkRegistrationInfo.NR_STATE_NONE;
- return regState.getNrState();
+ if (regInfo == null) return NetworkRegistrationInfo.NR_STATE_NONE;
+ return regInfo.getNrState();
}
/**
@@ -1775,7 +1775,11 @@
@SystemApi
public List<NetworkRegistrationInfo> getNetworkRegistrationInfoList() {
synchronized (mNetworkRegistrationInfos) {
- return new ArrayList<>(mNetworkRegistrationInfos);
+ List<NetworkRegistrationInfo> newList = new ArrayList<>();
+ for (NetworkRegistrationInfo nri : mNetworkRegistrationInfos) {
+ newList.add(new NetworkRegistrationInfo(nri));
+ }
+ return newList;
}
}
@@ -1795,7 +1799,7 @@
synchronized (mNetworkRegistrationInfos) {
for (NetworkRegistrationInfo networkRegistrationInfo : mNetworkRegistrationInfos) {
if (networkRegistrationInfo.getTransportType() == transportType) {
- list.add(networkRegistrationInfo);
+ list.add(new NetworkRegistrationInfo(networkRegistrationInfo));
}
}
}
@@ -1819,7 +1823,7 @@
synchronized (mNetworkRegistrationInfos) {
for (NetworkRegistrationInfo networkRegistrationInfo : mNetworkRegistrationInfos) {
if (networkRegistrationInfo.getDomain() == domain) {
- list.add(networkRegistrationInfo);
+ list.add(new NetworkRegistrationInfo(networkRegistrationInfo));
}
}
}
@@ -1844,7 +1848,7 @@
for (NetworkRegistrationInfo networkRegistrationInfo : mNetworkRegistrationInfos) {
if (networkRegistrationInfo.getTransportType() == transportType
&& networkRegistrationInfo.getDomain() == domain) {
- return networkRegistrationInfo;
+ return new NetworkRegistrationInfo(networkRegistrationInfo);
}
}
}
@@ -1856,20 +1860,20 @@
* @hide
*/
@TestApi
- public void addNetworkRegistrationInfo(NetworkRegistrationInfo regState) {
- if (regState == null) return;
+ public void addNetworkRegistrationInfo(NetworkRegistrationInfo nri) {
+ if (nri == null) return;
synchronized (mNetworkRegistrationInfos) {
for (int i = 0; i < mNetworkRegistrationInfos.size(); i++) {
NetworkRegistrationInfo curRegState = mNetworkRegistrationInfos.get(i);
- if (curRegState.getTransportType() == regState.getTransportType()
- && curRegState.getDomain() == regState.getDomain()) {
+ if (curRegState.getTransportType() == nri.getTransportType()
+ && curRegState.getDomain() == nri.getDomain()) {
mNetworkRegistrationInfos.remove(i);
break;
}
}
- mNetworkRegistrationInfos.add(regState);
+ mNetworkRegistrationInfos.add(new NetworkRegistrationInfo(nri));
}
}
diff --git a/telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java b/telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java
index 18a533a..d43181e 100644
--- a/telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java
+++ b/telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java
@@ -65,6 +65,19 @@
this.defaultRoamingIndicator = defaultRoamingIndicator;
}
+ /**
+ * Constructor from another voice specific registration info
+ *
+ * @param vsri another voice specific registration info
+ * @hide
+ */
+ VoiceSpecificRegistrationInfo(VoiceSpecificRegistrationInfo vsri) {
+ cssSupported = vsri.cssSupported;
+ roamingIndicator = vsri.roamingIndicator;
+ systemIsInPrl = vsri.systemIsInPrl;
+ defaultRoamingIndicator = vsri.defaultRoamingIndicator;
+ }
+
private VoiceSpecificRegistrationInfo(Parcel source) {
this.cssSupported = source.readBoolean();
this.roamingIndicator = source.readInt();
diff --git a/telephony/java/android/telephony/emergency/EmergencyNumber.java b/telephony/java/android/telephony/emergency/EmergencyNumber.java
index dba2207..2d6402d 100644
--- a/telephony/java/android/telephony/emergency/EmergencyNumber.java
+++ b/telephony/java/android/telephony/emergency/EmergencyNumber.java
@@ -635,7 +635,7 @@
!= second.getEmergencyServiceCategoryBitmask()) {
return false;
}
- if (first.getEmergencyUrns().equals(second.getEmergencyUrns())) {
+ if (!first.getEmergencyUrns().equals(second.getEmergencyUrns())) {
return false;
}
if (first.getEmergencyCallRouting() != second.getEmergencyCallRouting()) {
diff --git a/tests/net/Android.bp b/tests/net/Android.bp
index 9098f90..1fbb658 100644
--- a/tests/net/Android.bp
+++ b/tests/net/Android.bp
@@ -6,6 +6,7 @@
static_libs: [
"FrameworksNetCommonTests",
"frameworks-base-testutils",
+ "frameworks-net-testutils",
"framework-protos",
"androidx.test.rules",
"mockito-target-minus-junit4",
@@ -63,7 +64,7 @@
android_test {
name: "FrameworksNetTests",
defaults: ["FrameworksNetTests-jni-defaults"],
- srcs: ["java/**/*.java"],
+ srcs: ["java/**/*.java", "java/**/*.kt"],
platform_apis: true,
test_suites: ["device-tests"],
certificate: "platform",
diff --git a/tests/net/common/Android.bp b/tests/net/common/Android.bp
index 0a1ac75..3b2e34a 100644
--- a/tests/net/common/Android.bp
+++ b/tests/net/common/Android.bp
@@ -18,9 +18,10 @@
// They must be fast and stable, and exercise public or test APIs.
java_library {
name: "FrameworksNetCommonTests",
- srcs: ["java/**/*.java"],
+ srcs: ["java/**/*.java", "java/**/*.kt"],
static_libs: [
"androidx.test.rules",
+ "frameworks-net-testutils",
"junit",
],
libs: [
diff --git a/tests/net/java/android/net/LinkAddressTest.java b/tests/net/common/java/android/net/LinkAddressTest.java
similarity index 100%
rename from tests/net/java/android/net/LinkAddressTest.java
rename to tests/net/common/java/android/net/LinkAddressTest.java
diff --git a/tests/net/java/android/net/LinkPropertiesTest.java b/tests/net/common/java/android/net/LinkPropertiesTest.java
similarity index 99%
rename from tests/net/java/android/net/LinkPropertiesTest.java
rename to tests/net/common/java/android/net/LinkPropertiesTest.java
index 4177291..709f5f6 100644
--- a/tests/net/java/android/net/LinkPropertiesTest.java
+++ b/tests/net/common/java/android/net/LinkPropertiesTest.java
@@ -868,12 +868,12 @@
source.setNat64Prefix(new IpPrefix("2001:db8:1:2:64:64::/96"));
- TestUtils.assertParcelingIsLossless(source, LinkProperties.CREATOR);
+ TestUtils.assertParcelingIsLossless(source);
}
@Test
public void testParcelUninitialized() throws Exception {
LinkProperties empty = new LinkProperties();
- TestUtils.assertParcelingIsLossless(empty, LinkProperties.CREATOR);
+ TestUtils.assertParcelingIsLossless(empty);
}
}
diff --git a/tests/net/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
similarity index 100%
rename from tests/net/java/android/net/NetworkCapabilitiesTest.java
rename to tests/net/common/java/android/net/NetworkCapabilitiesTest.java
diff --git a/tests/net/java/android/net/NetworkTest.java b/tests/net/common/java/android/net/NetworkTest.java
similarity index 100%
rename from tests/net/java/android/net/NetworkTest.java
rename to tests/net/common/java/android/net/NetworkTest.java
diff --git a/tests/net/java/android/net/RouteInfoTest.java b/tests/net/common/java/android/net/RouteInfoTest.java
similarity index 100%
rename from tests/net/java/android/net/RouteInfoTest.java
rename to tests/net/common/java/android/net/RouteInfoTest.java
diff --git a/tests/net/java/android/net/StaticIpConfigurationTest.java b/tests/net/common/java/android/net/StaticIpConfigurationTest.java
similarity index 100%
rename from tests/net/java/android/net/StaticIpConfigurationTest.java
rename to tests/net/common/java/android/net/StaticIpConfigurationTest.java
diff --git a/tests/net/java/android/net/apf/ApfCapabilitiesTest.java b/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
similarity index 92%
rename from tests/net/java/android/net/apf/ApfCapabilitiesTest.java
rename to tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
index 75752c3..3ed8a86 100644
--- a/tests/net/java/android/net/apf/ApfCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
@@ -19,11 +19,10 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
-import android.net.shared.ParcelableTestUtil;
-
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.util.ParcelableTestUtil;
import com.android.internal.util.TestUtils;
import org.junit.Test;
@@ -37,7 +36,7 @@
final ApfCapabilities caps = new ApfCapabilities(123, 456, 789);
ParcelableTestUtil.assertFieldCountEquals(3, ApfCapabilities.class);
- TestUtils.assertParcelingIsLossless(caps, ApfCapabilities.CREATOR);
+ TestUtils.assertParcelingIsLossless(caps);
}
@Test
diff --git a/tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt b/tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt
new file mode 100644
index 0000000..e191953
--- /dev/null
+++ b/tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt
@@ -0,0 +1,67 @@
+package android.net.metrics
+
+import android.net.metrics.DhcpErrorEvent.errorCodeWithOption
+import android.net.metrics.DhcpErrorEvent.DHCP_INVALID_OPTION_LENGTH
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.internal.util.TestUtils.parcelingRoundTrip
+import java.lang.reflect.Modifier
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+
+private const val TEST_ERROR_CODE = 12345
+/**
+ * DHCP Optional Type: DHCP Subnet Mask (Copy from DhcpPacket.java)
+ */
+private const val DHCP_SUBNET_MASK = 1
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class DhcpErrorEventTest {
+
+ @Test
+ fun testConstructor() {
+ val event = DhcpErrorEvent(TEST_ERROR_CODE)
+ assertEquals(TEST_ERROR_CODE, event.errorCode)
+ }
+
+ @Test
+ fun testParcelUnparcel() {
+ val event = DhcpErrorEvent(TEST_ERROR_CODE)
+ val parceled = parcelingRoundTrip(event)
+ assertEquals(TEST_ERROR_CODE, parceled.errorCode)
+ }
+
+ @Test
+ fun testErrorCodeWithOption() {
+ val errorCode = errorCodeWithOption(DHCP_INVALID_OPTION_LENGTH, DHCP_SUBNET_MASK);
+ assertTrue((DHCP_INVALID_OPTION_LENGTH and errorCode) == DHCP_INVALID_OPTION_LENGTH);
+ assertTrue((DHCP_SUBNET_MASK and errorCode) == DHCP_SUBNET_MASK);
+ }
+
+ @Test
+ fun testToString() {
+ val names = listOf("L2_ERROR", "L3_ERROR", "L4_ERROR", "DHCP_ERROR", "MISC_ERROR")
+ val errorFields = DhcpErrorEvent::class.java.declaredFields.filter {
+ it.type == Int::class.javaPrimitiveType
+ && Modifier.isPublic(it.modifiers) && Modifier.isStatic(it.modifiers)
+ && it.name !in names
+ }
+
+ errorFields.forEach {
+ val intValue = it.getInt(null)
+ val stringValue = DhcpErrorEvent(intValue).toString()
+ assertTrue("Invalid string for error 0x%08X (field %s): %s".format(intValue, it.name,
+ stringValue),
+ stringValue.contains(it.name))
+ }
+ }
+
+ @Test
+ fun testToString_InvalidErrorCode() {
+ assertNotNull(DhcpErrorEvent(TEST_ERROR_CODE).toString())
+ }
+}
\ No newline at end of file
diff --git a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
index e0b7227..583d3fd 100644
--- a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
+++ b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
@@ -79,7 +79,7 @@
assertEquals(testInfo.tos, resultData.ipTos);
assertEquals(testInfo.ttl, resultData.ipTtl);
- TestUtils.assertParcelingIsLossless(resultData, TcpKeepalivePacketData.CREATOR);
+ TestUtils.assertParcelingIsLossless(resultData);
final byte[] packet = resultData.getPacket();
// IP version and IHL
diff --git a/tests/net/java/android/net/shared/InitialConfigurationTest.java b/tests/net/java/android/net/shared/InitialConfigurationTest.java
index 27bc13d..2fb8b19 100644
--- a/tests/net/java/android/net/shared/InitialConfigurationTest.java
+++ b/tests/net/java/android/net/shared/InitialConfigurationTest.java
@@ -17,7 +17,8 @@
package android.net.shared;
import static android.net.InetAddresses.parseNumericAddress;
-import static android.net.shared.ParcelableTestUtil.assertFieldCountEquals;
+
+import static com.android.internal.util.ParcelableTestUtil.assertFieldCountEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
diff --git a/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java b/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
index 21a4988..d8f01e9 100644
--- a/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
+++ b/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
@@ -19,7 +19,8 @@
import static android.net.InetAddresses.parseNumericAddress;
import static android.net.shared.IpConfigurationParcelableUtil.fromStableParcelable;
import static android.net.shared.IpConfigurationParcelableUtil.toStableParcelable;
-import static android.net.shared.ParcelableTestUtil.assertFieldCountEquals;
+
+import static com.android.internal.util.ParcelableTestUtil.assertFieldCountEquals;
import static org.junit.Assert.assertEquals;
diff --git a/tests/net/java/android/net/shared/ProvisioningConfigurationTest.java b/tests/net/java/android/net/shared/ProvisioningConfigurationTest.java
index 6fad89e..382afe0 100644
--- a/tests/net/java/android/net/shared/ProvisioningConfigurationTest.java
+++ b/tests/net/java/android/net/shared/ProvisioningConfigurationTest.java
@@ -17,9 +17,10 @@
package android.net.shared;
import static android.net.InetAddresses.parseNumericAddress;
-import static android.net.shared.ParcelableTestUtil.assertFieldCountEquals;
import static android.net.shared.ProvisioningConfiguration.fromStableParcelable;
+import static com.android.internal.util.ParcelableTestUtil.assertFieldCountEquals;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index e3c6c41..64672bd8a 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -4228,6 +4228,25 @@
callback.expectStarted();
ka.stop();
callback.expectStopped();
+
+ // Check that the same NATT socket cannot be used by 2 keepalives.
+ try (SocketKeepalive ka2 = mCm.createSocketKeepalive(
+ myNet, testSocket, myIPv4, dstIPv4, executor, callback)) {
+ // Check that second keepalive cannot be started if the first one is running.
+ ka.start(validKaInterval);
+ callback.expectStarted();
+ ka2.start(validKaInterval);
+ callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET);
+ ka.stop();
+ callback.expectStopped();
+
+ // Check that second keepalive can be started/stopped normally if the first one is
+ // stopped.
+ ka2.start(validKaInterval);
+ callback.expectStarted();
+ ka2.stop();
+ callback.expectStopped();
+ }
}
// Check that deleting the IP address stops the keepalive.
@@ -4291,6 +4310,10 @@
testSocket.close();
testSocket2.close();
}
+
+ // Check that the closed socket cannot be used to start keepalive.
+ ka.start(validKaInterval);
+ callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET);
}
// Check that there is no port leaked after all keepalives and sockets are closed.
diff --git a/tests/net/java/com/android/server/IpSecServiceTest.java b/tests/net/java/com/android/server/IpSecServiceTest.java
index 4a35015..6b5a220 100644
--- a/tests/net/java/com/android/server/IpSecServiceTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceTest.java
@@ -118,6 +118,7 @@
INetd mMockNetd;
IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
IpSecService mIpSecService;
+ int mUid = Os.getuid();
@Before
public void setUp() throws Exception {
@@ -665,4 +666,99 @@
mIpSecService.releaseNetId(releasedNetId);
assertEquals(releasedNetId, mIpSecService.reserveNetId());
}
+
+ @Test
+ public void testLockEncapSocketForNattKeepalive() throws Exception {
+ IpSecUdpEncapResponse udpEncapResp =
+ mIpSecService.openUdpEncapsulationSocket(0, new Binder());
+ assertNotNull(udpEncapResp);
+ assertEquals(IpSecManager.Status.OK, udpEncapResp.status);
+
+ // Verify no NATT keepalive records upon startup
+ IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
+ assertEquals(0, userRecord.mNattKeepaliveRecords.size());
+
+ int nattKeepaliveResourceId =
+ mIpSecService.lockEncapSocketForNattKeepalive(udpEncapResp.resourceId, mUid);
+
+ // Validate response, and record was added
+ assertNotEquals(IpSecManager.INVALID_RESOURCE_ID, nattKeepaliveResourceId);
+ assertEquals(1, userRecord.mNattKeepaliveRecords.size());
+
+ // Validate keepalive can be released and removed.
+ mIpSecService.releaseNattKeepalive(nattKeepaliveResourceId, mUid);
+ assertEquals(0, userRecord.mNattKeepaliveRecords.size());
+
+ mIpSecService.closeUdpEncapsulationSocket(udpEncapResp.resourceId);
+ }
+
+ @Test
+ public void testLockEncapSocketForNattKeepaliveInvalidUid() throws Exception {
+ IpSecUdpEncapResponse udpEncapResp =
+ mIpSecService.openUdpEncapsulationSocket(0, new Binder());
+ assertNotNull(udpEncapResp);
+ assertEquals(IpSecManager.Status.OK, udpEncapResp.status);
+
+ // Verify no NATT keepalive records upon startup
+ IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
+ assertEquals(0, userRecord.mNattKeepaliveRecords.size());
+
+ try {
+ int nattKeepaliveResourceId =
+ mIpSecService.lockEncapSocketForNattKeepalive(
+ udpEncapResp.resourceId, mUid + 1);
+ fail("Expected SecurityException for invalid user");
+ } catch (SecurityException expected) {
+ }
+
+ // Validate keepalive was not added to lists
+ assertEquals(0, userRecord.mNattKeepaliveRecords.size());
+ }
+
+ @Test
+ public void testLockEncapSocketForNattKeepaliveInvalidResourceId() throws Exception {
+ // Verify no NATT keepalive records upon startup
+ IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
+ assertEquals(0, userRecord.mNattKeepaliveRecords.size());
+
+ try {
+ int nattKeepaliveResourceId =
+ mIpSecService.lockEncapSocketForNattKeepalive(12345, mUid);
+ fail("Expected IllegalArgumentException for invalid resource ID");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ // Validate keepalive was not added to lists
+ assertEquals(0, userRecord.mNattKeepaliveRecords.size());
+ }
+
+ @Test
+ public void testEncapSocketReleasedBeforeKeepaliveReleased() throws Exception {
+ IpSecUdpEncapResponse udpEncapResp =
+ mIpSecService.openUdpEncapsulationSocket(0, new Binder());
+ assertNotNull(udpEncapResp);
+ assertEquals(IpSecManager.Status.OK, udpEncapResp.status);
+
+ // Get encap socket record, verify initial starting refcount.
+ IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
+ IpSecService.RefcountedResource encapSocketRefcountedRecord =
+ userRecord.mEncapSocketRecords.getRefcountedResourceOrThrow(
+ udpEncapResp.resourceId);
+ assertEquals(1, encapSocketRefcountedRecord.mRefCount);
+
+ // Verify that the reference was added
+ int nattKeepaliveResourceId =
+ mIpSecService.lockEncapSocketForNattKeepalive(udpEncapResp.resourceId, mUid);
+ assertNotEquals(IpSecManager.INVALID_RESOURCE_ID, nattKeepaliveResourceId);
+ assertEquals(2, encapSocketRefcountedRecord.mRefCount);
+
+ // Close UDP encap socket, but expect the refcountedRecord to still have a reference.
+ mIpSecService.closeUdpEncapsulationSocket(udpEncapResp.resourceId);
+ assertEquals(1, encapSocketRefcountedRecord.mRefCount);
+
+ // Verify UDP encap socket cleaned up once reference is removed. Expect -1 if cleanup
+ // was properly completed.
+ mIpSecService.releaseNattKeepalive(nattKeepaliveResourceId, mUid);
+ assertEquals(-1, encapSocketRefcountedRecord.mRefCount);
+ }
}
diff --git a/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt
new file mode 100644
index 0000000..f045369
--- /dev/null
+++ b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server
+
+import android.net.ConnectivityManager.TYPE_ETHERNET
+import android.net.ConnectivityManager.TYPE_MOBILE
+import android.net.ConnectivityManager.TYPE_WIFI
+import android.net.ConnectivityManager.TYPE_WIMAX
+import android.net.NetworkInfo.DetailedState.CONNECTED
+import android.net.NetworkInfo.DetailedState.DISCONNECTED
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.server.ConnectivityService.LegacyTypeTracker
+import com.android.server.connectivity.NetworkAgentInfo
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNull
+import org.junit.Assert.assertSame
+import org.junit.Assert.assertTrue
+import org.junit.Assert.fail
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.reset
+import org.mockito.Mockito.verify
+
+const val UNSUPPORTED_TYPE = TYPE_WIMAX
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class LegacyTypeTrackerTest {
+ private val supportedTypes = arrayOf(TYPE_MOBILE, TYPE_WIFI, TYPE_ETHERNET)
+
+ private val mMockService = mock(ConnectivityService::class.java).apply {
+ doReturn(false).`when`(this).isDefaultNetwork(any())
+ }
+ private val mTracker = LegacyTypeTracker(mMockService).apply {
+ supportedTypes.forEach {
+ addSupportedType(it)
+ }
+ }
+
+ @Test
+ fun testSupportedTypes() {
+ try {
+ mTracker.addSupportedType(supportedTypes[0])
+ fail("Expected IllegalStateException")
+ } catch (expected: IllegalStateException) {}
+ supportedTypes.forEach {
+ assertTrue(mTracker.isTypeSupported(it))
+ }
+ assertFalse(mTracker.isTypeSupported(UNSUPPORTED_TYPE))
+ }
+
+ @Test
+ fun testAddNetwork() {
+ val mobileNai = mock(NetworkAgentInfo::class.java)
+ val wifiNai = mock(NetworkAgentInfo::class.java)
+ mTracker.add(TYPE_MOBILE, mobileNai)
+ mTracker.add(TYPE_WIFI, wifiNai)
+ assertSame(mTracker.getNetworkForType(TYPE_MOBILE), mobileNai)
+ assertSame(mTracker.getNetworkForType(TYPE_WIFI), wifiNai)
+ // Make sure adding a second NAI does not change the results.
+ val secondMobileNai = mock(NetworkAgentInfo::class.java)
+ mTracker.add(TYPE_MOBILE, secondMobileNai)
+ assertSame(mTracker.getNetworkForType(TYPE_MOBILE), mobileNai)
+ assertSame(mTracker.getNetworkForType(TYPE_WIFI), wifiNai)
+ // Make sure removing a network that wasn't added for this type is a no-op.
+ mTracker.remove(TYPE_MOBILE, wifiNai, false /* wasDefault */)
+ assertSame(mTracker.getNetworkForType(TYPE_MOBILE), mobileNai)
+ assertSame(mTracker.getNetworkForType(TYPE_WIFI), wifiNai)
+ // Remove the top network for mobile and make sure the second one becomes the network
+ // of record for this type.
+ mTracker.remove(TYPE_MOBILE, mobileNai, false /* wasDefault */)
+ assertSame(mTracker.getNetworkForType(TYPE_MOBILE), secondMobileNai)
+ assertSame(mTracker.getNetworkForType(TYPE_WIFI), wifiNai)
+ // Make sure adding a network for an unsupported type does not register it.
+ mTracker.add(UNSUPPORTED_TYPE, mobileNai)
+ assertNull(mTracker.getNetworkForType(UNSUPPORTED_TYPE))
+ }
+
+ @Test
+ fun testBroadcastOnDisconnect() {
+ val mobileNai1 = mock(NetworkAgentInfo::class.java)
+ val mobileNai2 = mock(NetworkAgentInfo::class.java)
+ doReturn(false).`when`(mMockService).isDefaultNetwork(mobileNai1)
+ mTracker.add(TYPE_MOBILE, mobileNai1)
+ verify(mMockService).sendLegacyNetworkBroadcast(mobileNai1, CONNECTED, TYPE_MOBILE)
+ reset(mMockService)
+ doReturn(false).`when`(mMockService).isDefaultNetwork(mobileNai2)
+ mTracker.add(TYPE_MOBILE, mobileNai2)
+ verify(mMockService, never()).sendLegacyNetworkBroadcast(any(), any(), anyInt())
+ mTracker.remove(TYPE_MOBILE, mobileNai1, false /* wasDefault */)
+ verify(mMockService).sendLegacyNetworkBroadcast(mobileNai1, DISCONNECTED, TYPE_MOBILE)
+ verify(mMockService).sendLegacyNetworkBroadcast(mobileNai2, CONNECTED, TYPE_MOBILE)
+ }
+}
diff --git a/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java b/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java
index fb84611..a83faf3 100644
--- a/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java
+++ b/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server.net.ipmemorystore;
+package com.android.server.connectivity.ipmemorystore;
import static org.junit.Assert.assertEquals;
diff --git a/tests/net/util/Android.bp b/tests/net/util/Android.bp
new file mode 100644
index 0000000..d8c502d
--- /dev/null
+++ b/tests/net/util/Android.bp
@@ -0,0 +1,30 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// Common utilities for network tests.
+java_library {
+ name: "frameworks-net-testutils",
+ srcs: ["java/**/*.java"],
+ // test_current to be also appropriate for CTS tests
+ sdk_version: "test_current",
+ static_libs: [
+ "androidx.annotation_annotation",
+ "junit",
+ ],
+ libs: [
+ "android.test.base.stubs",
+ ],
+}
\ No newline at end of file
diff --git a/tests/net/java/android/net/shared/ParcelableTestUtil.java b/tests/net/util/java/com/android/internal/util/ParcelableTestUtil.java
similarity index 97%
rename from tests/net/java/android/net/shared/ParcelableTestUtil.java
rename to tests/net/util/java/com/android/internal/util/ParcelableTestUtil.java
index 088ea3c..87537b9 100644
--- a/tests/net/java/android/net/shared/ParcelableTestUtil.java
+++ b/tests/net/util/java/com/android/internal/util/ParcelableTestUtil.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.net.shared;
+package com.android.internal.util;
import static org.junit.Assert.assertEquals;
diff --git a/tests/net/java/com/android/internal/util/TestUtils.java b/tests/net/util/java/com/android/internal/util/TestUtils.java
similarity index 74%
rename from tests/net/java/com/android/internal/util/TestUtils.java
rename to tests/net/util/java/com/android/internal/util/TestUtils.java
index 57cc172..a99cd47 100644
--- a/tests/net/java/com/android/internal/util/TestUtils.java
+++ b/tests/net/util/java/com/android/internal/util/TestUtils.java
@@ -19,7 +19,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
-import android.annotation.NonNull;
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.HandlerThread;
@@ -27,6 +26,8 @@
import android.os.Parcel;
import android.os.Parcelable;
+import androidx.annotation.NonNull;
+
import java.util.concurrent.Executor;
public final class TestUtils {
@@ -36,7 +37,7 @@
* Block until the given Handler thread becomes idle, or until timeoutMs has passed.
*/
public static void waitForIdleHandler(HandlerThread handlerThread, long timeoutMs) {
- waitForIdleHandler(handlerThread.getThreadHandler(), timeoutMs);
+ waitForIdleLooper(handlerThread.getLooper(), timeoutMs);
}
/**
@@ -68,9 +69,17 @@
}
}
- // TODO : fetch the creator through reflection or something instead of passing it
- public static <T extends Parcelable, C extends Parcelable.Creator<T>>
- void assertParcelingIsLossless(T source, C creator) {
+ /**
+ * Return a new instance of {@code T} after being parceled then unparceled.
+ */
+ public static <T extends Parcelable> T parcelingRoundTrip(T source) {
+ final Parcelable.Creator<T> creator;
+ try {
+ creator = (Parcelable.Creator<T>) source.getClass().getField("CREATOR").get(null);
+ } catch (IllegalAccessException | NoSuchFieldException e) {
+ fail("Missing CREATOR field: " + e.getMessage());
+ return null;
+ }
Parcel p = Parcel.obtain();
source.writeToParcel(p, /* flags */ 0);
p.setDataPosition(0);
@@ -78,7 +87,14 @@
p = Parcel.obtain();
p.unmarshall(marshalled, 0, marshalled.length);
p.setDataPosition(0);
- T dest = creator.createFromParcel(p);
- assertEquals(source, dest);
+ return creator.createFromParcel(p);
+ }
+
+ /**
+ * Assert that after being parceled then unparceled, {@code source} is equal to the original
+ * object.
+ */
+ public static <T extends Parcelable> void assertParcelingIsLossless(T source) {
+ assertEquals(source, parcelingRoundTrip(source));
}
}
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index 99420de..609e366 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -497,9 +497,9 @@
}
// Try parsing the code name.
- std::pair<StringPiece, int> entry = GetDevelopmentSdkCodeNameAndVersion();
- if (entry.first == trimmed_str) {
- return entry.second;
+ Maybe<int> entry = GetDevelopmentSdkCodeNameVersion(trimmed_str);
+ if (entry) {
+ return entry.value();
}
return {};
}
diff --git a/tools/aapt2/SdkConstants.cpp b/tools/aapt2/SdkConstants.cpp
index 8ebde75..b4b6ff1 100644
--- a/tools/aapt2/SdkConstants.cpp
+++ b/tools/aapt2/SdkConstants.cpp
@@ -18,15 +18,17 @@
#include <algorithm>
#include <string>
-#include <unordered_map>
+#include <unordered_set>
#include <vector>
using android::StringPiece;
namespace aapt {
-static const char* sDevelopmentSdkCodeName = "P";
-static ApiVersion sDevelopmentSdkLevel = 28;
+static ApiVersion sDevelopmentSdkLevel = 10000;
+static const auto sDevelopmentSdkCodeNames = std::unordered_set<StringPiece>({
+ "Q", "R"
+});
static const std::vector<std::pair<uint16_t, ApiVersion>> sAttrIdMap = {
{0x021c, 1},
@@ -54,6 +56,7 @@
{0x0530, SDK_NOUGAT_MR1},
{0x0568, SDK_O},
{0x056d, SDK_O_MR1},
+ {0x0586, SDK_P},
};
static bool less_entry_id(const std::pair<uint16_t, ApiVersion>& p, uint16_t entryId) {
@@ -71,8 +74,9 @@
return iter->second;
}
-std::pair<StringPiece, ApiVersion> GetDevelopmentSdkCodeNameAndVersion() {
- return std::make_pair(StringPiece(sDevelopmentSdkCodeName), sDevelopmentSdkLevel);
+Maybe<ApiVersion> GetDevelopmentSdkCodeNameVersion(const StringPiece& code_name) {
+ return (sDevelopmentSdkCodeNames.find(code_name) == sDevelopmentSdkCodeNames.end())
+ ? Maybe<ApiVersion>() : sDevelopmentSdkLevel;
}
} // namespace aapt
diff --git a/tools/aapt2/SdkConstants.h b/tools/aapt2/SdkConstants.h
index 9fa29f2..adb034a 100644
--- a/tools/aapt2/SdkConstants.h
+++ b/tools/aapt2/SdkConstants.h
@@ -57,7 +57,7 @@
};
ApiVersion FindAttributeSdkLevel(const ResourceId& id);
-std::pair<android::StringPiece, ApiVersion> GetDevelopmentSdkCodeNameAndVersion();
+Maybe<ApiVersion> GetDevelopmentSdkCodeNameVersion(const android::StringPiece& code_name);
} // namespace aapt
diff --git a/tools/aapt2/configuration/ConfigurationParser_test.cpp b/tools/aapt2/configuration/ConfigurationParser_test.cpp
index 4c23bd3..2ef8b99 100644
--- a/tools/aapt2/configuration/ConfigurationParser_test.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser_test.cpp
@@ -705,35 +705,24 @@
}
TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_NonNumeric) {
- static constexpr const char* xml = R"xml(
+ auto doc = test::BuildXmlDom(R"xml(
<android-sdk
- label="P"
+ label="Q"
minSdkVersion="25"
- targetSdkVersion="%s"
- maxSdkVersion="%s">
- </android-sdk>)xml";
-
- const auto& dev_sdk = GetDevelopmentSdkCodeNameAndVersion();
- const char* codename = dev_sdk.first.data();
- const ApiVersion& version = dev_sdk.second;
-
- auto doc = test::BuildXmlDom(StringPrintf(xml, codename, codename));
+ targetSdkVersion="Q"
+ maxSdkVersion="Q">
+ </android-sdk>)xml");
PostProcessingConfiguration config;
- bool ok = AndroidSdkTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
- ASSERT_TRUE(ok);
-
+ ASSERT_TRUE(AndroidSdkTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_));
ASSERT_EQ(1ul, config.android_sdks.size());
- ASSERT_EQ(1u, config.android_sdks.count("P"));
-
- auto& out = config.android_sdks["P"];
+ ASSERT_EQ(1u, config.android_sdks.count("Q"));
AndroidSdk sdk;
sdk.min_sdk_version = 25;
- sdk.target_sdk_version = version;
- sdk.max_sdk_version = version;
-
- ASSERT_EQ(sdk, out);
+ sdk.target_sdk_version = 10000;
+ sdk.max_sdk_version = 10000;
+ ASSERT_EQ(sdk, config.android_sdks["Q"]);
}
TEST_F(ConfigurationParserTest, GlTextureGroupAction) {