blob: 67cf0f82700a69a88d2acb00816a63661d706377 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
17package android.database;
18
19import android.os.Binder;
Jeff Hamilton7cd51ef2010-05-12 17:30:27 -050020import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import android.os.IBinder;
22import android.os.Parcel;
Jeff Browndf6611d2011-10-09 12:28:54 -070023import android.os.Parcelable;
Jeff Hamilton7cd51ef2010-05-12 17:30:27 -050024import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025
26/**
27 * Native implementation of the bulk cursor. This is only for use in implementing
28 * IPC, application code should use the Cursor interface.
Jeff Browndf6611d2011-10-09 12:28:54 -070029 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030 * {@hide}
31 */
32public abstract class BulkCursorNative extends Binder implements IBulkCursor
33{
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 */
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
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);
Jeff Brownd2183652011-10-09 12:39:53 -070065 reply.writeNoException();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066 if (window == null) {
67 reply.writeInt(0);
Jeff Brownd2183652011-10-09 12:39:53 -070068 } else {
69 reply.writeInt(1);
70 window.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072 return true;
73 }
74
75 case COUNT_TRANSACTION: {
76 data.enforceInterface(IBulkCursor.descriptor);
77 int count = count();
78 reply.writeNoException();
79 reply.writeInt(count);
80 return true;
81 }
82
83 case GET_COLUMN_NAMES_TRANSACTION: {
84 data.enforceInterface(IBulkCursor.descriptor);
85 String[] columnNames = getColumnNames();
86 reply.writeNoException();
87 reply.writeInt(columnNames.length);
88 int length = columnNames.length;
89 for (int i = 0; i < length; i++) {
90 reply.writeString(columnNames[i]);
91 }
92 return true;
93 }
94
95 case DEACTIVATE_TRANSACTION: {
96 data.enforceInterface(IBulkCursor.descriptor);
97 deactivate();
98 reply.writeNoException();
99 return true;
100 }
101
102 case CLOSE_TRANSACTION: {
103 data.enforceInterface(IBulkCursor.descriptor);
104 close();
105 reply.writeNoException();
106 return true;
107 }
108
109 case REQUERY_TRANSACTION: {
110 data.enforceInterface(IBulkCursor.descriptor);
111 IContentObserver observer =
Jeff Brown0cde89f2011-10-10 14:50:10 -0700112 IContentObserver.Stub.asInterface(data.readStrongBinder());
113 int count = requery(observer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114 reply.writeNoException();
115 reply.writeInt(count);
116 reply.writeBundle(getExtras());
117 return true;
118 }
119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120 case ON_MOVE_TRANSACTION: {
121 data.enforceInterface(IBulkCursor.descriptor);
122 int position = data.readInt();
123 onMove(position);
124 reply.writeNoException();
125 return true;
126 }
127
128 case WANTS_ON_MOVE_TRANSACTION: {
129 data.enforceInterface(IBulkCursor.descriptor);
130 boolean result = getWantsAllOnMoveCalls();
131 reply.writeNoException();
132 reply.writeInt(result ? 1 : 0);
133 return true;
134 }
135
136 case GET_EXTRAS_TRANSACTION: {
137 data.enforceInterface(IBulkCursor.descriptor);
138 Bundle extras = getExtras();
139 reply.writeNoException();
140 reply.writeBundle(extras);
141 return true;
142 }
143
144 case RESPOND_TRANSACTION: {
145 data.enforceInterface(IBulkCursor.descriptor);
146 Bundle extras = data.readBundle();
147 Bundle returnExtras = respond(extras);
148 reply.writeNoException();
149 reply.writeBundle(returnExtras);
150 return true;
151 }
152 }
153 } catch (Exception e) {
154 DatabaseUtils.writeExceptionToParcel(reply, e);
155 return true;
156 }
157
158 return super.onTransact(code, data, reply, flags);
159 }
160
161 public IBinder asBinder()
162 {
163 return this;
164 }
165}
166
167
168final class BulkCursorProxy implements IBulkCursor {
169 private IBinder mRemote;
170 private Bundle mExtras;
171
172 public BulkCursorProxy(IBinder remote)
173 {
174 mRemote = remote;
175 mExtras = null;
176 }
177
178 public IBinder asBinder()
179 {
180 return mRemote;
181 }
182
Jeff Brown650de3d2011-10-27 14:52:28 -0700183 public CursorWindow getWindow(int position) throws RemoteException
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 {
185 Parcel data = Parcel.obtain();
186 Parcel reply = Parcel.obtain();
Jeff Browndf6611d2011-10-09 12:28:54 -0700187 try {
188 data.writeInterfaceToken(IBulkCursor.descriptor);
Jeff Brown650de3d2011-10-27 14:52:28 -0700189 data.writeInt(position);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190
Jeff Browndf6611d2011-10-09 12:28:54 -0700191 mRemote.transact(GET_CURSOR_WINDOW_TRANSACTION, data, reply, 0);
192 DatabaseUtils.readExceptionFromParcel(reply);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193
Jeff Browndf6611d2011-10-09 12:28:54 -0700194 CursorWindow window = null;
195 if (reply.readInt() == 1) {
196 window = CursorWindow.newFromParcel(reply);
197 }
198 return window;
199 } finally {
200 data.recycle();
201 reply.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 }
204
205 public void onMove(int position) throws RemoteException {
206 Parcel data = Parcel.obtain();
207 Parcel reply = Parcel.obtain();
Jeff Browndf6611d2011-10-09 12:28:54 -0700208 try {
209 data.writeInterfaceToken(IBulkCursor.descriptor);
210 data.writeInt(position);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211
Jeff Browndf6611d2011-10-09 12:28:54 -0700212 mRemote.transact(ON_MOVE_TRANSACTION, data, reply, 0);
213 DatabaseUtils.readExceptionFromParcel(reply);
214 } finally {
215 data.recycle();
216 reply.recycle();
217 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 }
219
220 public int count() throws RemoteException
221 {
222 Parcel data = Parcel.obtain();
223 Parcel reply = Parcel.obtain();
Jeff Browndf6611d2011-10-09 12:28:54 -0700224 try {
225 data.writeInterfaceToken(IBulkCursor.descriptor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226
Jeff Browndf6611d2011-10-09 12:28:54 -0700227 boolean result = mRemote.transact(COUNT_TRANSACTION, data, reply, 0);
228 DatabaseUtils.readExceptionFromParcel(reply);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229
Jeff Browndf6611d2011-10-09 12:28:54 -0700230 int count;
231 if (result == false) {
232 count = -1;
233 } else {
234 count = reply.readInt();
235 }
236 return count;
237 } finally {
238 data.recycle();
239 reply.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 }
242
243 public String[] getColumnNames() throws RemoteException
244 {
245 Parcel data = Parcel.obtain();
246 Parcel reply = Parcel.obtain();
Jeff Browndf6611d2011-10-09 12:28:54 -0700247 try {
248 data.writeInterfaceToken(IBulkCursor.descriptor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249
Jeff Browndf6611d2011-10-09 12:28:54 -0700250 mRemote.transact(GET_COLUMN_NAMES_TRANSACTION, data, reply, 0);
251 DatabaseUtils.readExceptionFromParcel(reply);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252
Jeff Browndf6611d2011-10-09 12:28:54 -0700253 String[] columnNames = null;
254 int numColumns = reply.readInt();
255 columnNames = new String[numColumns];
256 for (int i = 0; i < numColumns; i++) {
257 columnNames[i] = reply.readString();
258 }
259 return columnNames;
260 } finally {
261 data.recycle();
262 reply.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 }
265
266 public void deactivate() throws RemoteException
267 {
268 Parcel data = Parcel.obtain();
269 Parcel reply = Parcel.obtain();
Jeff Browndf6611d2011-10-09 12:28:54 -0700270 try {
271 data.writeInterfaceToken(IBulkCursor.descriptor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272
Jeff Browndf6611d2011-10-09 12:28:54 -0700273 mRemote.transact(DEACTIVATE_TRANSACTION, data, reply, 0);
274 DatabaseUtils.readExceptionFromParcel(reply);
275 } finally {
276 data.recycle();
277 reply.recycle();
278 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 }
280
281 public void close() throws RemoteException
282 {
283 Parcel data = Parcel.obtain();
284 Parcel reply = Parcel.obtain();
Jeff Browndf6611d2011-10-09 12:28:54 -0700285 try {
286 data.writeInterfaceToken(IBulkCursor.descriptor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800287
Jeff Browndf6611d2011-10-09 12:28:54 -0700288 mRemote.transact(CLOSE_TRANSACTION, data, reply, 0);
289 DatabaseUtils.readExceptionFromParcel(reply);
290 } finally {
291 data.recycle();
292 reply.recycle();
293 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294 }
295
Jeff Brown0cde89f2011-10-10 14:50:10 -0700296 public int requery(IContentObserver observer) throws RemoteException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 Parcel data = Parcel.obtain();
298 Parcel reply = Parcel.obtain();
Jeff Browndf6611d2011-10-09 12:28:54 -0700299 try {
300 data.writeInterfaceToken(IBulkCursor.descriptor);
301 data.writeStrongInterface(observer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800302
Jeff Browndf6611d2011-10-09 12:28:54 -0700303 boolean result = mRemote.transact(REQUERY_TRANSACTION, data, reply, 0);
304 DatabaseUtils.readExceptionFromParcel(reply);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305
Jeff Browndf6611d2011-10-09 12:28:54 -0700306 int count;
307 if (!result) {
308 count = -1;
309 } else {
310 count = reply.readInt();
311 mExtras = reply.readBundle();
312 }
313 return count;
314 } finally {
315 data.recycle();
316 reply.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318 }
319
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 public boolean getWantsAllOnMoveCalls() throws RemoteException {
321 Parcel data = Parcel.obtain();
322 Parcel reply = Parcel.obtain();
Jeff Browndf6611d2011-10-09 12:28:54 -0700323 try {
324 data.writeInterfaceToken(IBulkCursor.descriptor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325
Jeff Browndf6611d2011-10-09 12:28:54 -0700326 mRemote.transact(WANTS_ON_MOVE_TRANSACTION, data, reply, 0);
327 DatabaseUtils.readExceptionFromParcel(reply);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328
Jeff Browndf6611d2011-10-09 12:28:54 -0700329 int result = reply.readInt();
330 return result != 0;
331 } finally {
332 data.recycle();
333 reply.recycle();
334 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 }
336
337 public Bundle getExtras() throws RemoteException {
338 if (mExtras == null) {
339 Parcel data = Parcel.obtain();
340 Parcel reply = Parcel.obtain();
Jeff Browndf6611d2011-10-09 12:28:54 -0700341 try {
342 data.writeInterfaceToken(IBulkCursor.descriptor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343
Jeff Browndf6611d2011-10-09 12:28:54 -0700344 mRemote.transact(GET_EXTRAS_TRANSACTION, data, reply, 0);
345 DatabaseUtils.readExceptionFromParcel(reply);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346
Jeff Browndf6611d2011-10-09 12:28:54 -0700347 mExtras = reply.readBundle();
348 } finally {
349 data.recycle();
350 reply.recycle();
351 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352 }
353 return mExtras;
354 }
355
356 public Bundle respond(Bundle extras) throws RemoteException {
357 Parcel data = Parcel.obtain();
358 Parcel reply = Parcel.obtain();
Jeff Browndf6611d2011-10-09 12:28:54 -0700359 try {
360 data.writeInterfaceToken(IBulkCursor.descriptor);
361 data.writeBundle(extras);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800362
Jeff Browndf6611d2011-10-09 12:28:54 -0700363 mRemote.transact(RESPOND_TRANSACTION, data, reply, 0);
364 DatabaseUtils.readExceptionFromParcel(reply);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365
Jeff Browndf6611d2011-10-09 12:28:54 -0700366 Bundle returnExtras = reply.readBundle();
367 return returnExtras;
368 } finally {
369 data.recycle();
370 reply.recycle();
371 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 }
373}
374