Merge "Add NATT keepalive resources and methods into IpSecService"
diff --git a/Android.bp b/Android.bp
index ec8636d..57f6513 100644
--- a/Android.bp
+++ b/Android.bp
@@ -687,6 +687,7 @@
static_libs: [
"apex_aidl_interface-java",
"framework-protos",
+ "game-driver-protos",
"android.hidl.base-V1.0-java",
"android.hardware.cas-V1.0-java",
"android.hardware.contexthub-V1.0-java",
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/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 564e918..1ac6ea8 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -134,7 +134,7 @@
LowMemReported low_mem_reported = 81;
ThermalThrottlingStateChanged thermal_throttling = 86;
NetworkDnsEventReported network_dns_event_reported = 116;
- DataStallEvent data_stall_event = 121;
+ DataStallEvent data_stall_event = 121 [(log_from_module) = "network_stack"];
BluetoothLinkLayerConnectionEvent bluetooth_link_layer_connection_event = 125;
BluetoothAclConnectionStateChanged bluetooth_acl_connection_state_changed = 126;
BluetoothScoConnectionStateChanged bluetooth_sco_connection_state_changed = 127;
@@ -165,7 +165,7 @@
BluetoothSmpPairingEventReported bluetooth_smp_pairing_event_reported = 167;
ProcessStartTime process_start_time = 169;
BluetoothSocketConnectionStateChanged bluetooth_socket_connection_state_changed = 171;
- NetworkStackReported network_stack_reported = 182;
+ NetworkStackReported network_stack_reported = 182 [(log_from_module) = "network_stack"];
}
// Pulled events will start at field 10000.
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index f453289..d9c82ea 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1003,9 +1003,8 @@
}
public void updateHttpProxy() {
- final ConnectivityManager cm = ConnectivityManager.from(
+ ActivityThread.updateHttpProxy(
getApplication() != null ? getApplication() : getSystemContext());
- Proxy.setHttpProxySystemProperty(cm.getDefaultProxy());
}
public void processInBackground() {
@@ -6690,6 +6689,11 @@
return thread;
}
+ public static void updateHttpProxy(@NonNull Context context) {
+ final ConnectivityManager cm = ConnectivityManager.from(context);
+ Proxy.setHttpProxySystemProperty(cm.getDefaultProxy());
+ }
+
@UnsupportedAppUsage
public final void installSystemProviders(List<ProviderInfo> providers) {
if (providers != null) {
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/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 606c8f3..1aaee18 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -28,11 +28,11 @@
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;
/** @hide */
public class GraphicsEnvironment {
@@ -49,7 +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 GUP_WHITELIST_FILENAME = "whitelist.txt";
+ private static final String GAME_DRIVER_WHITELIST_ALL = "*";
private ClassLoader mClassLoader;
private String mLayerPath;
@@ -98,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())
@@ -136,37 +136,29 @@
setLayerPaths(mClassLoader, layerPaths);
}
+ private static List<String> getGlobalSettingsString(Bundle bundle, String globalSetting) {
+ List<String> valueList = null;
+ final String settingsValue = bundle.getString(globalSetting);
+
+ if (settingsValue != null) {
+ valueList = new ArrayList<>(Arrays.asList(settingsValue.split(",")));
+ } else {
+ valueList = new ArrayList<>();
+ }
+
+ return valueList;
+ }
+
/**
* 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;
}
- // 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();
- if (ai.isPrivilegedApp() || (ai.isSystemApp() && !ai.isUpdatedSystemApp())) {
- if (DEBUG) Log.v(TAG, "ignoring driver package for privileged/non-updated system app");
- return;
- }
-
- String applicationPackageName = context.getPackageName();
- String devOptInApplicationName = coreSettings.getString(
- Settings.Global.GUP_DEV_OPT_IN_APPS);
- boolean devOptIn = applicationPackageName.equals(devOptInApplicationName);
- boolean whitelisted = onWhitelist(context, driverPackageName, ai.packageName);
- if (!devOptIn && !whitelisted) {
- if (DEBUG) {
- Log.w(TAG, applicationPackageName + " is not on the whitelist.");
- }
- return;
- }
-
- ApplicationInfo driverInfo;
+ final ApplicationInfo driverInfo;
try {
driverInfo = context.getPackageManager().getApplicationInfo(driverPackageName,
PackageManager.MATCH_SYSTEM_ONLY);
@@ -184,7 +176,59 @@
return;
}
- String abi = chooseAbi(driverInfo);
+ // 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.
+ 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;
+ }
+
+ // GAME_DRIVER_ALL_APPS
+ // 0: Default (Invalid values fallback to default as well)
+ // 1: All apps use Game Driver
+ // 2: All apps use system graphics driver
+ 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");
+ }
+ return;
+ }
+
+ if (gameDriverAllApps != 1) {
+ // GAME_DRIVER_OPT_OUT_APPS has higher priority than GAME_DRIVER_OPT_IN_APPS
+ if (getGlobalSettingsString(coreSettings, Settings.Global.GAME_DRIVER_OPT_OUT_APPS)
+ .contains(ai.packageName)) {
+ if (DEBUG) {
+ Log.w(TAG, ai.packageName + " opts out from Game Driver.");
+ }
+ return;
+ }
+ final boolean isOptIn =
+ getGlobalSettingsString(coreSettings, Settings.Global.GAME_DRIVER_OPT_IN_APPS)
+ .contains(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 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;
+ }
+ }
+
+ 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
@@ -195,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);
}
/**
@@ -218,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);
},
@@ -227,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;
@@ -239,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(GUP_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/CallLog.java b/core/java/android/provider/CallLog.java
index ef28f07..0827fd6 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -967,6 +967,23 @@
// spam the call log with its own entries, causing entries from Telephony to be
// removed.
final Uri result = resolver.insert(uri, values);
+ if (result != null) {
+ String lastPathSegment = result.getLastPathSegment();
+ // When inserting into the call log, if ContentProvider#insert detect an appops
+ // denial a non-null "silent rejection" URI is returned which ends in 0.
+ // Example: content://call_log/calls/0
+ // The 0 in the last part of the path indicates a fake call id of 0.
+ // A denial when logging calls from the platform is bad; there is no other
+ // logging to indicate that this has happened so we will check for that scenario
+ // here and log a warning so we have a hint as to what is going on.
+ if (lastPathSegment != null && lastPathSegment.equals("0")) {
+ Log.w(LOG_TAG, "Failed to insert into call log due to appops denial;"
+ + " resultUri=" + result);
+ }
+ } else {
+ Log.w(LOG_TAG, "Failed to insert into call log; null result uri.");
+ }
+
if (values.containsKey(PHONE_ACCOUNT_ID)
&& !TextUtils.isEmpty(values.getAsString(PHONE_ACCOUNT_ID))
&& values.containsKey(PHONE_ACCOUNT_COMPONENT_NAME)
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index bf33e06..f98641d 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -11446,16 +11446,55 @@
public static final String GPU_DEBUG_APP = "gpu_debug_app";
/**
- * Apps that are selected to use Game Update Package.
+ * Game Driver global preference for all Apps.
+ * 0 = Default
+ * 1 = All Apps use Game Driver
+ * 2 = All Apps use system graphics driver
* @hide
*/
- public static final String GUP_DEV_OPT_IN_APPS = "gup_dev_opt_in_apps";
+ public static final String GAME_DRIVER_ALL_APPS = "game_driver_all_apps";
/**
- * Apps on the black list that are forbidden to useGame Update Package.
+ * List of Apps selected to use Game Driver.
+ * i.e. <pkg1>,<pkg2>,...,<pkgN>
* @hide
*/
- public static final String GUP_BLACK_LIST = "gup_black_list";
+ public static final String GAME_DRIVER_OPT_IN_APPS = "game_driver_opt_in_apps";
+
+ /**
+ * List of Apps selected not to use Game Driver.
+ * i.e. <pkg1>,<pkg2>,...,<pkgN>
+ * @hide
+ */
+ public static final String GAME_DRIVER_OPT_OUT_APPS = "game_driver_opt_out_apps";
+
+ /**
+ * Apps on the blacklist that are forbidden to use Game Driver.
+ * @hide
+ */
+ 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>
+ * @hide
+ */
+ 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
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 7c9176a..a44ec9a 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -384,11 +384,26 @@
// App allowed to load GPU debug layers.
optional SettingProto debug_app = 1;
optional SettingProto debug_layers = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // Apps opt in to load graphics driver from Game Update Package
- // instead of native graphcis driver through developer options.
- optional SettingProto gup_dev_opt_in_apps = 8;
- // Apps on the black list that are forbidden to useGame Update Package.
- optional SettingProto gup_black_list = 9;
+ // Game Driver - global preference for all Apps
+ // 0 = Default
+ // 1 = All Apps use Game Driver
+ // 2 = All Apps use system graphics driver
+ optional SettingProto game_driver_all_apps = 8;
+ // Game Driver - List of Apps selected to use Game Driver
+ // i.e. <pkg1>,<pkg2>,...,<pkgN>
+ optional SettingProto game_driver_opt_in_apps = 9;
+ // Game Driver - List of Apps selected not to use Game Driver
+ // i.e. <pkg1>,<pkg2>,...,<pkgN>
+ optional SettingProto game_driver_opt_out_apps = 10;
+ // Game Driver - List of Apps that are forbidden to use Game Driver
+ 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 7b72928..76356ed 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -444,8 +444,13 @@
Settings.Global.ENABLE_GPU_DEBUG_LAYERS,
Settings.Global.GPU_DEBUG_APP,
Settings.Global.GPU_DEBUG_LAYERS,
- Settings.Global.GUP_DEV_OPT_IN_APPS,
- Settings.Global.GUP_BLACK_LIST,
+ 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/graphics/proto/Android.bp b/graphics/proto/Android.bp
new file mode 100644
index 0000000..1d06348
--- /dev/null
+++ b/graphics/proto/Android.bp
@@ -0,0 +1,11 @@
+java_library_static {
+ name: "game-driver-protos",
+ host_supported: true,
+ proto: {
+ type: "lite",
+ },
+ srcs: ["game_driver.proto"],
+ no_framework_libs: true,
+ jarjar_rules: "jarjar-rules.txt",
+ sdk_version: "28",
+}
diff --git a/graphics/proto/game_driver.proto b/graphics/proto/game_driver.proto
new file mode 100644
index 0000000..fd7ffcc
--- /dev/null
+++ b/graphics/proto/game_driver.proto
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+syntax = "proto2";
+
+package android.gamedriver;
+
+option java_package = "android.gamedriver";
+option java_outer_classname = "GameDriverProto";
+
+message Blacklist {
+ optional int64 version_code = 1;
+ repeated string package_names = 2;
+}
+
+message Blacklists {
+ repeated Blacklist blacklists = 1;
+}
diff --git a/graphics/proto/jarjar-rules.txt b/graphics/proto/jarjar-rules.txt
new file mode 100644
index 0000000..4e40637
--- /dev/null
+++ b/graphics/proto/jarjar-rules.txt
@@ -0,0 +1 @@
+rule com.google.protobuf.** com.android.framework.protobuf.@1
diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp
index 5817118..e0bb862 100644
--- a/packages/NetworkStack/Android.bp
+++ b/packages/NetworkStack/Android.bp
@@ -37,6 +37,7 @@
"src/**/*.java",
":framework-networkstack-shared-srcs",
":services-networkstack-shared-srcs",
+ ":statslog-networkstack-java-gen",
],
static_libs: [
"androidx.annotation_annotation",
@@ -104,3 +105,11 @@
certificate: "networkstack",
manifest: "AndroidManifest.xml",
}
+
+genrule {
+ name: "statslog-networkstack-java-gen",
+ tools: ["stats-log-api-gen"],
+ cmd: "$(location stats-log-api-gen) --java $(out) --module network_stack" +
+ " --javaPackage com.android.networkstack.metrics --javaClass NetworkStackStatsLog",
+ out: ["com/android/networkstack/metrics/NetworkStackStatsLog.java"],
+}
diff --git a/packages/NetworkStack/src/android/net/metrics/DataStallDetectionStats.java b/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallDetectionStats.java
similarity index 99%
rename from packages/NetworkStack/src/android/net/metrics/DataStallDetectionStats.java
rename to packages/NetworkStack/src/com/android/networkstack/metrics/DataStallDetectionStats.java
index 225dc0f..2523ecd 100644
--- a/packages/NetworkStack/src/android/net/metrics/DataStallDetectionStats.java
+++ b/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallDetectionStats.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.net.metrics;
+package com.android.networkstack.metrics;
import android.annotation.NonNull;
import android.annotation.Nullable;
diff --git a/packages/NetworkStack/src/android/net/metrics/DataStallStatsUtils.java b/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallStatsUtils.java
similarity index 87%
rename from packages/NetworkStack/src/android/net/metrics/DataStallStatsUtils.java
rename to packages/NetworkStack/src/com/android/networkstack/metrics/DataStallStatsUtils.java
index c96411e..9308901 100644
--- a/packages/NetworkStack/src/android/net/metrics/DataStallStatsUtils.java
+++ b/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallStatsUtils.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.net.metrics;
+package com.android.networkstack.metrics;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -41,7 +41,6 @@
private static int probeResultToEnum(@Nullable final CaptivePortalProbeResult result) {
if (result == null) return DataStallEventProto.INVALID;
- // TODO: Add partial connectivity support.
if (result.isSuccessful()) {
return DataStallEventProto.VALID;
} else if (result.isPortal()) {
@@ -63,6 +62,12 @@
Log.d(TAG, "write: " + stats + " with result: " + validationResult
+ ", dns: " + HexDump.toHexString(stats.mDns));
}
- // TODO(b/124613085): Send to Statsd once the public StatsLog API is ready.
+ NetworkStackStatsLog.write(NetworkStackStatsLog.DATA_STALL_EVENT,
+ stats.mEvaluationType,
+ validationResult,
+ stats.mNetworkType,
+ stats.mWifiInfo,
+ stats.mCellularInfo,
+ stats.mDns);
}
}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
index d88e3dc..093235e 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
@@ -69,8 +69,6 @@
import android.net.Uri;
import android.net.captiveportal.CaptivePortalProbeResult;
import android.net.captiveportal.CaptivePortalProbeSpec;
-import android.net.metrics.DataStallDetectionStats;
-import android.net.metrics.DataStallStatsUtils;
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.NetworkEvent;
import android.net.metrics.ValidationProbeEvent;
@@ -106,6 +104,8 @@
import com.android.internal.util.StateMachine;
import com.android.internal.util.TrafficStatsConstants;
import com.android.networkstack.R;
+import com.android.networkstack.metrics.DataStallDetectionStats;
+import com.android.networkstack.metrics.DataStallStatsUtils;
import java.io.IOException;
import java.net.HttpURLConnection;
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..bee4bbd9 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 {
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 7d9eb9b..594f2ca 100644
--- a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -62,8 +62,6 @@
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.captiveportal.CaptivePortalProbeResult;
-import android.net.metrics.DataStallDetectionStats;
-import android.net.metrics.DataStallStatsUtils;
import android.net.metrics.IpConnectivityLog;
import android.net.util.SharedLog;
import android.net.wifi.WifiInfo;
@@ -81,6 +79,9 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.networkstack.metrics.DataStallDetectionStats;
+import com.android.networkstack.metrics.DataStallStatsUtils;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
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..a00eff7 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;
@@ -163,9 +163,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)
@@ -182,17 +182,17 @@
}
/** 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));
}
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 2c4abae..d5b1217 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1131,7 +1131,4 @@
<!-- The notice header of Third-party licenses. not translatable -->
<string name="notice_header" translatable="false"></string>
-
- <!-- UI debug setting: opt in to use updated graphics driver? [CHAR LIMIT=100] -->
- <string name="gup_dev_opt_in_app_summary">Opt in app to use Game Update Package in developement</string>
</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 759b51c..c60e352 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -648,11 +648,26 @@
Settings.Global.GPU_DEBUG_LAYERS,
GlobalSettingsProto.Gpu.DEBUG_LAYERS);
dumpSetting(s, p,
- Settings.Global.GUP_DEV_OPT_IN_APPS,
- GlobalSettingsProto.Gpu.GUP_DEV_OPT_IN_APPS);
+ Settings.Global.GAME_DRIVER_ALL_APPS,
+ GlobalSettingsProto.Gpu.GAME_DRIVER_ALL_APPS);
dumpSetting(s, p,
- Settings.Global.GUP_BLACK_LIST,
- GlobalSettingsProto.Gpu.GUP_BLACK_LIST);
+ Settings.Global.GAME_DRIVER_OPT_IN_APPS,
+ GlobalSettingsProto.Gpu.GAME_DRIVER_OPT_IN_APPS);
+ dumpSetting(s, p,
+ Settings.Global.GAME_DRIVER_OPT_OUT_APPS,
+ GlobalSettingsProto.Gpu.GAME_DRIVER_OPT_OUT_APPS);
+ dumpSetting(s, p,
+ Settings.Global.GAME_DRIVER_BLACKLIST,
+ GlobalSettingsProto.Gpu.GAME_DRIVER_BLACKLIST);
+ 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/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index d79d833..6902a70 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -6492,6 +6492,11 @@
// OS: Q
ACTION_EMERGENCY_DIALER_FROM_POWER_MENU = 1569;
+ // OPEN: Settings > Developer Options > Game Driver Preference
+ // CATEGORY: SETTINGS
+ // OS: Q
+ SETTINGS_GAME_DRIVER_DASHBOARD = 1613;
+
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index c1aff75..244fef4 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -634,7 +634,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 +661,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 +715,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);
}
}
@@ -737,15 +740,15 @@
if (wasFirstNetwork || wasDefault) {
maybeLogBroadcast(nai, state, type, wasDefault);
- sendLegacyNetworkBroadcast(nai, state, type);
+ mService.sendLegacyNetworkBroadcast(nai, state, 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, state, type, mService.isDefaultNetwork(replacement));
+ mService.sendLegacyNetworkBroadcast(replacement, state, 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
@@ -5371,7 +5374,8 @@
}
}
- private boolean isDefaultNetwork(NetworkAgentInfo nai) {
+ @VisibleForTesting
+ protected boolean isDefaultNetwork(NetworkAgentInfo nai) {
return nai == getDefaultNetwork();
}
@@ -6671,7 +6675,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
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/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e18f374..5ebd173 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -318,7 +318,6 @@
import android.media.audiofx.AudioEffect;
import android.metrics.LogMaker;
import android.net.Proxy;
-import android.net.ProxyInfo;
import android.net.Uri;
import android.os.BatteryStats;
import android.os.Binder;
@@ -2252,21 +2251,25 @@
}
} break;
case UPDATE_HTTP_PROXY_MSG: {
+ // Update the HTTP proxy for each application thread.
synchronized (ActivityManagerService.this) {
for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
ProcessRecord r = mLruProcesses.get(i);
// Don't dispatch to isolated processes as they can't access
- // ConnectivityManager and don't have network privileges anyway.
- if (r.thread != null && !r.isolated) {
+ // ConnectivityManager and don't have network privileges anyway. Exclude
+ // system server and update it separately outside the AMS lock, to avoid
+ // deadlock with Connectivity Service.
+ if (r.pid != MY_PID && r.thread != null && !r.isolated) {
try {
r.thread.updateHttpProxy();
} catch (RemoteException ex) {
- Slog.w(TAG, "Failed to update http proxy for: " +
- r.info.processName);
+ Slog.w(TAG, "Failed to update http proxy for: "
+ + r.info.processName);
}
}
}
}
+ ActivityThread.updateHttpProxy(mContext);
} break;
case PROC_START_TIMEOUT_MSG: {
ProcessRecord app = (ProcessRecord)msg.obj;
@@ -2607,7 +2610,7 @@
} break;
}
}
- };
+ }
static final int COLLECT_PSS_BG_MSG = 1;
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index 63300a1..9ff47e0 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -55,8 +55,13 @@
// add other system settings here...
sGlobalSettingToTypeMap.put(Settings.Global.DEBUG_VIEW_ATTRIBUTES, int.class);
- sGlobalSettingToTypeMap.put(Settings.Global.GUP_DEV_OPT_IN_APPS, String.class);
- sGlobalSettingToTypeMap.put(Settings.Global.GUP_BLACK_LIST, String.class);
+ sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_ALL_APPS, int.class);
+ sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_OPT_IN_APPS, String.class);
+ 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/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..f73a285 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -59,6 +59,7 @@
srcs: ["java/**/*.java"],
static_libs: [
"dnsresolver_aidl_interface-java",
+ "ipmemorystore-client",
"netd_aidl_interface-java",
"networkstack-aidl-interfaces-java",
]
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/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/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..22978a2
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java
@@ -0,0 +1,45 @@
+/*
+ * 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);
+ }
+ }
+ };
+ }
+}
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..9e7c1c8
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java
@@ -0,0 +1,45 @@
+/*
+ * 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);
+ }
+ }
+ };
+ }
+}
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..59da268
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.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;
+
+/**
+ * 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));
+ }
+ }
+ };
+ }
+}
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..0154fd2
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java
@@ -0,0 +1,48 @@
+/*
+ * 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));
+ }
+ }
+ };
+ }
+}
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..824b7b0
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnStatusListener.java
@@ -0,0 +1,44 @@
+/*
+ * 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));
+ }
+ }
+ };
+ }
+}
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/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 586c815..58c05aa 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -294,6 +294,19 @@
public static final String SUBSCRIPTION_TYPE = "subscription_type";
/**
+ * TelephonyProvider column name white_listed_apn_data.
+ * It's a bitmask of APN types that will be allowed on this subscription even if it's metered
+ * and mobile data is turned off by the user.
+ * <P>Type: INTEGER (int)</P> For example, if TYPE_MMS is is true, Telephony will allow MMS
+ * data connection to setup even if MMS is metered and mobile_data is turned off on that
+ * subscription.
+ *
+ * Default value is 0.
+ */
+ /** @hide */
+ public static final String WHITE_LISTED_APN_DATA = "white_listed_apn_data";
+
+ /**
* This constant is to designate a subscription as a Local-SIM Subscription.
* <p> A Local-SIM can be a physical SIM inserted into a sim-slot in the device, or eSIM on the
* device.
@@ -3087,6 +3100,31 @@
return subId;
}
+ /**
+ * Set whether a subscription always allows MMS connection. If true, MMS network
+ * request will be accepted by telephony even if user turns "mobile data" off
+ * on this subscription.
+ *
+ * @param subId which subscription it's setting to.
+ * @param alwaysAllow whether Mms data is always allowed.
+ * @return whether operation is successful.
+ *
+ * @hide
+ */
+ public boolean setAlwaysAllowMmsData(int subId, boolean alwaysAllow) {
+ try {
+ ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+ if (iSub != null) {
+ return iSub.setAlwaysAllowMmsData(subId, alwaysAllow);
+ }
+ } catch (RemoteException ex) {
+ if (!isSystemProcess()) {
+ ex.rethrowAsRuntimeException();
+ }
+ }
+ return false;
+ }
+
private interface CallISubMethodHelper {
int callMethod(ISub iSub) throws RemoteException;
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index e1425b9..82cc1df 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -64,6 +64,7 @@
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telephony.VisualVoicemailService.VisualVoicemailTask;
+import android.telephony.data.ApnSetting;
import android.telephony.emergency.EmergencyNumber;
import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
import android.telephony.ims.aidl.IImsConfig;
@@ -10888,4 +10889,58 @@
}
return new Pair<Integer, Integer>(-1, -1);
}
+
+ /**
+ * Return whether data is enabled for certain APN type. This will tell if framework will accept
+ * corresponding network requests on a subId.
+ *
+ * {@link #isDataEnabled()} is directly associated with users' Mobile data toggle on / off. If
+ * {@link #isDataEnabled()} returns false, it means in general all meter-ed data are disabled.
+ *
+ * This per APN type API gives a better idea whether data is allowed on a specific APN type.
+ * It will return true if:
+ *
+ * 1) User data is turned on, or
+ * 2) APN is un-metered for this subscription, or
+ * 3) APN type is whitelisted. E.g. MMS is whitelisted if
+ * {@link SubscriptionManager#setAlwaysAllowMmsData} is turned on.
+ *
+ * @return whether data is enabled for a apn type.
+ *
+ * @hide
+ */
+ public boolean isDataEnabledForApn(@ApnSetting.ApnType int apnType) {
+ String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ return service.isDataEnabledForApn(apnType, getSubId(), pkgForDebug);
+ }
+ } catch (RemoteException ex) {
+ if (!isSystemProcess()) {
+ ex.rethrowAsRuntimeException();
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Whether an APN type is metered or not. It will be evaluated with the subId associated
+ * with the TelephonyManager instance.
+ *
+ * @hide
+ */
+ public boolean isApnMetered(@ApnSetting.ApnType int apnType) {
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ return service.isApnMetered(apnType, getSubId());
+ }
+ } catch (RemoteException ex) {
+ if (!isSystemProcess()) {
+ ex.rethrowAsRuntimeException();
+ }
+ }
+ return true;
+ }
}
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/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index 6e8d038..bb5c251 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -94,6 +94,7 @@
public static final int EVENT_ROAMING_SETTING_CHANGE = BASE + 48;
public static final int EVENT_DATA_SERVICE_BINDING_CHANGED = BASE + 49;
public static final int EVENT_DEVICE_PROVISIONED_CHANGE = BASE + 50;
+ public static final int EVENT_APN_WHITE_LIST_CHANGE = BASE + 51;
/***** Constants *****/
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index 118f5e2..f248893 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -283,4 +283,6 @@
int getSimStateForSlotIndex(int slotIndex);
boolean isActiveSubId(int subId, String callingPackage);
+
+ boolean setAlwaysAllowMmsData(int subId, boolean alwaysAllow);
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d173cc9..0ad6096 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1958,4 +1958,8 @@
int getRadioHalVersion();
boolean isModemEnabledForSlot(int slotIndex, String callingPackage);
+
+ boolean isDataEnabledForApn(int apnType, int subId, String callingPackage);
+
+ boolean isApnMetered(int apnType, int subId);
}
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..9ee5858 100644
--- a/tests/net/common/Android.bp
+++ b/tests/net/common/Android.bp
@@ -21,6 +21,7 @@
srcs: ["java/**/*.java"],
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 100%
rename from tests/net/java/android/net/LinkPropertiesTest.java
rename to tests/net/common/java/android/net/LinkPropertiesTest.java
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 96%
rename from tests/net/java/android/net/apf/ApfCapabilitiesTest.java
rename to tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
index 75752c3..7238895 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;
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/LegacyTypeTrackerTest.kt b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt
new file mode 100644
index 0000000..d983b65
--- /dev/null
+++ b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt
@@ -0,0 +1,92 @@
+/*
+ * 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 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.Mockito.doReturn
+import org.mockito.Mockito.mock
+
+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))
+ }
+}
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 96%
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..75329a8 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);
}
/**
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) {
diff --git a/tools/locked_region_code_injection/src/lockedregioncodeinjection/Main.java b/tools/locked_region_code_injection/src/lockedregioncodeinjection/Main.java
index edb9a49..828cce7 100644
--- a/tools/locked_region_code_injection/src/lockedregioncodeinjection/Main.java
+++ b/tools/locked_region_code_injection/src/lockedregioncodeinjection/Main.java
@@ -13,6 +13,9 @@
*/
package lockedregioncodeinjection;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -24,8 +27,6 @@
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassWriter;
public class Main {
public static void main(String[] args) throws IOException {
@@ -74,6 +75,7 @@
while (srcEntries.hasMoreElements()) {
ZipEntry entry = srcEntries.nextElement();
ZipEntry newEntry = new ZipEntry(entry.getName());
+ newEntry.setTime(entry.getTime());
zos.putNextEntry(newEntry);
BufferedInputStream bis = new BufferedInputStream(zipSrc.getInputStream(entry));
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
index 49eee07..dc18b8d 100644
--- a/tools/stats_log_api_gen/Collation.cpp
+++ b/tools/stats_log_api_gen/Collation.cpp
@@ -219,6 +219,14 @@
errorCount++;
continue;
}
+
+ // Doubles are not supported yet.
+ if (javaType == JAVA_TYPE_DOUBLE) {
+ print_error(field, "Doubles are not supported in atoms. Please change field %s to float\n",
+ field->name().c_str());
+ errorCount++;
+ continue;
+ }
}
// Check that if there's an attribution chain, it's at position 1.
diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h
index e0ea2077..8e4cb9f 100644
--- a/tools/stats_log_api_gen/Collation.h
+++ b/tools/stats_log_api_gen/Collation.h
@@ -48,6 +48,7 @@
JAVA_TYPE_DOUBLE = 6,
JAVA_TYPE_STRING = 7,
JAVA_TYPE_ENUM = 8,
+ JAVA_TYPE_KEY_VALUE_PAIR = 9,
JAVA_TYPE_OBJECT = -1,
JAVA_TYPE_BYTE_ARRAY = -2,
@@ -118,4 +119,4 @@
} // namespace android
-#endif // ANDROID_STATS_LOG_API_GEN_COLLATION_H
\ No newline at end of file
+#endif // ANDROID_STATS_LOG_API_GEN_COLLATION_H
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index 2d9b988..43b79cc 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -27,6 +27,11 @@
const string DEFAULT_MODULE_NAME = "DEFAULT";
const string DEFAULT_CPP_NAMESPACE = "android,util";
const string DEFAULT_CPP_HEADER_IMPORT = "statslog.h";
+const string DEFAULT_JAVA_PACKAGE = "android.util";
+const string DEFAULT_JAVA_CLASS = "StatsLogInternal";
+
+const int JAVA_MODULE_REQUIRES_FLOAT = 0x01;
+const int JAVA_MODULE_REQUIRES_ATTRIBUTION = 0x02;
using android::os::statsd::Atom;
@@ -807,11 +812,350 @@
}
}
+static void write_java_helpers_for_module(
+ FILE * out,
+ const AtomDecl &attributionDecl,
+ const int requiredHelpers) {
+ fprintf(out, " private static void copyInt(byte[] buff, int pos, int val) {\n");
+ fprintf(out, " buff[pos] = (byte) (val);\n");
+ fprintf(out, " buff[pos + 1] = (byte) (val >> 8);\n");
+ fprintf(out, " buff[pos + 2] = (byte) (val >> 16);\n");
+ fprintf(out, " buff[pos + 3] = (byte) (val >> 24);\n");
+ fprintf(out, " return;\n");
+ fprintf(out, " }\n");
+ fprintf(out, "\n");
+
+ fprintf(out, " private static void copyLong(byte[] buff, int pos, long val) {\n");
+ fprintf(out, " buff[pos] = (byte) (val);\n");
+ fprintf(out, " buff[pos + 1] = (byte) (val >> 8);\n");
+ fprintf(out, " buff[pos + 2] = (byte) (val >> 16);\n");
+ fprintf(out, " buff[pos + 3] = (byte) (val >> 24);\n");
+ fprintf(out, " buff[pos + 4] = (byte) (val >> 32);\n");
+ fprintf(out, " buff[pos + 5] = (byte) (val >> 40);\n");
+ fprintf(out, " buff[pos + 6] = (byte) (val >> 48);\n");
+ fprintf(out, " buff[pos + 7] = (byte) (val >> 56);\n");
+ fprintf(out, " return;\n");
+ fprintf(out, " }\n");
+ fprintf(out, "\n");
+
+ if (requiredHelpers & JAVA_MODULE_REQUIRES_FLOAT) {
+ fprintf(out, " private static void copyFloat(byte[] buff, int pos, float val) {\n");
+ fprintf(out, " copyInt(buff, pos, Float.floatToIntBits(val));\n");
+ fprintf(out, " return;\n");
+ fprintf(out, " }\n");
+ fprintf(out, "\n");
+ }
+
+ if (requiredHelpers & JAVA_MODULE_REQUIRES_ATTRIBUTION) {
+ fprintf(out, " private static void writeAttributionChain(byte[] buff, int pos");
+ for (auto chainField : attributionDecl.fields) {
+ fprintf(out, ", %s[] %s",
+ java_type_name(chainField.javaType), chainField.name.c_str());
+ }
+ fprintf(out, ") {\n");
+
+ const char* uidName = attributionDecl.fields.front().name.c_str();
+ const char* tagName = attributionDecl.fields.back().name.c_str();
+
+ // Write the first list begin.
+ fprintf(out, " buff[pos] = LIST_TYPE;\n");
+ fprintf(out, " buff[pos + 1] = (byte) (%s.length);\n", tagName);
+ fprintf(out, " pos += LIST_TYPE_OVERHEAD;\n");
+
+ // Iterate through the attribution chain and write the nodes.
+ fprintf(out, " for (int i = 0; i < %s.length; i++) {\n", tagName);
+ // Write the list begin.
+ fprintf(out, " buff[pos] = LIST_TYPE;\n");
+ fprintf(out, " buff[pos + 1] = %lu;\n", attributionDecl.fields.size());
+ fprintf(out, " pos += LIST_TYPE_OVERHEAD;\n");
+
+ // Write the uid.
+ fprintf(out, " buff[pos] = INT_TYPE;\n");
+ fprintf(out, " copyInt(buff, pos + 1, %s[i]);\n", uidName);
+ fprintf(out, " pos += INT_TYPE_SIZE;\n");
+
+ // Write the tag.
+ fprintf(out, " String %sStr = (%s[i] == null) ? \"\" : %s[i];\n",
+ tagName, tagName, tagName);
+ fprintf(out, " byte[] %sByte = %sStr.getBytes(UTF_8);\n", tagName, tagName);
+ fprintf(out, " buff[pos] = STRING_TYPE;\n");
+ fprintf(out, " copyInt(buff, pos + 1, %sByte.length);\n", tagName);
+ fprintf(out, " System.arraycopy("
+ "%sByte, 0, buff, pos + STRING_TYPE_OVERHEAD, %sByte.length);\n",
+ tagName, tagName);
+ fprintf(out, " pos += STRING_TYPE_OVERHEAD + %sByte.length;\n", tagName);
+ fprintf(out, " }\n");
+ fprintf(out, " }\n");
+ fprintf(out, "\n");
+ }
+}
+
+
+static int write_java_non_chained_method_for_module(
+ FILE* out,
+ const map<vector<java_type_t>, set<string>>& signatures_to_modules,
+ const string& moduleName
+ ) {
+ for (auto signature_to_modules_it = signatures_to_modules.begin();
+ signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
+ // Skip if this signature is not needed for the module.
+ if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
+ continue;
+ }
+
+ // Print method signature.
+ vector<java_type_t> signature = signature_to_modules_it->first;
+ fprintf(out, " public static void write_non_chained(int code");
+ int argIndex = 1;
+ for (vector<java_type_t>::const_iterator arg = signature.begin();
+ arg != signature.end(); arg++) {
+ if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
+ // Non chained signatures should not have attribution chains.
+ return 1;
+ } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
+ // Module logging does not yet support key value pair.
+ return 1;
+ } else {
+ fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
+ }
+ argIndex++;
+ }
+ fprintf(out, ") {\n");
+
+ fprintf(out, " write(code");
+ argIndex = 1;
+ for (vector<java_type_t>::const_iterator arg = signature.begin();
+ arg != signature.end(); arg++) {
+ // First two args are uid and tag of attribution chain.
+ if (argIndex == 1) {
+ fprintf(out, ", new int[] {arg%d}", argIndex);
+ } else if (argIndex == 2) {
+ fprintf(out, ", new java.lang.String[] {arg%d}", argIndex);
+ } else {
+ fprintf(out, ", arg%d", argIndex);
+ }
+ argIndex++;
+ }
+ fprintf(out, ");\n");
+ fprintf(out, " }\n");
+ fprintf(out, "\n");
+ }
+ return 0;
+}
+
+static int write_java_method_for_module(
+ FILE* out,
+ const map<vector<java_type_t>, set<string>>& signatures_to_modules,
+ const AtomDecl &attributionDecl,
+ const string& moduleName,
+ int* requiredHelpers
+ ) {
+
+ for (auto signature_to_modules_it = signatures_to_modules.begin();
+ signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
+ // Skip if this signature is not needed for the module.
+ if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
+ continue;
+ }
+
+ // Print method signature.
+ vector<java_type_t> signature = signature_to_modules_it->first;
+ fprintf(out, " public static void write(int code");
+ int argIndex = 1;
+ for (vector<java_type_t>::const_iterator arg = signature.begin();
+ arg != signature.end(); arg++) {
+ if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
+ for (auto chainField : attributionDecl.fields) {
+ fprintf(out, ", %s[] %s",
+ java_type_name(chainField.javaType), chainField.name.c_str());
+ }
+ } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
+ // Module logging does not yet support key value pair.
+ return 1;
+ } else {
+ fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
+ }
+ argIndex++;
+ }
+ fprintf(out, ") {\n");
+
+ // Calculate the size of the buffer.
+ fprintf(out, " // Initial overhead of the list, timestamp, and atom tag.\n");
+ fprintf(out, " int needed = LIST_TYPE_OVERHEAD + LONG_TYPE_SIZE + INT_TYPE_SIZE;\n");
+ argIndex = 1;
+ for (vector<java_type_t>::const_iterator arg = signature.begin();
+ arg != signature.end(); arg++) {
+ switch (*arg) {
+ case JAVA_TYPE_BOOLEAN:
+ case JAVA_TYPE_INT:
+ case JAVA_TYPE_FLOAT:
+ case JAVA_TYPE_ENUM:
+ fprintf(out, " needed += INT_TYPE_SIZE;\n");
+ break;
+ case JAVA_TYPE_LONG:
+ // Longs take 9 bytes, 1 for the type and 8 for the value.
+ fprintf(out, " needed += LONG_TYPE_SIZE;\n");
+ break;
+ case JAVA_TYPE_STRING:
+ // Strings take 5 metadata bytes + length of byte encoded string.
+ fprintf(out, " if (arg%d == null) {\n", argIndex);
+ fprintf(out, " arg%d = \"\";\n", argIndex);
+ fprintf(out, " }\n");
+ fprintf(out, " byte[] arg%dBytes= arg%d.getBytes(UTF_8);\n",
+ argIndex, argIndex);
+ fprintf(out, " needed += STRING_TYPE_OVERHEAD + arg%dBytes.length;\n",
+ argIndex);
+ break;
+ case JAVA_TYPE_BYTE_ARRAY:
+ // Byte arrays take 5 metadata bytes + length of byte array.
+ fprintf(out, " if (arg%d == null) {\n", argIndex);
+ fprintf(out, " arg%d = new byte[0];\n", argIndex);
+ fprintf(out, " }\n");
+ fprintf(out, " needed += STRING_TYPE_OVERHEAD + arg%d.length;\n", argIndex);
+ break;
+ case JAVA_TYPE_ATTRIBUTION_CHAIN:
+ {
+ const char* uidName = attributionDecl.fields.front().name.c_str();
+ const char* tagName = attributionDecl.fields.back().name.c_str();
+ // Null checks on the params.
+ fprintf(out, " if (%s == null) {\n", uidName);
+ fprintf(out, " %s = new %s[0];\n", uidName,
+ java_type_name(attributionDecl.fields.front().javaType));
+ fprintf(out, " }\n");
+ fprintf(out, " if (%s == null) {\n", tagName);
+ fprintf(out, " %s = new %s[0];\n", tagName,
+ java_type_name(attributionDecl.fields.back().javaType));
+ fprintf(out, " }\n");
+
+ // First check that the lengths of the uid and tag arrays are the same.
+ fprintf(out, " if (%s.length != %s.length) {\n", uidName, tagName);
+ fprintf(out, " return;\n");
+ fprintf(out, " }\n");
+ fprintf(out, " int attrSize = LIST_TYPE_OVERHEAD;\n");
+ fprintf(out, " for (int i = 0; i < %s.length; i++) {\n", tagName);
+ fprintf(out, " String str%d = (%s[i] == null) ? \"\" : %s[i];\n",
+ argIndex, tagName, tagName);
+ fprintf(out, " int str%dlen = str%d.getBytes(UTF_8).length;\n",
+ argIndex, argIndex);
+ fprintf(out,
+ " attrSize += "
+ "LIST_TYPE_OVERHEAD + INT_TYPE_SIZE + STRING_TYPE_OVERHEAD + str%dlen;\n",
+ argIndex);
+ fprintf(out, " }\n");
+ fprintf(out, " needed += attrSize;\n");
+ break;
+ }
+ default:
+ // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIR.
+ return 1;
+ }
+ argIndex++;
+ }
+
+ // Now we have the size that is needed. Check for overflow and return if needed.
+ fprintf(out, " if (needed > MAX_EVENT_PAYLOAD) {\n");
+ fprintf(out, " return;\n");
+ fprintf(out, " }\n");
+
+ // Create new buffer, and associated data types.
+ fprintf(out, " byte[] buff = new byte[needed];\n");
+ fprintf(out, " int pos = 0;\n");
+
+ // Initialize the buffer with list data type.
+ fprintf(out, " buff[pos] = LIST_TYPE;\n");
+ fprintf(out, " buff[pos + 1] = %lu;\n", signature.size() + 2);
+ fprintf(out, " pos += LIST_TYPE_OVERHEAD;\n");
+
+ // Write timestamp.
+ fprintf(out, " long elapsedRealtime = SystemClock.elapsedRealtimeNanos();\n");
+ fprintf(out, " buff[pos] = LONG_TYPE;\n");
+ fprintf(out, " copyLong(buff, pos + 1, elapsedRealtime);\n");
+ fprintf(out, " pos += LONG_TYPE_SIZE;\n");
+
+ // Write atom code.
+ fprintf(out, " buff[pos] = INT_TYPE;\n");
+ fprintf(out, " copyInt(buff, pos + 1, code);\n");
+ fprintf(out, " pos += INT_TYPE_SIZE;\n");
+
+ // Write the args.
+ argIndex = 1;
+ for (vector<java_type_t>::const_iterator arg = signature.begin();
+ arg != signature.end(); arg++) {
+ switch (*arg) {
+ case JAVA_TYPE_BOOLEAN:
+ fprintf(out, " buff[pos] = INT_TYPE;\n");
+ fprintf(out, " copyInt(buff, pos + 1, arg%d? 1 : 0);\n", argIndex);
+ fprintf(out, " pos += INT_TYPE_SIZE;\n");
+ break;
+ case JAVA_TYPE_INT:
+ case JAVA_TYPE_ENUM:
+ fprintf(out, " buff[pos] = INT_TYPE;\n");
+ fprintf(out, " copyInt(buff, pos + 1, arg%d);\n", argIndex);
+ fprintf(out, " pos += INT_TYPE_SIZE;\n");
+ break;
+ case JAVA_TYPE_FLOAT:
+ *requiredHelpers |= JAVA_MODULE_REQUIRES_FLOAT;
+ fprintf(out, " buff[pos] = FLOAT_TYPE;\n");
+ fprintf(out, " copyFloat(buff, pos + 1, arg%d);\n", argIndex);
+ fprintf(out, " pos += FLOAT_TYPE_SIZE;\n");
+ break;
+ case JAVA_TYPE_LONG:
+ fprintf(out, " buff[pos] = LONG_TYPE;\n");
+ fprintf(out, " copyLong(buff, pos + 1, arg%d);\n", argIndex);
+ fprintf(out, " pos += LONG_TYPE_SIZE;\n");
+ break;
+ case JAVA_TYPE_STRING:
+ fprintf(out, " buff[pos] = STRING_TYPE;\n");
+ fprintf(out, " copyInt(buff, pos + 1, arg%dBytes.length);\n", argIndex);
+ fprintf(out, " System.arraycopy("
+ "arg%dBytes, 0, buff, pos + STRING_TYPE_OVERHEAD, arg%dBytes.length);\n",
+ argIndex, argIndex);
+ fprintf(out, " pos += STRING_TYPE_OVERHEAD + arg%dBytes.length;\n",
+ argIndex);
+ break;
+ case JAVA_TYPE_BYTE_ARRAY:
+ fprintf(out, " buff[pos] = STRING_TYPE;\n");
+ fprintf(out, " copyInt(buff, pos + 1, arg%d.length);\n", argIndex);
+ fprintf(out, " System.arraycopy("
+ "arg%d, 0, buff, pos + STRING_TYPE_OVERHEAD, arg%d.length);\n",
+ argIndex, argIndex);
+ fprintf(out, " pos += STRING_TYPE_OVERHEAD + arg%d.length;\n", argIndex);
+ break;
+ case JAVA_TYPE_ATTRIBUTION_CHAIN:
+ {
+ *requiredHelpers |= JAVA_MODULE_REQUIRES_ATTRIBUTION;
+ const char* uidName = attributionDecl.fields.front().name.c_str();
+ const char* tagName = attributionDecl.fields.back().name.c_str();
+
+ fprintf(out, " writeAttributionChain(buff, pos, %s, %s);\n",
+ uidName, tagName);
+ fprintf(out, " pos += attrSize;\n");
+ break;
+ }
+ default:
+ // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIR.
+ return 1;
+ }
+ argIndex++;
+ }
+
+ fprintf(out, " StatsLog.writeRaw(buff, pos);\n");
+ fprintf(out, " }\n");
+ fprintf(out, "\n");
+ }
+ return 0;
+}
+
static void write_java_work_source_method(FILE* out,
- const map<vector<java_type_t>, set<string>>& signatures_to_modules) {
+ const map<vector<java_type_t>, set<string>>& signatures_to_modules,
+ const string& moduleName) {
fprintf(out, "\n // WorkSource methods.\n");
for (auto signature_to_modules_it = signatures_to_modules.begin();
signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
+ // Skip if this signature is not needed for the module.
+ if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
+ continue;
+ }
vector<java_type_t> signature = signature_to_modules_it->first;
// Determine if there is Attribution in this signature.
int attributionArg = -1;
@@ -834,7 +1178,9 @@
}
// Method header (signature)
- fprintf(out, " /** @hide */\n");
+ if (moduleName == DEFAULT_MODULE_NAME) {
+ fprintf(out, " /** @hide */\n");
+ }
fprintf(out, " public static void write(int code");
int argIndex = 1;
for (vector<java_type_t>::const_iterator arg = signature.begin();
@@ -859,7 +1205,7 @@
}
}
fprintf(out, ");\n");
- fprintf(out, " }\n"); // close flor-loop
+ fprintf(out, " }\n"); // close for-loop
// write() component.
fprintf(out, " ArrayList<WorkSource.WorkChain> workChains = ws.getWorkChains();\n");
@@ -880,23 +1226,7 @@
}
}
-static int
-write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl)
-{
- // Print prelude
- fprintf(out, "// This file is autogenerated\n");
- fprintf(out, "\n");
- fprintf(out, "package android.util;\n");
- fprintf(out, "\n");
- fprintf(out, "import android.os.WorkSource;\n");
- fprintf(out, "import java.util.ArrayList;\n");
- fprintf(out, "\n");
- fprintf(out, "\n");
- fprintf(out, "/**\n");
- fprintf(out, " * API For logging statistics events.\n");
- fprintf(out, " * @hide\n");
- fprintf(out, " */\n");
- fprintf(out, "public class StatsLogInternal {\n");
+static void write_java_atom_codes(FILE* out, const Atoms& atoms, const string& moduleName) {
fprintf(out, " // Constants for atom codes.\n");
std::map<int, set<AtomDecl>::const_iterator> atom_code_to_non_chained_decl_map;
@@ -905,6 +1235,10 @@
// Print constants for the atom codes.
for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
atom != atoms.decls.end(); atom++) {
+ // Skip if the atom is not needed for the module.
+ if (!atom_needed_for_module(*atom, moduleName)) {
+ continue;
+ }
string constant = make_constant_name(atom->name);
fprintf(out, "\n");
fprintf(out, " /**\n");
@@ -914,16 +1248,23 @@
if (non_chained_decl != atom_code_to_non_chained_decl_map.end()) {
write_java_usage(out, "write_non_chained", constant, *non_chained_decl->second);
}
- fprintf(out, " * @hide\n");
+ if (moduleName == DEFAULT_MODULE_NAME) {
+ fprintf(out, " * @hide\n");
+ }
fprintf(out, " */\n");
fprintf(out, " public static final int %s = %d;\n", constant.c_str(), atom->code);
}
fprintf(out, "\n");
+}
- // Print constants for the enum values.
+static void write_java_enum_values(FILE* out, const Atoms& atoms, const string& moduleName) {
fprintf(out, " // Constants for enum values.\n\n");
for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
atom != atoms.decls.end(); atom++) {
+ // Skip if the atom is not needed for the module.
+ if (!atom_needed_for_module(*atom, moduleName)) {
+ continue;
+ }
for (vector<AtomField>::const_iterator field = atom->fields.begin();
field != atom->fields.end(); field++) {
if (field->javaType == JAVA_TYPE_ENUM) {
@@ -931,7 +1272,9 @@
field->name.c_str());
for (map<int, string>::const_iterator value = field->enumValues.begin();
value != field->enumValues.end(); value++) {
- fprintf(out, " /** @hide */\n");
+ if (moduleName == DEFAULT_MODULE_NAME) {
+ fprintf(out, " /** @hide */\n");
+ }
fprintf(out, " public static final int %s__%s__%s = %d;\n",
make_constant_name(atom->message).c_str(),
make_constant_name(field->name).c_str(),
@@ -942,19 +1285,107 @@
}
}
}
+}
+
+static int
+write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl)
+{
+ // Print prelude
+ fprintf(out, "// This file is autogenerated\n");
+ fprintf(out, "\n");
+ fprintf(out, "package android.util;\n");
+ fprintf(out, "\n");
+ fprintf(out, "import android.os.WorkSource;\n");
+ fprintf(out, "import android.util.SparseArray;\n");
+ fprintf(out, "import java.util.ArrayList;\n");
+ fprintf(out, "\n");
+ fprintf(out, "\n");
+ fprintf(out, "/**\n");
+ fprintf(out, " * API For logging statistics events.\n");
+ fprintf(out, " * @hide\n");
+ fprintf(out, " */\n");
+ fprintf(out, "public class StatsLogInternal {\n");
+ write_java_atom_codes(out, atoms, DEFAULT_MODULE_NAME);
+
+ write_java_enum_values(out, atoms, DEFAULT_MODULE_NAME);
// Print write methods
fprintf(out, " // Write methods\n");
write_java_method(out, "write", atoms.signatures_to_modules, attributionDecl);
write_java_method(out, "write_non_chained", atoms.non_chained_signatures_to_modules,
attributionDecl);
- write_java_work_source_method(out, atoms.signatures_to_modules);
+ write_java_work_source_method(out, atoms.signatures_to_modules, DEFAULT_MODULE_NAME);
fprintf(out, "}\n");
return 0;
}
+// TODO: Merge this with write_stats_log_java so that we can get rid of StatsLogInternal JNI.
+static int
+write_stats_log_java_for_module(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
+ const string& moduleName, const string& javaClass, const string& javaPackage)
+{
+ // Print prelude
+ fprintf(out, "// This file is autogenerated\n");
+ fprintf(out, "\n");
+ fprintf(out, "package %s;\n", javaPackage.c_str());
+ fprintf(out, "\n");
+ fprintf(out, "import static java.nio.charset.StandardCharsets.UTF_8;\n");
+ fprintf(out, "\n");
+ fprintf(out, "import android.util.StatsLog;\n");
+ fprintf(out, "import android.os.SystemClock;\n");
+ fprintf(out, "\n");
+ fprintf(out, "import java.util.ArrayList;\n");
+ fprintf(out, "\n");
+ fprintf(out, "\n");
+ fprintf(out, "/**\n");
+ fprintf(out, " * Utility class for logging statistics events.\n");
+ fprintf(out, " */\n");
+ fprintf(out, "public class %s {\n", javaClass.c_str());
+
+ // TODO: ideally these match with the native values (and automatically change if they change).
+ fprintf(out, " private static final int LOGGER_ENTRY_MAX_PAYLOAD = 4068;\n");
+ fprintf(out,
+ " private static final int MAX_EVENT_PAYLOAD = LOGGER_ENTRY_MAX_PAYLOAD - 4;\n");
+ // Value types. Must match with EventLog.java and log.h.
+ fprintf(out, " private static final byte INT_TYPE = 0;\n");
+ fprintf(out, " private static final byte LONG_TYPE = 1;\n");
+ fprintf(out, " private static final byte STRING_TYPE = 2;\n");
+ fprintf(out, " private static final byte LIST_TYPE = 3;\n");
+ fprintf(out, " private static final byte FLOAT_TYPE = 4;\n");
+
+ // Size of each value type.
+ // Booleans, ints, floats, and enums take 5 bytes, 1 for the type and 4 for the value.
+ fprintf(out, " private static final int INT_TYPE_SIZE = 5;\n");
+ fprintf(out, " private static final int FLOAT_TYPE_SIZE = 5;\n");
+ // Longs take 9 bytes, 1 for the type and 8 for the value.
+ fprintf(out, " private static final int LONG_TYPE_SIZE = 9;\n");
+ // Strings take 5 metadata bytes: 1 byte is for the type, 4 are for the length.
+ fprintf(out, " private static final int STRING_TYPE_OVERHEAD = 5;\n");
+ fprintf(out, " private static final int LIST_TYPE_OVERHEAD = 2;\n");
+
+ write_java_atom_codes(out, atoms, moduleName);
+
+ write_java_enum_values(out, atoms, moduleName);
+
+ int errors = 0;
+ int requiredHelpers = 0;
+ // Print write methods
+ fprintf(out, " // Write methods\n");
+ errors += write_java_method_for_module(out, atoms.signatures_to_modules, attributionDecl,
+ moduleName, &requiredHelpers);
+ errors += write_java_non_chained_method_for_module(out, atoms.non_chained_signatures_to_modules,
+ moduleName);
+
+ fprintf(out, " // Helper methods for copying primitives\n");
+ write_java_helpers_for_module(out, attributionDecl, requiredHelpers);
+
+ fprintf(out, "}\n");
+
+ return errors;
+}
+
static const char*
jni_type_name(java_type_t type)
{
@@ -1346,7 +1777,11 @@
fprintf(stderr, " --namespace COMMA,SEP,NAMESPACE required for cpp/header with module\n");
fprintf(stderr, " comma separated namespace of the files\n");
fprintf(stderr, " --importHeader NAME required for cpp/jni to say which header to import\n");
-}
+ fprintf(stderr, " --javaPackage PACKAGE the package for the java file.\n");
+ fprintf(stderr, " required for java with module\n");
+ fprintf(stderr, " --javaClass CLASS the class name of the java class.\n");
+ fprintf(stderr, " Optional for Java with module.\n");
+ fprintf(stderr, " Default is \"StatsLogInternal\"\n");}
/**
* Do the argument parsing and execute the tasks.
@@ -1362,6 +1797,8 @@
string moduleName = DEFAULT_MODULE_NAME;
string cppNamespace = DEFAULT_CPP_NAMESPACE;
string cppHeaderImport = DEFAULT_CPP_HEADER_IMPORT;
+ string javaPackage = DEFAULT_JAVA_PACKAGE;
+ string javaClass = DEFAULT_JAVA_CLASS;
int index = 1;
while (index < argc) {
@@ -1417,6 +1854,20 @@
return 1;
}
cppHeaderImport = argv[index];
+ } else if (0 == strcmp("--javaPackage", argv[index])) {
+ index++;
+ if (index >= argc) {
+ print_usage();
+ return 1;
+ }
+ javaPackage = argv[index];
+ } else if (0 == strcmp("--javaClass", argv[index])) {
+ index++;
+ if (index >= argc) {
+ print_usage();
+ return 1;
+ }
+ javaClass = argv[index];
}
index++;
}
@@ -1486,8 +1937,18 @@
fprintf(stderr, "Unable to open file for write: %s\n", javaFilename.c_str());
return 1;
}
- errorCount = android::stats_log_api_gen::write_stats_log_java(
- out, atoms, attributionDecl);
+ // If this is for a specific module, the java package must also be provided.
+ if (moduleName != DEFAULT_MODULE_NAME && javaPackage== DEFAULT_JAVA_PACKAGE) {
+ fprintf(stderr, "Must supply --javaPackage if supplying a specific module\n");
+ return 1;
+ }
+ if (moduleName == DEFAULT_MODULE_NAME) {
+ errorCount = android::stats_log_api_gen::write_stats_log_java(
+ out, atoms, attributionDecl);
+ } else {
+ errorCount = android::stats_log_api_gen::write_stats_log_java_for_module(
+ out, atoms, attributionDecl, moduleName, javaClass, javaPackage);
+ }
fclose(out);
}
@@ -1503,7 +1964,7 @@
fclose(out);
}
- return 0;
+ return errorCount;
}
}