1 /** 2 * Copyright (C) 2016 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 package com.android.server.vr; 17 18 import android.annotation.NonNull; 19 import android.content.BroadcastReceiver; 20 import android.content.ContentResolver; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.database.ContentObserver; 24 import android.net.Uri; 25 import android.os.Handler; 26 import android.os.UserHandle; 27 import android.provider.Settings; 28 import android.util.ArraySet; 29 30 import java.util.Objects; 31 import java.util.Set; 32 33 /** 34 * Detects changes in a given setting. 35 * 36 * @hide 37 */ 38 public class SettingsObserver { 39 40 private final String mSecureSettingName; 41 private final BroadcastReceiver mSettingRestoreReceiver; 42 private final ContentObserver mContentObserver; 43 private final Set<SettingChangeListener> mSettingsListeners = new ArraySet<>(); 44 45 /** 46 * Implement this to receive callbacks when the setting tracked by this observer changes. 47 */ 48 public interface SettingChangeListener { 49 50 /** 51 * Called when the tracked setting has changed. 52 */ onSettingChanged()53 void onSettingChanged(); 54 55 56 /** 57 * Called when the tracked setting has been restored for a particular user. 58 * 59 * @param prevValue the previous value of the setting. 60 * @param newValue the new value of the setting. 61 * @param userId the user ID for which this setting has been restored. 62 */ onSettingRestored(String prevValue, String newValue, int userId)63 void onSettingRestored(String prevValue, String newValue, int userId); 64 } 65 SettingsObserver(@onNull final Context context, @NonNull final Handler handler, @NonNull final Uri settingUri, @NonNull final String secureSettingName)66 private SettingsObserver(@NonNull final Context context, @NonNull final Handler handler, 67 @NonNull final Uri settingUri, @NonNull final String secureSettingName) { 68 69 mSecureSettingName = secureSettingName; 70 mSettingRestoreReceiver = new BroadcastReceiver() { 71 @Override 72 public void onReceive(Context context, Intent intent) { 73 if (Intent.ACTION_SETTING_RESTORED.equals(intent.getAction())) { 74 String element = intent.getStringExtra(Intent.EXTRA_SETTING_NAME); 75 if (Objects.equals(element, secureSettingName)) { 76 String prevValue = intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE); 77 String newValue = intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE); 78 sendSettingRestored(prevValue, newValue, getSendingUserId()); 79 } 80 } 81 } 82 }; 83 84 mContentObserver = new ContentObserver(handler) { 85 @Override 86 public void onChange(boolean selfChange, Uri uri) { 87 if (uri == null || settingUri.equals(uri)) { 88 sendSettingChanged(); 89 } 90 } 91 }; 92 93 ContentResolver resolver = context.getContentResolver(); 94 resolver.registerContentObserver(settingUri, false, mContentObserver, 95 UserHandle.USER_ALL); 96 } 97 98 /** 99 * Create a SettingsObserver instance. 100 * 101 * @param context the context to query for settings changes. 102 * @param handler the handler to use for a settings ContentObserver. 103 * @param settingName the setting to track. 104 * @return a SettingsObserver instance. 105 */ build(@onNull Context context, @NonNull Handler handler, @NonNull String settingName)106 public static SettingsObserver build(@NonNull Context context, @NonNull Handler handler, 107 @NonNull String settingName) { 108 Uri settingUri = Settings.Secure.getUriFor(settingName); 109 110 return new SettingsObserver(context, handler, settingUri, settingName); 111 } 112 113 /** 114 * Add a listener for setting changes. 115 * 116 * @param listener a {@link SettingChangeListener} instance. 117 */ addListener(@onNull SettingChangeListener listener)118 public void addListener(@NonNull SettingChangeListener listener) { 119 mSettingsListeners.add(listener); 120 } 121 122 /** 123 * Remove a listener for setting changes. 124 * 125 * @param listener a {@link SettingChangeListener} instance. 126 */ removeListener(@onNull SettingChangeListener listener)127 public void removeListener(@NonNull SettingChangeListener listener) { 128 mSettingsListeners.remove(listener); 129 130 } 131 sendSettingChanged()132 private void sendSettingChanged() { 133 for (SettingChangeListener l : mSettingsListeners) { 134 l.onSettingChanged(); 135 } 136 } 137 sendSettingRestored(final String prevValue, final String newValue, final int userId)138 private void sendSettingRestored(final String prevValue, final String newValue, final int userId) { 139 for (SettingChangeListener l : mSettingsListeners) { 140 l.onSettingRestored(prevValue, newValue, userId); 141 } 142 } 143 144 } 145