165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/* 265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Copyright (C) 2014 The Android Open Source Project 365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Licensed under the Apache License, Version 2.0 (the "License"); 565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * you may not use this file except in compliance with the License. 665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * You may obtain a copy of the License at 765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * http://www.apache.org/licenses/LICENSE-2.0 965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 1065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Unless required by applicable law or agreed to in writing, software 1165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * distributed under the License is distributed on an "AS IS" BASIS, 1265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * See the License for the specific language governing permissions and 1465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * limitations under the License. 1565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 1665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepackage com.android.tv.settings.util; 1865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.R; 2065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.ContentResolver; 2165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Context; 2265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.res.Resources; 2365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.AsyncTask; 2465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.IBinder; 2565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Parcel; 2665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.RemoteException; 2765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.ServiceManager; 2865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.SystemProperties; 2965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.provider.Settings; 3065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.provider.Settings.SettingNotFoundException; 3165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.util.Log; 3265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.IWindowManager; 3365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.View; 3465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 3565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.ArrayList; 3665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 3765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepublic class SettingsHelper { 3865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 3965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String TAG = "SettingsHelper"; 4065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final boolean DEBUG = false; 4165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private Context mContext; 4365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private ContentResolver mContentResolver; 4465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private Resources mResources; 4565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public SettingsHelper(Context context) { 4765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mContext = context; 4865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mContentResolver = context.getContentResolver(); 4965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mResources = context.getResources(); 5065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 5165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 5365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Returns a human readable Status description of the setting's value. 5465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 5565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public String getSecureStatusIntSetting(String setting) { 5665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane try { 5765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return getStatusStringFromInt(Settings.Secure.getInt(mContentResolver, setting)); 5865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } catch (SettingNotFoundException e) { 5965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.d(TAG, "setting: " + setting + " not found"); 6065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // TODO: show error message 6165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 6265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return null; 6365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 6465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 6665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Returns a string representation of the Integer setting's value. 6765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 6865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public String getSecureIntSetting(String setting, String def) { 6965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return Integer.toString( 7065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Settings.Secure.getInt(mContentResolver, setting, Integer.parseInt(def))); 7165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 7265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 7465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Returns the int as a boolean, for use in determining "on|off". 7565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 7665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public boolean getSecureIntValueSettingToBoolean(String setting) { 7765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane try { 7865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return Settings.Secure.getInt(mContentResolver, setting) == 1; 7965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } catch (SettingNotFoundException e) { 8065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return false; 8165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 8265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 8365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void setSecureIntSetting(String setting, boolean value) { 8565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int settingValue = value ? 1 : 0; 8665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Settings.Secure.putInt(mContentResolver, setting, settingValue); 8765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 8865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void setSecureIntValueSetting(String setting, Object value) { 9065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int settingValue = Integer.parseInt((String) value); 9165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Settings.Secure.putInt(mContentResolver, setting, settingValue); 9265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 9365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 9465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 9565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Returns a human readable description of the setting's value. 9665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 9765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public String getSystemIntSetting(String setting) { 9865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane try { 9965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return getStatusStringFromInt(Settings.System.getInt(mContentResolver, setting)); 10065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } catch (SettingNotFoundException e) { 10165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.d(TAG, "setting: " + setting + " not found"); 10265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // TODO: show error message 10365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 10465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return null; 10565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 10665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 10765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public boolean getSystemIntSettingToBoolean(String setting) { 10865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane try { 10965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return Settings.System.getInt(mContentResolver, setting) == 1; 11065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } catch (SettingNotFoundException e) { 11165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return false; 11265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 11365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 11465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 11565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void setSystemIntSetting(String setting, boolean value) { 11665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int settingValue = value ? 1 : 0; 11765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Settings.System.putInt(mContentResolver, setting, settingValue); 11865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 11965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 12065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void setSystemProperties(String setting, String value) { 12165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane SystemProperties.set(setting, value); 12265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane pokeSystemProperties(); 12365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 12465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 12565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public String getSystemProperties(String setting) { 12665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return SystemProperties.get(setting); 12765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 12865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 12965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 13065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Returns a human readable description of the setting's value. 13165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 13265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public String getSystemBooleanProperties(String setting) { 13365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return getStatusStringFromBoolean(SystemProperties.getBoolean(setting, false)); 13465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 13565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void pokeSystemProperties() { 13665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane (new SystemPropPoker()).execute(); 13765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 13865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 13965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane static class SystemPropPoker extends AsyncTask<Void, Void, Void> { 14065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 14165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected Void doInBackground(Void... params) { 14265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String[] services; 14365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane try { 14465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane services = ServiceManager.listServices(); 14565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } catch (RemoteException e) { 14665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return null; 14765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (String service : services) { 14965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane IBinder obj = ServiceManager.checkService(service); 15065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (obj != null) { 15165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Parcel data = Parcel.obtain(); 15265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane try { 15365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane obj.transact(IBinder.SYSPROPS_TRANSACTION, data, null, 0); 15465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } catch (RemoteException e) { 15565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } catch (Exception e) { 15665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.i(TAG, "Somone wrote a bad service '" + service 15765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane + "' that doesn't like to be poked: " + e); 15865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 15965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane data.recycle(); 16065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 16165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 16265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return null; 16365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 16465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 16565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 16665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public String getGlobalIntSetting(String setting) { 16765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane try { 16865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return getStatusStringFromInt(Settings.Global.getInt(mContentResolver, setting)); 16965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } catch (SettingNotFoundException e) { 17065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.d(TAG, "setting: " + setting + " not found"); 17165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // TODO: show error message 17265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 17365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Default to OFF if not found. 17465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mResources.getString(R.string.action_off_description); 17565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 17665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 17765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public int getGlobalIntSettingToInt(String setting) { 17865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane try { 17965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return Settings.Global.getInt(mContentResolver, setting); 18065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } catch (SettingNotFoundException e) { 18165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.d(TAG, "setting: " + setting + " not found"); 18265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // TODO: show error message 18365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 18465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return 0; 18565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 18665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 18765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public boolean getGlobalIntSettingAsBoolean(String setting) { 18865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return Settings.Global.getInt(mContentResolver, setting, 0) != 0; 18965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 19065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 19165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void setGlobalIntSetting(String setting, boolean value) { 19265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int settingValue = value ? 1 : 0; 19365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Settings.Global.putInt(mContentResolver, setting, settingValue); 19465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 19565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 19665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public String getStatusStringFromBoolean(boolean status) { 19765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int descResId = status ? R.string.action_on_description : R.string.action_off_description; 19865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mResources.getString(descResId); 19965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 20065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 20165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public String getStatusStringFromInt(int status) { 20265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int descResId = status > 0 ? R.string.action_on_description : 20365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.string.action_off_description; 20465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mResources.getString(descResId); 20565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 20665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 20765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 20865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Translates a status string into a boolean value. 20965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 21065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param status Status string ("ON"/"OFF") 21165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @return true if the provided status string equals the localized 21265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * R.string.action_on_description; false otherwise. 21365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 21465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public boolean getStatusFromString(String status) { 21565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (status == null) { 21665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return false; 21765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 21865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return status.equalsIgnoreCase(mResources.getString(R.string.action_on_description)); 21965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 22065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 22165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane} 222