blob: 63bb5e7f0e4a5c0a2b9f272681e0020a67542127 [file] [log] [blame]
/*
* Copyright (C) 2016 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.systemui.utils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import android.content.ContentResolver;
import android.os.Handler;
import android.os.HandlerThread;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
import android.support.test.runner.AndroidJUnit4;
import android.util.Log;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.utils.FakeSettingsProvider.AcquireTimeoutException;
import com.android.systemui.utils.FakeSettingsProvider.SettingOverrider;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class FakeSettingsProviderTest extends SysuiTestCase {
public static final String NONEXISTENT_SETTING = "nonexistent_setting";
private static final String TAG = "FakeSettingsProviderTest";
private SettingOverrider mOverrider;
private ContentResolver mContentResolver;
@Before
public void setup() throws AcquireTimeoutException {
mOverrider = mContext.getSettingsProvider().acquireOverridesBuilder(this)
.addSetting("secure", NONEXISTENT_SETTING)
.addSetting("global", NONEXISTENT_SETTING, "initial value")
.addSetting("global", Global.DEVICE_PROVISIONED)
.build();
mContentResolver = mContext.getContentResolver();
}
@After
public void teardown() {
if (mOverrider != null) {
mOverrider.release();
}
}
@Test
public void testInitialValueSecure() {
String value = Secure.getString(mContentResolver, NONEXISTENT_SETTING);
assertNull(value);
}
@Test
public void testInitialValueGlobal() {
String value = Global.getString(mContentResolver, NONEXISTENT_SETTING);
assertEquals("initial value", value);
}
@Test
public void testSeparateTables() {
Secure.putString(mContentResolver, NONEXISTENT_SETTING, "something");
Global.putString(mContentResolver, NONEXISTENT_SETTING, "else");
assertEquals("something", Secure.getString(mContentResolver, NONEXISTENT_SETTING));
assertEquals("something", mOverrider.get("secure", NONEXISTENT_SETTING));
assertEquals("else", Global.getString(mContentResolver, NONEXISTENT_SETTING));
assertEquals("else", mOverrider.get("global", NONEXISTENT_SETTING));
}
@Test
public void testPassThrough() {
// Grab the value of a setting that is not overridden.
assertTrue(Secure.getInt(mContentResolver, Secure.USER_SETUP_COMPLETE, 0) != 0);
}
@Test
public void testOverrideExisting() {
// Grab the value of a setting that is overridden and will be different than the actual
// value.
assertNull(Global.getString(mContentResolver, Global.DEVICE_PROVISIONED));
}
@Test
public void testRelease() {
// Verify different value.
assertNull(Global.getString(mContentResolver, Global.DEVICE_PROVISIONED));
mOverrider.release();
mOverrider = null;
// Verify actual value after release.
assertEquals("1", Global.getString(mContentResolver, Global.DEVICE_PROVISIONED));
}
@Test
public void testAutoRelease() throws Exception {
super.cleanup();
mContext.getSettingsProvider().acquireOverridesBuilder(this)
.addSetting("global", Global.DEVICE_PROVISIONED)
.build();
}
@Test
public void testContention() throws AcquireTimeoutException, InterruptedException {
SettingOverrider[] overriders = new SettingOverrider[2];
Object lock = new Object();
String secure = "secure";
String key = "something shared";
String[] result = new String[1];
overriders[0] = mContext.getSettingsProvider().acquireOverridesBuilder(this)
.addSetting(secure, key, "Some craziness")
.build();
synchronized (lock) {
HandlerThread t = runOnHandler(() -> {
try {
// Grab the lock that will be used for the settings ownership to ensure
// we have some contention going on.
synchronized (mContext.getSettingsProvider().getLock()) {
synchronized (lock) {
// Let the other thread know to release the settings, but it won't
// be able to until this thread waits in the build() method.
lock.notify();
}
overriders[1] = mContext.getSettingsProvider()
.acquireOverridesBuilder(FakeSettingsProviderTest.this)
.addSetting(secure, key, "default value")
.build();
// Ensure that the default is the one we set, and not left over from
// the other setting override.
result[0] = Settings.Secure.getString(mContentResolver, key);
synchronized (lock) {
// Let the main thread know we are done.
lock.notify();
}
}
} catch (AcquireTimeoutException e) {
Log.e(TAG, "Couldn't acquire setting", e);
}
});
// Wait for the thread to hold the acquire lock, then release the settings.
lock.wait();
overriders[0].release();
// Wait for the thread to be done getting the value.
lock.wait();
// Quit and cleanup.
t.quitSafely();
assertNotNull(overriders[1]);
overriders[1].release();
}
// Verify the value was the expected one from the thread's SettingOverride.
assertEquals("default value", result[0]);
}
private HandlerThread runOnHandler(Runnable r) {
HandlerThread t = new HandlerThread("Test Thread");
t.start();
new Handler(t.getLooper()).post(r);
return t;
}
}