diff options
author | Sudheer Shanka <sudheersai@google.com> | 2016-08-17 19:34:58 -0700 |
---|---|---|
committer | Sudheer Shanka <sudheersai@google.com> | 2016-08-19 16:36:23 -0700 |
commit | 53c23fdd5cf454c0f035e307ed5fda673b8b62dd (patch) | |
tree | 3fa3fc34b69a748414782cec8a3515e7cd2c3840 | |
parent | 412b630bb677e5734287ee4439253e111aa7bad0 (diff) |
Add usermanager related perf tests - part1
Bug: 30948225
Change-Id: I0668a012435e9954729e5085fdb4b1f5ce422d97
4 files changed, 235 insertions, 3 deletions
diff --git a/apct-tests/perftests/multiuser/Android.mk b/apct-tests/perftests/multiuser/Android.mk new file mode 100644 index 000000000000..f67004358ee6 --- /dev/null +++ b/apct-tests/perftests/multiuser/Android.mk @@ -0,0 +1,31 @@ +# Copyright (C) 2016 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. + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_STATIC_JAVA_LIBRARIES := \ + android-support-test \ + apct-perftests-utils + +LOCAL_PACKAGE_NAME := MultiUserPerfTests + +LOCAL_CERTIFICATE := platform + +include $(BUILD_PACKAGE) + diff --git a/apct-tests/perftests/multiuser/AndroidManifest.xml b/apct-tests/perftests/multiuser/AndroidManifest.xml new file mode 100644 index 000000000000..ace71068fe20 --- /dev/null +++ b/apct-tests/perftests/multiuser/AndroidManifest.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2016 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.multiuser.frameworks.perftests"> + + <uses-permission android:name="android.permission.MANAGE_USERS" /> + <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" /> + <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> + + <application> + <uses-library android:name="android.test.runner" /> + </application> + + <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.multiuser.frameworks.perftests"/> + +</manifest>
\ No newline at end of file diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java new file mode 100644 index 000000000000..bd0139f7811d --- /dev/null +++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2016 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.multiuser; + +import android.app.ActivityManager; +import android.app.ActivityManagerNative; +import android.app.IActivityManager; +import android.app.SynchronousUserSwitchObserver; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.UserInfo; +import android.os.RemoteException; +import android.os.UserHandle; +import android.os.UserManager; +import android.perftests.utils.BenchmarkState; +import android.perftests.utils.PerfStatusReporter; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.LargeTest; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.ArrayList; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +@LargeTest +@RunWith(AndroidJUnit4.class) +public class UserLifecycleTest { + private final int MIN_REPEAT_TIMES = 4; + + private final int TIMEOUT_REMOVE_USER_SEC = 4; + private final int CHECK_USER_REMOVED_INTERVAL_MS = 200; // 0.2 sec + + private final int TIMEOUT_USER_START_SEC = 4; // 4 sec + + private final int TIMEOUT_USER_SWITCH_SEC = 8; // 8 sec + + private UserManager mUm; + private ActivityManager mAm; + private IActivityManager mIam; + private BenchmarkState mState; + private ArrayList<Integer> mUsersToRemove; + + @Rule + public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); + + @Before + public void setUp() { + final Context context = InstrumentationRegistry.getContext(); + mUm = UserManager.get(context); + mAm = context.getSystemService(ActivityManager.class); + mIam = ActivityManagerNative.getDefault(); + mState = mPerfStatusReporter.getBenchmarkState(); + mState.setMinRepeatTimes(MIN_REPEAT_TIMES); + mUsersToRemove = new ArrayList<>(); + } + + @After + public void tearDown() { + for (int userId : mUsersToRemove) { + mUm.removeUser(userId); + } + } + + @Test + public void createAndStartUserPerf() throws Exception { + while (mState.keepRunning()) { + final UserInfo userInfo = mUm.createUser("TestUser", 0); + + final CountDownLatch latch = new CountDownLatch(1); + InstrumentationRegistry.getContext().registerReceiverAsUser(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (Intent.ACTION_USER_STARTED.equals(intent.getAction())) { + latch.countDown(); + } + } + }, UserHandle.ALL, new IntentFilter(Intent.ACTION_USER_STARTED), null, null); + mIam.startUserInBackground(userInfo.id); + latch.await(TIMEOUT_USER_START_SEC, TimeUnit.SECONDS); + + mState.pauseTiming(); + removeUser(userInfo.id); + mState.resumeTiming(); + } + } + + @Test + public void switchUserPerf() throws Exception { + while (mState.keepRunning()) { + mState.pauseTiming(); + final int startUser = mAm.getCurrentUser(); + final UserInfo userInfo = mUm.createUser("TestUser", 0); + mState.resumeTiming(); + + switchUser(userInfo.id); + + mState.pauseTiming(); + switchUser(startUser); + removeUser(userInfo.id); + mState.resumeTiming(); + } + } + + private void switchUser(int userId) throws Exception { + final CountDownLatch latch = new CountDownLatch(1); + registerUserSwitchObserver(latch); + mAm.switchUser(userId); + latch.await(TIMEOUT_USER_SWITCH_SEC, TimeUnit.SECONDS); + } + + private void registerUserSwitchObserver(final CountDownLatch latch) throws Exception { + ActivityManagerNative.getDefault().registerUserSwitchObserver( + new SynchronousUserSwitchObserver() { + @Override + public void onUserSwitching(int newUserId) throws RemoteException { + } + + @Override + public void onUserSwitchComplete(int newUserId) throws RemoteException { + latch.countDown(); + } + + @Override + public void onForegroundProfileSwitch(int newProfileId) throws RemoteException { + } + }, "UserLifecycleTest"); + } + + private void removeUser(int userId) throws Exception { + mUm.removeUser(userId); + final long startTime = System.currentTimeMillis(); + while (mUm.getUserInfo(userId) != null && + System.currentTimeMillis() - startTime < TIMEOUT_REMOVE_USER_SEC) { + Thread.sleep(CHECK_USER_REMOVED_INTERVAL_MS); + } + if (mUm.getUserInfo(userId) != null) { + mUsersToRemove.add(userId); + } + } +}
\ No newline at end of file diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java b/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java index 4213e4a3aa2b..b27d71b943a1 100644 --- a/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java +++ b/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java @@ -48,7 +48,6 @@ public class BenchmarkState { private static final int RUNNING = 2; // The benchmark is running. private static final int RUNNING_PAUSED = 3; // The benchmark is temporary paused. private static final int FINISHED = 4; // The benchmark has stopped. - private static final int MIN_REPEAT_TIMES = 16; private int mState = NOT_STARTED; // Current benchmark state. @@ -64,10 +63,20 @@ public class BenchmarkState { private double mMean = 0.0; private double mStandardDeviation = 0.0; + // Number of iterations needed for calculating the stats. + private int mMinRepeatTimes = 16; + // Individual duration in nano seconds. private ArrayList<Long> mResults = new ArrayList<>(); /** + * Sets the number of iterations needed for calculating the stats. Default is 16. + */ + public void setMinRepeatTimes(int minRepeatTimes) { + mMinRepeatTimes = minRepeatTimes; + } + + /** * Calculates statistics. */ private void calculateSatistics() { @@ -133,7 +142,7 @@ public class BenchmarkState { mNanoPausedDuration = 0; // To calculate statistics, needs two or more samples. - if (mResults.size() > MIN_REPEAT_TIMES && currentTime > mNanoFinishTime) { + if (mResults.size() > mMinRepeatTimes && currentTime > mNanoFinishTime) { calculateSatistics(); mState = FINISHED; return false; @@ -181,7 +190,7 @@ public class BenchmarkState { sb.append("sigma=").append(standardDeviation()).append(", "); sb.append("iteration=").append(mResults.size()).append(", "); // print out the first few iterations' number for double checking. - int sampleNumber = Math.min(mResults.size(), MIN_REPEAT_TIMES); + int sampleNumber = Math.min(mResults.size(), mMinRepeatTimes); for (int i = 0; i < sampleNumber; i++) { sb.append("No ").append(i).append(" result is ").append(mResults.get(i)).append(", "); } |