1/*
2 * Copyright (C) 2014 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.tv.settings.util;
18
19import com.android.tv.settings.R;
20import android.content.ContentResolver;
21import android.content.Context;
22import android.content.res.Resources;
23import android.os.AsyncTask;
24import android.os.IBinder;
25import android.os.Parcel;
26import android.os.RemoteException;
27import android.os.ServiceManager;
28import android.os.SystemProperties;
29import android.provider.Settings;
30import android.provider.Settings.SettingNotFoundException;
31import android.util.Log;
32import android.view.IWindowManager;
33import android.view.View;
34
35import java.util.ArrayList;
36
37public class SettingsHelper {
38
39    private static final String TAG = "SettingsHelper";
40    private static final boolean DEBUG = false;
41
42    private Context mContext;
43    private ContentResolver mContentResolver;
44    private Resources mResources;
45
46    public SettingsHelper(Context context) {
47        mContext = context;
48        mContentResolver = context.getContentResolver();
49        mResources = context.getResources();
50    }
51
52    /**
53     * Returns a human readable Status description of the setting's value.
54     */
55    public String getSecureStatusIntSetting(String setting) {
56        try {
57            return getStatusStringFromInt(Settings.Secure.getInt(mContentResolver, setting));
58        } catch (SettingNotFoundException e) {
59            Log.d(TAG, "setting: " + setting + " not found");
60            // TODO: show error message
61        }
62        return null;
63    }
64
65    /**
66     * Returns a string representation of the Integer setting's value.
67     */
68    public String getSecureIntSetting(String setting, String def) {
69        return Integer.toString(
70                Settings.Secure.getInt(mContentResolver, setting, Integer.parseInt(def)));
71    }
72
73    /**
74     * Returns the int as a boolean, for use in determining "on|off".
75     */
76    public boolean getSecureIntValueSettingToBoolean(String setting) {
77        try {
78            return Settings.Secure.getInt(mContentResolver, setting) == 1;
79        } catch (SettingNotFoundException e) {
80            return false;
81        }
82    }
83
84    public void setSecureIntSetting(String setting, boolean value) {
85        int settingValue = value ? 1 : 0;
86        Settings.Secure.putInt(mContentResolver, setting, settingValue);
87    }
88
89    public void setSecureIntValueSetting(String setting, Object value) {
90        int settingValue = Integer.parseInt((String) value);
91        Settings.Secure.putInt(mContentResolver, setting, settingValue);
92    }
93
94    /**
95     * Returns a human readable description of the setting's value.
96     */
97    public String getSystemIntSetting(String setting) {
98        try {
99            return getStatusStringFromInt(Settings.System.getInt(mContentResolver, setting));
100        } catch (SettingNotFoundException e) {
101            Log.d(TAG, "setting: " + setting + " not found");
102            // TODO: show error message
103        }
104        return null;
105    }
106
107    public boolean getSystemIntSettingToBoolean(String setting) {
108        try {
109            return Settings.System.getInt(mContentResolver, setting) == 1;
110        } catch (SettingNotFoundException e) {
111            return false;
112        }
113    }
114
115    public void setSystemIntSetting(String setting, boolean value) {
116        int settingValue = value ? 1 : 0;
117        Settings.System.putInt(mContentResolver, setting, settingValue);
118    }
119
120    public void setSystemProperties(String setting, String value) {
121        SystemProperties.set(setting, value);
122        pokeSystemProperties();
123    }
124
125    public String getSystemProperties(String setting) {
126        return SystemProperties.get(setting);
127    }
128
129    /**
130     * Returns a human readable description of the setting's value.
131     */
132    public String getSystemBooleanProperties(String setting) {
133        return getStatusStringFromBoolean(SystemProperties.getBoolean(setting, false));
134    }
135    private void pokeSystemProperties() {
136        (new SystemPropPoker()).execute();
137    }
138
139    static class SystemPropPoker extends AsyncTask<Void, Void, Void> {
140        @Override
141        protected Void doInBackground(Void... params) {
142            String[] services;
143            try {
144                services = ServiceManager.listServices();
145            } catch (RemoteException e) {
146                return null;
147            }
148            for (String service : services) {
149                IBinder obj = ServiceManager.checkService(service);
150                if (obj != null) {
151                    Parcel data = Parcel.obtain();
152                    try {
153                        obj.transact(IBinder.SYSPROPS_TRANSACTION, data, null, 0);
154                    } catch (RemoteException e) {
155                    } catch (Exception e) {
156                        Log.i(TAG, "Somone wrote a bad service '" + service
157                                + "' that doesn't like to be poked: " + e);
158                    }
159                    data.recycle();
160                }
161            }
162            return null;
163        }
164    }
165
166    public String getGlobalIntSetting(String setting) {
167        try {
168            return getStatusStringFromInt(Settings.Global.getInt(mContentResolver, setting));
169        } catch (SettingNotFoundException e) {
170            Log.d(TAG, "setting: " + setting + " not found");
171            // TODO: show error message
172        }
173        // Default to OFF if not found.
174        return mResources.getString(R.string.action_off_description);
175    }
176
177    public int getGlobalIntSettingToInt(String setting) {
178        try {
179            return Settings.Global.getInt(mContentResolver, setting);
180        } catch (SettingNotFoundException e) {
181            Log.d(TAG, "setting: " + setting + " not found");
182            // TODO: show error message
183        }
184        return 0;
185    }
186
187    public boolean getGlobalIntSettingAsBoolean(String setting) {
188        return Settings.Global.getInt(mContentResolver, setting, 0) != 0;
189    }
190
191    public void setGlobalIntSetting(String setting, boolean value) {
192        int settingValue = value ? 1 : 0;
193        Settings.Global.putInt(mContentResolver, setting, settingValue);
194    }
195
196    public String getStatusStringFromBoolean(boolean status) {
197        int descResId = status ? R.string.action_on_description : R.string.action_off_description;
198        return mResources.getString(descResId);
199    }
200
201    public String getStatusStringFromInt(int status) {
202        int descResId = status > 0 ? R.string.action_on_description :
203                R.string.action_off_description;
204        return mResources.getString(descResId);
205    }
206
207    /**
208     * Translates a status string into a boolean value.
209     *
210     * @param status Status string ("ON"/"OFF")
211     * @return true if the provided status string equals the localized
212     *         R.string.action_on_description; false otherwise.
213     */
214    public boolean getStatusFromString(String status) {
215        if (status == null) {
216            return false;
217        }
218        return status.equalsIgnoreCase(mResources.getString(R.string.action_on_description));
219    }
220
221}
222