19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.database;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brownimport android.net.Uri;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
2186b1df234397802895771fe14cd8f2813fa43415Svetoslavimport android.os.UserHandle;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
2486de0590b94bcce27e3038c27464bed510bb564aJeff Brown * Receives call backs for changes to content.
2586de0590b94bcce27e3038c27464bed510bb564aJeff Brown * Must be implemented by objects which are added to a {@link ContentObservable}.
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class ContentObserver {
2886de0590b94bcce27e3038c27464bed510bb564aJeff Brown    private final Object mLock = new Object();
2986de0590b94bcce27e3038c27464bed510bb564aJeff Brown    private Transport mTransport; // guarded by mLock
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3186de0590b94bcce27e3038c27464bed510bb564aJeff Brown    Handler mHandler;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3486de0590b94bcce27e3038c27464bed510bb564aJeff Brown     * Creates a content observer.
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3686de0590b94bcce27e3038c27464bed510bb564aJeff Brown     * @param handler The handler to run {@link #onChange} on, or null if none.
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ContentObserver(Handler handler) {
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler = handler;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Gets access to the binder transport object. Not for public consumption.
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public IContentObserver getContentObserver() {
4886de0590b94bcce27e3038c27464bed510bb564aJeff Brown        synchronized (mLock) {
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mTransport == null) {
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mTransport = new Transport(this);
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mTransport;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Gets access to the binder transport object, and unlinks the transport object
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * from the ContentObserver. Not for public consumption.
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public IContentObserver releaseContentObserver() {
6386de0590b94bcce27e3038c27464bed510bb564aJeff Brown        synchronized (mLock) {
6486de0590b94bcce27e3038c27464bed510bb564aJeff Brown            final Transport oldTransport = mTransport;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (oldTransport != null) {
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                oldTransport.releaseContentObserver();
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mTransport = null;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return oldTransport;
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7486de0590b94bcce27e3038c27464bed510bb564aJeff Brown     * Returns true if this observer is interested receiving self-change notifications.
7586de0590b94bcce27e3038c27464bed510bb564aJeff Brown     *
7686de0590b94bcce27e3038c27464bed510bb564aJeff Brown     * Subclasses should override this method to indicate whether the observer
7786de0590b94bcce27e3038c27464bed510bb564aJeff Brown     * is interested in receiving notifications for changes that it made to the
7886de0590b94bcce27e3038c27464bed510bb564aJeff Brown     * content itself.
7986de0590b94bcce27e3038c27464bed510bb564aJeff Brown     *
8086de0590b94bcce27e3038c27464bed510bb564aJeff Brown     * @return True if self-change notifications should be delivered to the observer.
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean deliverSelfNotifications() {
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8786de0590b94bcce27e3038c27464bed510bb564aJeff Brown     * This method is called when a content change occurs.
88655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * <p>
89655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * Subclasses should override this method to handle content changes.
90655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * </p>
9186de0590b94bcce27e3038c27464bed510bb564aJeff Brown     *
9286de0590b94bcce27e3038c27464bed510bb564aJeff Brown     * @param selfChange True if this is a self-change notification.
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9486de0590b94bcce27e3038c27464bed510bb564aJeff Brown    public void onChange(boolean selfChange) {
9586de0590b94bcce27e3038c27464bed510bb564aJeff Brown        // Do nothing.  Subclass should override.
9686de0590b94bcce27e3038c27464bed510bb564aJeff Brown    }
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9886de0590b94bcce27e3038c27464bed510bb564aJeff Brown    /**
99655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * This method is called when a content change occurs.
100655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * Includes the changed content Uri when available.
101655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * <p>
102655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * Subclasses should override this method to handle content changes.
103655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * To ensure correct operation on older versions of the framework that
104655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * did not provide a Uri argument, applications should also implement
105655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * the {@link #onChange(boolean)} overload of this method whenever they
106655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * implement the {@link #onChange(boolean, Uri)} overload.
107655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * </p><p>
108655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * Example implementation:
109655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * <pre><code>
110655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * // Implement the onChange(boolean) method to delegate the change notification to
111655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * // the onChange(boolean, Uri) method to ensure correct operation on older versions
112655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * // of the framework that did not have the onChange(boolean, Uri) method.
113655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * {@literal @Override}
114655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * public void onChange(boolean selfChange) {
115655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     *     onChange(selfChange, null);
116655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * }
117655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     *
118655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * // Implement the onChange(boolean, Uri) method to take advantage of the new Uri argument.
119655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * {@literal @Override}
120655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * public void onChange(boolean selfChange, Uri uri) {
121655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     *     // Handle change.
122655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * }
123655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * </code></pre>
124655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * </p>
12586de0590b94bcce27e3038c27464bed510bb564aJeff Brown     *
126655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * @param selfChange True if this is a self-change notification.
127655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * @param uri The Uri of the changed content, or null if unknown.
128655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     */
129655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown    public void onChange(boolean selfChange, Uri uri) {
130655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown        onChange(selfChange);
131655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown    }
132655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown
133655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown    /**
13486b1df234397802895771fe14cd8f2813fa43415Svetoslav     * Dispatches a change notification to the observer. Includes the changed
13586b1df234397802895771fe14cd8f2813fa43415Svetoslav     * content Uri when available and also the user whose content changed.
13686b1df234397802895771fe14cd8f2813fa43415Svetoslav     *
13786b1df234397802895771fe14cd8f2813fa43415Svetoslav     * @param selfChange True if this is a self-change notification.
13886b1df234397802895771fe14cd8f2813fa43415Svetoslav     * @param uri The Uri of the changed content, or null if unknown.
13986b1df234397802895771fe14cd8f2813fa43415Svetoslav     * @param userId The user whose content changed. Can be either a specific
14086b1df234397802895771fe14cd8f2813fa43415Svetoslav     *         user or {@link UserHandle#USER_ALL}.
14186b1df234397802895771fe14cd8f2813fa43415Svetoslav     *
14286b1df234397802895771fe14cd8f2813fa43415Svetoslav     * @hide
14386b1df234397802895771fe14cd8f2813fa43415Svetoslav     */
14486b1df234397802895771fe14cd8f2813fa43415Svetoslav    public void onChange(boolean selfChange, Uri uri, int userId) {
14586b1df234397802895771fe14cd8f2813fa43415Svetoslav        onChange(selfChange, uri);
14686b1df234397802895771fe14cd8f2813fa43415Svetoslav    }
14786b1df234397802895771fe14cd8f2813fa43415Svetoslav
14886b1df234397802895771fe14cd8f2813fa43415Svetoslav    /**
149655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * Dispatches a change notification to the observer.
150655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * <p>
15186de0590b94bcce27e3038c27464bed510bb564aJeff Brown     * If a {@link Handler} was supplied to the {@link ContentObserver} constructor,
15286de0590b94bcce27e3038c27464bed510bb564aJeff Brown     * then a call to the {@link #onChange} method is posted to the handler's message queue.
15386de0590b94bcce27e3038c27464bed510bb564aJeff Brown     * Otherwise, the {@link #onChange} method is invoked immediately on this thread.
154655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * </p>
15586de0590b94bcce27e3038c27464bed510bb564aJeff Brown     *
15686de0590b94bcce27e3038c27464bed510bb564aJeff Brown     * @param selfChange True if this is a self-change notification.
157655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     *
158655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * @deprecated Use {@link #dispatchChange(boolean, Uri)} instead.
15986de0590b94bcce27e3038c27464bed510bb564aJeff Brown     */
160655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown    @Deprecated
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final void dispatchChange(boolean selfChange) {
162655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown        dispatchChange(selfChange, null);
163655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown    }
164655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown
165655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown    /**
166655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * Dispatches a change notification to the observer.
167655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * Includes the changed content Uri when available.
168655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * <p>
169655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * If a {@link Handler} was supplied to the {@link ContentObserver} constructor,
170655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * then a call to the {@link #onChange} method is posted to the handler's message queue.
171655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * Otherwise, the {@link #onChange} method is invoked immediately on this thread.
172655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * </p>
173655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     *
174655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * @param selfChange True if this is a self-change notification.
175655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     * @param uri The Uri of the changed content, or null if unknown.
176655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown     */
177655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown    public final void dispatchChange(boolean selfChange, Uri uri) {
17886b1df234397802895771fe14cd8f2813fa43415Svetoslav        dispatchChange(selfChange, uri, UserHandle.getCallingUserId());
17986b1df234397802895771fe14cd8f2813fa43415Svetoslav    }
18086b1df234397802895771fe14cd8f2813fa43415Svetoslav
18186b1df234397802895771fe14cd8f2813fa43415Svetoslav    /**
18286b1df234397802895771fe14cd8f2813fa43415Svetoslav     * Dispatches a change notification to the observer. Includes the changed
18386b1df234397802895771fe14cd8f2813fa43415Svetoslav     * content Uri when available and also the user whose content changed.
18486b1df234397802895771fe14cd8f2813fa43415Svetoslav     * <p>
18586b1df234397802895771fe14cd8f2813fa43415Svetoslav     * If a {@link Handler} was supplied to the {@link ContentObserver} constructor,
18686b1df234397802895771fe14cd8f2813fa43415Svetoslav     * then a call to the {@link #onChange} method is posted to the handler's message queue.
18786b1df234397802895771fe14cd8f2813fa43415Svetoslav     * Otherwise, the {@link #onChange} method is invoked immediately on this thread.
18886b1df234397802895771fe14cd8f2813fa43415Svetoslav     * </p>
18986b1df234397802895771fe14cd8f2813fa43415Svetoslav     *
19086b1df234397802895771fe14cd8f2813fa43415Svetoslav     * @param selfChange True if this is a self-change notification.
19186b1df234397802895771fe14cd8f2813fa43415Svetoslav     * @param uri The Uri of the changed content, or null if unknown.
19286b1df234397802895771fe14cd8f2813fa43415Svetoslav     * @param userId The user whose content changed.
19386b1df234397802895771fe14cd8f2813fa43415Svetoslav     */
19486b1df234397802895771fe14cd8f2813fa43415Svetoslav    private void dispatchChange(boolean selfChange, Uri uri, int userId) {
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mHandler == null) {
19686b1df234397802895771fe14cd8f2813fa43415Svetoslav            onChange(selfChange, uri, userId);
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
19886b1df234397802895771fe14cd8f2813fa43415Svetoslav            mHandler.post(new NotificationRunnable(selfChange, uri, userId));
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20186de0590b94bcce27e3038c27464bed510bb564aJeff Brown
20286b1df234397802895771fe14cd8f2813fa43415Svetoslav
20386de0590b94bcce27e3038c27464bed510bb564aJeff Brown    private final class NotificationRunnable implements Runnable {
204655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown        private final boolean mSelfChange;
205655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown        private final Uri mUri;
20686b1df234397802895771fe14cd8f2813fa43415Svetoslav        private final int mUserId;
20786de0590b94bcce27e3038c27464bed510bb564aJeff Brown
20886b1df234397802895771fe14cd8f2813fa43415Svetoslav        public NotificationRunnable(boolean selfChange, Uri uri, int userId) {
209655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown            mSelfChange = selfChange;
210655e66bceba7595a2b80e7a328433e6ed5dc28a9Jeff Brown            mUri = uri;
21186b1df234397802895771fe14cd8f2813fa43415Svetoslav            mUserId = userId;
21286de0590b94bcce27e3038c27464bed510bb564aJeff Brown        }
21386de0590b94bcce27e3038c27464bed510bb564aJeff Brown
21486de0590b94bcce27e3038c27464bed510bb564aJeff Brown        @Override
21586de0590b94bcce27e3038c27464bed510bb564aJeff Brown        public void run() {
21686b1df234397802895771fe14cd8f2813fa43415Svetoslav            ContentObserver.this.onChange(mSelfChange, mUri, mUserId);
21786de0590b94bcce27e3038c27464bed510bb564aJeff Brown        }
21886de0590b94bcce27e3038c27464bed510bb564aJeff Brown    }
21986de0590b94bcce27e3038c27464bed510bb564aJeff Brown
22086de0590b94bcce27e3038c27464bed510bb564aJeff Brown    private static final class Transport extends IContentObserver.Stub {
22186de0590b94bcce27e3038c27464bed510bb564aJeff Brown        private ContentObserver mContentObserver;
22286de0590b94bcce27e3038c27464bed510bb564aJeff Brown
22386de0590b94bcce27e3038c27464bed510bb564aJeff Brown        public Transport(ContentObserver contentObserver) {
22486de0590b94bcce27e3038c27464bed510bb564aJeff Brown            mContentObserver = contentObserver;
22586de0590b94bcce27e3038c27464bed510bb564aJeff Brown        }
22686de0590b94bcce27e3038c27464bed510bb564aJeff Brown
22786de0590b94bcce27e3038c27464bed510bb564aJeff Brown        @Override
22886b1df234397802895771fe14cd8f2813fa43415Svetoslav        public void onChange(boolean selfChange, Uri uri, int userId) {
22986de0590b94bcce27e3038c27464bed510bb564aJeff Brown            ContentObserver contentObserver = mContentObserver;
23086de0590b94bcce27e3038c27464bed510bb564aJeff Brown            if (contentObserver != null) {
23186b1df234397802895771fe14cd8f2813fa43415Svetoslav                contentObserver.dispatchChange(selfChange, uri, userId);
23286de0590b94bcce27e3038c27464bed510bb564aJeff Brown            }
23386de0590b94bcce27e3038c27464bed510bb564aJeff Brown        }
23486de0590b94bcce27e3038c27464bed510bb564aJeff Brown
23586de0590b94bcce27e3038c27464bed510bb564aJeff Brown        public void releaseContentObserver() {
23686de0590b94bcce27e3038c27464bed510bb564aJeff Brown            mContentObserver = null;
23786de0590b94bcce27e3038c27464bed510bb564aJeff Brown        }
23886de0590b94bcce27e3038c27464bed510bb564aJeff Brown    }
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
240