Parcel.cpp revision 2c68d380c9ef765a7d46e5a4735f39e6c27849f2
199e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten/*
289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project
389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * you may not use this file except in compliance with the License.
689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * You may obtain a copy of the License at
789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
1089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * See the License for the specific language governing permissions and
1489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * limitations under the License.
1589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project */
1689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define LOG_TAG "Parcel"
1889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//#define LOG_NDEBUG 0
1989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <binder/Parcel.h>
2134fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn
22c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten#include <binder/IPCThreadState.h>
2389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <binder/Binder.h>
2434fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn#include <binder/BpBinder.h>
259f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#include <binder/ProcessState.h>
269f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#include <binder/TextOutput.h>
2789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <errno.h>
299f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#include <utils/Debug.h>
301ab85ec401801ef9a9184650d0f5a1639b45eeb9Glenn Kasten#include <utils/Log.h>
31e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent#include <utils/String8.h>
32cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung#include <utils/String16.h>
33fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include <utils/misc.h>
34b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald#include <utils/Flattenable.h>
35b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald#include <cutils/ashmem.h>
3653c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung
37511754b5839fd9b09fc56b89ae007fbc39084a33Glenn Kasten#include <private/binder/binder_module.h>
3889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
3933005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh#include <inttypes.h>
4033005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh#include <stdio.h>
414ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung#include <stdlib.h>
424ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung#include <stdint.h>
434ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung#include <sys/mman.h>
444ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung
454ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung#ifndef INT32_MAX
467f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung#define INT32_MAX ((int32_t)(2147483647))
477f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung#endif
487f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung
497f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung#define LOG_REFS(...)
507f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung//#define LOG_REFS(...) ALOG(LOG_DEBUG, "Parcel", __VA_ARGS__)
517f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung
527f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung// ---------------------------------------------------------------------------
537f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung
547f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung#define PAD_SIZE(s) (((s)+3)&~3)
557f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung
567f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung// Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER
577f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung#define STRICT_MODE_PENALTY_GATHER 0x100
587f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung
5933005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh// Note: must be kept in sync with android/os/Parcel.java's EX_HAS_REPLY_HEADER
6033005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh#define EX_HAS_REPLY_HEADER -128
61e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten
62fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten// Maximum size of a blob to transfer in-place.
6333005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yehstatic const size_t IN_PLACE_BLOB_LIMIT = 40 * 1024;
6433005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh
65d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten// XXX This can be made public if we want to provide
66d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten// support for typed data.
67d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kastenstruct small_flat_data
6804cd0186305e2b59d23c9147787046c6662029ccGlenn Kasten{
690e48d25606c82def035ad10a5b3923767a765cddAndy Hung    uint32_t type;
70e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    uint32_t data;
71e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten};
72e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten
730e48d25606c82def035ad10a5b3923767a765cddAndy Hungnamespace android {
743b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kasten
7566a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kastenvoid acquire_object(const sp<ProcessState>& proc,
7666a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten    const flat_binder_object& obj, const void* who)
7766a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten{
7870c0bfbe5ec88dcc3efa2bd8df26f36cff1cf03aGlenn Kasten    switch (obj.type) {
7970c0bfbe5ec88dcc3efa2bd8df26f36cff1cf03aGlenn Kasten        case BINDER_TYPE_BINDER:
8066a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten            if (obj.binder) {
8133005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh                LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
82e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten                reinterpret_cast<IBinder*>(obj.cookie)->incStrong(who);
8366a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten            }
8466a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten            return;
8570c0bfbe5ec88dcc3efa2bd8df26f36cff1cf03aGlenn Kasten        case BINDER_TYPE_WEAK_BINDER:
8670c0bfbe5ec88dcc3efa2bd8df26f36cff1cf03aGlenn Kasten            if (obj.binder)
8766a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten                reinterpret_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who);
8833005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh            return;
8933005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh        case BINDER_TYPE_HANDLE: {
9066a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten            const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
9166a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten            if (b != NULL) {
9270c0bfbe5ec88dcc3efa2bd8df26f36cff1cf03aGlenn Kasten                LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
9370c0bfbe5ec88dcc3efa2bd8df26f36cff1cf03aGlenn Kasten                b->incStrong(who);
9466a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten            }
9533005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh            return;
9633005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh        }
9733005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh        case BINDER_TYPE_WEAK_HANDLE: {
9833005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh            const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
999f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            if (b != NULL) b.get_refs()->incWeak(who);
1009f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            return;
1019f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        }
10233005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh        case BINDER_TYPE_FD: {
1030e48d25606c82def035ad10a5b3923767a765cddAndy Hung            // intentionally blank -- nothing to do to acquire this, but we do
1040e48d25606c82def035ad10a5b3923767a765cddAndy Hung            // recognize it as a legitimate object type.
1050e48d25606c82def035ad10a5b3923767a765cddAndy Hung            return;
1060e48d25606c82def035ad10a5b3923767a765cddAndy Hung        }
10766a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten    }
1080e48d25606c82def035ad10a5b3923767a765cddAndy Hung
10966a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten    ALOGD("Invalid object type 0x%08x", obj.type);
11066a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten}
11166a0467fdddada4caabd0f0a999fbb367fea7beeGlenn Kasten
1120e48d25606c82def035ad10a5b3923767a765cddAndy Hungvoid release_object(const sp<ProcessState>& proc,
1133acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    const flat_binder_object& obj, const void* who)
11433005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh{
11533005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh    switch (obj.type) {
11689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        case BINDER_TYPE_BINDER:
11789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (obj.binder) {
11889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
11989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                reinterpret_cast<IBinder*>(obj.cookie)->decStrong(who);
120879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten            }
1214ff14bae91075eb274eb1c2975982358946e7e63John Grossman            return;
1224ff14bae91075eb274eb1c2975982358946e7e63John Grossman        case BINDER_TYPE_WEAK_BINDER:
1237064fd2dcdfeafea53cd5a992bb78c413542f29fHaynes Mathew George            if (obj.binder)
1247064fd2dcdfeafea53cd5a992bb78c413542f29fHaynes Mathew George                reinterpret_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who);
12589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            return;
126faabb51ceef13bf1e3f692219ac410c1cd75d0deJean-Michel Trivi        case BINDER_TYPE_HANDLE: {
127faabb51ceef13bf1e3f692219ac410c1cd75d0deJean-Michel Trivi            const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
128faabb51ceef13bf1e3f692219ac410c1cd75d0deJean-Michel Trivi            if (b != NULL) {
129faabb51ceef13bf1e3f692219ac410c1cd75d0deJean-Michel Trivi                LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
13089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                b->decStrong(who);
13189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            }
13289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            return;
133fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten        }
13489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        case BINDER_TYPE_WEAK_HANDLE: {
135e1c3962e268ffc12bfd1bd9ea84da1f135f36960Glenn Kasten            const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
13628b76b334f92a15a2be3cc9e2f7d229a3275d1acGlenn Kasten            if (b != NULL) b.get_refs()->decWeak(who);
137bce50bfc3846ab008bafa75c5d3f29fd7b5395f7Glenn Kasten            return;
1380ca3cf94c0dfc173ad7886ae162c4b67067539f6Eric Laurent        }
13989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        case BINDER_TYPE_FD: {
14089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (obj.cookie != 0) close(obj.handle);
141838b3d8bafa4a781e277870dee4e0390165cff52Glenn Kasten            return;
1429f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        }
143ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    }
144462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen
145d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen    ALOGE("Invalid object type 0x%08x", obj.type);
146d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi}
147d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi
148879135196fd1c97deefc538c888037c56c2879a7Glenn Kasteninline static status_t finish_flatten_binder(
1494ff14bae91075eb274eb1c2975982358946e7e63John Grossman    const sp<IBinder>& /*binder*/, const flat_binder_object& flat, Parcel* out)
1504ff14bae91075eb274eb1c2975982358946e7e63John Grossman{
1517064fd2dcdfeafea53cd5a992bb78c413542f29fHaynes Mathew George    return out->writeObject(flat, false);
1527064fd2dcdfeafea53cd5a992bb78c413542f29fHaynes Mathew George}
15389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1540d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivistatus_t flatten_binder(const sp<ProcessState>& /*proc*/,
155a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent    const sp<IBinder>& binder, Parcel* out)
156462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen{
157d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi    flat_binder_object obj;
15889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
15989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
160c813985abd8ba61e999b3505f6a332574f87a1beAndreas Huber    if (binder != NULL) {
161fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten        IBinder *local = binder->localBinder();
16289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (!local) {
163e1c3962e268ffc12bfd1bd9ea84da1f135f36960Glenn Kasten            BpBinder *proxy = binder->remoteBinder();
16428b76b334f92a15a2be3cc9e2f7d229a3275d1acGlenn Kasten            if (proxy == NULL) {
16589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                ALOGE("null proxy");
1660ca3cf94c0dfc173ad7886ae162c4b67067539f6Eric Laurent            }
16789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            const int32_t handle = proxy ? proxy->handle() : 0;
16889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            obj.type = BINDER_TYPE_HANDLE;
169838b3d8bafa4a781e277870dee4e0390165cff52Glenn Kasten            obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
1709f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            obj.handle = handle;
171ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald            obj.cookie = 0;
172462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen        } else {
173d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen            obj.type = BINDER_TYPE_BINDER;
174d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi            obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
175d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi            obj.cookie = reinterpret_cast<uintptr_t>(local);
176879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten        }
1774ff14bae91075eb274eb1c2975982358946e7e63John Grossman    } else {
1784ff14bae91075eb274eb1c2975982358946e7e63John Grossman        obj.type = BINDER_TYPE_BINDER;
1797064fd2dcdfeafea53cd5a992bb78c413542f29fHaynes Mathew George        obj.binder = 0;
1807064fd2dcdfeafea53cd5a992bb78c413542f29fHaynes Mathew George        obj.cookie = 0;
18189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
1820d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi
18317a736c3e1d062d7fc916329eb32aef8935614afGlenn Kasten    return finish_flatten_binder(binder, obj, out);
184d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen}
185d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi
18689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t flatten_binder(const sp<ProcessState>& /*proc*/,
18789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const wp<IBinder>& binder, Parcel* out)
18889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
18989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    flat_binder_object obj;
19089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
19189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
19289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (binder != NULL) {
19389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        sp<IBinder> real = binder.promote();
19489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (real != NULL) {
19589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            IBinder *local = real->localBinder();
196b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald            if (!local) {
1973acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten                BpBinder *proxy = real->remoteBinder();
19889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                if (proxy == NULL) {
19989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    ALOGE("null proxy");
20089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                }
201f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen                const int32_t handle = proxy ? proxy->handle() : 0;
20253cec22821072719ee02c856e9ac2dda2496c570Glenn Kasten                obj.type = BINDER_TYPE_WEAK_HANDLE;
2033bcffa136909c1fb6e88ee4efd12ccac18360a85Eric Laurent                obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
2043bcffa136909c1fb6e88ee4efd12ccac18360a85Eric Laurent                obj.handle = handle;
20589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                obj.cookie = 0;
206d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen            } else {
207d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen                obj.type = BINDER_TYPE_WEAK_BINDER;
208d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen                obj.binder = reinterpret_cast<uintptr_t>(binder.get_refs());
20989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                obj.cookie = reinterpret_cast<uintptr_t>(binder.unsafe_get());
21089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            }
21189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            return finish_flatten_binder(real, obj, out);
21289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
213fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten
21489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // XXX How to deal?  In order to flatten the given binder,
215e1c3962e268ffc12bfd1bd9ea84da1f135f36960Glenn Kasten        // we need to probe it for information, which requires a primary
21628b76b334f92a15a2be3cc9e2f7d229a3275d1acGlenn Kasten        // reference...  but we don't have one.
217bce50bfc3846ab008bafa75c5d3f29fd7b5395f7Glenn Kasten        //
2180ca3cf94c0dfc173ad7886ae162c4b67067539f6Eric Laurent        // The OpenBinder implementation uses a dynamic_cast<> here,
21989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // but we can't do that with the different reference counting
22089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // implementation we are using.
221838b3d8bafa4a781e277870dee4e0390165cff52Glenn Kasten        ALOGE("Unable to unflatten Binder weak reference!");
22289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        obj.type = BINDER_TYPE_BINDER;
223be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        obj.binder = 0;
2249f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        obj.cookie = 0;
225ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald        return finish_flatten_binder(NULL, obj, out);
226462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen
227d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen    } else {
228faabb51ceef13bf1e3f692219ac410c1cd75d0deJean-Michel Trivi        obj.type = BINDER_TYPE_BINDER;
229d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi        obj.binder = 0;
23089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        obj.cookie = 0;
231bce50bfc3846ab008bafa75c5d3f29fd7b5395f7Glenn Kasten        return finish_flatten_binder(NULL, obj, out);
232838b3d8bafa4a781e277870dee4e0390165cff52Glenn Kasten    }
233bce50bfc3846ab008bafa75c5d3f29fd7b5395f7Glenn Kasten}
23486f04663032ddaa25110149d709bbf896ad83b02Glenn Kasten
23586f04663032ddaa25110149d709bbf896ad83b02Glenn Kasteninline static status_t finish_unflatten_binder(
2369f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    BpBinder* /*proxy*/, const flat_binder_object& /*flat*/,
2379f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    const Parcel& /*in*/)
2389f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten{
2399f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return NO_ERROR;
2409f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
2419f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2429f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenstatus_t unflatten_binder(const sp<ProcessState>& proc,
2439f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    const Parcel& in, sp<IBinder>* out)
2449f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten{
2459f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    const flat_binder_object* flat = in.readObject(false);
2469f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2479f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (flat) {
2489f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        switch (flat->type) {
2499f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            case BINDER_TYPE_BINDER:
2509f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                *out = reinterpret_cast<IBinder*>(flat->cookie);
2519f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                return finish_unflatten_binder(NULL, *flat, in);
2529f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            case BINDER_TYPE_HANDLE:
2539f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                *out = proc->getStrongProxyForHandle(flat->handle);
2549f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                return finish_unflatten_binder(
2559f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                    static_cast<BpBinder*>(out->get()), *flat, in);
2569f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        }
2579f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
2589f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return BAD_TYPE;
2599f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
2609f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2619f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenstatus_t unflatten_binder(const sp<ProcessState>& proc,
2629f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    const Parcel& in, wp<IBinder>* out)
2639f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten{
2649f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    const flat_binder_object* flat = in.readObject(false);
2659f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2669f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (flat) {
2679f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        switch (flat->type) {
2689f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            case BINDER_TYPE_BINDER:
269dd5f4c8c4059f890e81b28b026a688febb4e1dd9Glenn Kasten                *out = reinterpret_cast<IBinder*>(flat->cookie);
2709f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                return finish_unflatten_binder(NULL, *flat, in);
2719f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            case BINDER_TYPE_WEAK_BINDER:
27285ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                if (flat->binder != 0) {
27385ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    out->set_object_and_refs(
27489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                        reinterpret_cast<IBinder*>(flat->cookie),
27534fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn                        reinterpret_cast<RefBase::weakref_type*>(flat->binder));
2761a9ed11a472493cac7f6dfcbfac2064526a493edEric Laurent                } else {
2771703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                    *out = NULL;
2789f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                }
27953cec22821072719ee02c856e9ac2dda2496c570Glenn Kasten                return finish_unflatten_binder(NULL, *flat, in);
2801dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent            case BINDER_TYPE_HANDLE:
28129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            case BINDER_TYPE_WEAK_HANDLE:
28289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                *out = proc->getWeakProxyForHandle(flat->handle);
28389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                return finish_unflatten_binder(
28489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    static_cast<BpBinder*>(out->unsafe_get()), *flat, in);
28589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
286e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    }
287fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return BAD_TYPE;
28889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
289faabb51ceef13bf1e3f692219ac410c1cd75d0deJean-Michel Trivi
290223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent// ---------------------------------------------------------------------------
291faabb51ceef13bf1e3f692219ac410c1cd75d0deJean-Michel Trivi
292faabb51ceef13bf1e3f692219ac410c1cd75d0deJean-Michel TriviParcel::Parcel()
293faabb51ceef13bf1e3f692219ac410c1cd75d0deJean-Michel Trivi{
294faabb51ceef13bf1e3f692219ac410c1cd75d0deJean-Michel Trivi    initState();
295e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent}
296faabb51ceef13bf1e3f692219ac410c1cd75d0deJean-Michel Trivi
297faabb51ceef13bf1e3f692219ac410c1cd75d0deJean-Michel TriviParcel::~Parcel()
298faabb51ceef13bf1e3f692219ac410c1cd75d0deJean-Michel Trivi{
299faabb51ceef13bf1e3f692219ac410c1cd75d0deJean-Michel Trivi    freeDataNoInit();
300faabb51ceef13bf1e3f692219ac410c1cd75d0deJean-Michel Trivi}
301e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent
302c6bd5db9d9cf4bba1649b5b7ddea2d23f5de23a9Eric Laurentconst uint8_t* Parcel::data() const
303c6bd5db9d9cf4bba1649b5b7ddea2d23f5de23a9Eric Laurent{
304c6bd5db9d9cf4bba1649b5b7ddea2d23f5de23a9Eric Laurent    return mData;
305dd5f4c8c4059f890e81b28b026a688febb4e1dd9Glenn Kasten}
306ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten
30789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectsize_t Parcel::dataSize() const
308e1c3962e268ffc12bfd1bd9ea84da1f135f36960Glenn Kasten{
309fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return (mDataSize > mDataPos ? mDataSize : mDataPos);
31089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
31189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
31289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectsize_t Parcel::dataAvail() const
313fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
314cac3daa6332bf6d1f7d26adc4a9915f3d7992dd9Glenn Kasten    // TODO: decide what to do about the possibility that this can
31589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // report an available-data size that exceeds a Java int's max
31689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // positive value, causing havoc.  Fortunately this will only
317dd5f4c8c4059f890e81b28b026a688febb4e1dd9Glenn Kasten    // happen if someone constructs a Parcel containing more than two
318c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    // gigabytes of data, which on typical phone hardware is simply
3198ba90326d683b035d99e24db669093e4602a7149Glenn Kasten    // not possible.
3208ba90326d683b035d99e24db669093e4602a7149Glenn Kasten    return dataSize() - dataPosition();
3218ba90326d683b035d99e24db669093e4602a7149Glenn Kasten}
3228ba90326d683b035d99e24db669093e4602a7149Glenn Kasten
323e3247bf8dd4f8fa8dfa3a108260241ae4a967569Glenn Kastensize_t Parcel::dataPosition() const
324e541269be94f3a1072932d51537905b120ef4733Andy Hung{
325e3247bf8dd4f8fa8dfa3a108260241ae4a967569Glenn Kasten    return mDataPos;
3268ba90326d683b035d99e24db669093e4602a7149Glenn Kasten}
327c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent
328b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgeraldsize_t Parcel::dataCapacity() const
329b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald{
330b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    return mDataCapacity;
331b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald}
332b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald
333b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgeraldstatus_t Parcel::setDataSize(size_t size)
3340ca3cf94c0dfc173ad7886ae162c4b67067539f6Eric Laurent{
3353acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    status_t err;
3360ca3cf94c0dfc173ad7886ae162c4b67067539f6Eric Laurent    err = continueWrite(size);
337c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    if (err == NO_ERROR) {
338c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        mDataSize = size;
339d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent        ALOGV("setDataSize Setting data size of %p to %d\n", this, mDataSize);
340d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent    }
341d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent    return err;
342d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent}
343d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent
344b773038277ba328696832b690b91ce6e95bd1a6cGlenn Kastenvoid Parcel::setDataPosition(size_t pos) const
345b773038277ba328696832b690b91ce6e95bd1a6cGlenn Kasten{
346b773038277ba328696832b690b91ce6e95bd1a6cGlenn Kasten    mDataPos = pos;
347b773038277ba328696832b690b91ce6e95bd1a6cGlenn Kasten    mNextObjectHint = 0;
348b773038277ba328696832b690b91ce6e95bd1a6cGlenn Kasten}
349b773038277ba328696832b690b91ce6e95bd1a6cGlenn Kasten
350e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenstatus_t Parcel::setDataCapacity(size_t size)
351b773038277ba328696832b690b91ce6e95bd1a6cGlenn Kasten{
352b773038277ba328696832b690b91ce6e95bd1a6cGlenn Kasten    if (size > mDataCapacity) return continueWrite(size);
353b773038277ba328696832b690b91ce6e95bd1a6cGlenn Kasten    return NO_ERROR;
354b773038277ba328696832b690b91ce6e95bd1a6cGlenn Kasten}
355e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
356e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenstatus_t Parcel::setData(const uint8_t* buffer, size_t len)
3570d6db582f2ccc9f8943c5f3965e2994b7d137158Eric Laurent{
3580d6db582f2ccc9f8943c5f3965e2994b7d137158Eric Laurent    status_t err = restartWrite(len);
3590d6db582f2ccc9f8943c5f3965e2994b7d137158Eric Laurent    if (err == NO_ERROR) {
3600d6db582f2ccc9f8943c5f3965e2994b7d137158Eric Laurent        memcpy(const_cast<uint8_t*>(data()), buffer, len);
3610d6db582f2ccc9f8943c5f3965e2994b7d137158Eric Laurent        mDataSize = len;
3620d6db582f2ccc9f8943c5f3965e2994b7d137158Eric Laurent        mFdsKnown = false;
363b5ccb2d99b2af400c70777a6452f090ac14f5a96Glenn Kasten    }
364b5ccb2d99b2af400c70777a6452f090ac14f5a96Glenn Kasten    return err;
365b5ccb2d99b2af400c70777a6452f090ac14f5a96Glenn Kasten}
366b5ccb2d99b2af400c70777a6452f090ac14f5a96Glenn Kasten
367b5ccb2d99b2af400c70777a6452f090ac14f5a96Glenn Kastenstatus_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len)
368b5ccb2d99b2af400c70777a6452f090ac14f5a96Glenn Kasten{
369b5ccb2d99b2af400c70777a6452f090ac14f5a96Glenn Kasten    const sp<ProcessState> proc(ProcessState::self());
370b5ccb2d99b2af400c70777a6452f090ac14f5a96Glenn Kasten    status_t err;
371b5ccb2d99b2af400c70777a6452f090ac14f5a96Glenn Kasten    const uint8_t *data = parcel->mData;
372b5ccb2d99b2af400c70777a6452f090ac14f5a96Glenn Kasten    const binder_size_t *objects = parcel->mObjects;
37366e4635cb09fadcaccf912f37c387396c428378aGlenn Kasten    size_t size = parcel->mObjectsSize;
37466e4635cb09fadcaccf912f37c387396c428378aGlenn Kasten    int startPos = mDataPos;
37505632a5fa4b88ca474294887fc92a9fcdf0e2352Glenn Kasten    int firstIndex = -1, lastIndex = -2;
376396fabdb6efcdac5aea3d9f559d1beedf6a4cedcGlenn Kasten
377b603744e96b07b1d5bf745bde593fb2c025cefcfGlenn Kasten    if (len == 0) {
378d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        return NO_ERROR;
3799f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
380caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent
381caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent    // range checks against the source parcel size
382caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent    if ((offset > parcel->mDataSize)
383caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent            || (len > parcel->mDataSize)
384caf7f48a0ef558689d39aafd187c1571ff4128b4Eric Laurent            || (offset + len > parcel->mDataSize)) {
385d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen        return BAD_VALUE;
386d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen    }
387d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen
388462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen    // Count objects in range
389462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen    for (int i = 0; i < (int) size; i++) {
390462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen        size_t off = objects[i];
391462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen        if ((off >= offset) && (off < offset + len)) {
392d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen            if (firstIndex == -1) {
393d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen                firstIndex = i;
394d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen            }
395d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen            lastIndex = i;
396d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen        }
3972beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    }
398093000f7d11839b920e8dfaa42ed1d09f48e24b8Glenn Kasten    int numObjects = lastIndex - firstIndex + 1;
3994a4a0959bca78e03e3c3f486ba17829c28314d8cGlenn Kasten
400be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    if ((mDataSize+len) > mDataCapacity) {
401a997e7a7c5aa2fc7e95316218316f8b7b98786baGlenn Kasten        // grow data
402896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent        err = growData(len);
403a997e7a7c5aa2fc7e95316218316f8b7b98786baGlenn Kasten        if (err != NO_ERROR) {
404a997e7a7c5aa2fc7e95316218316f8b7b98786baGlenn Kasten            return err;
405a997e7a7c5aa2fc7e95316218316f8b7b98786baGlenn Kasten        }
40634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    }
4070d6db582f2ccc9f8943c5f3965e2994b7d137158Eric Laurent
408a997e7a7c5aa2fc7e95316218316f8b7b98786baGlenn Kasten    // append data
40934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    memcpy(mData + mDataPos, data + offset, len);
410a997e7a7c5aa2fc7e95316218316f8b7b98786baGlenn Kasten    mDataPos += len;
411b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    mDataSize += len;
412b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald
413a997e7a7c5aa2fc7e95316218316f8b7b98786baGlenn Kasten    err = NO_ERROR;
414a997e7a7c5aa2fc7e95316218316f8b7b98786baGlenn Kasten
41589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (numObjects > 0) {
41689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // grow objects
41734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        if (mObjectsCapacity < mObjectsSize + numObjects) {
41889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            int newSize = ((mObjectsSize + numObjects)*3)/2;
4199f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            binder_size_t *objects =
42089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
4214ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung            if (objects == (binder_size_t*)0) {
4224ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung                return NO_MEMORY;
4234ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung            }
42453c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung            mObjects = objects;
42589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mObjectsCapacity = newSize;
4262c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi        }
42789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
42889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // append and acquire objects
429200092b7f21d2b98f30b800e79d152636f9ba225Glenn Kasten        int idx = mObjectsSize;
430200092b7f21d2b98f30b800e79d152636f9ba225Glenn Kasten        for (int i = firstIndex; i <= lastIndex; i++) {
431200092b7f21d2b98f30b800e79d152636f9ba225Glenn Kasten            size_t off = objects[i] - offset + startPos;
4327f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung            mObjects[idx++] = off;
433d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen            mObjectsSize++;
4349f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
4359f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            flat_binder_object* flat
4369f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                = reinterpret_cast<flat_binder_object*>(mData + off);
4379f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            acquire_object(proc, *flat, this);
43889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
43989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (flat->type == BINDER_TYPE_FD) {
44089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                // If this is a file descriptor, we need to dup it so the
44189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                // new Parcel now owns its own fd, and can declare that we
44289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                // officially know we have fds.
443b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald                flat->handle = dup(flat->handle);
44489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                flat->cookie = 1;
445f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent                mHasFds = mFdsKnown = true;
446b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald                if (!mAllowFds) {
4479f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                    err = FDS_NOT_ALLOWED;
448b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald                }
4499f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            }
4501703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
4519f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
4522b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent
4539f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return err;
454b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald}
455b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald
456b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgeraldbool Parcel::pushAllowFds(bool allowFds)
457b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald{
458b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    const bool origValue = mAllowFds;
459200092b7f21d2b98f30b800e79d152636f9ba225Glenn Kasten    if (!allowFds) {
4609f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        mAllowFds = false;
4619f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
462200092b7f21d2b98f30b800e79d152636f9ba225Glenn Kasten    return origValue;
4637f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung}
4647f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung
4657f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hungvoid Parcel::restoreAllowFds(bool lastValue)
4667f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung{
4677f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung    mAllowFds = lastValue;
4687f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung}
469ec9a032c2e104ab1e3b5bf73e69dab1408ced0adEric Laurent
470ec9a032c2e104ab1e3b5bf73e69dab1408ced0adEric Laurentbool Parcel::hasFileDescriptors() const
471ec9a032c2e104ab1e3b5bf73e69dab1408ced0adEric Laurent{
47289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (!mFdsKnown) {
473200092b7f21d2b98f30b800e79d152636f9ba225Glenn Kasten        scanForFds();
47496f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten    }
47589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mHasFds;
47689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
4779f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
478b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald// Write RPC headers.  (previously just the interface token)
479b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgeraldstatus_t Parcel::writeInterfaceToken(const String16& interface)
480b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald{
481b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    writeInt32(IPCThreadState::self()->getStrictModePolicy() |
482b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald               STRICT_MODE_PENALTY_GATHER);
4839f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // currently the interface identification token is just its name as a string
4849f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return writeString16(interface);
4859f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
4869f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
4879f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenbool Parcel::checkInterface(IBinder* binder) const
48889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
4899f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return enforceInterface(binder->getInterfaceDescriptor());
4909f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
4919f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
4929f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenbool Parcel::enforceInterface(const String16& interface,
4939f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                              IPCThreadState* threadState) const
49489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
4959f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    int32_t strictPolicy = readInt32();
4969f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (threadState == NULL) {
4979f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        threadState = IPCThreadState::self();
4989f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
4999f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if ((threadState->getLastTransactionBinderFlags() &
5009f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten         IBinder::FLAG_ONEWAY) != 0) {
5019f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten      // For one-way calls, the callee is running entirely
5029f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten      // disconnected from the caller, so disable StrictMode entirely.
50389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      // Not only does disk/network usage not impact the caller, but
504b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald      // there's no way to commuicate back any violations anyway.
505b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald      threadState->setStrictModePolicy(0);
506b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    } else {
50789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      threadState->setStrictModePolicy(strictPolicy);
508879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten    }
509a636433cbd09c0708b85f337ef45c0cdef3bcb4dGlenn Kasten    const String16 str(readString16());
51089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (str == interface) {
51189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return true;
51289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else {
513b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald        ALOGW("**** enforceInterface() expected '%s' but read '%s'\n",
5149f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                String8(interface).string(), String8(str).string());
5159f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        return false;
5169f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
5179f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
5189f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
519397edb3377e5775f4df60afb8bf6d4711e5adc0eGlenn Kastenconst binder_size_t* Parcel::objects() const
5209f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten{
5219f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return mObjects;
5229f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
52323a7545c4de71e989c2d8ebf1d5b9dcf463c36a9Glenn Kasten
524b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgeraldsize_t Parcel::objectsCount() const
525b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald{
526b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    return mObjectsSize;
527c2813e568aa476e03d159529c0af28c99536db8dAndy Hung}
528b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald
529b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgeraldstatus_t Parcel::errorCheck() const
5309f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten{
5319f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return mError;
5329f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
5339f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
5349f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenvoid Parcel::setError(status_t err)
5359b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung{
5369f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    mError = err;
5379b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung}
5389b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung
5399b4615887c23548438fd0d8e3d8f04ac21912850Andy Hungstatus_t Parcel::finishWrite(size_t len)
5409f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten{
541b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    //printf("Finish write of %d\n", len);
5429f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    mDataPos += len;
5439f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ALOGV("finishWrite Setting data pos of %p to %d\n", this, mDataPos);
54423a7545c4de71e989c2d8ebf1d5b9dcf463c36a9Glenn Kasten    if (mDataPos > mDataSize) {
545b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald        mDataSize = mDataPos;
546b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald        ALOGV("finishWrite Setting data size of %p to %d\n", this, mDataSize);
5479f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
5489f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
5499f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return NO_ERROR;
5509f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
55189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
55289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t Parcel::writeUnpadded(const void* data, size_t len)
55389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
55489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    size_t end = mDataPos + len;
5559a2aaf927e56a4b4acab23ef16b3f133a9f48a63Glenn Kasten    if (end < mDataPos) {
5569f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        // integer overflow
55789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return BAD_VALUE;
55889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
55989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
56089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (end <= mDataCapacity) {
5619f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenrestart_write:
5629f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        memcpy(mData+mDataPos, data, len);
5639f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        return finishWrite(len);
5641703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    }
5659f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
5669f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    status_t err = growData(len);
5674bae3649d504d590a546717a8e49f96a30d9a745Glenn Kasten    if (err == NO_ERROR) goto restart_write;
5689f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return err;
5691703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent}
5701703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
5711703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentstatus_t Parcel::write(const void* data, size_t len)
5721703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent{
5739f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    void* const d = writeInplace(len);
574c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    if (d) {
5752c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi        memcpy(d, data, len);
5762c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi        return NO_ERROR;
5772c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi    }
5782c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi    return mError;
579b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald}
580c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent
5819f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenvoid* Parcel::writeInplace(size_t len)
582c2813e568aa476e03d159529c0af28c99536db8dAndy Hung{
58323a7545c4de71e989c2d8ebf1d5b9dcf463c36a9Glenn Kasten    const size_t padded = PAD_SIZE(len);
584b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald
585b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    // sanity check for integer overflow
5869f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (mDataPos+padded < mDataPos) {
5874bae3649d504d590a546717a8e49f96a30d9a745Glenn Kasten        return NULL;
58889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
58989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
59089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if ((mDataPos+padded) <= mDataCapacity) {
59189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectrestart_write:
592f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent        //printf("Writing %ld bytes, padded to %ld\n", len, padded);
593b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald        uint8_t* const data = mData+mDataPos;
594b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald
595b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald        // Need to pad at end?
596b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald        if (padded != len) {
597b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald#if BYTE_ORDER == BIG_ENDIAN
5989f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            static const uint32_t mask[4] = {
59989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                0x00000000, 0xffffff00, 0xffff0000, 0xff000000
6009f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            };
6019f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#endif
6027064fd2dcdfeafea53cd5a992bb78c413542f29fHaynes Mathew George#if BYTE_ORDER == LITTLE_ENDIAN
6033a90f2849d49bf65f2d6257fd6da30ae46d745faMarco Nelissen            static const uint32_t mask[4] = {
604142f519aa1acd5804d111e60d100f170fed28405Glenn Kasten                0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
6057f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung            };
6067f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung#endif
6077f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung            //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
6087f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung            //    *reinterpret_cast<void**>(data+padded-4));
6097f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung            *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
6107f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung        }
6117f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung
6127f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung        finishWrite(padded);
6137f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung        return data;
6147f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung    }
6157f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung
6167064fd2dcdfeafea53cd5a992bb78c413542f29fHaynes Mathew George    status_t err = growData(padded);
6177064fd2dcdfeafea53cd5a992bb78c413542f29fHaynes Mathew George    if (err == NO_ERROR) goto restart_write;
6187064fd2dcdfeafea53cd5a992bb78c413542f29fHaynes Mathew George    return NULL;
6197064fd2dcdfeafea53cd5a992bb78c413542f29fHaynes Mathew George}
6207064fd2dcdfeafea53cd5a992bb78c413542f29fHaynes Mathew George
62189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t Parcel::writeInt32(int32_t val)
62289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
623be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    return writeAligned(val);
62489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
625c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kastenstatus_t Parcel::writeInt32Array(size_t len, const int32_t *val) {
626c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    if (!val) {
627c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten        return writeAligned(-1);
628be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    }
629be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    status_t ret = writeAligned(len);
630be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    if (ret == NO_ERROR) {
6311703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        ret = write(val, len * sizeof(*val));
63266e4635cb09fadcaccf912f37c387396c428378aGlenn Kasten    }
63366e4635cb09fadcaccf912f37c387396c428378aGlenn Kasten    return ret;
63489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
635c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kastenstatus_t Parcel::writeByteArray(size_t len, const uint8_t *val) {
636be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    if (!val) {
63723a7545c4de71e989c2d8ebf1d5b9dcf463c36a9Glenn Kasten        return writeAligned(-1);
63859fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent    }
63959fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent    status_t ret = writeAligned(len);
640be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    if (ret == NO_ERROR) {
64189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        ret = write(val, len * sizeof(*val));
64289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
643b1c0993b215c5c3eebd1c6bafc22bba23d57a70bGlenn Kasten    return ret;
64489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
645b1c0993b215c5c3eebd1c6bafc22bba23d57a70bGlenn Kasten
646be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurentstatus_t Parcel::writeInt64(int64_t val)
647be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent{
6482beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    return writeAligned(val);
649be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent}
650c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten
651c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kastenstatus_t Parcel::writePointer(uintptr_t val)
652be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent{
653be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    return writeAligned<binder_uintptr_t>(val);
654be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent}
6559f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
656be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurentstatus_t Parcel::writeFloat(float val)
657e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten{
658be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    return writeAligned(val);
659be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent}
660be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent
661be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent#if defined(__mips__) && defined(__mips_hard_float)
662a5224f319e2ba4b51ddb4287705ccf8d4b8ecc51Glenn Kasten
663be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurentstatus_t Parcel::writeDouble(double val)
664be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent{
6659f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    union {
666be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        double d;
66789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        unsigned long long ll;
66889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } u;
6693b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kasten    u.d = val;
67089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return writeAligned(u.ll);
671ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent}
6724ff14bae91075eb274eb1c2975982358946e7e63John Grossman
6734ff14bae91075eb274eb1c2975982358946e7e63John Grossman#else
6744ff14bae91075eb274eb1c2975982358946e7e63John Grossman
6750d6db582f2ccc9f8943c5f3965e2994b7d137158Eric Laurentstatus_t Parcel::writeDouble(double val)
6760d6db582f2ccc9f8943c5f3965e2994b7d137158Eric Laurent{
6770d6db582f2ccc9f8943c5f3965e2994b7d137158Eric Laurent    return writeAligned(val);
6780d6db582f2ccc9f8943c5f3965e2994b7d137158Eric Laurent}
6799f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
6800d6db582f2ccc9f8943c5f3965e2994b7d137158Eric Laurent#endif
681573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent
68289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t Parcel::writeIntPtr(intptr_t val)
683cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung{
684d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    return writeAligned(val);
685d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten}
68689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
687e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenstatus_t Parcel::writeCString(const char* str)
688e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten{
689e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    return write(str, strlen(str)+1);
690573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent}
69189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
69289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t Parcel::writeString8(const String8& str)
693a5224f319e2ba4b51ddb4287705ccf8d4b8ecc51Glenn Kasten{
69489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    status_t err = writeInt32(str.bytes());
6954ff14bae91075eb274eb1c2975982358946e7e63John Grossman    // only write string if its length is more than zero characters,
6963b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kasten    // as readString8 will only read if the length field is non-zero.
6974ff14bae91075eb274eb1c2975982358946e7e63John Grossman    // this is slightly different from how writeString16 works.
6984ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (str.bytes() > 0 && err == NO_ERROR) {
6991703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        err = write(str.string(), str.bytes()+1);
7006f59db12a64f4496866952a251122ccb77a36c6bEric Laurent    }
7016f59db12a64f4496866952a251122ccb77a36c6bEric Laurent    return err;
7026f59db12a64f4496866952a251122ccb77a36c6bEric Laurent}
7036f59db12a64f4496866952a251122ccb77a36c6bEric Laurent
704ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurentstatus_t Parcel::writeString16(const String16& str)
705142f519aa1acd5804d111e60d100f170fed28405Glenn Kasten{
7066f59db12a64f4496866952a251122ccb77a36c6bEric Laurent    return writeString16(str.string(), str.size());
707b7f24b101d43139b4c747129bfbc4ecf5c468b86Jean-Michel Trivi}
7086f59db12a64f4496866952a251122ccb77a36c6bEric Laurent
7096f59db12a64f4496866952a251122ccb77a36c6bEric Laurentstatus_t Parcel::writeString16(const char16_t* str, size_t len)
7106f59db12a64f4496866952a251122ccb77a36c6bEric Laurent{
7116f59db12a64f4496866952a251122ccb77a36c6bEric Laurent    if (str == NULL) return writeInt32(-1);
7126f59db12a64f4496866952a251122ccb77a36c6bEric Laurent
713e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    status_t err = writeInt32(len);
71489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (err == NO_ERROR) {
71589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        len *= sizeof(char16_t);
71689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
71789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (data) {
718ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent            memcpy(data, str, len);
719083d1c1492d496960d5b28f4664ff02101736677Glenn Kasten            *reinterpret_cast<char16_t*>(data+len) = 0;
720083d1c1492d496960d5b28f4664ff02101736677Glenn Kasten            return NO_ERROR;
721083d1c1492d496960d5b28f4664ff02101736677Glenn Kasten        }
72289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        err = mError;
7239f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
7249f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return err;
7259f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
7269f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
7279f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenstatus_t Parcel::writeStrongBinder(const sp<IBinder>& val)
72889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
72989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return flatten_binder(ProcessState::self(), val, this);
73089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
7319f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
7329f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenstatus_t Parcel::writeWeakBinder(const wp<IBinder>& val)
7339f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten{
7349f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return flatten_binder(ProcessState::self(), val, this);
735c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent}
7369f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
73789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t Parcel::writeNativeHandle(const native_handle* handle)
73889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
73989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (!handle || handle->version != sizeof(native_handle))
7409f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        return BAD_TYPE;
7419f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
7424ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    status_t err;
7434ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    err = writeInt32(handle->numFds);
7444ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    if (err != NO_ERROR) return err;
7454ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung
7464ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    err = writeInt32(handle->numInts);
74753c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung    if (err != NO_ERROR) return err;
7489f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
7493c09c78aabcb9d314dfb400258fb99a37c7b50c9Andy Hung    for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++)
7503c09c78aabcb9d314dfb400258fb99a37c7b50c9Andy Hung        err = writeDupFileDescriptor(handle->data[i]);
7519f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
7529f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (err != NO_ERROR) {
75389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        ALOGD("write native handle, write dup fd failed");
75489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return err;
755fb1fdc9d6603aa228362e7349451f6455c9849c2Glenn Kasten    }
756ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent    err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
757d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    return err;
758d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten}
75989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
7609f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenstatus_t Parcel::writeFileDescriptor(int fd, bool takeOwnership)
76189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
7622c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi    flat_binder_object obj;
76389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    obj.type = BINDER_TYPE_FD;
7643c09c78aabcb9d314dfb400258fb99a37c7b50c9Andy Hung    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
7653c09c78aabcb9d314dfb400258fb99a37c7b50c9Andy Hung    obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
7663c09c78aabcb9d314dfb400258fb99a37c7b50c9Andy Hung    obj.handle = fd;
7673c09c78aabcb9d314dfb400258fb99a37c7b50c9Andy Hung    obj.cookie = takeOwnership ? 1 : 0;
76889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return writeObject(obj, true);
76989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
77089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
771a5224f319e2ba4b51ddb4287705ccf8d4b8ecc51Glenn Kastenstatus_t Parcel::writeDupFileDescriptor(int fd)
77289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
773ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent    int dupFd = dup(fd);
774b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    if (dupFd < 0) {
775b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald        return -errno;
776d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    }
777d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/);
778d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    if (err) {
77989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        close(dupFd);
7809f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
78189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return err;
78289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
78389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
78489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// WARNING: This method must stay in sync with
78589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Parcelable.Creator<ParcelFileDescriptor> CREATOR
78689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// in frameworks/base/core/java/android/os/ParcelFileDescriptor.java
78789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t Parcel::writeParcelFileDescriptor(int fd, int commChannel) {
788fb1fdc9d6603aa228362e7349451f6455c9849c2Glenn Kasten    status_t status;
789ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent
790d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    if (fd < 0) {
791d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        status = writeInt32(0); // ParcelFileDescriptor is null
79289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (status) return status;
7939f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    } else {
794200092b7f21d2b98f30b800e79d152636f9ba225Glenn Kasten        status = writeInt32(1); // ParcelFileDescriptor is not null
79589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (status) return status;
7962b2165c75790050810460c8de3f414876bce4c0eGlenn Kasten        status = writeDupFileDescriptor(fd);
7973c09c78aabcb9d314dfb400258fb99a37c7b50c9Andy Hung        if (status) return status;
7983c09c78aabcb9d314dfb400258fb99a37c7b50c9Andy Hung        if (commChannel < 0) {
7993c09c78aabcb9d314dfb400258fb99a37c7b50c9Andy Hung            status = writeInt32(0); // commChannel is null
8003c09c78aabcb9d314dfb400258fb99a37c7b50c9Andy Hung            if (status) return status;
80189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else {
80289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            status = writeInt32(1); // commChannel is not null
80389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (status) return status;
804a5224f319e2ba4b51ddb4287705ccf8d4b8ecc51Glenn Kasten            status = writeDupFileDescriptor(commChannel);
80589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
806ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent    }
807b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    return status;
808b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald}
809d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten
810d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kastenstatus_t Parcel::writeBlob(size_t len, WritableBlob* outBlob)
811d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten{
81289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    status_t status;
8139f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
81489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (!mAllowFds || len <= IN_PLACE_BLOB_LIMIT) {
81589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        ALOGV("writeBlob: write in place");
81689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        status = writeInt32(0);
81789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (status) return status;
81889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
81989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        void* ptr = writeInplace(len);
82089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (!ptr) return NO_MEMORY;
821ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent
822d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        outBlob->init(false /*mapped*/, ptr, len);
823d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        return NO_ERROR;
8249f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
8259c6745f128648f6e0144b74ee593911a9fa10d51Glenn Kasten
8269c6745f128648f6e0144b74ee593911a9fa10d51Glenn Kasten    ALOGV("writeBlob: write to ashmem");
8279c6745f128648f6e0144b74ee593911a9fa10d51Glenn Kasten    int fd = ashmem_create_region("Parcel Blob", len);
8289f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (fd < 0) return NO_MEMORY;
8299f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
8309f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
8319f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (result < 0) {
8329f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        status = result;
8339f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    } else {
8349f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        void* ptr = ::mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
8359f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        if (ptr == MAP_FAILED) {
8369f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            status = -errno;
837d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        } else {
8389b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            result = ashmem_set_prot_region(fd, PROT_READ);
839200092b7f21d2b98f30b800e79d152636f9ba225Glenn Kasten            if (result < 0) {
8409b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung                status = result;
8413c09c78aabcb9d314dfb400258fb99a37c7b50c9Andy Hung            } else {
8423c09c78aabcb9d314dfb400258fb99a37c7b50c9Andy Hung                status = writeInt32(1);
84389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                if (!status) {
84489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    status = writeFileDescriptor(fd, true /*takeOwnership*/);
84589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    if (!status) {
846200092b7f21d2b98f30b800e79d152636f9ba225Glenn Kasten                        outBlob->init(true /*mapped*/, ptr, len);
84789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                        return NO_ERROR;
848d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                    }
849d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                }
850d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            }
8519f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        }
8521703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        ::munmap(ptr, len);
853ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent    }
854b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    ::close(fd);
85589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return status;
856ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent}
8577064fd2dcdfeafea53cd5a992bb78c413542f29fHaynes Mathew George
8587064fd2dcdfeafea53cd5a992bb78c413542f29fHaynes Mathew Georgestatus_t Parcel::write(const FlattenableHelperInterface& val)
8597064fd2dcdfeafea53cd5a992bb78c413542f29fHaynes Mathew George{
8607064fd2dcdfeafea53cd5a992bb78c413542f29fHaynes Mathew George    status_t err;
8617064fd2dcdfeafea53cd5a992bb78c413542f29fHaynes Mathew George
862142f519aa1acd5804d111e60d100f170fed28405Glenn Kasten    // size if needed
863b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    const size_t len = val.getFlattenedSize();
864b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    const size_t fd_count = val.getFdCount();
865b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald
8667f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung    err = this->writeInt32(len);
8677f1bc8af1c46695191bf7e2aba6467f3616629c0Andy Hung    if (err) return err;
868b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald
869b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    err = this->writeInt32(fd_count);
870275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    if (err) return err;
871275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
872275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    // payload
873275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    void* const buf = this->writeInplace(PAD_SIZE(len));
874b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    if (buf == NULL)
875200092b7f21d2b98f30b800e79d152636f9ba225Glenn Kasten        return BAD_VALUE;
876200092b7f21d2b98f30b800e79d152636f9ba225Glenn Kasten
877b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    int* fds = NULL;
87889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (fd_count) {
87989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        fds = new int[fd_count];
88089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
881377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT
8829c6745f128648f6e0144b74ee593911a9fa10d51Glenn Kasten    err = val.flatten(buf, len, fds, fd_count);
8839c6745f128648f6e0144b74ee593911a9fa10d51Glenn Kasten    for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
8849c6745f128648f6e0144b74ee593911a9fa10d51Glenn Kasten        err = this->writeDupFileDescriptor( fds[i] );
8859c6745f128648f6e0144b74ee593911a9fa10d51Glenn Kasten    }
8869c6745f128648f6e0144b74ee593911a9fa10d51Glenn Kasten
8879c6745f128648f6e0144b74ee593911a9fa10d51Glenn Kasten    if (fd_count) {
8889c6745f128648f6e0144b74ee593911a9fa10d51Glenn Kasten        delete [] fds;
8899c6745f128648f6e0144b74ee593911a9fa10d51Glenn Kasten    }
8909f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
8919f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return err;
8929c6745f128648f6e0144b74ee593911a9fa10d51Glenn Kasten}
8939c6745f128648f6e0144b74ee593911a9fa10d51Glenn Kasten
8949c6745f128648f6e0144b74ee593911a9fa10d51Glenn Kastenstatus_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
89589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
89689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
897ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent    const bool enoughObjects = mObjectsSize < mObjectsCapacity;
898083d1c1492d496960d5b28f4664ff02101736677Glenn Kasten    if (enoughData && enoughObjects) {
899083d1c1492d496960d5b28f4664ff02101736677Glenn Kastenrestart_write:
900083d1c1492d496960d5b28f4664ff02101736677Glenn Kasten        *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
9011703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
9029f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        // Need to write meta-data?
9039f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        if (nullMetaData || val.binder != 0) {
904d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            mObjects[mObjectsSize] = mDataPos;
905d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            acquire_object(ProcessState::self(), val, this);
9069f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            mObjectsSize++;
9079b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung        }
9089b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung
90953c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung        // remember if it's a file descriptor
9109b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung        if (val.type == BINDER_TYPE_FD) {
91153c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung            if (!mAllowFds) {
91253c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung                return FDS_NOT_ALLOWED;
91353c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung            }
91453c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung            mHasFds = mFdsKnown = true;
91553c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung        }
91653c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung
91753c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung        return finishWrite(sizeof(flat_binder_object));
9189b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    }
91989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
92089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (!enoughData) {
92189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        const status_t err = growData(sizeof(val));
92238e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten        if (err != NO_ERROR) return err;
923c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    }
9241703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    if (!enoughObjects) {
925b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald        size_t newSize = ((mObjectsSize+2)*3)/2;
9261703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
9271703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (objects == NULL) return NO_MEMORY;
928be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        mObjects = objects;
929be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        mObjectsCapacity = newSize;
9309f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
9312beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent
9322beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    goto restart_write;
9332beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent}
9342beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent
9352beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurentstatus_t Parcel::writeNoException()
936be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent{
937be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    return writeInt32(0);
938e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent}
939e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent
940e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurentvoid Parcel::remove(size_t /*start*/, size_t /*amt*/)
941e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent{
942e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
943e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent}
944e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent
945e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurentstatus_t Parcel::read(void* outData, size_t len) const
94689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
94789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize
9481703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            && len <= PAD_SIZE(len)) {
949200092b7f21d2b98f30b800e79d152636f9ba225Glenn Kasten        memcpy(outData, mData+mDataPos, len);
95034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        mDataPos += PAD_SIZE(len);
95134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        ALOGV("read Setting data pos of %p to %d\n", this, mDataPos);
95234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        return NO_ERROR;
953e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    }
954e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    return NOT_ENOUGH_DATA;
95534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent}
95634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent
957e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurentconst void* Parcel::readInplace(size_t len) const
958e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent{
959e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize
960e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent            && len <= PAD_SIZE(len)) {
961e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        const void* data = mData+mDataPos;
962e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        mDataPos += PAD_SIZE(len);
963e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        ALOGV("readInplace Setting data pos of %p to %d\n", this, mDataPos);
964e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        return data;
965e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    }
966e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    return NULL;
9675bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi}
9685bd3f38638acab633d181359cc9ec27b80f84d43Jean-Michel Trivi
969e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurenttemplate<class T>
97038e905b3cbba4da443d799b16999989781afc6d8Glenn Kastenstatus_t Parcel::readAligned(T *pArg) const {
97138e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
97238e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten
97338e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten    if ((mDataPos+sizeof(T)) <= mDataSize) {
97438e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten        const void* data = mData+mDataPos;
97538e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten        mDataPos += sizeof(T);
976ce8828a016b082f730152af2204b8ea3610dc1ecGlenn Kasten        *pArg =  *reinterpret_cast<const T*>(data);
977ce8828a016b082f730152af2204b8ea3610dc1ecGlenn Kasten        return NO_ERROR;
978d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent    } else {
979241618f1b286f9e7e02fe61e96d9194e2e1e8a7aGlenn Kasten        return NOT_ENOUGH_DATA;
980ce8828a016b082f730152af2204b8ea3610dc1ecGlenn Kasten    }
9819f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
98238e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten
983d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurenttemplate<class T>
984d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric LaurentT Parcel::readAligned() const {
985ce8828a016b082f730152af2204b8ea3610dc1ecGlenn Kasten    T result;
986b7f24b101d43139b4c747129bfbc4ecf5c468b86Jean-Michel Trivi    if (readAligned(&result) != NO_ERROR) {
987ce8828a016b082f730152af2204b8ea3610dc1ecGlenn Kasten        result = 0;
988b7f24b101d43139b4c747129bfbc4ecf5c468b86Jean-Michel Trivi    }
98938e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten
990ce8828a016b082f730152af2204b8ea3610dc1ecGlenn Kasten    return result;
991ce8828a016b082f730152af2204b8ea3610dc1ecGlenn Kasten}
992ce8828a016b082f730152af2204b8ea3610dc1ecGlenn Kasten
993b7f24b101d43139b4c747129bfbc4ecf5c468b86Jean-Michel Trivitemplate<class T>
994ce8828a016b082f730152af2204b8ea3610dc1ecGlenn Kastenstatus_t Parcel::writeAligned(T val) {
995b7f24b101d43139b4c747129bfbc4ecf5c468b86Jean-Michel Trivi    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
99638e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten
997ce8828a016b082f730152af2204b8ea3610dc1ecGlenn Kasten    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
9980d6db582f2ccc9f8943c5f3965e2994b7d137158Eric Laurentrestart_write:
9990d6db582f2ccc9f8943c5f3965e2994b7d137158Eric Laurent        *reinterpret_cast<T*>(mData+mDataPos) = val;
10000d6db582f2ccc9f8943c5f3965e2994b7d137158Eric Laurent        return finishWrite(sizeof(val));
10014a4a0959bca78e03e3c3f486ba17829c28314d8cGlenn Kasten    }
10024a4a0959bca78e03e3c3f486ba17829c28314d8cGlenn Kasten
100343bdc1de363a3c72c7dcf9c9a898bac109dc7cb5Glenn Kasten    status_t err = growData(sizeof(val));
10044a4a0959bca78e03e3c3f486ba17829c28314d8cGlenn Kasten    if (err == NO_ERROR) goto restart_write;
10054a4a0959bca78e03e3c3f486ba17829c28314d8cGlenn Kasten    return err;
1006363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kasten}
1007c6ba823a397abf865b02f4f48fe18231f94d8e87Glenn Kasten
10081dfe2f9c2d03fc8d0ed0cdfe0b9fb894bc0bcc11Glenn Kastenstatus_t Parcel::readInt32(int32_t *pArg) const
10091dfe2f9c2d03fc8d0ed0cdfe0b9fb894bc0bcc11Glenn Kasten{
10101dfe2f9c2d03fc8d0ed0cdfe0b9fb894bc0bcc11Glenn Kasten    return readAligned(pArg);
101143bdc1de363a3c72c7dcf9c9a898bac109dc7cb5Glenn Kasten}
101243bdc1de363a3c72c7dcf9c9a898bac109dc7cb5Glenn Kasten
10133acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kastenint32_t Parcel::readInt32() const
1014093000f7d11839b920e8dfaa42ed1d09f48e24b8Glenn Kasten{
1015363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kasten    return readAligned<int32_t>();
10164a4a0959bca78e03e3c3f486ba17829c28314d8cGlenn Kasten}
1017e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten
10184a4a0959bca78e03e3c3f486ba17829c28314d8cGlenn Kasten
1019ce8828a016b082f730152af2204b8ea3610dc1ecGlenn Kastenstatus_t Parcel::readInt64(int64_t *pArg) const
1020b5fed68bcdd6f44424c9e4d12bfe9a3ff51bd62eGlenn Kasten{
1021b5fed68bcdd6f44424c9e4d12bfe9a3ff51bd62eGlenn Kasten    return readAligned(pArg);
10220e48d25606c82def035ad10a5b3923767a765cddAndy Hung}
10230e48d25606c82def035ad10a5b3923767a765cddAndy Hung
10240e48d25606c82def035ad10a5b3923767a765cddAndy Hung
1025ce8828a016b082f730152af2204b8ea3610dc1ecGlenn Kastenint64_t Parcel::readInt64() const
1026d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent{
1027e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    return readAligned<int64_t>();
1028363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kasten}
1029363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kasten
1030e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kastenstatus_t Parcel::readPointer(uintptr_t *pArg) const
1031363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kasten{
1032e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    status_t ret;
1033363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kasten    binder_uintptr_t ptr;
1034e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    ret = readAligned(&ptr);
1035e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    if (!ret)
1036d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        *pArg = ptr;
1037b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    return ret;
1038b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald}
1039b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald
1040363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kastenuintptr_t Parcel::readPointer() const
1041abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung{
1042abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung    return readAligned<binder_uintptr_t>();
1043abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung}
1044abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung
1045b773038277ba328696832b690b91ce6e95bd1a6cGlenn Kasten
1046abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hungstatus_t Parcel::readFloat(float *pArg) const
1047b773038277ba328696832b690b91ce6e95bd1a6cGlenn Kasten{
1048b773038277ba328696832b690b91ce6e95bd1a6cGlenn Kasten    return readAligned(pArg);
1049a42ff007a17d63df22c60dd5e5fd811ee45ca1b3Glenn Kasten}
1050e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten
1051e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten
1052e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kastenfloat Parcel::readFloat() const
10531d6fa7af1288b550faabe4ec2cf98684236723dbNarayan Kamath{
1054a42ff007a17d63df22c60dd5e5fd811ee45ca1b3Glenn Kasten    return readAligned<float>();
1055363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kasten}
105638e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten
105738e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten#if defined(__mips__) && defined(__mips_hard_float)
1058e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten
1059e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kastenstatus_t Parcel::readDouble(double *pArg) const
1060e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten{
1061e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    union {
1062e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten      double d;
1063e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten      unsigned long long ll;
1064abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung    } u;
1065e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    u.d = 0;
10660e48d25606c82def035ad10a5b3923767a765cddAndy Hung    status_t status;
10670e48d25606c82def035ad10a5b3923767a765cddAndy Hung    status = readAligned(&u.ll);
1068d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent    *pArg = u.d;
1069d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent    return status;
1070a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kasten}
1071a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kasten
1072a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kastendouble Parcel::readDouble() const
1073a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kasten{
10743acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    union {
10753acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten      double d;
1076363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kasten      unsigned long long ll;
10774a4a0959bca78e03e3c3f486ba17829c28314d8cGlenn Kasten    } u;
10783acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    u.ll = readAligned<unsigned long long>();
10793acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    return u.d;
10803acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten}
10814a4a0959bca78e03e3c3f486ba17829c28314d8cGlenn Kasten
10824a4a0959bca78e03e3c3f486ba17829c28314d8cGlenn Kasten#else
1083363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kasten
1084b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgeraldstatus_t Parcel::readDouble(double *pArg) const
1085b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald{
1086b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    return readAligned(pArg);
1087ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent}
1088ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent
1089ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurentdouble Parcel::readDouble() const
1090ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent{
109174935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten    return readAligned<double>();
109274935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten}
1093e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent
1094363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kasten#endif
1095abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung
1096a42ff007a17d63df22c60dd5e5fd811ee45ca1b3Glenn Kastenstatus_t Parcel::readIntPtr(intptr_t *pArg) const
109774935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten{
1098e0b07179a48ee50fda931d2aa1b3c751d167e4d7Glenn Kasten    return readAligned(pArg);
1099363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kasten}
110034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent
11013acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten
1102be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurentintptr_t Parcel::readIntPtr() const
1103462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen{
110434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    return readAligned<intptr_t>();
110534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent}
1106c08d20b6a37122ebf116262c9372509ed060d4c1Glenn Kasten
110729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block
110838e905b3cbba4da443d799b16999989781afc6d8Glenn Kastenconst char* Parcel::readCString() const
110934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent{
1110c08d20b6a37122ebf116262c9372509ed060d4c1Glenn Kasten    const size_t avail = mDataSize-mDataPos;
1111c08d20b6a37122ebf116262c9372509ed060d4c1Glenn Kasten    if (avail > 0) {
111238e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten        const char* str = reinterpret_cast<const char*>(mData+mDataPos);
111338e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten        // is the string's trailing NUL within the parcel's valid bounds?
111438e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten        const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
1115d2c38fc4d5dc742d7441444316849510dd2b7363Glenn Kasten        if (eos) {
1116d2c38fc4d5dc742d7441444316849510dd2b7363Glenn Kasten            const size_t len = eos - str;
111729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            mDataPos += PAD_SIZE(len+1);
111834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent            ALOGV("readCString Setting data pos of %p to %d\n", this, mDataPos);
111934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent            return str;
11200cde076ddb283c84c3801a2df4cc3df99bd1577fGlenn Kasten        }
11210cde076ddb283c84c3801a2df4cc3df99bd1577fGlenn Kasten    }
11220cde076ddb283c84c3801a2df4cc3df99bd1577fGlenn Kasten    return NULL;
11230cde076ddb283c84c3801a2df4cc3df99bd1577fGlenn Kasten}
11240cde076ddb283c84c3801a2df4cc3df99bd1577fGlenn Kasten
112553cec22821072719ee02c856e9ac2dda2496c570Glenn KastenString8 Parcel::readString8() const
11269f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten{
1127f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen    int32_t size = readInt32();
11289f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // watch for potential int overflow adding 1 for trailing NUL
11299f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (size > 0 && size < INT32_MAX) {
113034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        const char* str = (const char*)readInplace(size+1);
1131d2c38fc4d5dc742d7441444316849510dd2b7363Glenn Kasten        if (str) return String8(str, size);
11323bcffa136909c1fb6e88ee4efd12ccac18360a85Eric Laurent    }
11333bcffa136909c1fb6e88ee4efd12ccac18360a85Eric Laurent    return String8();
11340cde076ddb283c84c3801a2df4cc3df99bd1577fGlenn Kasten}
1135d2c38fc4d5dc742d7441444316849510dd2b7363Glenn Kasten
113674935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn KastenString16 Parcel::readString16() const
1137b603744e96b07b1d5bf745bde593fb2c025cefcfGlenn Kasten{
1138b603744e96b07b1d5bf745bde593fb2c025cefcfGlenn Kasten    size_t len;
1139b603744e96b07b1d5bf745bde593fb2c025cefcfGlenn Kasten    const char16_t* str = readString16Inplace(&len);
1140b603744e96b07b1d5bf745bde593fb2c025cefcfGlenn Kasten    if (str) return String16(str, len);
114134fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn    ALOGE("Reading a NULL string not supported here.");
1142b603744e96b07b1d5bf745bde593fb2c025cefcfGlenn Kasten    return String16();
1143b603744e96b07b1d5bf745bde593fb2c025cefcfGlenn Kasten}
11445f631515d098c29603cda88f7a7e7580a2d55b57Glenn Kasten
1145a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kastenconst char16_t* Parcel::readString16Inplace(size_t* outLen) const
1146363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kasten{
1147e0b07179a48ee50fda931d2aa1b3c751d167e4d7Glenn Kasten    int32_t size = readInt32();
114834fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn    // watch for potential int overflow from size+1
1149a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kasten    if (size >= 0 && size < INT32_MAX) {
11503acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten        *outLen = size;
115134fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn        const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
1152093000f7d11839b920e8dfaa42ed1d09f48e24b8Glenn Kasten        if (str != NULL) {
1153363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kasten            return str;
1154e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten        }
11553acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    }
1156363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kasten    *outLen = 0;
1157b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    return NULL;
1158b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald}
1159b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald
1160b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgeraldsp<IBinder> Parcel::readStrongBinder() const
1161363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kasten{
116238e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten    sp<IBinder> val;
116338e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten    unflatten_binder(ProcessState::self(), *this, &val);
1164b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    return val;
1165b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald}
1166ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent
1167ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurentwp<IBinder> Parcel::readWeakBinder() const
1168ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent{
1169ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent    wp<IBinder> val;
1170ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent    unflatten_binder(ProcessState::self(), *this, &val);
1171ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent    return val;
1172ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent}
1173ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent
1174ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurentint32_t Parcel::readExceptionCode() const
1175ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent{
11760e48d25606c82def035ad10a5b3923767a765cddAndy Hung  int32_t exception_code = readAligned<int32_t>();
11770e48d25606c82def035ad10a5b3923767a765cddAndy Hung  if (exception_code == EX_HAS_REPLY_HEADER) {
11780e48d25606c82def035ad10a5b3923767a765cddAndy Hung    int32_t header_start = dataPosition();
11790e48d25606c82def035ad10a5b3923767a765cddAndy Hung    int32_t header_size = readAligned<int32_t>();
11800e48d25606c82def035ad10a5b3923767a765cddAndy Hung    // Skip over fat responses headers.  Not used (or propagated) in
11810e48d25606c82def035ad10a5b3923767a765cddAndy Hung    // native code
11820e48d25606c82def035ad10a5b3923767a765cddAndy Hung    setDataPosition(header_start + header_size);
11830e48d25606c82def035ad10a5b3923767a765cddAndy Hung    // And fat response headers are currently only used when there are no
11840e48d25606c82def035ad10a5b3923767a765cddAndy Hung    // exceptions, so return no error:
11850e48d25606c82def035ad10a5b3923767a765cddAndy Hung    return 0;
1186b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald  }
118738e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten  return exception_code;
118838e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten}
11899f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
11909f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastennative_handle* Parcel::readNativeHandle() const
11919f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten{
11929f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    int numFds, numInts;
11939f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    status_t err;
11949f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    err = readInt32(&numFds);
11959f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (err != NO_ERROR) return 0;
1196363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kasten    err = readInt32(&numInts);
11979f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (err != NO_ERROR) return 0;
119834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent
1199363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kasten    native_handle* h = native_handle_create(numFds, numInts);
120034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
120134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        h->data[i] = dup(readFileDescriptor());
12022beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent        if (h->data[i] < 0) err = BAD_VALUE;
1203e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten    }
1204363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kasten    err = read(h->data + numFds, sizeof(int)*numInts);
12055f631515d098c29603cda88f7a7e7580a2d55b57Glenn Kasten    if (err != NO_ERROR) {
1206b603744e96b07b1d5bf745bde593fb2c025cefcfGlenn Kasten        native_handle_close(h);
1207093000f7d11839b920e8dfaa42ed1d09f48e24b8Glenn Kasten        native_handle_delete(h);
1208093000f7d11839b920e8dfaa42ed1d09f48e24b8Glenn Kasten        h = 0;
1209b603744e96b07b1d5bf745bde593fb2c025cefcfGlenn Kasten    }
1210b603744e96b07b1d5bf745bde593fb2c025cefcfGlenn Kasten    return h;
1211093000f7d11839b920e8dfaa42ed1d09f48e24b8Glenn Kasten}
1212e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
1213e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
1214363fb75db26698cbb50065506e0c80b61d1fbf92Glenn Kastenint Parcel::readFileDescriptor() const
12159f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten{
1216abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung    const flat_binder_object* flat = readObject(true);
12179f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (flat) {
1218abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung        switch (flat->type) {
12199f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            case BINDER_TYPE_FD:
12209f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                //ALOGI("Returning file descriptor %ld from parcel %p\n", flat->handle, this);
1221e6a9d65845032644b0865b6e3d0b5a820f35d9e4seunghak.han                return flat->handle;
1222e6a9d65845032644b0865b6e3d0b5a820f35d9e4seunghak.han        }
1223e6a9d65845032644b0865b6e3d0b5a820f35d9e4seunghak.han    }
1224e6a9d65845032644b0865b6e3d0b5a820f35d9e4seunghak.han    return BAD_TYPE;
1225e6a9d65845032644b0865b6e3d0b5a820f35d9e4seunghak.han}
1226e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
1227e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// WARNING: This method must stay in sync with writeToParcel()
12289f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten// in frameworks/base/core/java/android/os/ParcelFileDescriptor.java
12299f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenint Parcel::readParcelFileDescriptor(int& outCommChannel) const {
12309f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    int fd;
1231f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen    outCommChannel = -1;
1232e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
123334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    if (readInt32() == 0) {
123438e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten        fd = -1;
123538e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten    } else {
123638e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten        fd = readFileDescriptor();
1237e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent        if (fd >= 0 && readInt32() != 0) {
123838e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten            outCommChannel = readFileDescriptor();
123938e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten        }
124038e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten    }
124138e905b3cbba4da443d799b16999989781afc6d8Glenn Kasten    return fd;
124234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent}
124334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent
1244b46f394a85d704dd05287cf9bb77cf86e3c02a38Glenn Kastenstatus_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
124589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
12469f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    int32_t useAshmem;
12479f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    status_t status = readInt32(&useAshmem);
12489f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (status) return status;
12499f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
12509f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (!useAshmem) {
12519f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        ALOGV("readBlob: read in place");
12529f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        const void* ptr = readInplace(len);
12539f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        if (!ptr) return BAD_VALUE;
12549f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
12559f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        outBlob->init(false /*mapped*/, const_cast<void*>(ptr), len);
12569f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        return NO_ERROR;
1257df576995a5aad3428aeeef765387d650945c161dEric Laurent    }
12589f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
12599f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ALOGV("readBlob: read from ashmem");
12609f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    int fd = readFileDescriptor();
12619f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (fd == int(BAD_TYPE)) return BAD_VALUE;
12629f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
12639f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    void* ptr = ::mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
12649f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (!ptr) return NO_MEMORY;
12659f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
12669f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    outBlob->init(true /*mapped*/, ptr, len);
12679f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return NO_ERROR;
12689f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
12699f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
12709f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenstatus_t Parcel::read(FlattenableHelperInterface& val) const
1271b46f394a85d704dd05287cf9bb77cf86e3c02a38Glenn Kasten{
12729f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // size
12739f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    const size_t len = this->readInt32();
12749f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    const size_t fd_count = this->readInt32();
12759f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
12769f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // payload
12779f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    void const* const buf = this->readInplace(PAD_SIZE(len));
12789f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (buf == NULL)
12799f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        return BAD_VALUE;
1280e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
12819f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    int* fds = NULL;
12829f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (fd_count) {
128389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        fds = new int[fd_count];
12849f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
12859f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
128689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    status_t err = NO_ERROR;
12879f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
12889f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        fds[i] = dup(this->readFileDescriptor());
12899f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        if (fds[i] < 0) {
12909f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            err = BAD_VALUE;
12919f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            ALOGE("dup() failed in Parcel::read, i is %d, fds[i] is %d, fd_count is %d, error: %s",
129289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                i, fds[i], fd_count, strerror(errno));
12939f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        }
12949f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
12951703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
12969f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (err == NO_ERROR) {
12979f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        err = val.unflatten(buf, len, fds, fd_count);
12989f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
12999f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
13009f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (fd_count) {
13019f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        delete [] fds;
13029f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
1303b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald
1304b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    return err;
1305b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald}
13069f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenconst flat_binder_object* Parcel::readObject(bool nullMetaData) const
130789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
130889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const size_t DPOS = mDataPos;
13099f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
13109f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        const flat_binder_object* obj
1311c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent                = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
13129f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        mDataPos = DPOS + sizeof(flat_binder_object);
13139f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        if (!nullMetaData && (obj->cookie == 0 && obj->binder == 0)) {
13149f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            // When transferring a NULL object, we don't write it into
13159f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            // the object list, so we don't want to check for it when
1316b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald            // reading.
1317b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald            ALOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
1318b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald            return obj;
1319b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald        }
1320b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald
1321b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald        // Ensure that this object is valid...
1322b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald        binder_size_t* const OBJS = mObjects;
1323b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald        const size_t N = mObjectsSize;
13249f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        size_t opos = mNextObjectHint;
13259f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
13269f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        if (N > 0) {
132789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            ALOGV("Parcel %p looking for obj at %d, hint=%d\n",
132889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                 this, DPOS, opos);
13299f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
1330c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent            // Start at the current hint position, looking for an object at
13319f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            // the current data position.
13329f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            if (opos < N) {
13339f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                while (opos < (N-1) && OBJS[opos] < DPOS) {
133489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    opos++;
13359f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                }
133689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            } else {
13379f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                opos = N-1;
1338abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung            }
13399f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            if (OBJS[opos] == DPOS) {
13409f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                // Found it!
13419f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                ALOGV("Parcel found obj %d at index %d with forward search",
134289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                     this, DPOS, opos);
13439f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                mNextObjectHint = opos+1;
134489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                ALOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
134589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                return obj;
134654a8a456c2b4b382b3ffe3d99e40703df79c0717Glenn Kasten            }
134789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
13483f02be2ceeaa4b67dc0b1a81aebcfa049276fad8Glenn Kasten            // Look backwards for it...
13499f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            while (opos > 0 && OBJS[opos] > DPOS) {
13509f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                opos--;
13519f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            }
13529f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            if (OBJS[opos] == DPOS) {
1353abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung                // Found it!
13549f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                ALOGV("Parcel found obj %d at index %d with backward search",
13559f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                     this, DPOS, opos);
13569f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                mNextObjectHint = opos+1;
13579f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                ALOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
13589f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                return obj;
13599f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            }
13609f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        }
1361e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        ALOGW("Attempt to read object from Parcel %p at offset %zu that is not in the object list",
13621703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent             this, DPOS);
1363200092b7f21d2b98f30b800e79d152636f9ba225Glenn Kasten    }
13649f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return NULL;
13659f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
13669f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
13679f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenvoid Parcel::closeFileDescriptors()
13689f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten{
13699f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    size_t i = mObjectsSize;
137096f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten    if (i > 0) {
1371c5a17425986b4ce3384e6956762c86018b49c4a0Glenn Kasten        //ALOGI("Closing file descriptors for %d objects...", mObjectsSize);
13729f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
1373df839841d2db4cb8e2acb10205b3942622b3e7a2Eric Laurent    while (i > 0) {
1374df839841d2db4cb8e2acb10205b3942622b3e7a2Eric Laurent        i--;
1375df839841d2db4cb8e2acb10205b3942622b3e7a2Eric Laurent        const flat_binder_object* flat
137689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
137789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (flat->type == BINDER_TYPE_FD) {
137889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            //ALOGI("Closing fd: %ld\n", flat->handle);
137989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            close(flat->handle);
1380720ad9ddb2ac6b55b0dfbfcd2d8360151d8ac427Jean-Michel Trivi        }
138189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
13829f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
1383d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten
1384d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kastenuintptr_t Parcel::ipcData() const
138589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
1386ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent    return reinterpret_cast<uintptr_t>(mData);
1387ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent}
1388ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent
1389ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurentsize_t Parcel::ipcDataSize() const
1390ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent{
1391ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent    return (mDataSize > mDataPos ? mDataSize : mDataPos);
1392ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent}
1393ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent
1394ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurentuintptr_t Parcel::ipcObjects() const
1395ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent{
13969f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return reinterpret_cast<uintptr_t>(mObjects);
139799e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten}
139899e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten
1399377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETITsize_t Parcel::ipcObjectsCount() const
140089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
140189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mObjectsSize;
140289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
14039f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
140489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
140589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
14069f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten{
14079f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    binder_size_t minOffset = 0;
1408c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    freeDataNoInit();
1409720ad9ddb2ac6b55b0dfbfcd2d8360151d8ac427Jean-Michel Trivi    mError = NO_ERROR;
1410720ad9ddb2ac6b55b0dfbfcd2d8360151d8ac427Jean-Michel Trivi    mData = const_cast<uint8_t*>(data);
141189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mDataSize = mDataCapacity = dataSize;
14129f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)\n", this, mDataSize, getpid());
141389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mDataPos = 0;
1414d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    ALOGV("setDataReference Setting data pos of %p to %d\n", this, mDataPos);
141589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mObjects = const_cast<binder_size_t*>(objects);
141689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mObjectsSize = mObjectsCapacity = objectsCount;
141789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mNextObjectHint = 0;
141889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mOwner = relFunc;
1419abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung    mOwnerCookie = relCookie;
1420abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung    for (size_t i = 0; i < mObjectsSize; i++) {
14219f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        binder_size_t offset = mObjects[i];
142289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (offset < minOffset) {
142389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            ALOGE("%s: bad object offset %"PRIu64" < %"PRIu64"\n",
142489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                  __func__, (uint64_t)offset, (uint64_t)minOffset);
142589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mObjectsSize = 0;
14269f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            break;
142789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
142889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        minOffset = offset + sizeof(flat_binder_object);
142989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
143089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    scanForFds();
143189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
143289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
14334ff14bae91075eb274eb1c2975982358946e7e63John Grossmanvoid Parcel::print(TextOutput& to, uint32_t /*flags*/) const
14344ff14bae91075eb274eb1c2975982358946e7e63John Grossman{
14354ff14bae91075eb274eb1c2975982358946e7e63John Grossman    to << "Parcel(";
14364ff14bae91075eb274eb1c2975982358946e7e63John Grossman
14374ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (errorCheck() != NO_ERROR) {
14384ff14bae91075eb274eb1c2975982358946e7e63John Grossman        const status_t err = errorCheck();
1439d5ed6e88a9bea1879e41d7defaf1edea7c09f554Glenn Kasten        to << "Error: " << (void*)(intptr_t)err << " \"" << strerror(-err) << "\"";
14404ff14bae91075eb274eb1c2975982358946e7e63John Grossman    } else if (dataSize() > 0) {
14414ff14bae91075eb274eb1c2975982358946e7e63John Grossman        const uint8_t* DATA = data();
14429f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        to << indent << HexDump(DATA, dataSize()) << dedent;
1443d5ed6e88a9bea1879e41d7defaf1edea7c09f554Glenn Kasten        const binder_size_t* OBJS = objects();
1444d5ed6e88a9bea1879e41d7defaf1edea7c09f554Glenn Kasten        const size_t N = objectsCount();
1445d5ed6e88a9bea1879e41d7defaf1edea7c09f554Glenn Kasten        for (size_t i=0; i<N; i++) {
1446d5ed6e88a9bea1879e41d7defaf1edea7c09f554Glenn Kasten            const flat_binder_object* flat
14479f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
1448d5ed6e88a9bea1879e41d7defaf1edea7c09f554Glenn Kasten            to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
14494ff14bae91075eb274eb1c2975982358946e7e63John Grossman                << TypeCode(flat->type & 0x7f7f7f00)
14504ff14bae91075eb274eb1c2975982358946e7e63John Grossman                << " = " << flat->binder;
1451c3ae93f21280859086ae371428ffd32f39e76d50Glenn Kasten        }
1452d2c38fc4d5dc742d7441444316849510dd2b7363Glenn Kasten    } else {
145396f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten        to << "NULL";
14544ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
14554ff14bae91075eb274eb1c2975982358946e7e63John Grossman
145696f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten    to << ")";
14574ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
14584ff14bae91075eb274eb1c2975982358946e7e63John Grossman
14594ff14bae91075eb274eb1c2975982358946e7e63John Grossmanvoid Parcel::releaseObjects()
14604ff14bae91075eb274eb1c2975982358946e7e63John Grossman{
14614ff14bae91075eb274eb1c2975982358946e7e63John Grossman    const sp<ProcessState> proc(ProcessState::self());
146296f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten    size_t i = mObjectsSize;
14639f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    uint8_t* const data = mData;
14644ff14bae91075eb274eb1c2975982358946e7e63John Grossman    binder_size_t* const objects = mObjects;
14659f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    while (i > 0) {
14664ff14bae91075eb274eb1c2975982358946e7e63John Grossman        i--;
1467d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        const flat_binder_object* flat
14684ff14bae91075eb274eb1c2975982358946e7e63John Grossman            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
14694ff14bae91075eb274eb1c2975982358946e7e63John Grossman        release_object(proc, *flat, this);
14704ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
14714ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
14724ff14bae91075eb274eb1c2975982358946e7e63John Grossman
14734ff14bae91075eb274eb1c2975982358946e7e63John Grossmanvoid Parcel::acquireObjects()
14744ff14bae91075eb274eb1c2975982358946e7e63John Grossman{
14754ff14bae91075eb274eb1c2975982358946e7e63John Grossman    const sp<ProcessState> proc(ProcessState::self());
1476df839841d2db4cb8e2acb10205b3942622b3e7a2Eric Laurent    size_t i = mObjectsSize;
1477df839841d2db4cb8e2acb10205b3942622b3e7a2Eric Laurent    uint8_t* const data = mData;
1478df839841d2db4cb8e2acb10205b3942622b3e7a2Eric Laurent    binder_size_t* const objects = mObjects;
1479d2c38fc4d5dc742d7441444316849510dd2b7363Glenn Kasten    while (i > 0) {
1480df839841d2db4cb8e2acb10205b3942622b3e7a2Eric Laurent        i--;
1481df839841d2db4cb8e2acb10205b3942622b3e7a2Eric Laurent        const flat_binder_object* flat
148296f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
148396f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten        acquire_object(proc, *flat, this);
1484df839841d2db4cb8e2acb10205b3942622b3e7a2Eric Laurent    }
14859f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
1486df839841d2db4cb8e2acb10205b3942622b3e7a2Eric Laurent
1487df839841d2db4cb8e2acb10205b3942622b3e7a2Eric Laurentvoid Parcel::freeData()
14884ff14bae91075eb274eb1c2975982358946e7e63John Grossman{
1489df839841d2db4cb8e2acb10205b3942622b3e7a2Eric Laurent    freeDataNoInit();
14904ff14bae91075eb274eb1c2975982358946e7e63John Grossman    initState();
14914ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
14924ff14bae91075eb274eb1c2975982358946e7e63John Grossman
14934ff14bae91075eb274eb1c2975982358946e7e63John Grossmanvoid Parcel::freeDataNoInit()
14944ff14bae91075eb274eb1c2975982358946e7e63John Grossman{
14954ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (mOwner) {
14964ff14bae91075eb274eb1c2975982358946e7e63John Grossman        //ALOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
14974ff14bae91075eb274eb1c2975982358946e7e63John Grossman        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
14984ff14bae91075eb274eb1c2975982358946e7e63John Grossman    } else {
14994ff14bae91075eb274eb1c2975982358946e7e63John Grossman        releaseObjects();
15007c7be1e05634d96d08210efb4bdeb012ffba440dGlenn Kasten        if (mData) free(mData);
150189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (mObjects) free(mObjects);
1502fb1fdc9d6603aa228362e7349451f6455c9849c2Glenn Kasten    }
1503fb1fdc9d6603aa228362e7349451f6455c9849c2Glenn Kasten}
1504fb1fdc9d6603aa228362e7349451f6455c9849c2Glenn Kasten
1505fb1fdc9d6603aa228362e7349451f6455c9849c2Glenn Kastenstatus_t Parcel::growData(size_t len)
1506fb1fdc9d6603aa228362e7349451f6455c9849c2Glenn Kasten{
15071703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    size_t newSize = ((mDataSize+len)*3)/2;
1508a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kasten    return (newSize <= mDataSize)
1509a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kasten            ? (status_t) NO_MEMORY
1510a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kasten            : continueWrite(newSize);
1511a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kasten}
1512a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kasten
1513a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kastenstatus_t Parcel::restartWrite(size_t desired)
1514a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kasten{
1515a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kasten    if (mOwner) {
1516a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kasten        freeData();
1517a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kasten        return continueWrite(desired);
1518a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kasten    }
1519a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kasten
1520a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kasten    uint8_t* data = (uint8_t*)realloc(mData, desired);
1521a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kasten    if (!data && desired > mDataCapacity) {
1522a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kasten        mError = NO_MEMORY;
1523a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kasten        return NO_MEMORY;
1524a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kasten    }
1525b0dfd4613225a3b2a17bdf8d85e89a4b04d65ef3Glenn Kasten
1526b0dfd4613225a3b2a17bdf8d85e89a4b04d65ef3Glenn Kasten    releaseObjects();
1527a07f17ca46db04c9d5d9e7d6b2878db59ca2b9eaGlenn Kasten
15281703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    if (data) {
15299f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        mData = data;
15309f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        mDataCapacity = desired;
153196f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten    }
1532a47f3165f53c8e8fb8907a94de7417e2c3047eebGlenn Kasten
15339f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    mDataSize = mDataPos = 0;
15349f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ALOGV("restartWrite Setting data size of %p to %d\n", this, mDataSize);
1535b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    ALOGV("restartWrite Setting data pos of %p to %d\n", this, mDataPos);
1536b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald
1537b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    free(mObjects);
1538ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent    mObjects = NULL;
1539b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    mObjectsSize = mObjectsCapacity = 0;
154053c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung    mNextObjectHint = 0;
154153c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung    mHasFds = false;
1542b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    mFdsKnown = true;
154389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mAllowFds = true;
1544c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent
1545b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    return NO_ERROR;
15469f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
154789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
15489f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenstatus_t Parcel::continueWrite(size_t desired)
15499f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten{
15509f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // If shrinking, first adjust for any objects that appear
15519f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // after the new data size.
15529f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    size_t objectsSize = mObjectsSize;
15539f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (desired < mDataSize) {
15549f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        if (desired == 0) {
15559f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            objectsSize = 0;
15569f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        } else {
15579f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            while (objectsSize > 0) {
15589f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                if (mObjects[objectsSize-1] < desired)
15599f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                    break;
15609f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                objectsSize--;
15619f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            }
15629f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        }
15639f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
15649f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
15659f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (mOwner) {
156689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // If the size is going to zero, just release the owner's data.
156789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (desired == 0) {
15689f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            freeData();
1569200092b7f21d2b98f30b800e79d152636f9ba225Glenn Kasten            return NO_ERROR;
15709f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        }
157189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
15729f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        // If there is a different owner, we need to take
15739f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        // posession.
15749f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        uint8_t* data = (uint8_t*)malloc(desired);
15759f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        if (!data) {
15769f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            mError = NO_MEMORY;
15779f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            return NO_MEMORY;
15789f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        }
15799f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        binder_size_t* objects = NULL;
15809f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
15819f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        if (objectsSize) {
15829f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            objects = (binder_size_t*)malloc(objectsSize*sizeof(binder_size_t));
15839f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            if (!objects) {
15849f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                free(data);
15859f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
15869f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                mError = NO_MEMORY;
15879f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                return NO_MEMORY;
15889f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            }
15899f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
15909f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            // Little hack to only acquire references on objects
1591838b3d8bafa4a781e277870dee4e0390165cff52Glenn Kasten            // we will be keeping.
15929f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            size_t oldObjectsSize = mObjectsSize;
15939f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            mObjectsSize = objectsSize;
15949f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            acquireObjects();
15959f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            mObjectsSize = oldObjectsSize;
15969f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        }
15979f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
1598b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald        if (mData) {
159996f04886d1c1bfbc422e2be033ea66be83e42441Glenn Kasten            memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
16009f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        }
160153c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung        if (objects && mObjects) {
160253c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung            memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t));
160353c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung        }
160453c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung        //ALOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
160553c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
160653c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung        mOwner = NULL;
160753c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung
160853c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung        mData = data;
160953c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung        mObjects = objects;
161053c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung        mDataSize = (mDataSize < desired) ? mDataSize : desired;
161153c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung        ALOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
161253c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung        mDataCapacity = desired;
161353c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung        mObjectsSize = mObjectsCapacity = objectsSize;
161453c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung        mNextObjectHint = 0;
161553c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung
161653c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung    } else if (mData) {
161753c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung        if (objectsSize < mObjectsSize) {
161853c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung            // Need to release refs on any objects we are dropping.
161953c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung            const sp<ProcessState> proc(ProcessState::self());
162053c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung            for (size_t i=objectsSize; i<mObjectsSize; i++) {
162153c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung                const flat_binder_object* flat
162253c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung                    = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
16239f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                if (flat->type == BINDER_TYPE_FD) {
1624abdb990953ffe94a9dc544aea0bed17ef7d5f484Andy Hung                    // will need to rescan because we may have lopped off the only FDs
16259f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                    mFdsKnown = false;
16269f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                }
16279f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                release_object(proc, *flat, this);
16289f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            }
1629b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald            binder_size_t* objects =
1630b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald                (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
1631b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald            if (objects) {
1632b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald                mObjects = objects;
1633b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald            }
163496f04886d1c1bfbc422e2be033ea66be83e42441Glenn Kasten            mObjectsSize = objectsSize;
1635b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald            mNextObjectHint = 0;
1636b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald        }
1637b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald
1638b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald        // We own the data, so we can just do a realloc().
1639b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald        if (desired > mDataCapacity) {
164096f04886d1c1bfbc422e2be033ea66be83e42441Glenn Kasten            uint8_t* data = (uint8_t*)realloc(mData, desired);
164196f04886d1c1bfbc422e2be033ea66be83e42441Glenn Kasten            if (data) {
164296f04886d1c1bfbc422e2be033ea66be83e42441Glenn Kasten                mData = data;
164396f04886d1c1bfbc422e2be033ea66be83e42441Glenn Kasten                mDataCapacity = desired;
164496f04886d1c1bfbc422e2be033ea66be83e42441Glenn Kasten            } else if (desired > mDataCapacity) {
164596f04886d1c1bfbc422e2be033ea66be83e42441Glenn Kasten                mError = NO_MEMORY;
164696f04886d1c1bfbc422e2be033ea66be83e42441Glenn Kasten                return NO_MEMORY;
164796f04886d1c1bfbc422e2be033ea66be83e42441Glenn Kasten            }
1648c2813e568aa476e03d159529c0af28c99536db8dAndy Hung        } else {
1649b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald            if (mDataSize > desired) {
1650b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald                mDataSize = desired;
165196f04886d1c1bfbc422e2be033ea66be83e42441Glenn Kasten                ALOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
165296f04886d1c1bfbc422e2be033ea66be83e42441Glenn Kasten            }
165396f04886d1c1bfbc422e2be033ea66be83e42441Glenn Kasten            if (mDataPos > desired) {
165496f04886d1c1bfbc422e2be033ea66be83e42441Glenn Kasten                mDataPos = desired;
1655b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald                ALOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
165696f04886d1c1bfbc422e2be033ea66be83e42441Glenn Kasten            }
1657b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald        }
1658b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald
16599f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    } else {
16609f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        // This is the first data.  Easy!
16619f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        uint8_t* data = (uint8_t*)malloc(desired);
16629f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        if (!data) {
166353c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung            mError = NO_MEMORY;
16649f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            return NO_MEMORY;
166553c3b5fc1afe162a8669cb3d27d6bb14e1847e39Andy Hung        }
16669f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
16679f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        if(!(mDataCapacity == 0 && mObjects == NULL
16689f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten             && mObjectsCapacity == 0)) {
16699f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired);
16709f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        }
16719f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
16729f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        mData = data;
16739f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        mDataSize = mDataPos = 0;
16749f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        ALOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
16759f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        ALOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
16769f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        mDataCapacity = desired;
16779f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
16789f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
1679b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    return NO_ERROR;
16809f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
16819f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
16829f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenvoid Parcel::initState()
1683b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald{
1684ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent    mError = NO_ERROR;
1685b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    mData = 0;
1686b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    mDataSize = 0;
168789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mDataCapacity = 0;
168889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mDataPos = 0;
16899f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ALOGV("initState Setting data size of %p to %d\n", this, mDataSize);
16909f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ALOGV("initState Setting data pos of %p to %d\n", this, mDataPos);
16919f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    mObjects = NULL;
169289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mObjectsSize = 0;
169389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mObjectsCapacity = 0;
16949f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    mNextObjectHint = 0;
16959f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    mHasFds = false;
16969f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    mFdsKnown = true;
16979f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    mAllowFds = true;
16989f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    mOwner = NULL;
16999f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
17009f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
17012d85f097d653b21d1ff2c34f0b732c674d20ccc2Andy Hungvoid Parcel::scanForFds() const
17029f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten{
17039f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    bool hasFds = false;
17042d85f097d653b21d1ff2c34f0b732c674d20ccc2Andy Hung    for (size_t i=0; i<mObjectsSize; i++) {
17052d85f097d653b21d1ff2c34f0b732c674d20ccc2Andy Hung        const flat_binder_object* flat
170689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
170789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (flat->type == BINDER_TYPE_FD) {
17089f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            hasFds = true;
17099f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            break;
17109f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        }
17119f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
17122267ba18d0d2b2d4bd7f5411821ad89ac2659a88Eric Laurent    mHasFds = hasFds;
17132267ba18d0d2b2d4bd7f5411821ad89ac2659a88Eric Laurent    mFdsKnown = true;
17149f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
17159f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
17169f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten// --- Parcel::Blob ---
17179f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
17189f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn KastenParcel::Blob::Blob() :
17199f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        mMapped(false), mData(NULL), mSize(0) {
17209f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
17219f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
17229f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn KastenParcel::Blob::~Blob() {
17239f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    release();
17249f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
17259f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
172689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid Parcel::Blob::release() {
17279f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (mMapped && mData) {
17289f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        ::munmap(mData, mSize);
17299f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
17309f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    clear();
17319f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
17329f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
17339f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenvoid Parcel::Blob::init(bool mapped, void* data, size_t size) {
17349f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    mMapped = mapped;
17359f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    mData = data;
17369f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    mSize = size;
1737c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent}
17389f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
17399f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenvoid Parcel::Blob::clear() {
17409f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    mMapped = false;
17419f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    mData = NULL;
17429f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    mSize = 0;
174334fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn}
17449f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
17459f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}; // namespace android
174634fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn