133 lines
4.6 KiB
Java
133 lines
4.6 KiB
Java
/*
|
|
* Copyright (C) 2017 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.dialer.configprovider;
|
|
|
|
import android.app.IntentService;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.SharedPreferences;
|
|
import android.content.SharedPreferences.Editor;
|
|
import android.support.annotation.Nullable;
|
|
import com.android.dialer.common.Assert;
|
|
import com.android.dialer.common.LogUtil;
|
|
import com.android.dialer.storage.StorageComponent;
|
|
import com.android.dialer.storage.Unencrypted;
|
|
import com.android.dialer.strictmode.StrictModeUtils;
|
|
import javax.inject.Inject;
|
|
|
|
/**
|
|
* {@link ConfigProvider} which uses a shared preferences file.
|
|
*
|
|
* <p>Config flags can be written using adb (with root access), for example:
|
|
*
|
|
* <pre>
|
|
* adb root
|
|
* adb shell am startservice -n \
|
|
* 'com.android.dialer/.configprovider.SharedPrefConfigProvider\$Service' \
|
|
* --ez boolean_flag_name flag_value
|
|
* </pre>
|
|
*
|
|
* <p>(For longs use --el and for strings use --es.)
|
|
*
|
|
* <p>Flags can be viewed with:
|
|
*
|
|
* <pre>
|
|
* adb shell cat \
|
|
* /data/user_de/0/com.android.dialer/shared_prefs/com.android.dialer_preferences.xml
|
|
* </pre>
|
|
*/
|
|
public class SharedPrefConfigProvider implements ConfigProvider {
|
|
private static final String PREF_PREFIX = "config_provider_prefs_";
|
|
|
|
private final SharedPreferences sharedPreferences;
|
|
|
|
@Inject
|
|
SharedPrefConfigProvider(@Unencrypted SharedPreferences sharedPreferences) {
|
|
this.sharedPreferences = sharedPreferences;
|
|
}
|
|
|
|
/** Service to write values into {@link SharedPrefConfigProvider} using adb. */
|
|
public static class Service extends IntentService {
|
|
|
|
public Service() {
|
|
super("SharedPrefConfigProvider.Service");
|
|
}
|
|
|
|
@Override
|
|
protected void onHandleIntent(@Nullable Intent intent) {
|
|
if (intent == null || intent.getExtras() == null || intent.getExtras().size() != 1) {
|
|
LogUtil.w("SharedPrefConfigProvider.Service.onHandleIntent", "must set exactly one extra");
|
|
return;
|
|
}
|
|
String key = intent.getExtras().keySet().iterator().next();
|
|
Object value = intent.getExtras().get(key);
|
|
put(key, value);
|
|
}
|
|
|
|
private void put(String key, Object value) {
|
|
Editor editor = getSharedPrefs(getApplicationContext()).edit();
|
|
String prefixedKey = PREF_PREFIX + key;
|
|
if (value instanceof Boolean) {
|
|
editor.putBoolean(prefixedKey, (Boolean) value);
|
|
} else if (value instanceof Long) {
|
|
editor.putLong(prefixedKey, (Long) value);
|
|
} else if (value instanceof String) {
|
|
editor.putString(prefixedKey, (String) value);
|
|
} else {
|
|
throw Assert.createAssertionFailException("unsupported extra type: " + value.getClass());
|
|
}
|
|
editor.apply();
|
|
}
|
|
}
|
|
|
|
/** Set a boolean config value. */
|
|
public void putBoolean(String key, boolean value) {
|
|
sharedPreferences.edit().putBoolean(PREF_PREFIX + key, value).apply();
|
|
}
|
|
|
|
public void putLong(String key, long value) {
|
|
sharedPreferences.edit().putLong(PREF_PREFIX + key, value).apply();
|
|
}
|
|
|
|
public void putString(String key, String value) {
|
|
sharedPreferences.edit().putString(PREF_PREFIX + key, value).apply();
|
|
}
|
|
|
|
@Override
|
|
public String getString(String key, String defaultValue) {
|
|
// Reading shared prefs on the main thread is generally safe since a single instance is cached.
|
|
return StrictModeUtils.bypass(
|
|
() -> sharedPreferences.getString(PREF_PREFIX + key, defaultValue));
|
|
}
|
|
|
|
@Override
|
|
public long getLong(String key, long defaultValue) {
|
|
// Reading shared prefs on the main thread is generally safe since a single instance is cached.
|
|
return StrictModeUtils.bypass(() -> sharedPreferences.getLong(PREF_PREFIX + key, defaultValue));
|
|
}
|
|
|
|
@Override
|
|
public boolean getBoolean(String key, boolean defaultValue) {
|
|
// Reading shared prefs on the main thread is generally safe since a single instance is cached.
|
|
return StrictModeUtils.bypass(
|
|
() -> sharedPreferences.getBoolean(PREF_PREFIX + key, defaultValue));
|
|
}
|
|
|
|
private static SharedPreferences getSharedPrefs(Context appContext) {
|
|
return StorageComponent.get(appContext).unencryptedSharedPrefs();
|
|
}
|
|
}
|