Home | History | Annotate | Download | only in database
      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.os.Handler;
     20 
     21 /**
     22  * Receives call backs for changes to content. Must be implemented by objects which are added
     23  * to a {@link ContentObservable}.
     24  */
     25 public abstract class ContentObserver {
     26 
     27     private Transport mTransport;
     28 
     29     // Protects mTransport
     30     private Object lock = new Object();
     31 
     32     /* package */ Handler mHandler;
     33 
     34     private final class NotificationRunnable implements Runnable {
     35 
     36         private boolean mSelf;
     37 
     38         public NotificationRunnable(boolean self) {
     39             mSelf = self;
     40         }
     41 
     42         public void run() {
     43             ContentObserver.this.onChange(mSelf);
     44         }
     45     }
     46 
     47     private static final class Transport extends IContentObserver.Stub {
     48         ContentObserver mContentObserver;
     49 
     50         public Transport(ContentObserver contentObserver) {
     51             mContentObserver = contentObserver;
     52         }
     53 
     54         public boolean deliverSelfNotifications() {
     55             ContentObserver contentObserver = mContentObserver;
     56             if (contentObserver != null) {
     57                 return contentObserver.deliverSelfNotifications();
     58             }
     59             return false;
     60         }
     61 
     62         public void onChange(boolean selfChange) {
     63             ContentObserver contentObserver = mContentObserver;
     64             if (contentObserver != null) {
     65                 contentObserver.dispatchChange(selfChange);
     66             }
     67         }
     68 
     69         public void releaseContentObserver() {
     70             mContentObserver = null;
     71         }
     72     }
     73 
     74     /**
     75      * onChange() will happen on the provider Handler.
     76      *
     77      * @param handler The handler to run {@link #onChange} on.
     78      */
     79     public ContentObserver(Handler handler) {
     80         mHandler = handler;
     81     }
     82 
     83     /**
     84      * Gets access to the binder transport object. Not for public consumption.
     85      *
     86      * {@hide}
     87      */
     88     public IContentObserver getContentObserver() {
     89         synchronized(lock) {
     90             if (mTransport == null) {
     91                 mTransport = new Transport(this);
     92             }
     93             return mTransport;
     94         }
     95     }
     96 
     97     /**
     98      * Gets access to the binder transport object, and unlinks the transport object
     99      * from the ContentObserver. Not for public consumption.
    100      *
    101      * {@hide}
    102      */
    103     public IContentObserver releaseContentObserver() {
    104         synchronized(lock) {
    105             Transport oldTransport = mTransport;
    106             if (oldTransport != null) {
    107                 oldTransport.releaseContentObserver();
    108                 mTransport = null;
    109             }
    110             return oldTransport;
    111         }
    112     }
    113 
    114     /**
    115      * Returns true if this observer is interested in notifications for changes
    116      * made through the cursor the observer is registered with.
    117      */
    118     public boolean deliverSelfNotifications() {
    119         return false;
    120     }
    121 
    122     /**
    123      * This method is called when a change occurs to the cursor that
    124      * is being observed.
    125      *
    126      * @param selfChange true if the update was caused by a call to <code>commit</code> on the
    127      *  cursor that is being observed.
    128      */
    129     public void onChange(boolean selfChange) {}
    130 
    131     public final void dispatchChange(boolean selfChange) {
    132         if (mHandler == null) {
    133             onChange(selfChange);
    134         } else {
    135             mHandler.post(new NotificationRunnable(selfChange));
    136         }
    137     }
    138 }
    139