1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.emulatorprovisionlib; 18 19 import android.app.Activity; 20 import android.app.StatusBarManager; 21 import android.content.ComponentName; 22 import android.content.Context; 23 import android.content.pm.PackageManager; 24 import android.hardware.input.InputManagerGlobal; 25 import android.hardware.input.KeyboardLayout; 26 import android.location.LocationManager; 27 import android.net.wifi.WifiManager; 28 import android.net.wifi.WifiConfiguration; 29 import android.provider.Settings; 30 import android.os.Bundle; 31 import android.os.Process; 32 import android.os.RemoteException; 33 import android.os.ServiceManager; 34 import android.os.SystemProperties; 35 import android.telephony.TelephonyManager; 36 import android.util.Log; 37 import android.view.InputDevice; 38 39 import com.android.internal.widget.LockPatternUtils; 40 41 public abstract class ProvisionActivity extends Activity { TAG()42 protected abstract String TAG(); 43 private StatusBarManager mStatusBarManager; 44 45 @Override onCreate(Bundle icicle)46 protected void onCreate(Bundle icicle) { 47 super.onCreate(icicle); 48 49 if (Settings.Global.getInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 1) { 50 preProvivion(); 51 doProvision(); 52 postProvision(); 53 } else { 54 Log.w(TAG(), "Already provisioned, remove itself."); 55 removeSelf(); 56 } 57 58 finish(); // terminate the activity. 59 } 60 preProvivion()61 protected void preProvivion() { 62 final Context appContext = getApplicationContext(); 63 mStatusBarManager = appContext.getSystemService(StatusBarManager.class); 64 65 mStatusBarManager.setDisabledForSetup(true); 66 } 67 postProvision()68 protected void postProvision() { 69 mStatusBarManager.setDisabledForSetup(false); 70 71 removeSelf(); 72 73 // Add a persistent setting to allow other apps to know the device has been provisioned. 74 Settings.Secure.putInt(getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 1); 75 Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1); 76 } 77 78 // remove this activity from the package manager. removeSelf()79 protected void removeSelf() { 80 getPackageManager().setComponentEnabledSetting( 81 new ComponentName(this, this.getClass()), 82 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 83 PackageManager.DONT_KILL_APP); 84 } 85 doProvision()86 protected void doProvision() { 87 provisionWifi("AndroidWifi"); 88 provisionKeyboard("qwerty2"); 89 provisionDisplay(); 90 provisionTelephony(); 91 provisionLocation(); 92 provisionAdb(); 93 94 Settings.Secure.putInt(getContentResolver(), Settings.Secure.INSTALL_NON_MARKET_APPS, 1); 95 } 96 provisionWifi(final String ssid)97 protected void provisionWifi(final String ssid) { 98 Settings.Global.putInt(getContentResolver(), Settings.Global.TETHER_OFFLOAD_DISABLED, 1); 99 100 final int ADD_NETWORK_FAIL = -1; 101 final String quotedSsid = "\"" + ssid + "\""; 102 103 final WifiConfiguration config = new WifiConfiguration(); 104 config.SSID = quotedSsid; 105 config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN); 106 107 final WifiManager mWifiManager = getApplicationContext().getSystemService(WifiManager.class); 108 final int netId = mWifiManager.addNetwork(config); 109 110 if (netId == ADD_NETWORK_FAIL || !mWifiManager.enableNetwork(netId, true)) { 111 Log.e(TAG(), "Unable to add Wi-Fi network " + quotedSsid + "."); 112 } 113 } 114 115 // Set physical keyboard layout based on the system property set by emulator host. provisionKeyboard(final String deviceName)116 protected void provisionKeyboard(final String deviceName) { 117 final String layoutName = SystemProperties.get("vendor.qemu.keyboard_layout"); 118 final InputDevice device = getKeyboardDevice(deviceName); 119 if (device != null && !layoutName.isEmpty()) { 120 setKeyboardLayout(device, layoutName); 121 } 122 } 123 provisionDisplay()124 protected void provisionDisplay() { 125 final int screen_off_timeout = 126 SystemProperties.getInt("ro.boot.qemu.settings.system.screen_off_timeout", 0); 127 if (screen_off_timeout > 0) { 128 Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, screen_off_timeout); 129 Log.i(TAG(), "Setting system screen_off_timeout to be " + screen_off_timeout + " ms"); 130 } 131 132 (new LockPatternUtils(this)).setLockScreenDisabled(true, 133 android.os.Process.myUserHandle().getIdentifier()); 134 135 final String displaySettingsProp = "ro.boot.qemu.display.settings.xml"; 136 final String displaySettingsName = SystemProperties.get(displaySettingsProp); 137 if ("freeform".equals(displaySettingsName)) { 138 Settings.Global.putInt(getContentResolver(), "sf", 1); 139 Settings.Global.putString(getContentResolver(), 140 Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, "1"); 141 Settings.Global.putString(getContentResolver(), 142 Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, "1"); 143 Settings.Global.putString(getContentResolver(), 144 Settings.Global.DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH, 145 "vendor/etc/display_settings_freeform.xml"); 146 } else if ("resizable".equals(displaySettingsName)) { 147 // Enable auto rotate for resizable AVD 148 Settings.System.putString(getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, "1"); 149 } else if (!displaySettingsName.isEmpty()) { 150 Log.e(TAG(), "Unexpected value `" + displaySettingsName + "` in " + displaySettingsProp); 151 } 152 final String autoRotateProp = "ro.boot.qemu.autorotate"; 153 final String autoRotateSetting = SystemProperties.get(autoRotateProp); 154 if (!autoRotateSetting.isEmpty()) { 155 Settings.System.putString(getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, autoRotateSetting); 156 } 157 } 158 159 // required for CTS which uses the mock modem provisionMockModem()160 private void provisionMockModem() { 161 String value = SystemProperties.get("ro.boot.radio.allow_mock_modem"); 162 if (!value.isEmpty()) { 163 if (value.equals("1")) { 164 value = "true"; 165 } else if (value.equals("0")) { 166 value = "false"; 167 } 168 169 SystemProperties.set("persist.radio.allow_mock_modem", value); 170 } 171 } 172 provisionTelephony()173 protected void provisionTelephony() { 174 // b/193418404 175 // the following blocks, TODO: find out why and fix it. disable this for now. 176 // TelephonyManager mTelephony = getApplicationContext().getSystemService(TelephonyManager.class); 177 // mTelephony.setPreferredNetworkTypeBitmask(TelephonyManager.NETWORK_TYPE_BITMASK_NR); 178 179 provisionMockModem(); 180 } 181 provisionLocation()182 protected void provisionLocation() { 183 final LocationManager lm = getSystemService(LocationManager.class); 184 lm.setLocationEnabledForUser(true, Process.myUserHandle()); 185 186 // Enable the GPS. 187 // Not needed since this SDK will contain the Settings app. 188 Settings.Secure.putString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, 189 LocationManager.GPS_PROVIDER); 190 } 191 provisionAdb()192 protected void provisionAdb() { 193 Settings.Global.putInt(getContentResolver(), Settings.Global.ADB_ENABLED, 1); 194 Settings.Global.putInt(getContentResolver(), Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 0); 195 } 196 getKeyboardDevice(final String keyboardDeviceName)197 protected InputDevice getKeyboardDevice(final String keyboardDeviceName) { 198 final int[] deviceIds = InputDevice.getDeviceIds(); 199 200 for (int deviceId : deviceIds) { 201 InputDevice inputDevice = InputDevice.getDevice(deviceId); 202 if (inputDevice != null 203 && inputDevice.supportsSource(InputDevice.SOURCE_KEYBOARD) 204 && inputDevice.getName().equals(keyboardDeviceName)) { 205 return inputDevice; 206 } 207 } 208 209 return null; 210 } 211 setKeyboardLayout(final InputDevice keyboardDevice, final String layoutName)212 protected void setKeyboardLayout(final InputDevice keyboardDevice, final String layoutName) { 213 final InputManagerGlobal im = InputManagerGlobal.getInstance(); 214 215 final KeyboardLayout[] keyboardLayouts = 216 im.getKeyboardLayoutsForInputDevice(keyboardDevice.getIdentifier()); 217 218 for (KeyboardLayout keyboardLayout : keyboardLayouts) { 219 if (keyboardLayout.getDescriptor().endsWith(layoutName)) { 220 im.setCurrentKeyboardLayoutForInputDevice( 221 keyboardDevice.getIdentifier(), keyboardLayout.getDescriptor()); 222 return; 223 } 224 } 225 } 226 } 227