/*
 * 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.sdksetup;

import android.app.Activity;
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.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.Build;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.InputDevice;

/**
 * Entry point for SDK SetupWizard.
 *
 */
public class DefaultActivity extends Activity {
    private static final String TAG = "SdkSetup";
    private static final int ADD_NETWORK_FAIL = -1;
    @Override
    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        // Edit Settings only for Emulator
        if (Build.IS_EMULATOR) {
            // Add network with SSID "AndroidWifi"
            WifiConfiguration config = new WifiConfiguration();
            config.SSID = "\"AndroidWifi\"";
            config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN);
            WifiManager mWifiManager = getApplicationContext().getSystemService(WifiManager.class);
            int netId = mWifiManager.addNetwork(config);
            if (netId == ADD_NETWORK_FAIL || mWifiManager.enableNetwork(netId, true)) {
                Log.e(TAG, "Unable to add Wi-Fi network AndroidWifi.");
            }

            // Set physical keyboard layout based on the system property set by emulator host.
            String layoutName = SystemProperties.get("vendor.qemu.keyboard_layout");
            String displaySettingsName = SystemProperties.get("ro.boot.qemu.display.settings.xml");
            String deviceName = "qwerty2";
            InputDevice device = getKeyboardDevice(deviceName);
            if (device != null && !layoutName.isEmpty()) {
                setKeyboardLayout(device, layoutName);
            }
            // Add a persistent setting to allow other apps to know the device has been provisioned.
            Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);

            Settings.Secure.putInt(getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 1);

            // Disables a dialog shown on adb install execution.
            Settings.Global.putInt(getContentResolver(), Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 0);

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

            // enable install from non market
            Settings.Secure.putInt(getContentResolver(), Settings.Secure.INSTALL_NON_MARKET_APPS, 1);

            Settings.Global.putInt(getContentResolver(), Settings.Global.ADB_ENABLED, 1);

            // Disable offload wifi tethering
            Settings.Global.putInt(getContentResolver(), Settings.Global.TETHER_OFFLOAD_DISABLED, 1);

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

        // remove this activity from the package manager.
        PackageManager pm = getPackageManager();
        ComponentName name = new ComponentName(this, DefaultActivity.class);
        pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);

        // terminate the activity.
        finish();
    }

    private InputDevice getKeyboardDevice(String keyboardDeviceName) {
        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;
    }

    private void setKeyboardLayout(InputDevice keyboardDevice, String layoutName) {
        InputManager im = InputManager.getInstance();

        KeyboardLayout[] keyboardLayouts =
                im.getKeyboardLayoutsForInputDevice(keyboardDevice.getIdentifier());

        for (KeyboardLayout keyboardLayout : keyboardLayouts) {
            if (keyboardLayout.getDescriptor().endsWith(layoutName)) {
                im.setCurrentKeyboardLayoutForInputDevice(
                        keyboardDevice.getIdentifier(), keyboardLayout.getDescriptor());
                return;
            }
        }
    }
}

