• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package android.database;
18 
19 import android.net.Uri;
20 import android.os.Handler;
21 
22 /**
23  * Receives call backs for changes to content.
24  * Must be implemented by objects which are added to a {@link ContentObservable}.
25  */
26 public abstract class ContentObserver {
27     private final Object mLock = new Object();
28     private Transport mTransport; // guarded by mLock
29 
30     Handler mHandler;
31 
32     /**
33      * Creates a content observer.
34      *
35      * @param handler The handler to run {@link #onChange} on, or null if none.
36      */
ContentObserver(Handler handler)37     public ContentObserver(Handler handler) {
38         mHandler = handler;
39     }
40 
41     /**
42      * Gets access to the binder transport object. Not for public consumption.
43      *
44      * {@hide}
45      */
getContentObserver()46     public IContentObserver getContentObserver() {
47         synchronized (mLock) {
48             if (mTransport == null) {
49                 mTransport = new Transport(this);
50             }
51             return mTransport;
52         }
53     }
54 
55     /**
56      * Gets access to the binder transport object, and unlinks the transport object
57      * from the ContentObserver. Not for public consumption.
58      *
59      * {@hide}
60      */
releaseContentObserver()61     public IContentObserver releaseContentObserver() {
62         synchronized (mLock) {
63             final Transport oldTransport = mTransport;
64             if (oldTransport != null) {
65                 oldTransport.releaseContentObserver();
66                 mTransport = null;
67             }
68             return oldTransport;
69         }
70     }
71 
72     /**
73      * Returns true if this observer is interested receiving self-change notifications.
74      *
75      * Subclasses should override this method to indicate whether the observer
76      * is interested in receiving notifications for changes that it made to the
77      * content itself.
78      *
79      * @return True if self-change notifications should be delivered to the observer.
80      */
deliverSelfNotifications()81     public boolean deliverSelfNotifications() {
82         return false;
83     }
84 
85     /**
86      * This method is called when a content change occurs.
87      * <p>
88      * Subclasses should override this method to handle content changes.
89      * </p>
90      *
91      * @param selfChange True if this is a self-change notification.
92      */
onChange(boolean selfChange)93     public void onChange(boolean selfChange) {
94         // Do nothing.  Subclass should override.
95     }
96 
97     /**
98      * This method is called when a content change occurs.
99      * Includes the changed content Uri when available.
100      * <p>
101      * Subclasses should override this method to handle content changes.
102      * To ensure correct operation on older versions of the framework that
103      * did not provide a Uri argument, applications should also implement
104      * the {@link #onChange(boolean)} overload of this method whenever they
105      * implement the {@link #onChange(boolean, Uri)} overload.
106      * </p><p>
107      * Example implementation:
108      * <pre><code>
109      * // Implement the onChange(boolean) method to delegate the change notification to
110      * // the onChange(boolean, Uri) method to ensure correct operation on older versions
111      * // of the framework that did not have the onChange(boolean, Uri) method.
112      * {@literal @Override}
113      * public void onChange(boolean selfChange) {
114      *     onChange(selfChange, null);
115      * }
116      *
117      * // Implement the onChange(boolean, Uri) method to take advantage of the new Uri argument.
118      * {@literal @Override}
119      * public void onChange(boolean selfChange, Uri uri) {
120      *     // Handle change.
121      * }
122      * </code></pre>
123      * </p>
124      *
125      * @param selfChange True if this is a self-change notification.
126      * @param uri The Uri of the changed content, or null if unknown.
127      */
onChange(boolean selfChange, Uri uri)128     public void onChange(boolean selfChange, Uri uri) {
129         onChange(selfChange);
130     }
131 
132     /**
133      * Dispatches a change notification to the observer.
134      * <p>
135      * If a {@link Handler} was supplied to the {@link ContentObserver} constructor,
136      * then a call to the {@link #onChange} method is posted to the handler's message queue.
137      * Otherwise, the {@link #onChange} method is invoked immediately on this thread.
138      * </p>
139      *
140      * @param selfChange True if this is a self-change notification.
141      *
142      * @deprecated Use {@link #dispatchChange(boolean, Uri)} instead.
143      */
144     @Deprecated
dispatchChange(boolean selfChange)145     public final void dispatchChange(boolean selfChange) {
146         dispatchChange(selfChange, null);
147     }
148 
149     /**
150      * Dispatches a change notification to the observer.
151      * Includes the changed content Uri when available.
152      * <p>
153      * 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.
156      * </p>
157      *
158      * @param selfChange True if this is a self-change notification.
159      * @param uri The Uri of the changed content, or null if unknown.
160      */
dispatchChange(boolean selfChange, Uri uri)161     public final void dispatchChange(boolean selfChange, Uri uri) {
162         if (mHandler == null) {
163             onChange(selfChange, uri);
164         } else {
165             mHandler.post(new NotificationRunnable(selfChange, uri));
166         }
167     }
168 
169     private final class NotificationRunnable implements Runnable {
170         private final boolean mSelfChange;
171         private final Uri mUri;
172 
NotificationRunnable(boolean selfChange, Uri uri)173         public NotificationRunnable(boolean selfChange, Uri uri) {
174             mSelfChange = selfChange;
175             mUri = uri;
176         }
177 
178         @Override
run()179         public void run() {
180             ContentObserver.this.onChange(mSelfChange, mUri);
181         }
182     }
183 
184     private static final class Transport extends IContentObserver.Stub {
185         private ContentObserver mContentObserver;
186 
Transport(ContentObserver contentObserver)187         public Transport(ContentObserver contentObserver) {
188             mContentObserver = contentObserver;
189         }
190 
191         @Override
onChange(boolean selfChange, Uri uri)192         public void onChange(boolean selfChange, Uri uri) {
193             ContentObserver contentObserver = mContentObserver;
194             if (contentObserver != null) {
195                 contentObserver.dispatchChange(selfChange, uri);
196             }
197         }
198 
releaseContentObserver()199         public void releaseContentObserver() {
200             mContentObserver = null;
201         }
202     }
203 }
204