• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 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.Binder;
20 import android.os.Bundle;
21 import android.os.IBinder;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 import android.os.RemoteException;
25 
26 /**
27  * Native implementation of the bulk cursor. This is only for use in implementing
28  * IPC, application code should use the Cursor interface.
29  *
30  * {@hide}
31  */
32 public abstract class BulkCursorNative extends Binder implements IBulkCursor
33 {
BulkCursorNative()34     public BulkCursorNative()
35     {
36         attachInterface(this, descriptor);
37     }
38 
39     /**
40      * Cast a Binder object into a content resolver interface, generating
41      * a proxy if needed.
42      */
asInterface(IBinder obj)43     static public IBulkCursor asInterface(IBinder obj)
44     {
45         if (obj == null) {
46             return null;
47         }
48         IBulkCursor in = (IBulkCursor)obj.queryLocalInterface(descriptor);
49         if (in != null) {
50             return in;
51         }
52 
53         return new BulkCursorProxy(obj);
54     }
55 
56     @Override
onTransact(int code, Parcel data, Parcel reply, int flags)57     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
58             throws RemoteException {
59         try {
60             switch (code) {
61                 case GET_CURSOR_WINDOW_TRANSACTION: {
62                     data.enforceInterface(IBulkCursor.descriptor);
63                     int startPos = data.readInt();
64                     CursorWindow window = getWindow(startPos);
65                     reply.writeNoException();
66                     if (window == null) {
67                         reply.writeInt(0);
68                     } else {
69                         reply.writeInt(1);
70                         window.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
71                     }
72                     return true;
73                 }
74 
75                 case DEACTIVATE_TRANSACTION: {
76                     data.enforceInterface(IBulkCursor.descriptor);
77                     deactivate();
78                     reply.writeNoException();
79                     return true;
80                 }
81 
82                 case CLOSE_TRANSACTION: {
83                     data.enforceInterface(IBulkCursor.descriptor);
84                     close();
85                     reply.writeNoException();
86                     return true;
87                 }
88 
89                 case REQUERY_TRANSACTION: {
90                     data.enforceInterface(IBulkCursor.descriptor);
91                     IContentObserver observer =
92                             IContentObserver.Stub.asInterface(data.readStrongBinder());
93                     int count = requery(observer);
94                     reply.writeNoException();
95                     reply.writeInt(count);
96                     reply.writeBundle(getExtras());
97                     return true;
98                 }
99 
100                 case ON_MOVE_TRANSACTION: {
101                     data.enforceInterface(IBulkCursor.descriptor);
102                     int position = data.readInt();
103                     onMove(position);
104                     reply.writeNoException();
105                     return true;
106                 }
107 
108                 case GET_EXTRAS_TRANSACTION: {
109                     data.enforceInterface(IBulkCursor.descriptor);
110                     Bundle extras = getExtras();
111                     reply.writeNoException();
112                     reply.writeBundle(extras);
113                     return true;
114                 }
115 
116                 case RESPOND_TRANSACTION: {
117                     data.enforceInterface(IBulkCursor.descriptor);
118                     Bundle extras = data.readBundle();
119                     Bundle returnExtras = respond(extras);
120                     reply.writeNoException();
121                     reply.writeBundle(returnExtras);
122                     return true;
123                 }
124             }
125         } catch (Exception e) {
126             DatabaseUtils.writeExceptionToParcel(reply, e);
127             return true;
128         }
129 
130         return super.onTransact(code, data, reply, flags);
131     }
132 
asBinder()133     public IBinder asBinder()
134     {
135         return this;
136     }
137 }
138 
139 
140 final class BulkCursorProxy implements IBulkCursor {
141     private IBinder mRemote;
142     private Bundle mExtras;
143 
BulkCursorProxy(IBinder remote)144     public BulkCursorProxy(IBinder remote)
145     {
146         mRemote = remote;
147         mExtras = null;
148     }
149 
asBinder()150     public IBinder asBinder()
151     {
152         return mRemote;
153     }
154 
getWindow(int position)155     public CursorWindow getWindow(int position) throws RemoteException
156     {
157         Parcel data = Parcel.obtain();
158         Parcel reply = Parcel.obtain();
159         try {
160             data.writeInterfaceToken(IBulkCursor.descriptor);
161             data.writeInt(position);
162 
163             mRemote.transact(GET_CURSOR_WINDOW_TRANSACTION, data, reply, 0);
164             DatabaseUtils.readExceptionFromParcel(reply);
165 
166             CursorWindow window = null;
167             if (reply.readInt() == 1) {
168                 window = CursorWindow.newFromParcel(reply);
169             }
170             return window;
171         } finally {
172             data.recycle();
173             reply.recycle();
174         }
175     }
176 
onMove(int position)177     public void onMove(int position) throws RemoteException {
178         Parcel data = Parcel.obtain();
179         Parcel reply = Parcel.obtain();
180         try {
181             data.writeInterfaceToken(IBulkCursor.descriptor);
182             data.writeInt(position);
183 
184             mRemote.transact(ON_MOVE_TRANSACTION, data, reply, 0);
185             DatabaseUtils.readExceptionFromParcel(reply);
186         } finally {
187             data.recycle();
188             reply.recycle();
189         }
190     }
191 
deactivate()192     public void deactivate() throws RemoteException
193     {
194         Parcel data = Parcel.obtain();
195         Parcel reply = Parcel.obtain();
196         try {
197             data.writeInterfaceToken(IBulkCursor.descriptor);
198 
199             mRemote.transact(DEACTIVATE_TRANSACTION, data, reply, 0);
200             DatabaseUtils.readExceptionFromParcel(reply);
201         } finally {
202             data.recycle();
203             reply.recycle();
204         }
205     }
206 
close()207     public void close() throws RemoteException
208     {
209         Parcel data = Parcel.obtain();
210         Parcel reply = Parcel.obtain();
211         try {
212             data.writeInterfaceToken(IBulkCursor.descriptor);
213 
214             mRemote.transact(CLOSE_TRANSACTION, data, reply, 0);
215             DatabaseUtils.readExceptionFromParcel(reply);
216         } finally {
217             data.recycle();
218             reply.recycle();
219         }
220     }
221 
requery(IContentObserver observer)222     public int requery(IContentObserver observer) throws RemoteException {
223         Parcel data = Parcel.obtain();
224         Parcel reply = Parcel.obtain();
225         try {
226             data.writeInterfaceToken(IBulkCursor.descriptor);
227             data.writeStrongInterface(observer);
228 
229             boolean result = mRemote.transact(REQUERY_TRANSACTION, data, reply, 0);
230             DatabaseUtils.readExceptionFromParcel(reply);
231 
232             int count;
233             if (!result) {
234                 count = -1;
235             } else {
236                 count = reply.readInt();
237                 mExtras = reply.readBundle();
238             }
239             return count;
240         } finally {
241             data.recycle();
242             reply.recycle();
243         }
244     }
245 
getExtras()246     public Bundle getExtras() throws RemoteException {
247         if (mExtras == null) {
248             Parcel data = Parcel.obtain();
249             Parcel reply = Parcel.obtain();
250             try {
251                 data.writeInterfaceToken(IBulkCursor.descriptor);
252 
253                 mRemote.transact(GET_EXTRAS_TRANSACTION, data, reply, 0);
254                 DatabaseUtils.readExceptionFromParcel(reply);
255 
256                 mExtras = reply.readBundle();
257             } finally {
258                 data.recycle();
259                 reply.recycle();
260             }
261         }
262         return mExtras;
263     }
264 
respond(Bundle extras)265     public Bundle respond(Bundle extras) throws RemoteException {
266         Parcel data = Parcel.obtain();
267         Parcel reply = Parcel.obtain();
268         try {
269             data.writeInterfaceToken(IBulkCursor.descriptor);
270             data.writeBundle(extras);
271 
272             mRemote.transact(RESPOND_TRANSACTION, data, reply, 0);
273             DatabaseUtils.readExceptionFromParcel(reply);
274 
275             Bundle returnExtras = reply.readBundle();
276             return returnExtras;
277         } finally {
278             data.recycle();
279             reply.recycle();
280         }
281     }
282 }
283 
284