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
17package com.android.providers.settings;
18
19import java.util.Locale;
20
21import android.app.ActivityManagerNative;
22import android.app.IActivityManager;
23import android.app.backup.BackupDataInput;
24import android.app.backup.IBackupManager;
25import android.content.ContentResolver;
26import android.content.Context;
27import android.content.IContentService;
28import android.content.res.Configuration;
29import android.location.LocationManager;
30import android.media.AudioManager;
31import android.os.IPowerManager;
32import android.os.RemoteException;
33import android.os.ServiceManager;
34import android.provider.Settings;
35import android.text.TextUtils;
36import android.util.Log;
37
38public class SettingsHelper {
39    private static final String TAG = "SettingsHelper";
40
41    private Context mContext;
42    private AudioManager mAudioManager;
43    private IContentService mContentService;
44    private IPowerManager mPowerManager;
45
46    private boolean mSilent;
47    private boolean mVibrate;
48
49    public SettingsHelper(Context context) {
50        mContext = context;
51        mAudioManager = (AudioManager) context
52                .getSystemService(Context.AUDIO_SERVICE);
53        mContentService = ContentResolver.getContentService();
54        mPowerManager = IPowerManager.Stub.asInterface(
55                ServiceManager.getService("power"));
56    }
57
58    /**
59     * Sets the property via a call to the appropriate API, if any, and returns
60     * whether or not the setting should be saved to the database as well.
61     * @param name the name of the setting
62     * @param value the string value of the setting
63     * @return whether to continue with writing the value to the database. In
64     * some cases the data will be written by the call to the appropriate API,
65     * and in some cases the property value needs to be modified before setting.
66     */
67    public boolean restoreValue(String name, String value) {
68        if (Settings.System.SCREEN_BRIGHTNESS.equals(name)) {
69            setBrightness(Integer.parseInt(value));
70        } else if (Settings.System.SOUND_EFFECTS_ENABLED.equals(name)) {
71            setSoundEffects(Integer.parseInt(value) == 1);
72        } else if (Settings.Secure.LOCATION_PROVIDERS_ALLOWED.equals(name)) {
73            setGpsLocation(value);
74            return false;
75        } else if (Settings.Secure.BACKUP_AUTO_RESTORE.equals(name)) {
76            setAutoRestore(Integer.parseInt(value) == 1);
77        }
78        return true;
79    }
80
81    private void setAutoRestore(boolean enabled) {
82        try {
83            IBackupManager bm = IBackupManager.Stub.asInterface(
84                    ServiceManager.getService(Context.BACKUP_SERVICE));
85            if (bm != null) {
86                bm.setAutoRestore(enabled);
87            }
88        } catch (RemoteException e) {}
89    }
90
91    private void setGpsLocation(String value) {
92        final String GPS = LocationManager.GPS_PROVIDER;
93        boolean enabled =
94                GPS.equals(value) ||
95                value.startsWith(GPS + ",") ||
96                value.endsWith("," + GPS) ||
97                value.contains("," + GPS + ",");
98        Settings.Secure.setLocationProviderEnabled(
99                mContext.getContentResolver(), GPS, enabled);
100    }
101
102    private void setSoundEffects(boolean enable) {
103        if (enable) {
104            mAudioManager.loadSoundEffects();
105        } else {
106            mAudioManager.unloadSoundEffects();
107        }
108    }
109
110    private void setBrightness(int brightness) {
111        try {
112            IPowerManager power = IPowerManager.Stub.asInterface(
113                    ServiceManager.getService("power"));
114            if (power != null) {
115                power.setBacklightBrightness(brightness);
116            }
117        } catch (RemoteException doe) {
118
119        }
120    }
121
122    private void setRingerMode() {
123        if (mSilent) {
124            mAudioManager.setRingerMode(mVibrate ? AudioManager.RINGER_MODE_VIBRATE :
125                AudioManager.RINGER_MODE_SILENT);
126        } else {
127            mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
128            mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,
129                    mVibrate ? AudioManager.VIBRATE_SETTING_ON
130                            : AudioManager.VIBRATE_SETTING_OFF);
131        }
132    }
133
134    byte[] getLocaleData() {
135        Configuration conf = mContext.getResources().getConfiguration();
136        final Locale loc = conf.locale;
137        String localeString = loc.getLanguage();
138        String country = loc.getCountry();
139        if (!TextUtils.isEmpty(country)) {
140            localeString += "_" + country;
141        }
142        return localeString.getBytes();
143    }
144
145    /**
146     * Sets the locale specified. Input data is the equivalent of "ll_cc".getBytes(), where
147     * "ll" is the language code and "cc" is the country code.
148     * @param data the locale string in bytes.
149     */
150    void setLocaleData(byte[] data, int size) {
151        // Check if locale was set by the user:
152        Configuration conf = mContext.getResources().getConfiguration();
153        Locale loc = conf.locale;
154        // TODO: The following is not working as intended because the network is forcing a locale
155        // change after registering. Need to find some other way to detect if the user manually
156        // changed the locale
157        if (conf.userSetLocale) return; // Don't change if user set it in the SetupWizard
158
159        final String[] availableLocales = mContext.getAssets().getLocales();
160        String localeCode = new String(data, 0, size);
161        String language = new String(data, 0, 2);
162        String country = size > 4 ? new String(data, 3, 2) : "";
163        loc = null;
164        for (int i = 0; i < availableLocales.length; i++) {
165            if (availableLocales[i].equals(localeCode)) {
166                loc = new Locale(language, country);
167                break;
168            }
169        }
170        if (loc == null) return; // Couldn't find the saved locale in this version of the software
171
172        try {
173            IActivityManager am = ActivityManagerNative.getDefault();
174            Configuration config = am.getConfiguration();
175            config.locale = loc;
176            // indicate this isn't some passing default - the user wants this remembered
177            config.userSetLocale = true;
178
179            am.updateConfiguration(config);
180        } catch (RemoteException e) {
181            // Intentionally left blank
182        }
183    }
184
185    /**
186     * Informs the audio service of changes to the settings so that
187     * they can be re-read and applied.
188     */
189    void applyAudioSettings() {
190        AudioManager am = new AudioManager(mContext);
191        am.reloadAudioSettings();
192    }
193}
194