Clean up BT stack log level preference controller and tests

Problem: These tests were failing because the resource ID used in the
test and its version of the R class resolved to a different integer
(and subsequently a different string array) than the R class used on
device. This was causing different string arrays with different lengths
and values to sometimes appear, especially when the source and tests
were builts separately.

Solution: Manually lookup the resource ID to use by name instead of
using the pre-baked R class and assuming its ID is correct. This allows
us to get the proper ID every time and trust the values in the array.
This trust allows for some clean up on the code and tests, such that now
our tests can iterate on values instead of relying on private constants
being made visible or even hardcoded values.

Flag: EXEMPT, test fix and minor refactor with no behavior change
Bug: 339148064
Test: atest com.android.settings.development.bluetooth.BluetoothStackLogPreferenceControllerTest
Change-Id: I8149bd06ed70589afb3797a9f453eb2a11c3c410
This commit is contained in:
Sal Savage
2024-07-10 15:50:11 -07:00
parent 40b6a49287
commit da2e2c3e4a
2 changed files with 237 additions and 166 deletions

View File

@@ -30,85 +30,184 @@ import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.development.DeveloperOptionsPreferenceController; import com.android.settingslib.development.DeveloperOptionsPreferenceController;
/**
* This preference represents the default log level for the Bluetooth stack
*
* The default log level is captured and held in an Android Log Framework log tag, using "bluetooth"
* as the tag name. The Log framework does not provide methods to directly write a log tag value,
* but instead leverages special system properties to hold the value of a log tag.
*
* This preferences aims to keep the selection in sync with the currently set log tag value. It
* writes directly to the system properties that hold the level associated with the bluetooth log
* tag. It leverages the Log.isLoggable("bluetooth", level) function to discern the current value.
* The default level is INFO.
*
* This value is read once at start of the Bluetooth stack. To use a new value once setting it, be
* sure to turn Bluetooth off and back on again.
*/
public class BluetoothStackLogPreferenceController extends DeveloperOptionsPreferenceController public class BluetoothStackLogPreferenceController extends DeveloperOptionsPreferenceController
implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin { implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
private static final String TAG = BluetoothStackLogPreferenceController.class.getSimpleName();
private static final String PREFERENCE_KEY = "bt_stack_log_level";
/* Ensure that the indexes match with bt_stack_log_values and bt_stack_log_entries ordering */ /* Ensure that the indexes match with bt_stack_log_values and bt_stack_log_entries ordering */
private static final String PREFERENCE_KEY = "bt_stack_log_level"; private static final int BT_LOG_LEVEL_VERBOSE_INDEX = 0;
@VisibleForTesting static final int BTSTACK_LOG_MODE_VERBOSE_INDEX = 0; private static final int BT_LOG_LEVEL_DEBUG_INDEX = 1;
@VisibleForTesting static final int BTSTACK_LOG_MODE_DEBUG_INDEX = 1; private static final int BT_LOG_LEVEL_INFO_INDEX = 2;
@VisibleForTesting static final int BTSTACK_LOG_MODE_INFO_INDEX = 2; private static final int BT_LOG_LEVEL_WARN_INDEX = 3;
@VisibleForTesting static final int BTSTACK_LOG_MODE_WARN_INDEX = 3; private static final int BT_LOG_LEVEL_ERROR_INDEX = 4;
@VisibleForTesting static final int BTSTACK_LOG_MODE_ERROR_INDEX = 4; @VisibleForTesting static final int BT_LOG_LEVEL_DEFAULT_INDEX = BT_LOG_LEVEL_INFO_INDEX;
@VisibleForTesting private static final String BT_LOG_TAG = "bluetooth";
static final String BLUETOOTH_BTSTACK_LOG_MODE_PROPERTY_PERSIST = "persist.log.tag.bluetooth"; @VisibleForTesting static final String BT_LOG_LEVEL_PROP_PERSIST = "persist.log.tag.bluetooth";
static final String BLUETOOTH_BTSTACK_LOG_MODE_PROPERTY = "log.tag.bluetooth"; @VisibleForTesting static final String BT_LOG_LEVEL_PROP = "log.tag.bluetooth";
static final String BLUETOOTH_STRING_NAME = "bluetooth";
static final int DEFAULT_MODE = BTSTACK_LOG_MODE_INFO_INDEX;
private final String[] mListValues;
private final String[] mListEntries;
// Values represents the untranslatable log level strings that should be used for writing to
// system properties. Entries represents the translatable log level strings that should be used
// in the UI to communicate to the user their options for this preference.
private String[] mListValues;
private String[] mListEntries;
/**
* Create a BluetoothStackLogPreferenceController instance
*/
public BluetoothStackLogPreferenceController(@NonNull Context context) { public BluetoothStackLogPreferenceController(@NonNull Context context) {
super(context); super(context);
mListValues = context.getResources().getStringArray(R.array.bt_stack_log_level_values); mListValues = context.getResources().getStringArray(R.array.bt_stack_log_level_values);
mListEntries = context.getResources().getStringArray(R.array.bt_stack_log_level_entries); mListEntries = context.getResources().getStringArray(R.array.bt_stack_log_level_entries);
} }
/** returns default log level index of INFO */ /**
public int getDefaultModeIndex() { * Returns the preference key associated with this preference
return DEFAULT_MODE; *
} * Note that this key is _usually_ a system property in and of itself, which is expected to hold
* the value of the preference. In this case though, this key *does not* hold the preference. It
* is only really used to tie this controller to the list preference defined in the XML file.
*
* @return the preference key associated with this preference
*/
@Override @Override
@Nullable @Nullable
public String getPreferenceKey() { public String getPreferenceKey() {
return PREFERENCE_KEY; return PREFERENCE_KEY;
} }
/**
* Update the state of the preference based on what the user has selected
*
* This function is invoked when the user has selected a new value for this preference. The new
* value is the entry value at the index of the list the user has selected. This value will be
* one of the values from the array returned in getEntryValues(). Specifically, this array is
* set using R.array.bt_stack_log_level_values
*
* @param preference - the preference object to set the value of
* @param newValue - the value the user has selected, as an Object
* @return True when updated successfully
*/
@Override @Override
public boolean onPreferenceChange(@NonNull Preference preference, @NonNull Object newValue) { public boolean onPreferenceChange(@NonNull Preference preference, @NonNull Object newValue) {
SystemProperties.set(BLUETOOTH_BTSTACK_LOG_MODE_PROPERTY_PERSIST, newValue.toString()); Log.v(TAG, "onPreferenceChange(pref=" + preference + "value=" + newValue.toString() + ")");
SystemProperties.set(BLUETOOTH_BTSTACK_LOG_MODE_PROPERTY, newValue.toString()); setBluetoothLogTag(newValue.toString());
updateState(mPreference); setBluetoothLogLevelIndex(getBluetoothLogLevelIndex());
return true; return true;
} }
/**
* Refresh the state of this preference based on the state stored on the system
*
* Read the Bluetooth stack log level from the underlying system property/log tag, and map that
* level to the proper index in the values and entries array. Use those strings to set the value
* and summary of the preference.
*
* @param preference - the preference object to refresh the state of
*/
@Override @Override
public void updateState(@NonNull Preference preference) { public void updateState(@NonNull Preference preference) {
final ListPreference listPreference = (ListPreference) preference; Log.v(TAG, "updateState(pref=" + preference + "): refresh preference state");
int index = getBluetoothLogLevelIndex(); setBluetoothLogLevelIndex(getBluetoothLogLevelIndex());
listPreference.setValue(mListValues[index]);
listPreference.setSummary(mListEntries[index]);
} }
/** /**
* Returns the current log level from Log.isLoggable(). * Notify this developer options preference of a change to developer options visibility
*
* We developer options are closed, we should clear out the value of this developer option
* preference and revert it back to the default state of INFO.
*/ */
@VisibleForTesting
public int getBluetoothLogLevelIndex() {
if (Log.isLoggable(BLUETOOTH_STRING_NAME, Log.VERBOSE)) {
return BTSTACK_LOG_MODE_VERBOSE_INDEX;
} else if (Log.isLoggable(BLUETOOTH_STRING_NAME, Log.DEBUG)) {
return BTSTACK_LOG_MODE_DEBUG_INDEX;
} else if (Log.isLoggable(BLUETOOTH_STRING_NAME, Log.INFO)) {
return BTSTACK_LOG_MODE_INFO_INDEX;
} else if (Log.isLoggable(BLUETOOTH_STRING_NAME, Log.WARN)) {
return BTSTACK_LOG_MODE_WARN_INDEX;
} else if (Log.isLoggable(BLUETOOTH_STRING_NAME, Log.ERROR)) {
return BTSTACK_LOG_MODE_ERROR_INDEX;
}
return BTSTACK_LOG_MODE_INFO_INDEX;
}
@Override @Override
protected void onDeveloperOptionsSwitchDisabled() { protected void onDeveloperOptionsSwitchDisabled() {
super.onDeveloperOptionsSwitchDisabled(); super.onDeveloperOptionsSwitchDisabled();
SystemProperties.set(BLUETOOTH_BTSTACK_LOG_MODE_PROPERTY_PERSIST, null); Log.v(TAG, "onDeveloperOptionsSwitchDisabled(): Revert stack log to default");
SystemProperties.set(BLUETOOTH_BTSTACK_LOG_MODE_PROPERTY, null); setBluetoothLogTag(null);
((ListPreference) mPreference).setValue(mListValues[getDefaultModeIndex()]); setBluetoothLogLevelIndex(BT_LOG_LEVEL_DEFAULT_INDEX);
((ListPreference) mPreference).setSummary(mListEntries[getDefaultModeIndex()]); }
/**
* Set the system property values used by the Log framework to read the "bluetooth" log tag
*
* @param logLevel - the log level to set the Bluetooth stack minimum log level to
*/
private void setBluetoothLogTag(@Nullable String logLevel) {
Log.i(TAG, "setBluetoothLogTag(logLevel=" + logLevel + "): Set properties for log tag");
SystemProperties.set(BT_LOG_LEVEL_PROP_PERSIST, logLevel);
SystemProperties.set(BT_LOG_LEVEL_PROP, logLevel);
}
/**
* Get the entry and value index corresponding to the current Bluetooth stack log level
*
* Since this preference uses an actual log tag and not a specific/private system property, we
* can read the value using the Log.isLoggable() function with our "bluetooth" log tag that
* represents the log level of the Bluetooth stack. This is safer than trying to replacate the
* logic used in the Log framework around the various persist, ro, and blank variants of the tag
*
* If no value is present, INFO is used.
*
* @return the entry/value index corresponding to the current log level of the tag "bluetooth"
*/
@VisibleForTesting
public int getBluetoothLogLevelIndex() {
int level = BT_LOG_LEVEL_DEFAULT_INDEX;
if (Log.isLoggable(BT_LOG_TAG, Log.VERBOSE)) {
level = BT_LOG_LEVEL_VERBOSE_INDEX;
} else if (Log.isLoggable(BT_LOG_TAG, Log.DEBUG)) {
level = BT_LOG_LEVEL_DEBUG_INDEX;
} else if (Log.isLoggable(BT_LOG_TAG, Log.INFO)) {
level = BT_LOG_LEVEL_INFO_INDEX;
} else if (Log.isLoggable(BT_LOG_TAG, Log.WARN)) {
level = BT_LOG_LEVEL_WARN_INDEX;
} else if (Log.isLoggable(BT_LOG_TAG, Log.ERROR)) {
level = BT_LOG_LEVEL_ERROR_INDEX;
}
Log.v(TAG, "getBluetoothLogLevelIndex() -> " + level);
return level;
}
/**
* Set the current Bluetooth stack log level displayed in the list for this preference
*
* @param index - the index representing the log level choice of this preference
*/
private void setBluetoothLogLevelIndex(int index) {
if (index < BT_LOG_LEVEL_VERBOSE_INDEX || index > BT_LOG_LEVEL_ERROR_INDEX) {
Log.e(TAG, "setBluetoothLogLevelIndex(index=" + index + "): Log level invalid");
return;
}
String value = mListValues[index];
String entryValue = mListEntries[index];
ListPreference preference = ((ListPreference) mPreference);
if (preference == null) {
Log.e(TAG, "setBluetoothLogLevelIndex(index=" + index + "): mPreference is null");
return;
}
preference.setValue(value);
preference.setSummary(entryValue);
Log.i(TAG, "setBluetoothLogLevelIndex(index=" + index
+ "): Updated Bluetooth stack log level to value='" + value + "', entryValue='"
+ entryValue + "'");
} }
} }

