Update CtsHostsideNetworkTests to take network capability into account.
Bug: 177641226
Test: atest ./tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
Ignore-AOSP-First: Expedited jobs are not available in AOSP
Change-Id: Ic75ebdc184764b7e7ac02d3e2ca18cbba1c55ee5
diff --git a/tests/cts/hostside/app2/Android.bp b/tests/cts/hostside/app2/Android.bp
index b448459..dd33eed 100644
--- a/tests/cts/hostside/app2/Android.bp
+++ b/tests/cts/hostside/app2/Android.bp
@@ -21,7 +21,7 @@
android_test_helper_app {
name: "CtsHostsideNetworkTestsApp2",
defaults: ["cts_support_defaults"],
- sdk_version: "current",
+ sdk_version: "test_current",
static_libs: ["CtsHostsideNetworkTestsAidl"],
srcs: ["src/**/*.java"],
// Tag this module as a cts test artifact
diff --git a/tests/cts/hostside/app2/AndroidManifest.xml b/tests/cts/hostside/app2/AndroidManifest.xml
index b85d800..99b653c 100644
--- a/tests/cts/hostside/app2/AndroidManifest.xml
+++ b/tests/cts/hostside/app2/AndroidManifest.xml
@@ -21,20 +21,23 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.INTERNET"/>
+ <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
<!--
- This application is used to listen to RESTRICT_BACKGROUND_CHANGED intents and store
- them in a shared preferences which is then read by the test app. These broadcasts are
- handled by 2 listeners, one defined the manifest and another dynamically registered by
- a service.
+ This application is used to listen to RESTRICT_BACKGROUND_CHANGED intents and store
+ them in a shared preferences which is then read by the test app. These broadcasts are
+ handled by 2 listeners, one defined the manifest and another dynamically registered by
+ a service.
- The manifest-defined listener also handles ordered broadcasts used to share data with the
- test app.
+ The manifest-defined listener also handles ordered broadcasts used to share data with the
+ test app.
- This application also provides a service, RemoteSocketFactoryService, that the test app can
- use to open sockets to remote hosts as a different user ID.
- -->
- <application android:usesCleartextTraffic="true">
+ This application also provides a service, RemoteSocketFactoryService, that the test app can
+ use to open sockets to remote hosts as a different user ID.
+ -->
+ <application android:usesCleartextTraffic="true"
+ android:testOnly="true">
+
<activity android:name=".MyActivity"
android:exported="true"/>
<service android:name=".MyService"
diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java
index 5c45d44..62b508c 100644
--- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java
+++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java
@@ -15,11 +15,13 @@
*/
package com.android.cts.net.hostside.app2;
+import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
@@ -53,6 +55,11 @@
static final String TEST_PKG = "com.android.cts.net.hostside";
static final String KEY_NETWORK_STATE_OBSERVER = TEST_PKG + ".observer";
+ static final String KEY_SKIP_VALIDATION_CHECKS = TEST_PKG + ".skip_validation_checks";
+
+ static final int TYPE_COMPONENT_ACTIVTY = 0;
+ static final int TYPE_COMPONENT_FOREGROUND_SERVICE = 1;
+ static final int TYPE_COMPONENT_EXPEDITED_JOB = 2;
static int getUid(Context context) {
final String packageName = context.getPackageName();
@@ -63,15 +70,57 @@
}
}
- static void notifyNetworkStateObserver(Context context, Intent intent) {
+ private static boolean validateComponentState(Context context, int componentType,
+ INetworkStateObserver observer) throws RemoteException {
+ final ActivityManager activityManager = context.getSystemService(ActivityManager.class);
+ switch (componentType) {
+ case TYPE_COMPONENT_ACTIVTY: {
+ final int procState = activityManager.getUidProcessState(Process.myUid());
+ if (procState != ActivityManager.PROCESS_STATE_TOP) {
+ observer.onNetworkStateChecked(
+ INetworkStateObserver.RESULT_ERROR_UNEXPECTED_PROC_STATE,
+ "Unexpected procstate: " + procState);
+ return false;
+ }
+ return true;
+ }
+ case TYPE_COMPONENT_FOREGROUND_SERVICE: {
+ final int procState = activityManager.getUidProcessState(Process.myUid());
+ if (procState != ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
+ observer.onNetworkStateChecked(
+ INetworkStateObserver.RESULT_ERROR_UNEXPECTED_PROC_STATE,
+ "Unexpected procstate: " + procState);
+ return false;
+ }
+ return true;
+ }
+ case TYPE_COMPONENT_EXPEDITED_JOB: {
+ final int capabilities = activityManager.getUidProcessCapabilities(Process.myUid());
+ if ((capabilities & ActivityManager.PROCESS_CAPABILITY_NETWORK) == 0) {
+ observer.onNetworkStateChecked(
+ INetworkStateObserver.RESULT_ERROR_UNEXPECTED_CAPABILITIES,
+ "Unexpected capabilities: " + capabilities);
+ return false;
+ }
+ return true;
+ }
+ default: {
+ observer.onNetworkStateChecked(INetworkStateObserver.RESULT_ERROR_OTHER,
+ "Unknown component type: " + componentType);
+ return false;
+ }
+ }
+ }
+
+ static void notifyNetworkStateObserver(Context context, Intent intent, int componentType) {
if (intent == null) {
return;
}
final Bundle extras = intent.getExtras();
- notifyNetworkStateObserver(context, extras);
+ notifyNetworkStateObserver(context, extras, componentType);
}
- static void notifyNetworkStateObserver(Context context, Bundle extras) {
+ static void notifyNetworkStateObserver(Context context, Bundle extras, int componentType) {
if (extras == null) {
return;
}
@@ -79,17 +128,17 @@
extras.getBinder(KEY_NETWORK_STATE_OBSERVER));
if (observer != null) {
try {
- if (!observer.isForeground()) {
- Log.e(TAG, "App didn't come to foreground");
- observer.onNetworkStateChecked(null);
+ final boolean skipValidation = extras.getBoolean(KEY_SKIP_VALIDATION_CHECKS);
+ if (!skipValidation && !validateComponentState(context, componentType, observer)) {
return;
}
} catch (RemoteException e) {
- Log.e(TAG, "Error occurred while reading the proc state: " + e);
+ Log.e(TAG, "Error occurred while informing the validation result: " + e);
}
AsyncTask.execute(() -> {
try {
observer.onNetworkStateChecked(
+ INetworkStateObserver.RESULT_SUCCESS_NETWORK_STATE_CHECKED,
MyBroadcastReceiver.checkNetworkStatus(context));
} catch (RemoteException e) {
Log.e(TAG, "Error occurred while notifying the observer: " + e);
diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java
index 286cc2f..9fdb9c9 100644
--- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java
+++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java
@@ -18,6 +18,7 @@
import static com.android.cts.net.hostside.app2.Common.ACTION_FINISH_ACTIVITY;
import static com.android.cts.net.hostside.app2.Common.TAG;
import static com.android.cts.net.hostside.app2.Common.TEST_PKG;
+import static com.android.cts.net.hostside.app2.Common.TYPE_COMPONENT_ACTIVTY;
import android.app.Activity;
import android.content.BroadcastReceiver;
@@ -42,7 +43,7 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "MyActivity.onCreate()");
- Common.notifyNetworkStateObserver(this, getIntent());
+ Common.notifyNetworkStateObserver(this, getIntent(), TYPE_COMPONENT_ACTIVTY);
finishCommandReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java
index ff4ba65..b55761c 100644
--- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java
+++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java
@@ -17,6 +17,7 @@
import static com.android.cts.net.hostside.app2.Common.TAG;
import static com.android.cts.net.hostside.app2.Common.TEST_PKG;
+import static com.android.cts.net.hostside.app2.Common.TYPE_COMPONENT_FOREGROUND_SERVICE;
import android.R;
import android.app.Notification;
@@ -58,7 +59,7 @@
startForeground(42, new Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_dialog_alert) // any icon is fine
.build());
- Common.notifyNetworkStateObserver(this, intent);
+ Common.notifyNetworkStateObserver(this, intent, TYPE_COMPONENT_FOREGROUND_SERVICE);
break;
case FLAG_STOP_FOREGROUND:
Log.d(TAG, "Stopping foreground");
diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyJobService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyJobService.java
index fd4bd32..51c3157 100644
--- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyJobService.java
+++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyJobService.java
@@ -17,6 +17,7 @@
import static com.android.cts.net.hostside.app2.Common.ACTION_FINISH_JOB;
import static com.android.cts.net.hostside.app2.Common.TAG;
+import static com.android.cts.net.hostside.app2.Common.TYPE_COMPONENT_EXPEDITED_JOB;
import android.app.job.JobParameters;
import android.app.job.JobService;
@@ -39,7 +40,8 @@
@Override
public boolean onStartJob(JobParameters params) {
Log.v(TAG, "MyJobService.onStartJob()");
- Common.notifyNetworkStateObserver(this, params.getTransientExtras());
+ Common.notifyNetworkStateObserver(this, params.getTransientExtras(),
+ TYPE_COMPONENT_EXPEDITED_JOB);
mFinishCommandReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {