Home | History | Annotate | Download | only in settings
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.camera.settings;
     18 
     19 import com.android.camera.async.Observable;
     20 import com.android.camera.async.SafeCloseable;
     21 
     22 import java.util.concurrent.Executor;
     23 
     24 import javax.annotation.CheckReturnValue;
     25 import javax.annotation.Nonnull;
     26 import javax.annotation.concurrent.ThreadSafe;
     27 
     28 /**
     29  * Wraps a {@link SettingsManager} setting with thread-safe interfaces for
     30  * observing changes.
     31  */
     32 @ThreadSafe
     33 public final class SettingObserver<T> implements Observable<T> {
     34     private class Listener implements SettingsManager.OnSettingChangedListener, SafeCloseable {
     35         private final Runnable mRunnable;
     36         private final Executor mExecutor;
     37 
     38         private Listener(Runnable runnable, Executor executor) {
     39             mRunnable = runnable;
     40             mExecutor = executor;
     41         }
     42 
     43         @Override
     44         public void onSettingChanged(SettingsManager settingsManager, String key) {
     45             mExecutor.execute(mRunnable);
     46         }
     47 
     48         @Override
     49         public void close() {
     50             mSettingsManager.removeListener(this);
     51         }
     52     }
     53 
     54     private final SettingsManager mSettingsManager;
     55     private final String mScope;
     56     private final String mKey;
     57     private final Class<T> mTClass;
     58 
     59     private SettingObserver(SettingsManager manager, String scope, String key, Class<T> tClass) {
     60         mSettingsManager = manager;
     61         mScope = scope;
     62         mKey = key;
     63         mTClass = tClass;
     64     }
     65 
     66     public static SettingObserver<Integer> ofInteger(SettingsManager manager,
     67             String scope, String key) {
     68         return new SettingObserver<>(manager, scope, key,
     69                 Integer.class);
     70     }
     71 
     72     public static SettingObserver<String> ofString(SettingsManager manager,
     73             String scope, String key) {
     74         return new SettingObserver<>(manager, scope, key,
     75                 String.class);
     76     }
     77 
     78     public static SettingObserver<Boolean> ofBoolean(SettingsManager manager,
     79             String scope, String key) {
     80         return new SettingObserver<>(manager, scope, key,
     81                 Boolean.class);
     82     }
     83 
     84     @CheckReturnValue
     85     @Nonnull
     86     @Override
     87     public SafeCloseable addCallback(@Nonnull Runnable callback, @Nonnull Executor executor) {
     88         Listener listener = new Listener(callback, executor);
     89         mSettingsManager.addListener(listener);
     90         return listener;
     91     }
     92 
     93     @Nonnull
     94     @Override
     95     @SuppressWarnings("unchecked")
     96     public T get() {
     97         if (mTClass.equals(Integer.class)) {
     98             return (T) Integer.valueOf(mSettingsManager.getInteger(mScope, mKey));
     99         } else if (mTClass.equals(String.class)) {
    100             Object string = mSettingsManager.getString(mScope, mKey);
    101             if (string == null) {
    102                 return null;
    103             } else {
    104                 return (T) string;
    105             }
    106         } else if (mTClass.equals(Boolean.class)) {
    107             return (T) Boolean.valueOf(mSettingsManager.getBoolean(mScope, mKey));
    108         } else {
    109             // Impossible branch
    110             throw new IllegalStateException("T must be one of {Integer, Boolean, String}");
    111         }
    112     }
    113 }
    114