| /* |
| * 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); |
| } |
| |
| } |