/* * Copyright (C) 2015 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.camera.settings; import com.android.camera.async.Observable; import com.android.camera.async.SafeCloseable; import java.util.concurrent.Executor; import javax.annotation.CheckReturnValue; import javax.annotation.Nonnull; import javax.annotation.concurrent.ThreadSafe; /** * Wraps a {@link SettingsManager} setting with thread-safe interfaces for * observing changes. */ @ThreadSafe public final class SettingObserver implements Observable { private class Listener implements SettingsManager.OnSettingChangedListener, SafeCloseable { private final Runnable mRunnable; private final Executor mExecutor; private Listener(Runnable runnable, Executor executor) { mRunnable = runnable; mExecutor = executor; } @Override public void onSettingChanged(SettingsManager settingsManager, String key) { mExecutor.execute(mRunnable); } @Override public void close() { mSettingsManager.removeListener(this); } } private final SettingsManager mSettingsManager; private final String mScope; private final String mKey; private final Class mTClass; private SettingObserver(SettingsManager manager, String scope, String key, Class tClass) { mSettingsManager = manager; mScope = scope; mKey = key; mTClass = tClass; } public static SettingObserver ofInteger(SettingsManager manager, String scope, String key) { return new SettingObserver<>(manager, scope, key, Integer.class); } public static SettingObserver ofString(SettingsManager manager, String scope, String key) { return new SettingObserver<>(manager, scope, key, String.class); } public static SettingObserver ofBoolean(SettingsManager manager, String scope, String key) { return new SettingObserver<>(manager, scope, key, Boolean.class); } @CheckReturnValue @Nonnull @Override public SafeCloseable addCallback(@Nonnull Runnable callback, @Nonnull Executor executor) { Listener listener = new Listener(callback, executor); mSettingsManager.addListener(listener); return listener; } @Nonnull @Override @SuppressWarnings("unchecked") public T get() { if (mTClass.equals(Integer.class)) { return (T) Integer.valueOf(mSettingsManager.getInteger(mScope, mKey)); } else if (mTClass.equals(String.class)) { Object string = mSettingsManager.getString(mScope, mKey); if (string == null) { return null; } else { return (T) string; } } else if (mTClass.equals(Boolean.class)) { return (T) Boolean.valueOf(mSettingsManager.getBoolean(mScope, mKey)); } else { // Impossible branch throw new IllegalStateException("T must be one of {Integer, Boolean, String}"); } } }