| /* |
| * Copyright (C) 2008 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.emulatorprovisionlib; |
| |
| import android.app.Activity; |
| import android.app.StatusBarManager; |
| import android.content.ComponentName; |
| import android.content.Context; |
| import android.content.pm.PackageManager; |
| import android.hardware.input.InputManager; |
| import android.hardware.input.KeyboardLayout; |
| import android.location.LocationManager; |
| import android.net.wifi.WifiManager; |
| import android.net.wifi.WifiConfiguration; |
| import android.provider.Settings; |
| import android.os.Bundle; |
| import android.os.Process; |
| import android.os.RemoteException; |
| import android.os.ServiceManager; |
| import android.os.SystemProperties; |
| import android.telephony.TelephonyManager; |
| import android.util.Log; |
| import android.view.InputDevice; |
| |
| public abstract class ProvisionActivity extends Activity { |
| protected abstract String TAG(); |
| private StatusBarManager mStatusBarManager; |
| |
| @Override |
| protected void onCreate(Bundle icicle) { |
| super.onCreate(icicle); |
| |
| if (Settings.Global.getInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 1) { |
| preProvivion(); |
| doProvision(); |
| postProvision(); |
| } else { |
| Log.w(TAG(), "Already provisioned, remove itself."); |
| removeSelf(); |
| } |
| |
| finish(); // terminate the activity. |
| } |
| |
| protected void preProvivion() { |
| final Context appContext = getApplicationContext(); |
| mStatusBarManager = appContext.getSystemService(StatusBarManager.class); |
| |
| mStatusBarManager.setDisabledForSetup(true); |
| } |
| |
| protected void postProvision() { |
| mStatusBarManager.setDisabledForSetup(false); |
| |
| removeSelf(); |
| |
| // Add a persistent setting to allow other apps to know the device has been provisioned. |
| Settings.Secure.putInt(getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 1); |
| Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1); |
| } |
| |
| // remove this activity from the package manager. |
| protected void removeSelf() { |
| getPackageManager().setComponentEnabledSetting( |
| new ComponentName(this, this.getClass()), |
| PackageManager.COMPONENT_ENABLED_STATE_DISABLED, |
| PackageManager.DONT_KILL_APP); |
| } |
| |
| protected void doProvision() { |
| provisionWifi("AndroidWifi"); |
| provisionKeyboard("qwerty2"); |
| provisionDisplay(); |
| provisionTelephony(); |
| provisionLocation(); |
| provisionAdb(); |
| |
| Settings.Secure.putInt(getContentResolver(), Settings.Secure.INSTALL_NON_MARKET_APPS, 1); |
| } |
| |
| protected void provisionWifi(final String ssid) { |
| Settings.Global.putInt(getContentResolver(), Settings.Global.TETHER_OFFLOAD_DISABLED, 1); |
| |
| final int ADD_NETWORK_FAIL = -1; |
| final String quotedSsid = "\"" + ssid + "\""; |
| |
| final WifiConfiguration config = new WifiConfiguration(); |
| config.SSID = quotedSsid; |
| config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN); |
| |
| final WifiManager mWifiManager = getApplicationContext().getSystemService(WifiManager.class); |
| final int netId = mWifiManager.addNetwork(config); |
| |
| if (netId == ADD_NETWORK_FAIL || !mWifiManager.enableNetwork(netId, true)) { |
| Log.e(TAG(), "Unable to add Wi-Fi network " + quotedSsid + "."); |
| } |
| } |
| |
| // Set physical keyboard layout based on the system property set by emulator host. |
| protected void provisionKeyboard(final String deviceName) { |
| final String layoutName = SystemProperties.get("vendor.qemu.keyboard_layout"); |
| final InputDevice device = getKeyboardDevice(deviceName); |
| if (device != null && !layoutName.isEmpty()) { |
| setKeyboardLayout(device, layoutName); |
| } |
| } |
| |
| protected void provisionDisplay() { |
| final int screen_off_timeout = |
| SystemProperties.getInt("ro.boot.qemu.settings.system.screen_off_timeout", 0); |
| if (screen_off_timeout > 0) { |
| Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, screen_off_timeout); |
| Log.i(TAG(), "Setting system screen_off_timeout to be " + screen_off_timeout + " ms"); |
| } |
| |
| final String displaySettingsProp = "ro.boot.qemu.display.settings.xml"; |
| final String displaySettingsName = SystemProperties.get(displaySettingsProp); |
| if ("freeform".equals(displaySettingsName)) { |
| Settings.Global.putInt(getContentResolver(), "sf", 1); |
| Settings.Global.putString(getContentResolver(), |
| Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, "1"); |
| Settings.Global.putString(getContentResolver(), |
| Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, "1"); |
| Settings.Global.putString(getContentResolver(), |
| Settings.Global.DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH, |
| "vendor/etc/display_settings_freeform.xml"); |
| } else if ("resizable".equals(displaySettingsName)) { |
| // Enable auto rotate for resizable AVD |
| Settings.System.putString(getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, "1"); |
| } else if (!displaySettingsName.isEmpty()) { |
| Log.e(TAG(), "Unexpected value `" + displaySettingsName + "` in " + displaySettingsProp); |
| } |
| } |
| |
| protected void provisionTelephony() { |
| // b/193418404 |
| // the following blocks, TODO: find out why and fix it. disable this for now. |
| // TelephonyManager mTelephony = getApplicationContext().getSystemService(TelephonyManager.class); |
| // mTelephony.setPreferredNetworkTypeBitmask(TelephonyManager.NETWORK_TYPE_BITMASK_NR); |
| } |
| |
| protected void provisionLocation() { |
| final LocationManager lm = getSystemService(LocationManager.class); |
| lm.setLocationEnabledForUser(true, Process.myUserHandle()); |
| |
| // Enable the GPS. |
| // Not needed since this SDK will contain the Settings app. |
| Settings.Secure.putString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, |
| LocationManager.GPS_PROVIDER); |
| } |
| |
| protected void provisionAdb() { |
| Settings.Global.putInt(getContentResolver(), Settings.Global.ADB_ENABLED, 1); |
| Settings.Global.putInt(getContentResolver(), Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 0); |
| } |
| |
| protected InputDevice getKeyboardDevice(final String keyboardDeviceName) { |
| final int[] deviceIds = InputDevice.getDeviceIds(); |
| |
| for (int deviceId : deviceIds) { |
| InputDevice inputDevice = InputDevice.getDevice(deviceId); |
| if (inputDevice != null |
| && inputDevice.supportsSource(InputDevice.SOURCE_KEYBOARD) |
| && inputDevice.getName().equals(keyboardDeviceName)) { |
| return inputDevice; |
| } |
| } |
| |
| return null; |
| } |
| |
| protected void setKeyboardLayout(final InputDevice keyboardDevice, final String layoutName) { |
| final InputManager im = InputManager.getInstance(); |
| |
| final KeyboardLayout[] keyboardLayouts = |
| im.getKeyboardLayoutsForInputDevice(keyboardDevice.getIdentifier()); |
| |
| for (KeyboardLayout keyboardLayout : keyboardLayouts) { |
| if (keyboardLayout.getDescriptor().endsWith(layoutName)) { |
| im.setCurrentKeyboardLayoutForInputDevice( |
| keyboardDevice.getIdentifier(), keyboardLayout.getDescriptor()); |
| return; |
| } |
| } |
| } |
| } |