summaryrefslogtreecommitdiff
path: root/native
diff options
context:
space:
mode:
authorChong Zhang <chz@google.com>2020-12-04 17:15:45 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2020-12-04 17:15:45 +0000
commitc4be44372d4059d41656c4b5207bead1bf4ec273 (patch)
tree20c2e2490a81ddbb7c69678f12518d42b5488e4f /native
parentcb95b8375bcdf7ce3ef02177f2dd3bc1bff9a195 (diff)
parente6bcd1bbb1331549cab40011d422f3b6fccbe90d (diff)
Merge "Add AActivityManager UidImportance test"
Diffstat (limited to 'native')
-rw-r--r--native/android/tests/activitymanager/UidImportanceHelperApps/Android.bp11
-rw-r--r--native/android/tests/activitymanager/UidImportanceHelperApps/HelperAppManifest.xml33
-rw-r--r--native/android/tests/activitymanager/UidImportanceHelperApps/src/com/android/tests/UidImportanceHelper/MainActivity.java107
-rw-r--r--native/android/tests/activitymanager/nativeTests/Android.bp39
-rw-r--r--native/android/tests/activitymanager/nativeTests/AndroidTest.xml53
-rw-r--r--native/android/tests/activitymanager/nativeTests/src/ActivityManagerNativeTest.cpp139
6 files changed, 382 insertions, 0 deletions
diff --git a/native/android/tests/activitymanager/UidImportanceHelperApps/Android.bp b/native/android/tests/activitymanager/UidImportanceHelperApps/Android.bp
new file mode 100644
index 000000000000..1a51218616d2
--- /dev/null
+++ b/native/android/tests/activitymanager/UidImportanceHelperApps/Android.bp
@@ -0,0 +1,11 @@
+android_test_helper_app {
+ name: "UidImportanceHelperApp",
+ manifest: "HelperAppManifest.xml",
+ static_libs: ["androidx.test.rules"],
+ sdk_version: "test_current",
+ srcs: ["src/**/*.java"],
+ test_suites: [
+ "general-tests",
+ ],
+}
+
diff --git a/native/android/tests/activitymanager/UidImportanceHelperApps/HelperAppManifest.xml b/native/android/tests/activitymanager/UidImportanceHelperApps/HelperAppManifest.xml
new file mode 100644
index 000000000000..3583b33756e9
--- /dev/null
+++ b/native/android/tests/activitymanager/UidImportanceHelperApps/HelperAppManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.tests.UidImportanceHelper"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <application android:label="UidImportanceHelper">
+ <activity android:name="com.android.tests.UidImportanceHelper.MainActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
+
diff --git a/native/android/tests/activitymanager/UidImportanceHelperApps/src/com/android/tests/UidImportanceHelper/MainActivity.java b/native/android/tests/activitymanager/UidImportanceHelperApps/src/com/android/tests/UidImportanceHelper/MainActivity.java
new file mode 100644
index 000000000000..db0f2b5ed967
--- /dev/null
+++ b/native/android/tests/activitymanager/UidImportanceHelperApps/src/com/android/tests/UidImportanceHelper/MainActivity.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2020 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.tests.UidImportanceHelper;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * This is an empty activity for testing the UID policy of media transcoding service.
+ */
+public class MainActivity extends Activity {
+ private static final String TAG = "MainActivity";
+
+ // Called at the start of the full lifetime.
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // Initialize Activity and inflate the UI.
+ }
+
+ // Called after onCreate has finished, use to restore UI state
+ @Override
+ public void onRestoreInstanceState(Bundle savedInstanceState) {
+ super.onRestoreInstanceState(savedInstanceState);
+ // Restore UI state from the savedInstanceState.
+ // This bundle has also been passed to onCreate.
+ // Will only be called if the Activity has been
+ // killed by the system since it was last visible.
+ }
+
+ // Called before subsequent visible lifetimes
+ // for an activity process.
+ @Override
+ public void onRestart() {
+ super.onRestart();
+ // Load changes knowing that the Activity has already
+ // been visible within this process.
+ }
+
+ // Called at the start of the visible lifetime.
+ @Override
+ public void onStart() {
+ super.onStart();
+ // Apply any required UI change now that the Activity is visible.
+ }
+
+ // Called at the start of the active lifetime.
+ @Override
+ public void onResume() {
+ super.onResume();
+ // Resume any paused UI updates, threads, or processes required
+ // by the Activity but suspended when it was inactive.
+ }
+
+ // Called to save UI state changes at the
+ // end of the active lifecycle.
+ @Override
+ public void onSaveInstanceState(Bundle savedInstanceState) {
+ // Save UI state changes to the savedInstanceState.
+ // This bundle will be passed to onCreate and
+ // onRestoreInstanceState if the process is
+ // killed and restarted by the run time.
+ super.onSaveInstanceState(savedInstanceState);
+ }
+
+ // Called at the end of the active lifetime.
+ @Override
+ public void onPause() {
+ // Suspend UI updates, threads, or CPU intensive processes
+ // that don't need to be updated when the Activity isn't
+ // the active foreground Activity.
+ super.onPause();
+ }
+
+ // Called at the end of the visible lifetime.
+ @Override
+ public void onStop() {
+ // Suspend remaining UI updates, threads, or processing
+ // that aren't required when the Activity isn't visible.
+ // Persist all edits or state changes
+ // as after this call the process is likely to be killed.
+ super.onStop();
+ }
+
+ // Sometimes called at the end of the full lifetime.
+ @Override
+ public void onDestroy() {
+ // Clean up any resources including ending threads,
+ // closing database connections etc.
+ super.onDestroy();
+ }
+}
diff --git a/native/android/tests/activitymanager/nativeTests/Android.bp b/native/android/tests/activitymanager/nativeTests/Android.bp
new file mode 100644
index 000000000000..d4b5015ad8f3
--- /dev/null
+++ b/native/android/tests/activitymanager/nativeTests/Android.bp
@@ -0,0 +1,39 @@
+cc_test {
+ name: "ActivityManagerNativeTestCases",
+
+ multilib: {
+ lib32: {
+ suffix: "32",
+ },
+ lib64: {
+ suffix: "64",
+ },
+ },
+
+ srcs: ["src/ActivityManagerNativeTest.cpp"],
+
+ shared_libs: [
+ "liblog",
+ "libutils",
+ "libandroid",
+ "libbinder",
+ ],
+
+ static_libs: [
+ "libbase",
+ "libgtest",
+ ],
+ stl: "c++_shared",
+
+ test_suites: [
+ "general-tests",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+ required: [
+ "UidImportanceHelperApp",
+ ],
+}
diff --git a/native/android/tests/activitymanager/nativeTests/AndroidTest.xml b/native/android/tests/activitymanager/nativeTests/AndroidTest.xml
new file mode 100644
index 000000000000..bf6287ad4883
--- /dev/null
+++ b/native/android/tests/activitymanager/nativeTests/AndroidTest.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Config for ActivityManager native test cases">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+ <option name="config-descriptor:metadata" key="component" value="framework" />
+ <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+
+ <!-- Force root to allow registering UidImportanceListener from native test -->
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ <option name="force-root" value="true" />
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command" value="input keyevent KEYCODE_WAKEUP" />
+ <option name="run-command" value="wm dismiss-keyguard" />
+ </target_preparer>
+ <!-- Install the helper apk -->
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="UidImportanceHelperApp.apk" />
+ </target_preparer>
+
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+ <option name="cleanup" value="true" />
+ <option name="push" value="ActivityManagerNativeTestCases->/data/local/tmp/ActivityManagerNativeTestCases" />
+ <option name="append-bitness" value="true" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="ActivityManagerNativeTestCases" />
+ <option name="runtime-hint" value="1m" />
+ </test>
+
+ <!-- Controller that will skip the module if a native bridge situation is detected -->
+ <!-- For example: module wants to run arm and device is x86 -->
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.NativeBridgeModuleController" />
+</configuration>
diff --git a/native/android/tests/activitymanager/nativeTests/src/ActivityManagerNativeTest.cpp b/native/android/tests/activitymanager/nativeTests/src/ActivityManagerNativeTest.cpp
new file mode 100644
index 000000000000..75ba0ffb229a
--- /dev/null
+++ b/native/android/tests/activitymanager/nativeTests/src/ActivityManagerNativeTest.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#define LOG_TAG "ActivityManagerNativeTest"
+
+#include <android-base/logging.h>
+#include <android/activity_manager.h>
+#include <binder/PermissionController.h>
+#include <binder/ProcessState.h>
+#include <gtest/gtest.h>
+
+constexpr const char* kTestPackage = "com.android.tests.UidImportanceHelper";
+constexpr const char* kTestActivity = "com.android.tests.UidImportanceHelper.MainActivity";
+constexpr int64_t kEventTimeoutUs = 500000;
+
+//-----------------------------------------------------------------
+class ActivityManagerNativeTest : public ::testing::Test {
+protected:
+ ActivityManagerNativeTest() : mUidObserver(nullptr), mTestAppUid(-1), mLastUidImportance(-1) {}
+
+ virtual ~ActivityManagerNativeTest() {}
+
+ /* Test setup*/
+ virtual void SetUp() { android::ProcessState::self()->startThreadPool(); }
+
+ /* Test tear down */
+ virtual void TearDown() {}
+
+ bool waitForImportance(int32_t val, int64_t timeoutUs) {
+ std::unique_lock lock(mLock);
+
+ if (mLastUidImportance != val && timeoutUs > 0) {
+ mCondition.wait_for(lock, std::chrono::microseconds(timeoutUs));
+ }
+
+ return mLastUidImportance == val;
+ }
+
+ void onUidImportanceChanged(uid_t uid, int32_t uidImportance) {
+ LOG(ERROR) << "OnUidImportance: uid " << uid << ", importance " << uidImportance;
+ std::unique_lock lock(mLock);
+
+ if (uid == mTestAppUid) {
+ mLastUidImportance = uidImportance;
+ mCondition.notify_one();
+ }
+ }
+
+ static void OnUidImportance(uid_t uid, int32_t uidImportance, void* cookie) {
+ ActivityManagerNativeTest* owner = reinterpret_cast<ActivityManagerNativeTest*>(cookie);
+ owner->onUidImportanceChanged(uid, uidImportance);
+ }
+
+ AActivityManager_UidImportanceListener* mUidObserver;
+ uid_t mTestAppUid;
+ std::mutex mLock;
+ std::condition_variable mCondition;
+ int32_t mLastUidImportance;
+};
+
+static bool getUidForPackage(const char* packageName, /*inout*/ uid_t& uid) {
+ android::PermissionController pc;
+ uid = pc.getPackageUid(android::String16(packageName), 0);
+ if (uid <= 0) {
+ ALOGE("Unknown package: '%s'", packageName);
+ return false;
+ }
+ return true;
+}
+
+struct ShellHelper {
+ static bool RunCmd(const std::string& cmdStr) {
+ int ret = system(cmdStr.c_str());
+ if (ret != 0) {
+ LOG(ERROR) << "Failed to run cmd: " << cmdStr << ", exitcode " << ret;
+ return false;
+ }
+ return true;
+ }
+
+ static bool Start(const char* packageName, const char* activityName) {
+ return RunCmd("am start -W " + std::string(packageName) + "/" + std::string(activityName) +
+ " &> /dev/null");
+ }
+
+ static bool Stop(const char* packageName) {
+ return RunCmd("am force-stop " + std::string(packageName));
+ }
+};
+
+//-------------------------------------------------------------------------------------------------
+TEST_F(ActivityManagerNativeTest, testUidImportance) {
+ pid_t selfPid = ::getpid();
+ uid_t selfUid = ::getuid();
+
+ uid_t testAppUid;
+ EXPECT_TRUE(getUidForPackage(kTestPackage, testAppUid));
+ LOG(INFO) << "testUidImportance: uidselfUid" << selfUid << ", selfPid " << selfPid
+ << ", testAppUid " << testAppUid;
+ mTestAppUid = testAppUid;
+
+ // Expect the initial UidImportance to be GONE.
+ EXPECT_FALSE(AActivityManager_isUidActive(testAppUid));
+ EXPECT_EQ(AActivityManager_getUidImportance(testAppUid), AACTIVITYMANAGER_IMPORTANCE_GONE);
+
+ mUidObserver = AActivityManager_addUidImportanceListener(&OnUidImportance,
+ AACTIVITYMANAGER_IMPORTANCE_FOREGROUND,
+ (void*)this);
+ EXPECT_TRUE(mUidObserver != nullptr);
+
+ // Start the test activity, and expect to receive UidImportance change to FOREGROUND.
+ EXPECT_TRUE(ShellHelper::Start(kTestPackage, kTestActivity));
+ EXPECT_TRUE(waitForImportance(AACTIVITYMANAGER_IMPORTANCE_FOREGROUND, kEventTimeoutUs));
+ EXPECT_TRUE(AActivityManager_isUidActive(testAppUid));
+ EXPECT_EQ(AActivityManager_getUidImportance(testAppUid),
+ AACTIVITYMANAGER_IMPORTANCE_FOREGROUND);
+
+ // Stop the test activity, and expect to receive UidImportance change to GONE.
+ EXPECT_TRUE(ShellHelper::Stop(kTestPackage));
+ EXPECT_TRUE(waitForImportance(AACTIVITYMANAGER_IMPORTANCE_GONE, kEventTimeoutUs));
+ EXPECT_FALSE(AActivityManager_isUidActive(testAppUid));
+ EXPECT_EQ(AActivityManager_getUidImportance(testAppUid), AACTIVITYMANAGER_IMPORTANCE_GONE);
+
+ AActivityManager_removeUidImportanceListener(mUidObserver);
+ mUidObserver = nullptr;
+}