Loading apct-tests/perftests/multiuser/Android.mk 0 → 100644 +31 −0 Original line number Diff line number Diff line # 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) apct-tests/perftests/multiuser/AndroidManifest.xml 0 → 100644 +31 −0 Original line number Diff line number Diff line <?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 apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java 0 → 100644 +161 −0 Original line number Diff line number Diff line /* * 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 apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java +12 −3 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -64,9 +63,19 @@ 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. */ Loading Loading @@ -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; Loading Loading @@ -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(", "); } Loading Loading
apct-tests/perftests/multiuser/Android.mk 0 → 100644 +31 −0 Original line number Diff line number Diff line # 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)
apct-tests/perftests/multiuser/AndroidManifest.xml 0 → 100644 +31 −0 Original line number Diff line number Diff line <?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
apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java 0 → 100644 +161 −0 Original line number Diff line number Diff line /* * 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
apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java +12 −3 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -64,9 +63,19 @@ 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. */ Loading Loading @@ -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; Loading Loading @@ -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(", "); } Loading