blob: 038c1f464d860999a04fed512740c34403e834e6 [file] [log] [blame]
/*
* 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);
}
}