blob: 69ca581e1559587ae52ad850a66da80acd1d0387 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 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
17package android.database;
18
Artur Satayev26958002019-12-10 17:47:52 +000019import android.compat.annotation.UnsupportedAppUsage;
Jeff Brown655e66b2012-01-23 15:51:41 -080020import android.net.Uri;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import android.os.Handler;
Svetoslav86b1df22014-08-21 14:22:53 -070022import android.os.UserHandle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023
24/**
Jeff Brown86de0592012-01-23 13:01:18 -080025 * Receives call backs for changes to content.
26 * Must be implemented by objects which are added to a {@link ContentObservable}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027 */
28public abstract class ContentObserver {
Jeff Brown86de0592012-01-23 13:01:18 -080029 private final Object mLock = new Object();
30 private Transport mTransport; // guarded by mLock
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031
Jeff Brown86de0592012-01-23 13:01:18 -080032 Handler mHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033
34 /**
Jeff Brown86de0592012-01-23 13:01:18 -080035 * Creates a content observer.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036 *
Jeff Brown86de0592012-01-23 13:01:18 -080037 * @param handler The handler to run {@link #onChange} on, or null if none.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038 */
39 public ContentObserver(Handler handler) {
40 mHandler = handler;
41 }
42
43 /**
44 * Gets access to the binder transport object. Not for public consumption.
45 *
46 * {@hide}
47 */
48 public IContentObserver getContentObserver() {
Jeff Brown86de0592012-01-23 13:01:18 -080049 synchronized (mLock) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050 if (mTransport == null) {
51 mTransport = new Transport(this);
52 }
53 return mTransport;
54 }
55 }
56
57 /**
58 * Gets access to the binder transport object, and unlinks the transport object
59 * from the ContentObserver. Not for public consumption.
60 *
61 * {@hide}
62 */
Mathew Inwood41b31942018-08-10 16:00:53 +010063 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064 public IContentObserver releaseContentObserver() {
Jeff Brown86de0592012-01-23 13:01:18 -080065 synchronized (mLock) {
66 final Transport oldTransport = mTransport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067 if (oldTransport != null) {
68 oldTransport.releaseContentObserver();
69 mTransport = null;
70 }
71 return oldTransport;
72 }
73 }
74
75 /**
Jeff Brown86de0592012-01-23 13:01:18 -080076 * Returns true if this observer is interested receiving self-change notifications.
77 *
78 * Subclasses should override this method to indicate whether the observer
79 * is interested in receiving notifications for changes that it made to the
80 * content itself.
81 *
82 * @return True if self-change notifications should be delivered to the observer.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083 */
84 public boolean deliverSelfNotifications() {
85 return false;
86 }
87
88 /**
Jeff Brown86de0592012-01-23 13:01:18 -080089 * This method is called when a content change occurs.
Jeff Brown655e66b2012-01-23 15:51:41 -080090 * <p>
91 * Subclasses should override this method to handle content changes.
92 * </p>
Jeff Brown86de0592012-01-23 13:01:18 -080093 *
94 * @param selfChange True if this is a self-change notification.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 */
Jeff Brown86de0592012-01-23 13:01:18 -080096 public void onChange(boolean selfChange) {
97 // Do nothing. Subclass should override.
98 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099
Jeff Brown86de0592012-01-23 13:01:18 -0800100 /**
Jeff Brown655e66b2012-01-23 15:51:41 -0800101 * This method is called when a content change occurs.
102 * Includes the changed content Uri when available.
103 * <p>
104 * Subclasses should override this method to handle content changes.
105 * To ensure correct operation on older versions of the framework that
106 * did not provide a Uri argument, applications should also implement
107 * the {@link #onChange(boolean)} overload of this method whenever they
108 * implement the {@link #onChange(boolean, Uri)} overload.
109 * </p><p>
110 * Example implementation:
111 * <pre><code>
112 * // Implement the onChange(boolean) method to delegate the change notification to
113 * // the onChange(boolean, Uri) method to ensure correct operation on older versions
114 * // of the framework that did not have the onChange(boolean, Uri) method.
115 * {@literal @Override}
116 * public void onChange(boolean selfChange) {
117 * onChange(selfChange, null);
118 * }
Jeff Brown86de0592012-01-23 13:01:18 -0800119 *
Jeff Brown655e66b2012-01-23 15:51:41 -0800120 * // Implement the onChange(boolean, Uri) method to take advantage of the new Uri argument.
121 * {@literal @Override}
122 * public void onChange(boolean selfChange, Uri uri) {
123 * // Handle change.
124 * }
125 * </code></pre>
126 * </p>
127 *
128 * @param selfChange True if this is a self-change notification.
129 * @param uri The Uri of the changed content, or null if unknown.
130 */
131 public void onChange(boolean selfChange, Uri uri) {
132 onChange(selfChange);
133 }
134
135 /**
Svetoslav86b1df22014-08-21 14:22:53 -0700136 * Dispatches a change notification to the observer. Includes the changed
137 * content Uri when available and also the user whose content changed.
138 *
139 * @param selfChange True if this is a self-change notification.
140 * @param uri The Uri of the changed content, or null if unknown.
141 * @param userId The user whose content changed. Can be either a specific
142 * user or {@link UserHandle#USER_ALL}.
143 *
144 * @hide
145 */
146 public void onChange(boolean selfChange, Uri uri, int userId) {
147 onChange(selfChange, uri);
148 }
149
150 /**
Jeff Brown655e66b2012-01-23 15:51:41 -0800151 * Dispatches a change notification to the observer.
152 * <p>
Jeff Brown86de0592012-01-23 13:01:18 -0800153 * If a {@link Handler} was supplied to the {@link ContentObserver} constructor,
154 * then a call to the {@link #onChange} method is posted to the handler's message queue.
155 * Otherwise, the {@link #onChange} method is invoked immediately on this thread.
Jeff Brown655e66b2012-01-23 15:51:41 -0800156 * </p>
Jeff Brown86de0592012-01-23 13:01:18 -0800157 *
158 * @param selfChange True if this is a self-change notification.
Jeff Brown655e66b2012-01-23 15:51:41 -0800159 *
160 * @deprecated Use {@link #dispatchChange(boolean, Uri)} instead.
Jeff Brown86de0592012-01-23 13:01:18 -0800161 */
Jeff Brown655e66b2012-01-23 15:51:41 -0800162 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 public final void dispatchChange(boolean selfChange) {
Jeff Brown655e66b2012-01-23 15:51:41 -0800164 dispatchChange(selfChange, null);
165 }
166
167 /**
168 * Dispatches a change notification to the observer.
169 * Includes the changed content Uri when available.
170 * <p>
171 * If a {@link Handler} was supplied to the {@link ContentObserver} constructor,
172 * then a call to the {@link #onChange} method is posted to the handler's message queue.
173 * Otherwise, the {@link #onChange} method is invoked immediately on this thread.
174 * </p>
175 *
176 * @param selfChange True if this is a self-change notification.
177 * @param uri The Uri of the changed content, or null if unknown.
178 */
179 public final void dispatchChange(boolean selfChange, Uri uri) {
Svetoslav86b1df22014-08-21 14:22:53 -0700180 dispatchChange(selfChange, uri, UserHandle.getCallingUserId());
181 }
182
183 /**
184 * Dispatches a change notification to the observer. Includes the changed
185 * content Uri when available and also the user whose content changed.
186 * <p>
187 * If a {@link Handler} was supplied to the {@link ContentObserver} constructor,
188 * then a call to the {@link #onChange} method is posted to the handler's message queue.
189 * Otherwise, the {@link #onChange} method is invoked immediately on this thread.
190 * </p>
191 *
192 * @param selfChange True if this is a self-change notification.
193 * @param uri The Uri of the changed content, or null if unknown.
194 * @param userId The user whose content changed.
195 */
196 private void dispatchChange(boolean selfChange, Uri uri, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 if (mHandler == null) {
Svetoslav86b1df22014-08-21 14:22:53 -0700198 onChange(selfChange, uri, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199 } else {
Svetoslav86b1df22014-08-21 14:22:53 -0700200 mHandler.post(new NotificationRunnable(selfChange, uri, userId));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800201 }
202 }
Jeff Brown86de0592012-01-23 13:01:18 -0800203
Svetoslav86b1df22014-08-21 14:22:53 -0700204
Jeff Brown86de0592012-01-23 13:01:18 -0800205 private final class NotificationRunnable implements Runnable {
Jeff Brown655e66b2012-01-23 15:51:41 -0800206 private final boolean mSelfChange;
207 private final Uri mUri;
Svetoslav86b1df22014-08-21 14:22:53 -0700208 private final int mUserId;
Jeff Brown86de0592012-01-23 13:01:18 -0800209
Svetoslav86b1df22014-08-21 14:22:53 -0700210 public NotificationRunnable(boolean selfChange, Uri uri, int userId) {
Jeff Brown655e66b2012-01-23 15:51:41 -0800211 mSelfChange = selfChange;
212 mUri = uri;
Svetoslav86b1df22014-08-21 14:22:53 -0700213 mUserId = userId;
Jeff Brown86de0592012-01-23 13:01:18 -0800214 }
215
216 @Override
217 public void run() {
Svetoslav86b1df22014-08-21 14:22:53 -0700218 ContentObserver.this.onChange(mSelfChange, mUri, mUserId);
Jeff Brown86de0592012-01-23 13:01:18 -0800219 }
220 }
221
222 private static final class Transport extends IContentObserver.Stub {
223 private ContentObserver mContentObserver;
224
225 public Transport(ContentObserver contentObserver) {
226 mContentObserver = contentObserver;
227 }
228
229 @Override
Svetoslav86b1df22014-08-21 14:22:53 -0700230 public void onChange(boolean selfChange, Uri uri, int userId) {
Jeff Brown86de0592012-01-23 13:01:18 -0800231 ContentObserver contentObserver = mContentObserver;
232 if (contentObserver != null) {
Svetoslav86b1df22014-08-21 14:22:53 -0700233 contentObserver.dispatchChange(selfChange, uri, userId);
Jeff Brown86de0592012-01-23 13:01:18 -0800234 }
235 }
236
237 public void releaseContentObserver() {
238 mContentObserver = null;
239 }
240 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241}