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 (provisionRequired()) { 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 WifiManager mWifiManager = getApplicationContext().getSystemService(WifiManager.class); 101 if (!mWifiManager.setWifiEnabled(true)) { 102 Log.e(TAG(), "Unable to turn on Wi-Fi"); 103 return; 104 } 105 106 final int ADD_NETWORK_FAIL = -1; 107 final String quotedSsid = "\"" + ssid + "\""; 108 109 final WifiConfiguration config = new WifiConfiguration(); 110 config.SSID = quotedSsid; 111 config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN); 112 113 final int netId = mWifiManager.addNetwork(config); 114 115 if (netId == ADD_NETWORK_FAIL || !mWifiManager.enableNetwork(netId, true)) { 116 Log.e(TAG(), "Unable to add Wi-Fi network " + quotedSsid + "."); 117 } 118 } 119 120 // Set physical keyboard layout based on the system property set by emulator host. provisionKeyboard(final String deviceName)121 protected void provisionKeyboard(final String deviceName) { 122 Settings.Secure.putInt(getContentResolver(), Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 1); 123 124 final String layoutName = SystemProperties.get("vendor.qemu.keyboard_layout"); 125 final InputDevice device = getKeyboardDevice(deviceName); 126 if (device != null && !layoutName.isEmpty()) { 127 setKeyboardLayout(device, layoutName); 128 } 129 } 130 provisionDisplay()131 protected void provisionDisplay() { 132 Settings.Global.putInt(getContentResolver(), Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 1); 133 134 final int screen_off_timeout = 135 SystemProperties.getInt("ro.boot.qemu.settings.system.screen_off_timeout", 0); 136 if (screen_off_timeout > 0) { 137 Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, screen_off_timeout); 138 Log.i(TAG(), "Setting system screen_off_timeout to be " + screen_off_timeout + " ms"); 139 } 140 141 (new LockPatternUtils(this)).setLockScreenDisabled(true, 142 android.os.Process.myUserHandle().getIdentifier()); 143 144 final String displaySettingsProp = "ro.boot.qemu.display.settings.xml"; 145 final String displaySettingsName = SystemProperties.get(displaySettingsProp); 146 if ("freeform".equals(displaySettingsName)) { 147 Settings.Global.putInt(getContentResolver(), "sf", 1); 148 Settings.Global.putString(getContentResolver(), 149 Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, "1"); 150 Settings.Global.putString(getContentResolver(), 151 Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, "1"); 152 Settings.Global.putString(getContentResolver(), 153 Settings.Global.DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH, 154 "vendor/etc/display_settings_freeform.xml"); 155 } else if ("resizable".equals(displaySettingsName)) { 156 // Enable auto rotate for resizable AVD 157 Settings.System.putString(getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, "1"); 158 } else if (!displaySettingsName.isEmpty()) { 159 Log.e(TAG(), "Unexpected value `" + displaySettingsName + "` in " + displaySettingsProp); 160 } 161 final String autoRotateProp = "ro.boot.qemu.autorotate"; 162 final String autoRotateSetting = SystemProperties.get(autoRotateProp); 163 if (!autoRotateSetting.isEmpty()) { 164 Settings.System.putString(getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, autoRotateSetting); 165 } 166 } 167 168 // required for CTS which uses the mock modem provisionMockModem()169 private void provisionMockModem() { 170 String value = SystemProperties.get("ro.boot.radio.allow_mock_modem"); 171 if (!value.isEmpty()) { 172 if (value.equals("1")) { 173 value = "true"; 174 } else if (value.equals("0")) { 175 value = "false"; 176 } 177 178 SystemProperties.set("persist.radio.allow_mock_modem", value); 179 } 180 } 181 provisionTelephony()182 protected void provisionTelephony() { 183 // b/193418404 184 // the following blocks, TODO: find out why and fix it. disable this for now. 185 // TelephonyManager mTelephony = getApplicationContext().getSystemService(TelephonyManager.class); 186 // mTelephony.setPreferredNetworkTypeBitmask(TelephonyManager.NETWORK_TYPE_BITMASK_NR); 187 188 provisionMockModem(); 189 } 190 provisionLocation()191 protected void provisionLocation() { 192 final LocationManager lm = getSystemService(LocationManager.class); 193 lm.setLocationEnabledForUser(true, Process.myUserHandle()); 194 195 // Enable the GPS. 196 // Not needed since this SDK will contain the Settings app. 197 Settings.Secure.putString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, 198 LocationManager.GPS_PROVIDER); 199 } 200 provisionAdb()201 protected void provisionAdb() { 202 Settings.Global.putInt(getContentResolver(), Settings.Global.ADB_ENABLED, 1); 203 Settings.Global.putInt(getContentResolver(), Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 0); 204 } 205 getKeyboardDevice(final String keyboardDeviceName)206 protected InputDevice getKeyboardDevice(final String keyboardDeviceName) { 207 final int[] deviceIds = InputDevice.getDeviceIds(); 208 209 for (int deviceId : deviceIds) { 210 InputDevice inputDevice = InputDevice.getDevice(deviceId); 211 if (inputDevice != null 212 && inputDevice.supportsSource(InputDevice.SOURCE_KEYBOARD) 213 && inputDevice.getName().equals(keyboardDeviceName)) { 214 return inputDevice; 215 } 216 } 217 218 return null; 219 } 220 setKeyboardLayout(final InputDevice keyboardDevice, final String layoutName)221 protected void setKeyboardLayout(final InputDevice keyboardDevice, final String layoutName) { 222 final InputManagerGlobal im = InputManagerGlobal.getInstance(); 223 224 final KeyboardLayout[] keyboardLayouts = 225 im.getKeyboardLayoutsForInputDevice(keyboardDevice.getIdentifier()); 226 227 for (KeyboardLayout keyboardLayout : keyboardLayouts) { 228 if (keyboardLayout.getDescriptor().endsWith(layoutName)) { 229 im.setCurrentKeyboardLayoutForInputDevice( 230 keyboardDevice.getIdentifier(), keyboardLayout.getDescriptor()); 231 return; 232 } 233 } 234 } 235 provisionRequired()236 protected boolean provisionRequired() { 237 return (Settings.Global.getInt(getContentResolver(), 238 Settings.Global.DEVICE_PROVISIONED, 0) != 1) || forceProvision(); 239 } 240 forceProvision()241 protected boolean forceProvision() { 242 return SystemProperties.get("ro.automotive_emulator.provisioning", "").equals("SdkSetup"); 243 } 244 } 245