blob: 3b829a3d3f1d1957d3a4c5a0d89e6f31405f77a5 [file] [log] [blame]
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.database;
import android.os.Handler;
/**
* Receives call backs for changes to content. Must be implemented by objects which are added
* to a {@link ContentObservable}.
*/
public abstract class ContentObserver {
private Transport mTransport;
// Protects mTransport
private Object lock = new Object();
/* package */ Handler mHandler;
private final class NotificationRunnable implements Runnable {
private boolean mSelf;
public NotificationRunnable(boolean self) {
mSelf = self;
}
public void run() {
ContentObserver.this.onChange(mSelf);
}
}
private static final class Transport extends IContentObserver.Stub {
ContentObserver mContentObserver;
public Transport(ContentObserver contentObserver) {
mContentObserver = contentObserver;
}
public boolean deliverSelfNotifications() {
ContentObserver contentObserver = mContentObserver;
if (contentObserver != null) {
return contentObserver.deliverSelfNotifications();
}
return false;
}
public void onChange(boolean selfChange) {
ContentObserver contentObserver = mContentObserver;
if (contentObserver != null) {
contentObserver.dispatchChange(selfChange);
}
}
public void releaseContentObserver() {
mContentObserver = null;
}
}
/**
* onChange() will happen on the provider Handler.
*
* @param handler The handler to run {@link #onChange} on.
*/
public ContentObserver(Handler handler) {
mHandler = handler;
}
/**
* Gets access to the binder transport object. Not for public consumption.
*
* {@hide}
*/
public IContentObserver getContentObserver() {
synchronized(lock) {
if (mTransport == null) {
mTransport = new Transport(this);
}
return mTransport;
}
}
/**
* Gets access to the binder transport object, and unlinks the transport object
* from the ContentObserver. Not for public consumption.
*
* {@hide}
*/
public IContentObserver releaseContentObserver() {
synchronized(lock) {
Transport oldTransport = mTransport;
if (oldTransport != null) {
oldTransport.releaseContentObserver();
mTransport = null;
}
return oldTransport;
}
}
/**
* Returns true if this observer is interested in notifications for changes
* made through the cursor the observer is registered with.
*/
public boolean deliverSelfNotifications() {
return false;
}
/**
* This method is called when a change occurs to the cursor that
* is being observed.
*
* @param selfChange true if the update was caused by a call to <code>commit</code> on the
* cursor that is being observed.
*/
public void onChange(boolean selfChange) {}
public final void dispatchChange(boolean selfChange) {
if (mHandler == null) {
onChange(selfChange);
} else {
mHandler.post(new NotificationRunnable(selfChange));
}
}
}