1 /* 2 * Copyright (C) 2018 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 android.util; 18 19 import android.content.ContentResolver; 20 import android.database.ContentObserver; 21 import android.net.Uri; 22 import android.os.Handler; 23 24 /** 25 * Abstract class for observing changes to a specified setting stored as a comma-separated key value 26 * list of parameters. Registers and unregisters a {@link ContentObserver} and handles updates when 27 * the setting changes. 28 * 29 * <p>Subclasses should pass in the relevant setting's {@link Uri} in the constructor and implement 30 * {@link #update(KeyValueListParser)} to receive updates when the value changes. 31 * Calls to {@link #update(KeyValueListParser)} only trigger after calling {@link 32 * #start()}. 33 * 34 * <p>To get the most up-to-date parameter values, first call {@link #start()} before accessing the 35 * values to start observing changes, and then call {@link #stop()} once finished. 36 * 37 * @hide 38 */ 39 public abstract class KeyValueSettingObserver { 40 private static final String TAG = "KeyValueSettingObserver"; 41 42 private final KeyValueListParser mParser = new KeyValueListParser(','); 43 44 private final ContentObserver mObserver; 45 private final ContentResolver mResolver; 46 private final Uri mSettingUri; 47 48 public KeyValueSettingObserver(Handler handler, ContentResolver resolver, 49 Uri uri) { 50 mObserver = new SettingObserver(handler); 51 mResolver = resolver; 52 mSettingUri = uri; 53 } 54 55 /** Starts observing changes for the setting. Pair with {@link #stop()}. */ 56 public void start() { 57 mResolver.registerContentObserver(mSettingUri, false, mObserver); 58 setParserValue(); 59 update(mParser); 60 } 61 62 /** Stops observing changes for the setting. */ 63 public void stop() { 64 mResolver.unregisterContentObserver(mObserver); 65 } 66 67 /** 68 * Returns the {@link String} representation of the setting. Subclasses should implement this 69 * for their setting. 70 */ 71 public abstract String getSettingValue(ContentResolver resolver); 72 73 /** Updates the parser with the current setting value. */ 74 private void setParserValue() { 75 String setting = getSettingValue(mResolver); 76 try { 77 mParser.setString(setting); 78 } catch (IllegalArgumentException e) { 79 Slog.e(TAG, "Malformed setting: " + setting); 80 } 81 } 82 83 /** Subclasses should implement this to update references to their parameters. */ 84 public abstract void update(KeyValueListParser parser); 85 86 private class SettingObserver extends ContentObserver { 87 private SettingObserver(Handler handler) { 88 super(handler); 89 } 90 91 @Override 92 public void onChange(boolean selfChange) { 93 setParserValue(); 94 update(mParser); 95 } 96 } 97 } 98