Merge "Add AActivityManager UidImportance test"

This commit is contained in:
Chong Zhang
2020-12-04 17:15:45 +00:00
committed by Android (Google) Code Review
6 changed files with 382 additions and 0 deletions

View File

@@ -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",
],
}

View File

@@ -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>

View File

@@ -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();
}
}

View File

@@ -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",
],
}

View File

@@ -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>

View File

@@ -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;
}