/*
 * Copyright (C) 2006-2011 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.server.am;

import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import java.util.HashMap;
import java.util.Map;

/**
 * Helper class for watching a set of core settings which the framework
 * propagates to application processes to avoid multiple lookups and potentially
 * disk I/O operations. Note: This class assumes that all core settings reside
 * in {@link Settings.Secure}.
 */
final class CoreSettingsObserver extends ContentObserver {
    private static final String LOG_TAG = CoreSettingsObserver.class.getSimpleName();

    // mapping form property name to its type
    private static final Map<String, Class<?>> sSecureSettingToTypeMap = new HashMap<
            String, Class<?>>();
    private static final Map<String, Class<?>> sSystemSettingToTypeMap = new HashMap<
            String, Class<?>>();
    private static final Map<String, Class<?>> sGlobalSettingToTypeMap = new HashMap<
            String, Class<?>>();
    static {
        sSecureSettingToTypeMap.put(Settings.Secure.LONG_PRESS_TIMEOUT, int.class);
        sSecureSettingToTypeMap.put(Settings.Secure.MULTI_PRESS_TIMEOUT, int.class);
        // add other secure settings here...

        sSystemSettingToTypeMap.put(Settings.System.TIME_12_24, String.class);
        // add other system settings here...

        sGlobalSettingToTypeMap.put(Settings.Global.DEBUG_VIEW_ATTRIBUTES, int.class);
        sGlobalSettingToTypeMap.put(Settings.Global.WAIT_FOR_NETWORK_TIMEOUT_MS, long.class);
        // add other global settings here...
    }

    private final Bundle mCoreSettings = new Bundle();

    private final ActivityManagerService mActivityManagerService;

    private static final long WAIT_FOR_NETWORK_TIMEOUT_DEFAULT_MS = 2000; // 2 sec

    public CoreSettingsObserver(ActivityManagerService activityManagerService) {
        super(activityManagerService.mHandler);
        mActivityManagerService = activityManagerService;
        beginObserveCoreSettings();
        sendCoreSettings();
    }

    public Bundle getCoreSettingsLocked() {
        return (Bundle) mCoreSettings.clone();
    }

    @Override
    public void onChange(boolean selfChange) {
        synchronized (mActivityManagerService) {
            sendCoreSettings();
        }
    }

    private void sendCoreSettings() {
        populateSettings(mCoreSettings, sSecureSettingToTypeMap);
        populateSettings(mCoreSettings, sSystemSettingToTypeMap);
        populateSettings(mCoreSettings, sGlobalSettingToTypeMap);
        mActivityManagerService.onCoreSettingsChange(mCoreSettings);
    }

    private void beginObserveCoreSettings() {
        for (String setting : sSecureSettingToTypeMap.keySet()) {
            Uri uri = Settings.Secure.getUriFor(setting);
            mActivityManagerService.mContext.getContentResolver().registerContentObserver(
                    uri, false, this);
        }

        for (String setting : sSystemSettingToTypeMap.keySet()) {
            Uri uri = Settings.System.getUriFor(setting);
            mActivityManagerService.mContext.getContentResolver().registerContentObserver(
                    uri, false, this);
        }

        for (String setting : sGlobalSettingToTypeMap.keySet()) {
            Uri uri = Settings.Global.getUriFor(setting);
            mActivityManagerService.mContext.getContentResolver().registerContentObserver(
                    uri, false, this);
        }
    }

    private void populateSettings(Bundle snapshot, Map<String, Class<?>> map) {
        Context context = mActivityManagerService.mContext;
        for (Map.Entry<String, Class<?>> entry : map.entrySet()) {
            String setting = entry.getKey();
            Class<?> type = entry.getValue();
            if (type == String.class) {
                final String value;
                if (map == sSecureSettingToTypeMap) {
                    value = Settings.Secure.getString(context.getContentResolver(), setting);
                } else if (map == sSystemSettingToTypeMap) {
                    value = Settings.System.getString(context.getContentResolver(), setting);
                } else {
                    value = Settings.Global.getString(context.getContentResolver(), setting);
                }
                snapshot.putString(setting, value);
            } else if (type == int.class) {
                final int value;
                if (map == sSecureSettingToTypeMap) {
                    value = Settings.Secure.getInt(context.getContentResolver(), setting, 0);
                } else if (map == sSystemSettingToTypeMap) {
                    value = Settings.System.getInt(context.getContentResolver(), setting, 0);
                } else {
                    value = Settings.Global.getInt(context.getContentResolver(), setting, 0);
                }
                snapshot.putInt(setting, value);
            } else if (type == float.class) {
                final float value;
                if (map == sSecureSettingToTypeMap) {
                    value = Settings.Secure.getFloat(context.getContentResolver(), setting, 0);
                } else if (map == sSystemSettingToTypeMap) {
                    value = Settings.System.getFloat(context.getContentResolver(), setting, 0);
                } else {
                    value = Settings.Global.getFloat(context.getContentResolver(), setting, 0);
                }
                snapshot.putFloat(setting, value);
            } else if (type == long.class) {
                final long value;
                if (map == sSecureSettingToTypeMap) {
                    value = Settings.Secure.getLong(context.getContentResolver(), setting, 0);
                } else if (map == sSystemSettingToTypeMap) {
                    value = Settings.System.getLong(context.getContentResolver(), setting, 0);
                } else {
                    // TODO: remove this conditional and set the default in settings provider.
                    if (Settings.Global.WAIT_FOR_NETWORK_TIMEOUT_MS.equals(setting)) {
                        value = Settings.Global.getLong(context.getContentResolver(), setting,
                                WAIT_FOR_NETWORK_TIMEOUT_DEFAULT_MS);
                    } else {
                        value = Settings.Global.getLong(context.getContentResolver(), setting, 0);
                    }
                }
                snapshot.putLong(setting, value);
            }
        }
    }
}