View File

@@ -16,13 +16,9 @@
package com.android.settings.development.bluetooth; package com.android.settings.development.bluetooth;
import static com.android.settings.development.bluetooth.BluetoothStackLogPreferenceController.BLUETOOTH_BTSTACK_LOG_MODE_PROPERTY; import static com.android.settings.development.bluetooth.BluetoothStackLogPreferenceController.BT_LOG_LEVEL_DEFAULT_INDEX;
import static com.android.settings.development.bluetooth.BluetoothStackLogPreferenceController.BLUETOOTH_BTSTACK_LOG_MODE_PROPERTY_PERSIST; import static com.android.settings.development.bluetooth.BluetoothStackLogPreferenceController.BT_LOG_LEVEL_PROP;
import static com.android.settings.development.bluetooth.BluetoothStackLogPreferenceController.BTSTACK_LOG_MODE_VERBOSE_INDEX; import static com.android.settings.development.bluetooth.BluetoothStackLogPreferenceController.BT_LOG_LEVEL_PROP_PERSIST;
import static com.android.settings.development.bluetooth.BluetoothStackLogPreferenceController.BTSTACK_LOG_MODE_DEBUG_INDEX;
import static com.android.settings.development.bluetooth.BluetoothStackLogPreferenceController.BTSTACK_LOG_MODE_INFO_INDEX;
import static com.android.settings.development.bluetooth.BluetoothStackLogPreferenceController.BTSTACK_LOG_MODE_WARN_INDEX;
import static com.android.settings.development.bluetooth.BluetoothStackLogPreferenceController.BTSTACK_LOG_MODE_ERROR_INDEX;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
@@ -37,18 +33,21 @@ import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@Ignore("b/339148064")
public class BluetoothStackLogPreferenceControllerTest { public class BluetoothStackLogPreferenceControllerTest {
private static final String TAG = "BluetoothStackLogPreferenceControllerTest"; private static final String COM_ANDROID_SETTINGS = "com.android.settings";
private static final String TYPE_ARRAY = "array";
@Mock private Context mContext; private static final String XML_DEFINED_PREFERENCE_KEY = "bt_stack_log_level";
private static final String XML_DEFINED_ENTRIES_RESOURCE = "bt_stack_log_level_entries";
private static final String XML_DEFINED_VALUES_RESOURCE = "bt_stack_log_level_values";
private static final String PROPERTY_CLEARED = "";
private Context mContext;
private ListPreference mPreference; private ListPreference mPreference;
private PreferenceManager mPreferenceManager; private PreferenceManager mPreferenceManager;
@@ -61,7 +60,6 @@ public class BluetoothStackLogPreferenceControllerTest {
@Before @Before
public void setup() { public void setup() {
MockitoAnnotations.initMocks(this);
mContext = ApplicationProvider.getApplicationContext(); mContext = ApplicationProvider.getApplicationContext();
if (Looper.myLooper() == null) { if (Looper.myLooper() == null) {
@@ -71,12 +69,11 @@ public class BluetoothStackLogPreferenceControllerTest {
mPreferenceManager = new PreferenceManager(mContext); mPreferenceManager = new PreferenceManager(mContext);
mPreferenceScreen = mPreferenceManager.createPreferenceScreen(mContext); mPreferenceScreen = mPreferenceManager.createPreferenceScreen(mContext);
mPreference = new ListPreference(mContext); mPreference = new ListPreference(mContext);
mController = new BluetoothStackLogPreferenceController(mContext); mController = new BluetoothStackLogPreferenceController(mContext);
mPreference.setKey(mController.getPreferenceKey()); mPreference.setKey(mController.getPreferenceKey());
mPreference.setEntries(com.android.settings.R.array.bt_stack_log_level_entries); mPreference.setEntries(getStringArrayResourceId(XML_DEFINED_ENTRIES_RESOURCE));
mPreference.setEntryValues(com.android.settings.R.array.bt_stack_log_level_values); mPreference.setEntryValues(getStringArrayResourceId(XML_DEFINED_VALUES_RESOURCE));
mPreferenceScreen.addPreference(mPreference); mPreferenceScreen.addPreference(mPreference);
mController.displayPreference(mPreferenceScreen); mController.displayPreference(mPreferenceScreen);
@@ -86,134 +83,109 @@ public class BluetoothStackLogPreferenceControllerTest {
} }
/** /**
* Test that default log level is set to INFO * Get the resource ID associated with a resource name
*
* This looks up the resource id by name using our device's context. This way, we can avoid
* hardcoding a resource ID or value from the R class which may not match the resource IDs on
* the device under test.
*
* Usage: int valuesResId = getStringArrayResource("bt_stack_log_level_values");
* Usage: int entriesResId = getStringArrayResource("bt_stack_log_level_entries");
*
* @param res - The resource name to look up
* @return The integer resource ID corresponding to the given resource name
*/ */
@Test public int getStringArrayResourceId(String res) {
public void verifyDefaultState_enablesDefaultLogLevelEntriesAndValuesSameSize() { return mContext.getResources().getIdentifier(res, TYPE_ARRAY, COM_ANDROID_SETTINGS);
mController.onPreferenceChange(mPreference, mController.getDefaultModeIndex());
assertThat(mPreference.getValue().toString()).isEqualTo(mListValues
[BTSTACK_LOG_MODE_INFO_INDEX].toString());
assertThat(mPreference.getSummary().toString()).isEqualTo(mListEntries
[BTSTACK_LOG_MODE_INFO_INDEX].toString());
} }
/** /**
* Test that log level is changed to VERBOSE when VERBOSE is selected * Test that, for each possible value a user can select, our controller properly handles the
* value to update the underlying system property _and_ set the UI entry to the proper value.
*/ */
@Test @Test
public void onPreferenceChanged_enableBluetoothStackVerboseLogLevel() { public void onPreferenceChange_withEachValue_uiSetProperlyAndAllValuesWrittenToProperties() {
mController.onPreferenceChange(mPreference, mListValues[BTSTACK_LOG_MODE_VERBOSE_INDEX] for (int index = 0; index < mListValues.length; index++) {
.toString()); String value = mListValues[index].toString();
String entry = mListEntries[index].toString();
final String persistedLogLevel = SystemProperties.get( mController.onPreferenceChange(mPreference, value);
BLUETOOTH_BTSTACK_LOG_MODE_PROPERTY_PERSIST);
final String logLevel = SystemProperties.get(BLUETOOTH_BTSTACK_LOG_MODE_PROPERTY);
assertThat(persistedLogLevel).isEqualTo(mListValues[BTSTACK_LOG_MODE_VERBOSE_INDEX]
.toString());
assertThat(logLevel).isEqualTo(mListValues[BTSTACK_LOG_MODE_VERBOSE_INDEX].toString());
assertThat(mPreference.getValue().toString()).isEqualTo(mListValues final String persistedLogLevel = SystemProperties.get(BT_LOG_LEVEL_PROP_PERSIST);
[BTSTACK_LOG_MODE_VERBOSE_INDEX].toString()); final String logLevel = SystemProperties.get(BT_LOG_LEVEL_PROP);
assertThat(mPreference.getSummary().toString()).isEqualTo(mListEntries final String currentValue = mPreference.getValue().toString();
[BTSTACK_LOG_MODE_VERBOSE_INDEX].toString()); final String currentEntry = mPreference.getEntry().toString();
final String currentSummary = mPreference.getSummary().toString();
final int currentIndex = mPreference.findIndexOfValue(currentValue);
assertThat(persistedLogLevel).isEqualTo(value);
assertThat(logLevel).isEqualTo(value);
assertThat(currentIndex).isEqualTo(index);
assertThat(currentValue).isEqualTo(value);
assertThat(currentEntry).isEqualTo(entry);
assertThat(currentSummary).isEqualTo(entry);
}
} }
/** /**
* Test that log level is changed to DEBUG when DEBUG is selected * Test that, for each possible log tag log level value, our controller properly handles the
* value to set the UI entry to the proper value.
*/ */
@Test @Test
public void onPreferenceChanged_enableBluetoothStackDebugLogLevel() { public void updateState_withEachValue_uiSetProperly() {
mController.onPreferenceChange(mPreference, mListValues[BTSTACK_LOG_MODE_DEBUG_INDEX] for (int index = 0; index < mListValues.length; index++) {
.toString()); String value = mListValues[index].toString();
String entry = mListEntries[index].toString();
final String persistedLogLevel = SystemProperties.get( SystemProperties.set(BT_LOG_LEVEL_PROP_PERSIST, value);
BLUETOOTH_BTSTACK_LOG_MODE_PROPERTY_PERSIST); SystemProperties.set(BT_LOG_LEVEL_PROP, value);
final String logLevel = SystemProperties.get(BLUETOOTH_BTSTACK_LOG_MODE_PROPERTY);
assertThat(persistedLogLevel).isEqualTo(mListValues[BTSTACK_LOG_MODE_DEBUG_INDEX]
.toString());
assertThat(logLevel).isEqualTo(mListValues[BTSTACK_LOG_MODE_DEBUG_INDEX].toString());
assertThat(mPreference.getValue().toString()).isEqualTo(mListValues mController.updateState(mPreference);
[BTSTACK_LOG_MODE_DEBUG_INDEX].toString());
assertThat(mPreference.getSummary().toString()).isEqualTo(mListEntries final String currentValue = mPreference.getValue().toString();
[BTSTACK_LOG_MODE_DEBUG_INDEX].toString()); final String currentEntry = mPreference.getEntry().toString();
final String currentSummary = mPreference.getSummary().toString();
final int currentIndex = mPreference.findIndexOfValue(currentValue);
assertThat(currentIndex).isEqualTo(index);
assertThat(currentValue).isEqualTo(value);
assertThat(currentEntry).isEqualTo(entry);
assertThat(currentSummary).isEqualTo(entry);
}
} }
/** /**
* Test that log level is changed to INFO when INFO is selected * Test that our controller reverts the log level back to a missing/default value when we're
* notified that Developer Options has been disabled.
*/ */
@Test @Test
public void onPreferenceChanged_enableBluetoothStackInfoLogLevel() { public void onDeveloperOptionsSwitchDisabled_preferenceSetToDefault() {
mController.onPreferenceChange(mPreference, mListValues[BTSTACK_LOG_MODE_INFO_INDEX] mController.onDeveloperOptionsSwitchDisabled();
.toString());
final String persistedLogLevel = SystemProperties.get( final String defaultEntry = mListEntries[BT_LOG_LEVEL_DEFAULT_INDEX].toString();
BLUETOOTH_BTSTACK_LOG_MODE_PROPERTY_PERSIST); final String defaultValue = mListValues[BT_LOG_LEVEL_DEFAULT_INDEX].toString();
final String logLevel = SystemProperties.get(BLUETOOTH_BTSTACK_LOG_MODE_PROPERTY);
assertThat(persistedLogLevel).isEqualTo(mListValues[BTSTACK_LOG_MODE_INFO_INDEX]
.toString());
assertThat(logLevel).isEqualTo(mListValues[BTSTACK_LOG_MODE_INFO_INDEX].toString());
assertThat(mPreference.getValue().toString()).isEqualTo(mListValues final String persistedLogLevel = SystemProperties.get(BT_LOG_LEVEL_PROP_PERSIST);
[BTSTACK_LOG_MODE_INFO_INDEX].toString()); final String logLevel = SystemProperties.get(BT_LOG_LEVEL_PROP);
assertThat(mPreference.getSummary().toString()).isEqualTo(mListEntries final String currentValue = mPreference.getValue().toString();
[BTSTACK_LOG_MODE_INFO_INDEX].toString()); final String currentEntry = mPreference.getEntry().toString();
final String currentSummary = mPreference.getSummary().toString();
final int currentIndex = mPreference.findIndexOfValue(currentValue);
assertThat(persistedLogLevel).isEqualTo(PROPERTY_CLEARED);
assertThat(logLevel).isEqualTo(PROPERTY_CLEARED);
assertThat(currentIndex).isEqualTo(BT_LOG_LEVEL_DEFAULT_INDEX);
assertThat(currentValue).isEqualTo(defaultValue);
assertThat(currentEntry).isEqualTo(defaultEntry);
assertThat(currentSummary).isEqualTo(defaultEntry);
} }
/** /**
* Test that log level is changed to WARN when WARN is selected * Test that our preference key returned by our controller matches the one defined in the XML
* definition.
*/ */
@Test @Test
public void onPreferenceChanged_enableBluetoothStackWarnLogLevel() { public void getPreferenceKey_matchesXmlDefinedPreferenceKey() {
mController.onPreferenceChange(mPreference, mListValues[BTSTACK_LOG_MODE_WARN_INDEX] assertThat(mController.getPreferenceKey()).isEqualTo(XML_DEFINED_PREFERENCE_KEY);
.toString());
final String persistedLogLevel = SystemProperties.get(
BLUETOOTH_BTSTACK_LOG_MODE_PROPERTY_PERSIST);
final String logLevel = SystemProperties.get(BLUETOOTH_BTSTACK_LOG_MODE_PROPERTY);
assertThat(persistedLogLevel).isEqualTo(mListValues[BTSTACK_LOG_MODE_WARN_INDEX]
.toString());
assertThat(logLevel).isEqualTo(mListValues[BTSTACK_LOG_MODE_WARN_INDEX].toString());
assertThat(mPreference.getValue().toString()).isEqualTo(mListValues
[BTSTACK_LOG_MODE_WARN_INDEX].toString());
assertThat(mPreference.getSummary().toString()).isEqualTo(mListEntries
[BTSTACK_LOG_MODE_WARN_INDEX].toString());
}
/**
* Test that log level is changed to ERROR when ERROR is selected
*/
@Test
public void onPreferenceChanged_enableBluetoothStackErrorLogLevel() {
mController.onPreferenceChange(mPreference, mListValues[BTSTACK_LOG_MODE_ERROR_INDEX]
.toString());
final String persistedLogLevel = SystemProperties.get(
BLUETOOTH_BTSTACK_LOG_MODE_PROPERTY_PERSIST);
final String logLevel = SystemProperties.get(BLUETOOTH_BTSTACK_LOG_MODE_PROPERTY);
assertThat(persistedLogLevel).isEqualTo(mListValues[BTSTACK_LOG_MODE_ERROR_INDEX]
.toString());
assertThat(logLevel).isEqualTo(mListValues[BTSTACK_LOG_MODE_ERROR_INDEX].toString());
assertThat(mPreference.getValue().toString()).isEqualTo(mListValues
[BTSTACK_LOG_MODE_ERROR_INDEX].toString());
assertThat(mPreference.getSummary().toString()).isEqualTo(mListEntries
[BTSTACK_LOG_MODE_ERROR_INDEX].toString());
}
/**
* Test that preference is disabled when developer options is disabled
* Log level is also reset to default
*/
@Test
public void onDeveloperOptionsDisabled_shouldDisablePreference() {
mController.onDeveloperOptionsDisabled();
assertThat(mPreference.isEnabled()).isFalse();
assertThat(mPreference.getValue().toString()).isEqualTo(mListValues[mController
.getDefaultModeIndex()].toString());
assertThat(mPreference.getSummary().toString()).isEqualTo(mListEntries[mController
.getDefaultModeIndex()].toString());
} }
} }