diff options
Diffstat (limited to 'core/java/android/content/ContentServiceNative.java')
-rw-r--r-- | core/java/android/content/ContentServiceNative.java | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/core/java/android/content/ContentServiceNative.java b/core/java/android/content/ContentServiceNative.java new file mode 100644 index 0000000..f050501 --- /dev/null +++ b/core/java/android/content/ContentServiceNative.java @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2006 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.content; + +import android.database.IContentObserver; +import android.net.Uri; +import android.os.Binder; +import android.os.RemoteException; +import android.os.IBinder; +import android.os.Parcel; +import android.os.ServiceManager; +import android.os.Bundle; +import android.util.Config; +import android.util.Log; + +/** + * {@hide} + */ +abstract class ContentServiceNative extends Binder implements IContentService +{ + public ContentServiceNative() + { + attachInterface(this, descriptor); + } + + /** + * Cast a Binder object into a content resolver interface, generating + * a proxy if needed. + */ + static public IContentService asInterface(IBinder obj) + { + if (obj == null) { + return null; + } + IContentService in = + (IContentService)obj.queryLocalInterface(descriptor); + if (in != null) { + return in; + } + + return new ContentServiceProxy(obj); + } + + /** + * Retrieve the system's default/global content service. + */ + static public IContentService getDefault() + { + if (gDefault != null) { + return gDefault; + } + IBinder b = ServiceManager.getService("content"); + if (Config.LOGV) Log.v("ContentService", "default service binder = " + b); + gDefault = asInterface(b); + if (Config.LOGV) Log.v("ContentService", "default service = " + gDefault); + return gDefault; + } + + @Override + public boolean onTransact(int code, Parcel data, Parcel reply, int flags) + { + try { + switch (code) { + case REGISTER_CONTENT_OBSERVER_TRANSACTION: { + Uri uri = Uri.CREATOR.createFromParcel(data); + boolean notifyForDescendents = data.readInt() != 0; + IContentObserver observer = IContentObserver.Stub.asInterface(data.readStrongBinder()); + registerContentObserver(uri, notifyForDescendents, observer); + return true; + } + + case UNREGISTER_CHANGE_OBSERVER_TRANSACTION: { + IContentObserver observer = IContentObserver.Stub.asInterface(data.readStrongBinder()); + unregisterContentObserver(observer); + return true; + } + + case NOTIFY_CHANGE_TRANSACTION: { + Uri uri = Uri.CREATOR.createFromParcel(data); + IContentObserver observer = IContentObserver.Stub.asInterface(data.readStrongBinder()); + boolean observerWantsSelfNotifications = data.readInt() != 0; + boolean syncToNetwork = data.readInt() != 0; + notifyChange(uri, observer, observerWantsSelfNotifications, syncToNetwork); + return true; + } + + case START_SYNC_TRANSACTION: { + Uri url = null; + int hasUrl = data.readInt(); + if (hasUrl != 0) { + url = Uri.CREATOR.createFromParcel(data); + } + startSync(url, data.readBundle()); + return true; + } + + case CANCEL_SYNC_TRANSACTION: { + Uri url = null; + int hasUrl = data.readInt(); + if (hasUrl != 0) { + url = Uri.CREATOR.createFromParcel(data); + } + cancelSync(url); + return true; + } + + default: + return super.onTransact(code, data, reply, flags); + } + } catch (Exception e) { + Log.e("ContentServiceNative", "Caught exception in transact", e); + } + + return false; + } + + public IBinder asBinder() + { + return this; + } + + private static IContentService gDefault; +} + + +final class ContentServiceProxy implements IContentService +{ + public ContentServiceProxy(IBinder remote) + { + mRemote = remote; + } + + public IBinder asBinder() + { + return mRemote; + } + + public void registerContentObserver(Uri uri, boolean notifyForDescendents, + IContentObserver observer) throws RemoteException + { + Parcel data = Parcel.obtain(); + uri.writeToParcel(data, 0); + data.writeInt(notifyForDescendents ? 1 : 0); + data.writeStrongInterface(observer); + mRemote.transact(REGISTER_CONTENT_OBSERVER_TRANSACTION, data, null, 0); + data.recycle(); + } + + public void unregisterContentObserver(IContentObserver observer) throws RemoteException { + Parcel data = Parcel.obtain(); + data.writeStrongInterface(observer); + mRemote.transact(UNREGISTER_CHANGE_OBSERVER_TRANSACTION, data, null, 0); + data.recycle(); + } + + public void notifyChange(Uri uri, IContentObserver observer, + boolean observerWantsSelfNotifications, boolean syncToNetwork) + throws RemoteException { + Parcel data = Parcel.obtain(); + uri.writeToParcel(data, 0); + data.writeStrongInterface(observer); + data.writeInt(observerWantsSelfNotifications ? 1 : 0); + data.writeInt(syncToNetwork ? 1 : 0); + mRemote.transact(NOTIFY_CHANGE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); + data.recycle(); + } + + public void startSync(Uri url, Bundle extras) throws RemoteException { + Parcel data = Parcel.obtain(); + if (url == null) { + data.writeInt(0); + } else { + data.writeInt(1); + url.writeToParcel(data, 0); + } + extras.writeToParcel(data, 0); + mRemote.transact(START_SYNC_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); + data.recycle(); + } + + public void cancelSync(Uri url) throws RemoteException { + Parcel data = Parcel.obtain(); + if (url == null) { + data.writeInt(0); + } else { + data.writeInt(1); + url.writeToParcel(data, 0); + } + mRemote.transact(CANCEL_SYNC_TRANSACTION, data, null /* reply */, IBinder.FLAG_ONEWAY); + data.recycle(); + } + + private IBinder mRemote; +} + |