Fix and enable ConnOnActivityStartTest.
- Set parole duration to 0 so that it won't affect app standby test.
- Use a bound service to send commands to test app instead of broadcasts.
- Remove code to install/delete test app as it will be done as part of tests
initialization.
Bug: 38432755
Test: forrest --extra_args='--class com.android.server.net.ConnOnActivityStartTest' \
test FrameworksServicesTests
Change-Id: Ic6cd574a60c4449195f2c8cd4e04b9cb47f225c8
Merged-In: Ic6cd574a60c4449195f2c8cd4e04b9cb47f225c8
This commit is contained in:
@@ -29,7 +29,8 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||
|
||||
LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/aidl
|
||||
|
||||
LOCAL_SRC_FILES += aidl/com/android/servicestests/aidl/INetworkStateObserver.aidl
|
||||
LOCAL_SRC_FILES += aidl/com/android/servicestests/aidl/INetworkStateObserver.aidl \
|
||||
aidl/com/android/servicestests/aidl/ICmdReceiverService.aidl
|
||||
|
||||
LOCAL_JAVA_LIBRARIES := android.test.mock legacy-android-test
|
||||
|
||||
@@ -61,3 +62,5 @@ LOCAL_DX_FLAGS := --multi-dex
|
||||
LOCAL_STATIC_JAVA_LIBRARIES += ub-uiautomator
|
||||
|
||||
include $(BUILD_PACKAGE)
|
||||
|
||||
include $(call all-makefiles-under, $(LOCAL_PATH))
|
||||
@@ -16,6 +16,7 @@
|
||||
<configuration description="Runs Frameworks Services Tests.">
|
||||
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
|
||||
<option name="test-file-name" value="FrameworksServicesTests.apk" />
|
||||
<option name="test-file-name" value="ConnTestApp.apk" />
|
||||
</target_preparer>
|
||||
|
||||
<option name="test-suite-tag" value="apct" />
|
||||
|
||||
@@ -18,6 +18,7 @@ include $(CLEAR_VARS)
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
LOCAL_SDK_VERSION := current
|
||||
LOCAL_SRC_FILES := \
|
||||
com/android/servicestests/aidl/INetworkStateObserver.aidl
|
||||
com/android/servicestests/aidl/INetworkStateObserver.aidl \
|
||||
com/android/servicestests/aidl/ICmdReceiverService.aidl
|
||||
LOCAL_MODULE := servicestests-aidl
|
||||
include $(BUILD_STATIC_JAVA_LIBRARY)
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.servicestests.aidl;
|
||||
|
||||
interface ICmdReceiverService {
|
||||
void finishActivity();
|
||||
}
|
||||
Binary file not shown.
@@ -16,48 +16,37 @@
|
||||
|
||||
package com.android.server.net;
|
||||
|
||||
import static android.util.DebugUtils.valueToString;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import com.android.frameworks.servicestests.R;
|
||||
import com.android.servicestests.aidl.ICmdReceiverService;
|
||||
import com.android.servicestests.aidl.INetworkStateObserver;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.IntentSender;
|
||||
import android.content.pm.IPackageDeleteObserver;
|
||||
import android.content.pm.PackageInstaller;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.IBinder;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.filters.LargeTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.util.Log;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -76,62 +65,118 @@ import java.util.concurrent.TimeUnit;
|
||||
* Run: adb shell am instrument -e class com.android.server.net.ConnOnActivityStartTest -w \
|
||||
* com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
|
||||
*/
|
||||
@Ignore
|
||||
@LargeTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ConnOnActivityStartTest {
|
||||
private static final String TAG = ConnOnActivityStartTest.class.getSimpleName();
|
||||
|
||||
private static final String ACTION_INSTALL_COMPLETE = "com.android.server.net.INSTALL_COMPLETE";
|
||||
|
||||
private static final String TEST_APP_URI =
|
||||
"android.resource://com.android.frameworks.servicestests/raw/conntestapp";
|
||||
private static final String TEST_PKG = "com.android.servicestests.apps.conntestapp";
|
||||
private static final String TEST_ACTIVITY_CLASS = TEST_PKG + ".ConnTestActivity";
|
||||
|
||||
private static final String ACTION_FINISH_ACTIVITY = TEST_PKG + ".FINISH";
|
||||
private static final String TEST_SERVICE_CLASS = TEST_PKG + ".CmdReceiverService";
|
||||
|
||||
private static final String EXTRA_NETWORK_STATE_OBSERVER = TEST_PKG + ".observer";
|
||||
|
||||
private static final long BATTERY_OFF_TIMEOUT_MS = 2000; // 2 sec
|
||||
private static final long BATTERY_OFF_CHECK_INTERVAL_MS = 200; // 0.2 sec
|
||||
|
||||
private static final long WAIT_FOR_INSTALL_TIMEOUT_MS = 2000; // 2 sec
|
||||
|
||||
private static final long NETWORK_CHECK_TIMEOUT_MS = 4000; // 4 sec
|
||||
|
||||
private static final long SCREEN_ON_DELAY_MS = 500; // 0.5 sec
|
||||
|
||||
private static final long BIND_SERVICE_TIMEOUT_SEC = 4;
|
||||
|
||||
private static final int REPEAT_TEST_COUNT = 5;
|
||||
|
||||
private static final String KEY_PAROLE_DURATION = "parole_duration";
|
||||
private static final String DESIRED_PAROLE_DURATION = "0";
|
||||
|
||||
private static Context mContext;
|
||||
private static UiDevice mUiDevice;
|
||||
private static int mTestPkgUid;
|
||||
private static BatteryManager mBatteryManager;
|
||||
|
||||
private static boolean mAppIdleConstsUpdated;
|
||||
private static String mOriginalAppIdleConsts;
|
||||
|
||||
private static ServiceConnection mServiceConnection;
|
||||
private static ICmdReceiverService mCmdReceiverService;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpOnce() throws Exception {
|
||||
mContext = InstrumentationRegistry.getContext();
|
||||
mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
|
||||
|
||||
installAppAndAssertInstalled();
|
||||
setDesiredParoleDuration();
|
||||
mContext.getPackageManager().setApplicationEnabledSetting(TEST_PKG,
|
||||
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
|
||||
mTestPkgUid = mContext.getPackageManager().getPackageUid(TEST_PKG, 0);
|
||||
|
||||
mBatteryManager = (BatteryManager) mContext.getSystemService(Context.BATTERY_SERVICE);
|
||||
bindService();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownOnce() {
|
||||
mContext.getPackageManager().deletePackage(TEST_PKG,
|
||||
new IPackageDeleteObserver.Stub() {
|
||||
@Override
|
||||
public void packageDeleted(String packageName, int returnCode)
|
||||
throws RemoteException {
|
||||
Log.e(TAG, packageName + " deleted, returnCode: " + returnCode);
|
||||
}
|
||||
}, 0);
|
||||
if (mAppIdleConstsUpdated) {
|
||||
Settings.Global.putString(mContext.getContentResolver(),
|
||||
Settings.Global.APP_IDLE_CONSTANTS, mOriginalAppIdleConsts);
|
||||
}
|
||||
unbindService();
|
||||
}
|
||||
|
||||
private static void bindService() throws Exception {
|
||||
final CountDownLatch bindLatch = new CountDownLatch(1);
|
||||
mServiceConnection = new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
Log.i(TAG, "Service connected");
|
||||
mCmdReceiverService = ICmdReceiverService.Stub.asInterface(service);
|
||||
bindLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
Log.i(TAG, "Service disconnected");
|
||||
}
|
||||
};
|
||||
final Intent intent = new Intent()
|
||||
.setComponent(new ComponentName(TEST_PKG, TEST_SERVICE_CLASS));
|
||||
// Needs to use BIND_ALLOW_OOM_MANAGEMENT and BIND_NOT_FOREGROUND so that the test app
|
||||
// does not run in the same process state as this app.
|
||||
mContext.bindService(intent, mServiceConnection,
|
||||
Context.BIND_AUTO_CREATE
|
||||
| Context.BIND_ALLOW_OOM_MANAGEMENT
|
||||
| Context.BIND_NOT_FOREGROUND);
|
||||
if (!bindLatch.await(BIND_SERVICE_TIMEOUT_SEC, TimeUnit.SECONDS)) {
|
||||
fail("Timed out waiting for the service to bind in " + mTestPkgUid);
|
||||
}
|
||||
}
|
||||
|
||||
private static void unbindService() {
|
||||
if (mCmdReceiverService != null) {
|
||||
mContext.unbindService(mServiceConnection);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setDesiredParoleDuration() {
|
||||
mOriginalAppIdleConsts = Settings.Global.getString(mContext.getContentResolver(),
|
||||
Settings.Global.APP_IDLE_CONSTANTS);
|
||||
String newAppIdleConstants;
|
||||
final String newConstant = KEY_PAROLE_DURATION + "=" + DESIRED_PAROLE_DURATION;
|
||||
if (mOriginalAppIdleConsts == null || "null".equals(mOriginalAppIdleConsts)) {
|
||||
// app_idle_constants is initially empty, so just assign the desired value.
|
||||
newAppIdleConstants = newConstant;
|
||||
} else if (mOriginalAppIdleConsts.contains(KEY_PAROLE_DURATION)) {
|
||||
// app_idle_constants contains parole_duration, so replace it with the desired value.
|
||||
newAppIdleConstants = mOriginalAppIdleConsts.replaceAll(
|
||||
KEY_PAROLE_DURATION + "=\\d+", newConstant);
|
||||
} else {
|
||||
// app_idle_constants didn't have parole_duration, so append the desired value.
|
||||
newAppIdleConstants = mOriginalAppIdleConsts + "," + newConstant;
|
||||
}
|
||||
Settings.Global.putString(mContext.getContentResolver(),
|
||||
Settings.Global.APP_IDLE_CONSTANTS, newAppIdleConstants);
|
||||
mAppIdleConstsUpdated = true;
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -174,6 +219,7 @@ public class ConnOnActivityStartTest {
|
||||
startActivityAndCheckNetworkAccess();
|
||||
} finally {
|
||||
turnBatteryOn();
|
||||
finishActivity();
|
||||
setAppIdle(false);
|
||||
}
|
||||
}
|
||||
@@ -195,9 +241,9 @@ public class ConnOnActivityStartTest {
|
||||
turnScreenOn();
|
||||
SystemClock.sleep(SCREEN_ON_DELAY_MS);
|
||||
startActivityAndCheckNetworkAccess();
|
||||
Log.d(TAG, testName + " end #" + i);
|
||||
} finally {
|
||||
finishActivity();
|
||||
Log.d(TAG, testName + " end #" + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -348,74 +394,7 @@ public class ConnOnActivityStartTest {
|
||||
}
|
||||
}
|
||||
|
||||
private void finishActivity() {
|
||||
final Intent finishIntent = new Intent(ACTION_FINISH_ACTIVITY)
|
||||
.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
|
||||
mContext.sendBroadcast(finishIntent);
|
||||
}
|
||||
private static void installAppAndAssertInstalled() throws Exception {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
final int[] result = {PackageInstaller.STATUS_SUCCESS};
|
||||
final BroadcastReceiver installStatusReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
final String pkgName = intent.getStringExtra(PackageInstaller.EXTRA_PACKAGE_NAME);
|
||||
if (!TEST_PKG.equals(pkgName)) {
|
||||
return;
|
||||
}
|
||||
result[0] = intent.getIntExtra(PackageInstaller.EXTRA_STATUS,
|
||||
PackageInstaller.STATUS_FAILURE);
|
||||
latch.countDown();
|
||||
}
|
||||
};
|
||||
mContext.registerReceiver(installStatusReceiver, new IntentFilter(ACTION_INSTALL_COMPLETE));
|
||||
try {
|
||||
installApp();
|
||||
if (latch.await(WAIT_FOR_INSTALL_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
|
||||
if (result[0] != PackageInstaller.STATUS_SUCCESS) {
|
||||
fail("Couldn't install test app, result: "
|
||||
+ valueToString(PackageInstaller.class, "STATUS_", result[0]));
|
||||
}
|
||||
} else {
|
||||
fail("Timed out waiting for the test app to install");
|
||||
}
|
||||
} finally {
|
||||
mContext.unregisterReceiver(installStatusReceiver);
|
||||
}
|
||||
}
|
||||
|
||||
private static void installApp() throws Exception {
|
||||
final Uri packageUri = Uri.parse(TEST_APP_URI);
|
||||
final InputStream in = mContext.getContentResolver().openInputStream(packageUri);
|
||||
|
||||
final PackageInstaller packageInstaller
|
||||
= mContext.getPackageManager().getPackageInstaller();
|
||||
final PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
|
||||
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
|
||||
params.setAppPackageName(TEST_PKG);
|
||||
|
||||
final int sessionId = packageInstaller.createSession(params);
|
||||
final PackageInstaller.Session session = packageInstaller.openSession(sessionId);
|
||||
|
||||
OutputStream out = null;
|
||||
try {
|
||||
out = session.openWrite(TAG, 0, -1);
|
||||
final byte[] buffer = new byte[65536];
|
||||
int c;
|
||||
while ((c = in.read(buffer)) != -1) {
|
||||
out.write(buffer, 0, c);
|
||||
}
|
||||
session.fsync(out);
|
||||
} finally {
|
||||
IoUtils.closeQuietly(in);
|
||||
IoUtils.closeQuietly(out);
|
||||
}
|
||||
session.commit(createIntentSender(mContext, sessionId));
|
||||
}
|
||||
|
||||
private static IntentSender createIntentSender(Context context, int sessionId) {
|
||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(
|
||||
context, sessionId, new Intent(ACTION_INSTALL_COMPLETE), 0);
|
||||
return pendingIntent.getIntentSender();
|
||||
private void finishActivity() throws Exception {
|
||||
mCmdReceiverService.finishActivity();
|
||||
}
|
||||
}
|
||||
1
services/tests/servicestests/test-apps/Android.mk
Normal file
1
services/tests/servicestests/test-apps/Android.mk
Normal file
@@ -0,0 +1 @@
|
||||
include $(call all-subdir-makefiles)
|
||||
@@ -18,6 +18,8 @@ include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
|
||||
LOCAL_COMPATIBILITY_SUITE := device-tests
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := servicestests-aidl
|
||||
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
<application>
|
||||
<activity android:name=".ConnTestActivity"
|
||||
android:exported="true" />
|
||||
<service android:name=".CmdReceiverService"
|
||||
android:exported="true" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.servicestests.apps.conntestapp;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
|
||||
import com.android.servicestests.aidl.ICmdReceiverService;
|
||||
|
||||
public class CmdReceiverService extends Service {
|
||||
private ICmdReceiverService.Stub mBinder = new ICmdReceiverService.Stub() {
|
||||
@Override
|
||||
public void finishActivity() {
|
||||
ConnTestActivity.finishSelf();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.servicestests.aidl.INetworkStateObserver;
|
||||
|
||||
public class ConnTestActivity extends Activity {
|
||||
@@ -39,31 +40,64 @@ public class ConnTestActivity extends Activity {
|
||||
private static final String ACTION_FINISH_ACTIVITY = TEST_PKG + ".FINISH";
|
||||
private static final String EXTRA_NETWORK_STATE_OBSERVER = TEST_PKG + ".observer";
|
||||
|
||||
private static final Object INSTANCE_LOCK = new Object();
|
||||
@GuardedBy("instanceLock")
|
||||
private static Activity sInstance;
|
||||
|
||||
private BroadcastReceiver finishCommandReceiver = null;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
synchronized (INSTANCE_LOCK) {
|
||||
sInstance = this;
|
||||
}
|
||||
Log.i(TAG, "onCreate called");
|
||||
|
||||
notifyNetworkStateObserver();
|
||||
|
||||
finishCommandReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Log.i(TAG, "finish command received");
|
||||
ConnTestActivity.this.finish();
|
||||
}
|
||||
};
|
||||
registerReceiver(finishCommandReceiver, new IntentFilter(ACTION_FINISH_ACTIVITY));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
Log.i(TAG, "onResume called");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
Log.i(TAG, "onStop called");
|
||||
if (finishCommandReceiver != null) {
|
||||
unregisterReceiver(finishCommandReceiver);
|
||||
}
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
synchronized (INSTANCE_LOCK) {
|
||||
sInstance = null;
|
||||
}
|
||||
Log.i(TAG, "finish called");
|
||||
super.finish();
|
||||
}
|
||||
|
||||
public static void finishSelf() {
|
||||
synchronized (INSTANCE_LOCK) {
|
||||
if (sInstance != null) {
|
||||
sInstance.finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyNetworkStateObserver() {
|
||||
if (getIntent() == null) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user