1 /*
2  * Copyright (C) 2006-2011 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.server.am;
18 
19 import android.content.Context;
20 import android.database.ContentObserver;
21 import android.net.Uri;
22 import android.os.Bundle;
23 import android.provider.Settings;
24 import java.util.HashMap;
25 import java.util.Map;
26 
27 /**
28  * Helper class for watching a set of core settings which the framework
29  * propagates to application processes to avoid multiple lookups and potentially
30  * disk I/O operations. Note: This class assumes that all core settings reside
31  * in {@link Settings.Secure}.
32  */
33 final class CoreSettingsObserver extends ContentObserver {
34     private static final String LOG_TAG = CoreSettingsObserver.class.getSimpleName();
35 
36     // mapping form property name to its type
37     private static final Map<String, Class<?>> sSecureSettingToTypeMap = new HashMap<
38             String, Class<?>>();
39     private static final Map<String, Class<?>> sSystemSettingToTypeMap = new HashMap<
40             String, Class<?>>();
41     private static final Map<String, Class<?>> sGlobalSettingToTypeMap = new HashMap<
42             String, Class<?>>();
43     static {
sSecureSettingToTypeMap.put(Settings.Secure.LONG_PRESS_TIMEOUT, int.class)44         sSecureSettingToTypeMap.put(Settings.Secure.LONG_PRESS_TIMEOUT, int.class);
45         // add other secure settings here...
46 
sSystemSettingToTypeMap.put(Settings.System.TIME_12_24, String.class)47         sSystemSettingToTypeMap.put(Settings.System.TIME_12_24, String.class);
48         // add other system settings here...
49 
sGlobalSettingToTypeMap.put(Settings.Global.DEBUG_VIEW_ATTRIBUTES, int.class)50         sGlobalSettingToTypeMap.put(Settings.Global.DEBUG_VIEW_ATTRIBUTES, int.class);
51         // add other global settings here...
52     }
53 
54     private final Bundle mCoreSettings = new Bundle();
55 
56     private final ActivityManagerService mActivityManagerService;
57 
CoreSettingsObserver(ActivityManagerService activityManagerService)58     public CoreSettingsObserver(ActivityManagerService activityManagerService) {
59         super(activityManagerService.mHandler);
60         mActivityManagerService = activityManagerService;
61         beginObserveCoreSettings();
62         sendCoreSettings();
63     }
64 
getCoreSettingsLocked()65     public Bundle getCoreSettingsLocked() {
66         return (Bundle) mCoreSettings.clone();
67     }
68 
69     @Override
onChange(boolean selfChange)70     public void onChange(boolean selfChange) {
71         synchronized (mActivityManagerService) {
72             sendCoreSettings();
73         }
74     }
75 
sendCoreSettings()76     private void sendCoreSettings() {
77         populateSettings(mCoreSettings, sSecureSettingToTypeMap);
78         populateSettings(mCoreSettings, sSystemSettingToTypeMap);
79         populateSettings(mCoreSettings, sGlobalSettingToTypeMap);
80         mActivityManagerService.onCoreSettingsChange(mCoreSettings);
81     }
82 
beginObserveCoreSettings()83     private void beginObserveCoreSettings() {
84         for (String setting : sSecureSettingToTypeMap.keySet()) {
85             Uri uri = Settings.Secure.getUriFor(setting);
86             mActivityManagerService.mContext.getContentResolver().registerContentObserver(
87                     uri, false, this);
88         }
89 
90         for (String setting : sSystemSettingToTypeMap.keySet()) {
91             Uri uri = Settings.System.getUriFor(setting);
92             mActivityManagerService.mContext.getContentResolver().registerContentObserver(
93                     uri, false, this);
94         }
95 
96         for (String setting : sGlobalSettingToTypeMap.keySet()) {
97             Uri uri = Settings.Global.getUriFor(setting);
98             mActivityManagerService.mContext.getContentResolver().registerContentObserver(
99                     uri, false, this);
100         }
101     }
102 
populateSettings(Bundle snapshot, Map<String, Class<?>> map)103     private void populateSettings(Bundle snapshot, Map<String, Class<?>> map) {
104         Context context = mActivityManagerService.mContext;
105         for (Map.Entry<String, Class<?>> entry : map.entrySet()) {
106             String setting = entry.getKey();
107             Class<?> type = entry.getValue();
108             if (type == String.class) {
109                 final String value;
110                 if (map == sSecureSettingToTypeMap) {
111                     value = Settings.Secure.getString(context.getContentResolver(), setting);
112                 } else if (map == sSystemSettingToTypeMap) {
113                     value = Settings.System.getString(context.getContentResolver(), setting);
114                 } else {
115                     value = Settings.Global.getString(context.getContentResolver(), setting);
116                 }
117                 snapshot.putString(setting, value);
118             } else if (type == int.class) {
119                 final int value;
120                 if (map == sSecureSettingToTypeMap) {
121                     value = Settings.Secure.getInt(context.getContentResolver(), setting, 0);
122                 } else if (map == sSystemSettingToTypeMap) {
123                     value = Settings.System.getInt(context.getContentResolver(), setting, 0);
124                 } else {
125                     value = Settings.Global.getInt(context.getContentResolver(), setting, 0);
126                 }
127                 snapshot.putInt(setting, value);
128             } else if (type == float.class) {
129                 final float value;
130                 if (map == sSecureSettingToTypeMap) {
131                     value = Settings.Secure.getFloat(context.getContentResolver(), setting, 0);
132                 } else if (map == sSystemSettingToTypeMap) {
133                     value = Settings.System.getFloat(context.getContentResolver(), setting, 0);
134                 } else {
135                     value = Settings.Global.getFloat(context.getContentResolver(), setting, 0);
136                 }
137                 snapshot.putFloat(setting, value);
138             } else if (type == long.class) {
139                 final long value;
140                 if (map == sSecureSettingToTypeMap) {
141                     value = Settings.Secure.getLong(context.getContentResolver(), setting, 0);
142                 } else if (map == sSystemSettingToTypeMap) {
143                     value = Settings.System.getLong(context.getContentResolver(), setting, 0);
144                 } else {
145                     value = Settings.Global.getLong(context.getContentResolver(), setting, 0);
146                 }
147                 snapshot.putLong(setting, value);
148             }
149         }
150     }
151 }
152