• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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