diff options
author | Jinhui Wang <jinhuiw@google.com> | 2016-06-10 17:24:24 -0700 |
---|---|---|
committer | Jinhui Wang <jinhuiw@google.com> | 2016-06-21 22:32:51 -0700 |
commit | 631b333f646cf60560a7e869901b484fe5bdb7d4 (patch) | |
tree | d525547c86af904e73cc0e8b9e6fafecbf40b927 | |
parent | 8c28a9831d53a17178c4f3acd96ff992eef2eb77 (diff) | |
download | AfwTestHarness-631b333f646cf60560a7e869901b484fe5bdb7d4.tar.gz |
Import AfwThSystemUtil module
Change-Id: I45cf7055face09b2795ec4837d2e82de5f7dc5c7
12 files changed, 466 insertions, 7 deletions
diff --git a/apps/Android.mk b/apps/Android.mk new file mode 100644 index 0000000..6801acf --- /dev/null +++ b/apps/Android.mk @@ -0,0 +1,18 @@ +# +# 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. +# + +include $(call all-subdir-makefiles) + diff --git a/apps/DeviceAdmin/Android.mk b/apps/DeviceAdmin/Android.mk index 8a154d9..a107fbe 100644 --- a/apps/DeviceAdmin/Android.mk +++ b/apps/DeviceAdmin/Android.mk @@ -22,7 +22,7 @@ LOCAL_MODULE_TAGS := optional LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) -LOCAL_STATIC_JAVA_LIBRARIES := AfwTestCommonLib +LOCAL_STATIC_JAVA_LIBRARIES := AfwThCommonLib LOCAL_SRC_FILES := $(call all-java-files-under, src) @@ -30,4 +30,4 @@ LOCAL_PACKAGE_NAME := AfwThDeviceAdmin LOCAL_SDK_VERSION := 22 -include $(BUILD_AFW_TEST_SUPPORT_PACKAGE) +include $(BUILD_AFW_TH_SUPPORT_PACKAGE) diff --git a/apps/SystemUtil/Android.mk b/apps/SystemUtil/Android.mk new file mode 100644 index 0000000..2ea02ab --- /dev/null +++ b/apps/SystemUtil/Android.mk @@ -0,0 +1,33 @@ +# +# 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 := optional + +LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) + +LOCAL_STATIC_JAVA_LIBRARIES := AfwThCommonLib + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_PACKAGE_NAME := AfwThSystemUtil + +LOCAL_SDK_VERSION := 22 + +include $(BUILD_AFW_TH_SUPPORT_PACKAGE) diff --git a/apps/SystemUtil/AndroidManifest.xml b/apps/SystemUtil/AndroidManifest.xml new file mode 100644 index 0000000..0d0436b --- /dev/null +++ b/apps/SystemUtil/AndroidManifest.xml @@ -0,0 +1,51 @@ +<?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.afwtest.systemutil" > + + <uses-sdk android:minSdkVersion="22" /> + + <uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/> + <uses-permission android:name="android.permission.DISPATCH_NFC_MESSAGE" /> + <uses-permission android:name="android.permission.GET_ACCOUNTS" /> + <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" /> + + <instrumentation + android:name=".RemoveGoogleAccount" + android:label="Remove Google Account" + android:targetPackage="com.android.afwtest.systemutil" > + </instrumentation> + + <instrumentation + android:name=".ChangeLocale" + android:label="Change the device locale" + android:targetPackage="com.android.afwtest.systemutil" > + </instrumentation> + + <application android:label="Afw Test Harness System Util"> + <!-- NFC Bump Sender activity --> + <activity + android:name="com.android.afwtest.systemutil.NfcBumpSender" + android:label="NFC Bump Sender" > + <intent-filter> + <action android:name="com.android.afwtest.systemutil.action.SEND_NFC_BUMP" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/apps/SystemUtil/README b/apps/SystemUtil/README new file mode 100644 index 0000000..fc4e3a0 --- /dev/null +++ b/apps/SystemUtil/README @@ -0,0 +1,34 @@ +- About + + System util app. It must be pushed to /system/priv-app on the device. + Requires a device where 'adb root' is possible, typically a userdebug build. + +- Build & Install: + + make AfwThSystemUtil + adb root + adb remount + adb push AfwThSystemUtil.apk /system/priv-app + adb reboot + +- Usage + + - Remove all Google accounts: + adb shell am instrument -w com.android.afwtest.systemutil/.RemoveGoogleAccount + + - Remove a Google account: + adb shell am instrument \ + -w -e account accountName com.android.afwtest.systemutil/.RemoveGoogleAccount + + - Change system locale + adb shell am instrument \ + -w -e locale locale_code com.android.afwtest.systemutil/.ChangeLocale + + - locale_code can be language code only or languageCode_COUNTRYCODE, e.g. en, en_US, en_UK, zh_CN. + + - Simulate a NFC bump + Configure the parameters you would like to be sent in the nfc bump by editing afw-test.props + + adb push afw-test.props /data/local/tmp/afw-test.props + adb shell am start -n com.android.afwtest.systemutil/.NfcBumpSender + -e NFCBumpFile "/data/local/tmp/afw-test.props" diff --git a/apps/SystemUtil/src/com/android/afwtest/systemutil/ChangeLocale.java b/apps/SystemUtil/src/com/android/afwtest/systemutil/ChangeLocale.java new file mode 100644 index 0000000..038c1f4 --- /dev/null +++ b/apps/SystemUtil/src/com/android/afwtest/systemutil/ChangeLocale.java @@ -0,0 +1,111 @@ +/* + * 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 com.android.afwtest.systemutil; + +import android.app.Activity; +import android.app.Instrumentation; +import android.content.res.Configuration; +import android.os.Bundle; +import android.util.Log; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Locale; + +/** + * Change the system locale. + **/ +public class ChangeLocale extends Instrumentation { + private static final String TAG = "afwtest.ChangeLocale"; + + // Locale code, expecting something like: en, en_US, en_UK, zh, zh_CN, zh_TW. + private String mLocale; + + /** + * {@inheritDoc} + */ + @Override + public void onCreate(Bundle arguments) { + super.onCreate(arguments); + mLocale = arguments.getString("locale", ""); + start(); + } + + /** + * {@inheritDoc} + */ + @Override + public void onStart() { + super.onStart(); + + // Locale must be specified. + if (mLocale.isEmpty()) { + handleError("Locale is not specified"); + return; + } + + Log.i(TAG, String.format("Attempting to change locale to %s", mLocale)); + + try { + // It could be en_US or en. + final String[] codes = mLocale.split("_"); + final Locale locale = + codes.length > 1 ? new Locale(codes[0], codes[1]) : new Locale(codes[0]); + + // Change locale through reflection. + Class amnClass = Class.forName("android.app.ActivityManagerNative"); + Method getDefault = amnClass.getMethod("getDefault"); + getDefault.setAccessible(true); + Object amn = getDefault.invoke(amnClass); + + Method getConfig = amnClass.getMethod("getConfiguration"); + getConfig.setAccessible(true); + Configuration config = (Configuration) getConfig.invoke(amn); + + Field field = config.getClass().getField("userSetLocale"); + field.setBoolean(config, true); + + // Set new locale. + config.locale = locale; + + // Update configuration. + Method updateConfig = amnClass.getMethod("updateConfiguration", Configuration.class); + updateConfig.setAccessible(true); + updateConfig.invoke(amn, config); + + // Success + Bundle results = new Bundle(); + results.putString("result", "SUCCESS"); + finish(Activity.RESULT_OK, results); + } catch (Exception e) { + Log.e(TAG, "Failed to change locale", e); + handleError(String.format("Failed to change locale: %s", e)); + } + } + + /** + * Handles error by exiting instrumentation. + * + * @param errorMsg error msg + */ + private void handleError(String errorMsg) { + Bundle results = new Bundle(); + results.putString("error", errorMsg); + finish(Activity.RESULT_CANCELED, results); + } + +} diff --git a/apps/SystemUtil/src/com/android/afwtest/systemutil/NfcBumpSender.java b/apps/SystemUtil/src/com/android/afwtest/systemutil/NfcBumpSender.java new file mode 100644 index 0000000..636d537 --- /dev/null +++ b/apps/SystemUtil/src/com/android/afwtest/systemutil/NfcBumpSender.java @@ -0,0 +1,61 @@ +/* + * 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 com.android.afwtest.systemutil; + +import static com.android.afwtest.common.Constants.NFC_BUMP_FILE; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; + +import java.io.IOException; + +import com.android.afwtest.common.nfcprovisioning.NfcBumpSimulator; + +/** + * Activity to send a nfc bump. + */ +public class NfcBumpSender extends Activity { + + private static final String TAG = "afwtest.NfcBumpSender"; + + /** + * {@inheritDoc} + */ + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + try { + Intent intent = getIntent(); + // Gets the path of the file that containing the parameters to be sent + // in the nfc bump. + if (intent.hasExtra(NFC_BUMP_FILE)) { + String bumpFileLocation = getIntent().getStringExtra(NFC_BUMP_FILE); + NfcBumpSimulator.sendNfcBump(this, bumpFileLocation); + Log.d(TAG, String.format("%s=%s", NFC_BUMP_FILE, bumpFileLocation)); + } else { + Log.e(TAG, String.format("Nfc bump not sent." + + "Intent doesn't contain extra %s.", NFC_BUMP_FILE)); + } + } catch (IOException e) { + Log.e(TAG, "Failed to send Nfc Bump", e); + } + finish(); + } +} diff --git a/apps/SystemUtil/src/com/android/afwtest/systemutil/RemoveGoogleAccount.java b/apps/SystemUtil/src/com/android/afwtest/systemutil/RemoveGoogleAccount.java new file mode 100644 index 0000000..dc57c1d --- /dev/null +++ b/apps/SystemUtil/src/com/android/afwtest/systemutil/RemoveGoogleAccount.java @@ -0,0 +1,151 @@ +/* + * 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 com.android.afwtest.systemutil; + +import android.accounts.Account; +import android.accounts.AccountManager; +import android.accounts.AccountManagerCallback; +import android.accounts.AccountManagerFuture; +import android.accounts.AuthenticatorException; +import android.accounts.OperationCanceledException; +import android.app.Activity; +import android.app.Instrumentation; +import android.os.Bundle; +import android.util.Log; + +import java.io.IOException; +import java.util.concurrent.Semaphore; + +/** + * An instrumentation utility to remove Google account from device. + */ +public class RemoveGoogleAccount extends Instrumentation { + + private static final String TAG = "afwtest.RemoveGoogleAccount"; + + // Account to remove; remove all Google accounts if null. + private String mAccount; + + @Override + public void onCreate(Bundle arguments) { + super.onCreate(arguments); + mAccount = arguments.getString("account", null); + start(); + } + + /** + * {@inheritDoc} + */ + @Override + public void onStart() { + super.onStart(); + + Log.d(TAG, "Attempting to remove Google accounts"); + Bundle results = new Bundle(); + + AccountManager accountManager = AccountManager.get(getContext()); + Account[] accounts = accountManager.getAccountsByType("com.google"); + for (Account account : accounts) { + if (mAccount == null || account.name.equals(mAccount)) { + Log.i(TAG, String.format("Removing account %s", account.name)); + RemoveCallback callback = new RemoveCallback(); + accountManager.removeAccount(account, callback, null /* handler */); + if (!callback.waitForRemoveCompletion()) { + String error = String.format("Failed to remove account %s: Reason: %s", + account.name, callback.getErrorMessage()); + results.putString("error", error); + finish(Activity.RESULT_CANCELED, results); + return; + } + } + } + results.putString("result", "SUCCESS"); + finish(Activity.RESULT_OK, results); + } + + /** + * Callback which will block until account removal result is available or exception throws. + */ + private static class RemoveCallback implements AccountManagerCallback<Boolean> { + + private static final String TAG = "afwtest.RemoveCallback"; + + /** + * Stores the result of account removal. + */ + private boolean mResult = false; + + /** + * Error message if any. + */ + private String mErrorMessage = null; + + /** + * {@link Semaphore}, indicating result is available if it's value > 0. + */ + private Semaphore mLock = new Semaphore(0); + + /** + * Block and wait for the remove callback to complete. + * + * @return the {@link Bundle} result from the remove op. + */ + + public Boolean waitForRemoveCompletion() { + try { + // Blocks until semaphore count > 0 + mLock.acquire(); + } catch (InterruptedException e) { + handleException(e); + } + return mResult; + } + + /** + * {@inheritDoc} + */ + @Override + public void run(AccountManagerFuture<Boolean> future) { + try { + mResult = future.getResult(); + } catch (OperationCanceledException | IOException | AuthenticatorException e) { + handleException(e); + } finally { + // Increment semaphore count by 1. + mLock.release(); + } + } + + /** + * Gets the error message. + * + * @return error message + */ + public String getErrorMessage() { + return mErrorMessage; + } + + /** + * Creates a result bundle for given exception + */ + private void handleException(Exception e) { + Log.e(TAG, "Failed to remove account", e); + mResult = false; + mErrorMessage = e.toString(); + } + } +} diff --git a/libs/CommonLib/src/com/android/afwtest/common/Constants.java b/libs/CommonLib/src/com/android/afwtest/common/Constants.java index b708037..de50839 100644 --- a/libs/CommonLib/src/com/android/afwtest/common/Constants.java +++ b/libs/CommonLib/src/com/android/afwtest/common/Constants.java @@ -164,13 +164,13 @@ public final class Constants { /** * Package name of system util app. */ - public static final String SYSTEM_UTIL_PKG_NAME = "com.google.android.afwtest.systemutil"; + public static final String SYSTEM_UTIL_PKG_NAME = "com.android.afwtest.systemutil"; /** * Send NFC bump action. */ public static final String ACTION_SEND_NFC_BUMP - = "com.google.android.afwtest.systemutil.action.SEND_NFC_BUMP"; + = "com.android.afwtest.systemutil.action.SEND_NFC_BUMP"; /** * Private constructor to prevent instantiation. diff --git a/libs/CommonLib/src/com/android/afwtest/common/nfcprovisioning/NfcBumpSimulator.java b/libs/CommonLib/src/com/android/afwtest/common/nfcprovisioning/NfcBumpSimulator.java index 44e2505..d38a997 100644 --- a/libs/CommonLib/src/com/android/afwtest/common/nfcprovisioning/NfcBumpSimulator.java +++ b/libs/CommonLib/src/com/android/afwtest/common/nfcprovisioning/NfcBumpSimulator.java @@ -56,7 +56,7 @@ public final class NfcBumpSimulator { * @param propsConfigFile {@link Properties} configuration file containing NFC bump properties. * @return Device admin package name after provisioning completes successfully */ - public static String sendNfcBump(Context context, String propsConfigFile) throws Exception { + public static String sendNfcBump(Context context, String propsConfigFile) throws IOException { TestConfig testConfig = TestConfig.get(propsConfigFile); diff --git a/libs/CommonLib/src/com/android/afwtest/common/nfcprovisioning/Utils.java b/libs/CommonLib/src/com/android/afwtest/common/nfcprovisioning/Utils.java index 45fec51..810846a 100644 --- a/libs/CommonLib/src/com/android/afwtest/common/nfcprovisioning/Utils.java +++ b/libs/CommonLib/src/com/android/afwtest/common/nfcprovisioning/Utils.java @@ -36,7 +36,7 @@ import java.util.Properties; public final class Utils { /** - * Start provisioning by sending an intent to AfwTestSystemUtil app. + * Start provisioning by sending an intent to AfwThSystemUtil app. * * @param context {@link Context} object * @param nfcBumpFilePath path of the file containing the parameters to be sent in the Nfc bump diff --git a/libs/UiAutomatorLib/src/com/android/afwtest/uiautomator/Constants.java b/libs/UiAutomatorLib/src/com/android/afwtest/uiautomator/Constants.java index 51e3101..5bb5bcf 100644 --- a/libs/UiAutomatorLib/src/com/android/afwtest/uiautomator/Constants.java +++ b/libs/UiAutomatorLib/src/com/android/afwtest/uiautomator/Constants.java @@ -35,7 +35,7 @@ public final class Constants { public static final String ANDROID_PKG_NAME = "android"; /** - * GMSCore Pakcage name. + * GMSCore package name. */ public static final String GMS_PKG_NAME = "com.google.android.gms"; |