154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project/*
254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project
354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *
454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * you may not use this file except in compliance with the License.
654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * You may obtain a copy of the License at
754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *
854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *
1054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * See the License for the specific language governing permissions and
1454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * limitations under the License.
1554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */
1654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
1754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#define LOG_TAG "Parcel"
1854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project//#define LOG_NDEBUG 0
1954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
200795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/Parcel.h>
2154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
2227b3a7a75960d026655f3acd1de8a672e80a5776Brad Fitzpatrick#include <binder/IPCThreadState.h>
230795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/Binder.h>
240795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/BpBinder.h>
2554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include <utils/Debug.h>
260795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/ProcessState.h>
2754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include <utils/Log.h>
2854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include <utils/String8.h>
2954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include <utils/String16.h>
3054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include <utils/TextOutput.h>
3154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include <utils/misc.h>
32c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian#include <utils/Flattenable.h>
336579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown#include <cutils/ashmem.h>
3454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
3525ba5b6564224dceefa086b5c439ef28dad530caMathias Agopian#include <private/binder/binder_module.h>
3654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
3754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include <stdio.h>
3854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include <stdlib.h>
3954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include <stdint.h>
406579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown#include <sys/mman.h>
4154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
4254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#ifndef INT32_MAX
4354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#define INT32_MAX ((int32_t)(2147483647))
4454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#endif
4554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
4654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#define LOG_REFS(...)
4754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project//#define LOG_REFS(...) LOG(LOG_DEBUG, "Parcel", __VA_ARGS__)
4854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
4954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project// ---------------------------------------------------------------------------
5054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
5154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#define PAD_SIZE(s) (((s)+3)&~3)
5254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
53727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick// Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER
54727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick#define STRICT_MODE_PENALTY_GATHER 0x100
55727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick
565b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick// Note: must be kept in sync with android/os/Parcel.java's EX_HAS_REPLY_HEADER
575b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick#define EX_HAS_REPLY_HEADER -128
585b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick
596579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown// Maximum size of a blob to transfer in-place.
606579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brownstatic const size_t IN_PLACE_BLOB_LIMIT = 40 * 1024;
616579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown
6254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project// XXX This can be made public if we want to provide
6354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project// support for typed data.
6454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstruct small_flat_data
6554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
6654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    uint32_t type;
6754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    uint32_t data;
6854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project};
6954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
7054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectnamespace android {
7154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
7254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid acquire_object(const sp<ProcessState>& proc,
7354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const flat_binder_object& obj, const void* who)
7454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
7554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    switch (obj.type) {
7654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        case BINDER_TYPE_BINDER:
7754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (obj.binder) {
7854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
7954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                static_cast<IBinder*>(obj.cookie)->incStrong(who);
8054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
8154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return;
8254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        case BINDER_TYPE_WEAK_BINDER:
8354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (obj.binder)
8454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                static_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who);
8554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return;
8654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        case BINDER_TYPE_HANDLE: {
8754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
8854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (b != NULL) {
8954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
9054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                b->incStrong(who);
9154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
9254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return;
9354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
9454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        case BINDER_TYPE_WEAK_HANDLE: {
9554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
9654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (b != NULL) b.get_refs()->incWeak(who);
9754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return;
9854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
9954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        case BINDER_TYPE_FD: {
10054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // intentionally blank -- nothing to do to acquire this, but we do
10154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // recognize it as a legitimate object type.
10254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return;
10354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
10454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
10554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
10654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    LOGD("Invalid object type 0x%08lx", obj.type);
10754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
10854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
10954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid release_object(const sp<ProcessState>& proc,
11054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const flat_binder_object& obj, const void* who)
11154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
11254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    switch (obj.type) {
11354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        case BINDER_TYPE_BINDER:
11454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (obj.binder) {
11554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
11654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                static_cast<IBinder*>(obj.cookie)->decStrong(who);
11754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
11854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return;
11954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        case BINDER_TYPE_WEAK_BINDER:
12054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (obj.binder)
12154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                static_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who);
12254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return;
12354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        case BINDER_TYPE_HANDLE: {
12454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
12554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (b != NULL) {
12654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
12754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                b->decStrong(who);
12854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
12954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return;
13054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
13154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        case BINDER_TYPE_WEAK_HANDLE: {
13254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
13354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (b != NULL) b.get_refs()->decWeak(who);
13454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return;
13554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
13654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        case BINDER_TYPE_FD: {
13754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (obj.cookie != (void*)0) close(obj.handle);
13854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return;
13954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
14054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
14154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
14254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    LOGE("Invalid object type 0x%08lx", obj.type);
14354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
14454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
14554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectinline static status_t finish_flatten_binder(
14654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const sp<IBinder>& binder, const flat_binder_object& flat, Parcel* out)
14754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
14854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return out->writeObject(flat, false);
14954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
15054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
15154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t flatten_binder(const sp<ProcessState>& proc,
15254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const sp<IBinder>& binder, Parcel* out)
15354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
15454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    flat_binder_object obj;
15554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
15654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
15754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (binder != NULL) {
15854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        IBinder *local = binder->localBinder();
15954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (!local) {
16054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            BpBinder *proxy = binder->remoteBinder();
16154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (proxy == NULL) {
16254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                LOGE("null proxy");
16354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
16454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const int32_t handle = proxy ? proxy->handle() : 0;
16554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            obj.type = BINDER_TYPE_HANDLE;
16654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            obj.handle = handle;
16754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            obj.cookie = NULL;
16854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        } else {
16954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            obj.type = BINDER_TYPE_BINDER;
17054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            obj.binder = local->getWeakRefs();
17154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            obj.cookie = local;
17254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
17354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    } else {
17454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        obj.type = BINDER_TYPE_BINDER;
17554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        obj.binder = NULL;
17654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        obj.cookie = NULL;
17754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
17854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
17954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return finish_flatten_binder(binder, obj, out);
18054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
18154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
18254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t flatten_binder(const sp<ProcessState>& proc,
18354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const wp<IBinder>& binder, Parcel* out)
18454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
18554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    flat_binder_object obj;
18654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
18754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
18854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (binder != NULL) {
18954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        sp<IBinder> real = binder.promote();
19054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (real != NULL) {
19154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            IBinder *local = real->localBinder();
19254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (!local) {
19354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                BpBinder *proxy = real->remoteBinder();
19454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                if (proxy == NULL) {
19554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    LOGE("null proxy");
19654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
19754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                const int32_t handle = proxy ? proxy->handle() : 0;
19854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                obj.type = BINDER_TYPE_WEAK_HANDLE;
19954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                obj.handle = handle;
20054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                obj.cookie = NULL;
20154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            } else {
20254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                obj.type = BINDER_TYPE_WEAK_BINDER;
20354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                obj.binder = binder.get_refs();
20454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                obj.cookie = binder.unsafe_get();
20554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
20654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return finish_flatten_binder(real, obj, out);
20754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
20854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
20954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // XXX How to deal?  In order to flatten the given binder,
21054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // we need to probe it for information, which requires a primary
21154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // reference...  but we don't have one.
21254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        //
21354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // The OpenBinder implementation uses a dynamic_cast<> here,
21454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // but we can't do that with the different reference counting
21554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // implementation we are using.
21654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        LOGE("Unable to unflatten Binder weak reference!");
21754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        obj.type = BINDER_TYPE_BINDER;
21854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        obj.binder = NULL;
21954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        obj.cookie = NULL;
22054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return finish_flatten_binder(NULL, obj, out);
22154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
22254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    } else {
22354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        obj.type = BINDER_TYPE_BINDER;
22454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        obj.binder = NULL;
22554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        obj.cookie = NULL;
22654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return finish_flatten_binder(NULL, obj, out);
22754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
22854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
22954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
23054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectinline static status_t finish_unflatten_binder(
23154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    BpBinder* proxy, const flat_binder_object& flat, const Parcel& in)
23254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
23354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return NO_ERROR;
23454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
23554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
23654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t unflatten_binder(const sp<ProcessState>& proc,
23754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const Parcel& in, sp<IBinder>* out)
23854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
23954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const flat_binder_object* flat = in.readObject(false);
24054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
24154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (flat) {
24254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        switch (flat->type) {
24354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            case BINDER_TYPE_BINDER:
24454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                *out = static_cast<IBinder*>(flat->cookie);
24554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                return finish_unflatten_binder(NULL, *flat, in);
24654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            case BINDER_TYPE_HANDLE:
24754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                *out = proc->getStrongProxyForHandle(flat->handle);
24854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                return finish_unflatten_binder(
24954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    static_cast<BpBinder*>(out->get()), *flat, in);
25054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
25154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
25254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return BAD_TYPE;
25354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
25454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
25554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t unflatten_binder(const sp<ProcessState>& proc,
25654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const Parcel& in, wp<IBinder>* out)
25754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
25854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const flat_binder_object* flat = in.readObject(false);
25954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
26054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (flat) {
26154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        switch (flat->type) {
26254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            case BINDER_TYPE_BINDER:
26354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                *out = static_cast<IBinder*>(flat->cookie);
26454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                return finish_unflatten_binder(NULL, *flat, in);
26554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            case BINDER_TYPE_WEAK_BINDER:
26654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                if (flat->binder != NULL) {
26754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    out->set_object_and_refs(
26854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        static_cast<IBinder*>(flat->cookie),
26954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        static_cast<RefBase::weakref_type*>(flat->binder));
27054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                } else {
27154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    *out = NULL;
27254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
27354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                return finish_unflatten_binder(NULL, *flat, in);
27454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            case BINDER_TYPE_HANDLE:
27554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            case BINDER_TYPE_WEAK_HANDLE:
27654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                *out = proc->getWeakProxyForHandle(flat->handle);
27754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                return finish_unflatten_binder(
27854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    static_cast<BpBinder*>(out->unsafe_get()), *flat, in);
27954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
28054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
28154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return BAD_TYPE;
28254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
28354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
28454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project// ---------------------------------------------------------------------------
28554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
28654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectParcel::Parcel()
28754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
28854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    initState();
28954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
29054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
29154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectParcel::~Parcel()
29254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
29354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    freeDataNoInit();
29454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
29554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
29654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectconst uint8_t* Parcel::data() const
29754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
29854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return mData;
29954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
30054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
30154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectsize_t Parcel::dataSize() const
30254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
30354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return (mDataSize > mDataPos ? mDataSize : mDataPos);
30454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
30554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
30654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectsize_t Parcel::dataAvail() const
30754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
30854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // TODO: decide what to do about the possibility that this can
30954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // report an available-data size that exceeds a Java int's max
31054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // positive value, causing havoc.  Fortunately this will only
31154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // happen if someone constructs a Parcel containing more than two
31254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // gigabytes of data, which on typical phone hardware is simply
31354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // not possible.
31454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return dataSize() - dataPosition();
31554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
31654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
31754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectsize_t Parcel::dataPosition() const
31854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
31954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return mDataPos;
32054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
32154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
32254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectsize_t Parcel::dataCapacity() const
32354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
32454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return mDataCapacity;
32554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
32654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
32754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::setDataSize(size_t size)
32854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
32954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    status_t err;
33054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    err = continueWrite(size);
33154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (err == NO_ERROR) {
33254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mDataSize = size;
33354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        LOGV("setDataSize Setting data size of %p to %d\n", this, mDataSize);
33454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
33554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return err;
33654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
33754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
33854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid Parcel::setDataPosition(size_t pos) const
33954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
34054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mDataPos = pos;
34154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mNextObjectHint = 0;
34254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
34354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
34454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::setDataCapacity(size_t size)
34554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
3460ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn    if (size > mDataCapacity) return continueWrite(size);
34754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return NO_ERROR;
34854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
34954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
35054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::setData(const uint8_t* buffer, size_t len)
35154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
35254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    status_t err = restartWrite(len);
35354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (err == NO_ERROR) {
35454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        memcpy(const_cast<uint8_t*>(data()), buffer, len);
35554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mDataSize = len;
35654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mFdsKnown = false;
35754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
35854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return err;
35954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
36054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
3610a47f4f711514ceb3e5f6d3ecdbc4c74f7b3bbefAndreas Huberstatus_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len)
36254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
36354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const sp<ProcessState> proc(ProcessState::self());
36454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    status_t err;
3650a47f4f711514ceb3e5f6d3ecdbc4c74f7b3bbefAndreas Huber    const uint8_t *data = parcel->mData;
3660a47f4f711514ceb3e5f6d3ecdbc4c74f7b3bbefAndreas Huber    const size_t *objects = parcel->mObjects;
36754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    size_t size = parcel->mObjectsSize;
36854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int startPos = mDataPos;
36954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int firstIndex = -1, lastIndex = -2;
37054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
37154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (len == 0) {
37254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return NO_ERROR;
37354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
37454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
37554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // range checks against the source parcel size
37654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if ((offset > parcel->mDataSize)
37754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            || (len > parcel->mDataSize)
37854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            || (offset + len > parcel->mDataSize)) {
37954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return BAD_VALUE;
38054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
38154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
38254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // Count objects in range
38354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    for (int i = 0; i < (int) size; i++) {
38454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        size_t off = objects[i];
38554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if ((off >= offset) && (off < offset + len)) {
38654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (firstIndex == -1) {
38754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                firstIndex = i;
38854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
38954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            lastIndex = i;
39054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
39154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
39254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int numObjects = lastIndex - firstIndex + 1;
39354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
3940ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn    if ((mDataSize+len) > mDataCapacity) {
3950ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn        // grow data
3960ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn        err = growData(len);
3970ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn        if (err != NO_ERROR) {
3980ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn            return err;
3990ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn        }
40054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
40154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
40254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // append data
40354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    memcpy(mData + mDataPos, data + offset, len);
40454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mDataPos += len;
40554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mDataSize += len;
40654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
4079ecebbfbf768fd63e9a6c9a09c86d81c7737ee2dDianne Hackborn    err = NO_ERROR;
4089ecebbfbf768fd63e9a6c9a09c86d81c7737ee2dDianne Hackborn
40954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (numObjects > 0) {
41054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // grow objects
41154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (mObjectsCapacity < mObjectsSize + numObjects) {
41254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            int newSize = ((mObjectsSize + numObjects)*3)/2;
41354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            size_t *objects =
41454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                (size_t*)realloc(mObjects, newSize*sizeof(size_t));
41554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (objects == (size_t*)0) {
41654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                return NO_MEMORY;
41754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
41854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mObjects = objects;
41954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mObjectsCapacity = newSize;
42054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
42154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
42254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // append and acquire objects
42354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int idx = mObjectsSize;
42454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        for (int i = firstIndex; i <= lastIndex; i++) {
42554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            size_t off = objects[i] - offset + startPos;
42654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mObjects[idx++] = off;
42754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mObjectsSize++;
42854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
4296aff905048ba3b03724f17e2aba9089872e14cd2Dianne Hackborn            flat_binder_object* flat
43054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                = reinterpret_cast<flat_binder_object*>(mData + off);
43154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            acquire_object(proc, *flat, this);
43254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
43354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (flat->type == BINDER_TYPE_FD) {
4346aff905048ba3b03724f17e2aba9089872e14cd2Dianne Hackborn                // If this is a file descriptor, we need to dup it so the
4356aff905048ba3b03724f17e2aba9089872e14cd2Dianne Hackborn                // new Parcel now owns its own fd, and can declare that we
4366aff905048ba3b03724f17e2aba9089872e14cd2Dianne Hackborn                // officially know we have fds.
4376aff905048ba3b03724f17e2aba9089872e14cd2Dianne Hackborn                flat->handle = dup(flat->handle);
4386aff905048ba3b03724f17e2aba9089872e14cd2Dianne Hackborn                flat->cookie = (void*)1;
43954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mHasFds = mFdsKnown = true;
4409ecebbfbf768fd63e9a6c9a09c86d81c7737ee2dDianne Hackborn                if (!mAllowFds) {
4419ecebbfbf768fd63e9a6c9a09c86d81c7737ee2dDianne Hackborn                    err = FDS_NOT_ALLOWED;
4429ecebbfbf768fd63e9a6c9a09c86d81c7737ee2dDianne Hackborn                }
44354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
44454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
44554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
44654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
4479ecebbfbf768fd63e9a6c9a09c86d81c7737ee2dDianne Hackborn    return err;
4489ecebbfbf768fd63e9a6c9a09c86d81c7737ee2dDianne Hackborn}
4499ecebbfbf768fd63e9a6c9a09c86d81c7737ee2dDianne Hackborn
450c04db7e06737c5b9bae276ac462858d44002672eDianne Hackbornbool Parcel::pushAllowFds(bool allowFds)
4519ecebbfbf768fd63e9a6c9a09c86d81c7737ee2dDianne Hackborn{
4529ecebbfbf768fd63e9a6c9a09c86d81c7737ee2dDianne Hackborn    const bool origValue = mAllowFds;
453c04db7e06737c5b9bae276ac462858d44002672eDianne Hackborn    if (!allowFds) {
454c04db7e06737c5b9bae276ac462858d44002672eDianne Hackborn        mAllowFds = false;
455c04db7e06737c5b9bae276ac462858d44002672eDianne Hackborn    }
4569ecebbfbf768fd63e9a6c9a09c86d81c7737ee2dDianne Hackborn    return origValue;
45754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
45854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
459c04db7e06737c5b9bae276ac462858d44002672eDianne Hackbornvoid Parcel::restoreAllowFds(bool lastValue)
460c04db7e06737c5b9bae276ac462858d44002672eDianne Hackborn{
461c04db7e06737c5b9bae276ac462858d44002672eDianne Hackborn    mAllowFds = lastValue;
462c04db7e06737c5b9bae276ac462858d44002672eDianne Hackborn}
463c04db7e06737c5b9bae276ac462858d44002672eDianne Hackborn
46454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectbool Parcel::hasFileDescriptors() const
46554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
46654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (!mFdsKnown) {
46754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        scanForFds();
46854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
46954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return mHasFds;
47054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
47154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
47227b3a7a75960d026655f3acd1de8a672e80a5776Brad Fitzpatrick// Write RPC headers.  (previously just the interface token)
47354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::writeInterfaceToken(const String16& interface)
47454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
475727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    writeInt32(IPCThreadState::self()->getStrictModePolicy() |
476727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick               STRICT_MODE_PENALTY_GATHER);
47754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // currently the interface identification token is just its name as a string
47854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return writeString16(interface);
47954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
48054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
481aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopianbool Parcel::checkInterface(IBinder* binder) const
482aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian{
48327b3a7a75960d026655f3acd1de8a672e80a5776Brad Fitzpatrick    return enforceInterface(binder->getInterfaceDescriptor());
484aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian}
485aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian
486727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrickbool Parcel::enforceInterface(const String16& interface,
4877bcad8a315f12bd6251a998781efac7b11c2ca84Brad Fitzpatrick                              IPCThreadState* threadState) const
48854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
4897bcad8a315f12bd6251a998781efac7b11c2ca84Brad Fitzpatrick    int32_t strictPolicy = readInt32();
4907bcad8a315f12bd6251a998781efac7b11c2ca84Brad Fitzpatrick    if (threadState == NULL) {
4917bcad8a315f12bd6251a998781efac7b11c2ca84Brad Fitzpatrick        threadState = IPCThreadState::self();
492727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    }
4930234376503ce421c4b871d5d811c541f5094301aBrad Fitzpatrick    if ((threadState->getLastTransactionBinderFlags() &
4940234376503ce421c4b871d5d811c541f5094301aBrad Fitzpatrick         IBinder::FLAG_ONEWAY) != 0) {
4950234376503ce421c4b871d5d811c541f5094301aBrad Fitzpatrick      // For one-way calls, the callee is running entirely
4960234376503ce421c4b871d5d811c541f5094301aBrad Fitzpatrick      // disconnected from the caller, so disable StrictMode entirely.
4970234376503ce421c4b871d5d811c541f5094301aBrad Fitzpatrick      // Not only does disk/network usage not impact the caller, but
4980234376503ce421c4b871d5d811c541f5094301aBrad Fitzpatrick      // there's no way to commuicate back any violations anyway.
4990234376503ce421c4b871d5d811c541f5094301aBrad Fitzpatrick      threadState->setStrictModePolicy(0);
5000234376503ce421c4b871d5d811c541f5094301aBrad Fitzpatrick    } else {
5010234376503ce421c4b871d5d811c541f5094301aBrad Fitzpatrick      threadState->setStrictModePolicy(strictPolicy);
5020234376503ce421c4b871d5d811c541f5094301aBrad Fitzpatrick    }
503aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian    const String16 str(readString16());
50454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (str == interface) {
50554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return true;
50654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    } else {
50754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        LOGW("**** enforceInterface() expected '%s' but read '%s'\n",
50854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                String8(interface).string(), String8(str).string());
50954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return false;
51054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
51127b3a7a75960d026655f3acd1de8a672e80a5776Brad Fitzpatrick}
51254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
51354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectconst size_t* Parcel::objects() const
51454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
51554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return mObjects;
51654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
51754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
51854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectsize_t Parcel::objectsCount() const
51954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
52054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return mObjectsSize;
52154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
52254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
52354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::errorCheck() const
52454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
52554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return mError;
52654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
52754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
52854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid Parcel::setError(status_t err)
52954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
53054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mError = err;
53154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
53254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
53354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::finishWrite(size_t len)
53454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
53554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    //printf("Finish write of %d\n", len);
53654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mDataPos += len;
53754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    LOGV("finishWrite Setting data pos of %p to %d\n", this, mDataPos);
53854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (mDataPos > mDataSize) {
53954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mDataSize = mDataPos;
54054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        LOGV("finishWrite Setting data size of %p to %d\n", this, mDataSize);
54154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
54254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
54354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return NO_ERROR;
54454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
54554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
54654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::writeUnpadded(const void* data, size_t len)
54754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
54854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    size_t end = mDataPos + len;
54954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (end < mDataPos) {
55054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // integer overflow
55154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return BAD_VALUE;
55254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
55354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
55454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (end <= mDataCapacity) {
55554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectrestart_write:
55654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        memcpy(mData+mDataPos, data, len);
55754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return finishWrite(len);
55854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
55954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
56054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    status_t err = growData(len);
56154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (err == NO_ERROR) goto restart_write;
56254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return err;
56354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
56454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
56554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::write(const void* data, size_t len)
56654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
56754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    void* const d = writeInplace(len);
56854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (d) {
56954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        memcpy(d, data, len);
57054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return NO_ERROR;
57154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
57254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return mError;
57354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
57454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
57554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid* Parcel::writeInplace(size_t len)
57654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
57754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const size_t padded = PAD_SIZE(len);
57854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
57954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // sanity check for integer overflow
58054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (mDataPos+padded < mDataPos) {
58154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return NULL;
58254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
58354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
58454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if ((mDataPos+padded) <= mDataCapacity) {
58554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectrestart_write:
58654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        //printf("Writing %ld bytes, padded to %ld\n", len, padded);
58754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        uint8_t* const data = mData+mDataPos;
58854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
58954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // Need to pad at end?
59054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (padded != len) {
59154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#if BYTE_ORDER == BIG_ENDIAN
59254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            static const uint32_t mask[4] = {
59354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                0x00000000, 0xffffff00, 0xffff0000, 0xff000000
59454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            };
59554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#endif
59654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#if BYTE_ORDER == LITTLE_ENDIAN
59754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            static const uint32_t mask[4] = {
59854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
59954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            };
60054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#endif
60154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
60254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //    *reinterpret_cast<void**>(data+padded-4));
60354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
60454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
60554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
60654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        finishWrite(padded);
60754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return data;
60854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
60954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
61054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    status_t err = growData(padded);
61154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (err == NO_ERROR) goto restart_write;
61254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return NULL;
61354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
61454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
61554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::writeInt32(int32_t val)
61654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
6172f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    return writeAligned(val);
61854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
61954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
62054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::writeInt64(int64_t val)
62154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
6222f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    return writeAligned(val);
62354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
62454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
62554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::writeFloat(float val)
62654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
6272f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    return writeAligned(val);
62854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
62954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
63054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::writeDouble(double val)
63154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
6322f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    return writeAligned(val);
6332f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber}
63454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
6352f10ae08d435b12e1798d93e0b90605717c66081Andreas Huberstatus_t Parcel::writeIntPtr(intptr_t val)
6362f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber{
6372f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    return writeAligned(val);
63854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
63954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
64054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::writeCString(const char* str)
64154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
64254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return write(str, strlen(str)+1);
64354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
64454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
64554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::writeString8(const String8& str)
64654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
64754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    status_t err = writeInt32(str.bytes());
648b803c04cdaf3ce9dec387a874cabf141f0d8500fPravat Dalbehera    // only write string if its length is more than zero characters,
649b803c04cdaf3ce9dec387a874cabf141f0d8500fPravat Dalbehera    // as readString8 will only read if the length field is non-zero.
650b803c04cdaf3ce9dec387a874cabf141f0d8500fPravat Dalbehera    // this is slightly different from how writeString16 works.
651b803c04cdaf3ce9dec387a874cabf141f0d8500fPravat Dalbehera    if (str.bytes() > 0 && err == NO_ERROR) {
65254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        err = write(str.string(), str.bytes()+1);
65354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
65454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return err;
65554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
65654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
65754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::writeString16(const String16& str)
65854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
65954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return writeString16(str.string(), str.size());
66054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
66154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
66254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::writeString16(const char16_t* str, size_t len)
66354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
66454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (str == NULL) return writeInt32(-1);
66554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
66654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    status_t err = writeInt32(len);
66754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (err == NO_ERROR) {
66854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        len *= sizeof(char16_t);
66954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
67054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (data) {
67154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            memcpy(data, str, len);
67254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            *reinterpret_cast<char16_t*>(data+len) = 0;
67354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return NO_ERROR;
67454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
67554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        err = mError;
67654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
67754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return err;
67854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
67954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
68054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::writeStrongBinder(const sp<IBinder>& val)
68154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
68254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return flatten_binder(ProcessState::self(), val, this);
68354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
68454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
68554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::writeWeakBinder(const wp<IBinder>& val)
68654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
68754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return flatten_binder(ProcessState::self(), val, this);
68854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
68954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
690dfece80c790934e4413def863070ac0dd21f6e29Mathias Agopianstatus_t Parcel::writeNativeHandle(const native_handle* handle)
69122f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project{
692f1db4aec6569d7cf9e1fb84f1d9c1292032eac30Mathias Agopian    if (!handle || handle->version != sizeof(native_handle))
69322f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project        return BAD_TYPE;
69422f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project
69522f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project    status_t err;
696dfece80c790934e4413def863070ac0dd21f6e29Mathias Agopian    err = writeInt32(handle->numFds);
69722f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project    if (err != NO_ERROR) return err;
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
699dfece80c790934e4413def863070ac0dd21f6e29Mathias Agopian    err = writeInt32(handle->numInts);
70022f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project    if (err != NO_ERROR) return err;
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
702dfece80c790934e4413def863070ac0dd21f6e29Mathias Agopian    for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++)
703dfece80c790934e4413def863070ac0dd21f6e29Mathias Agopian        err = writeDupFileDescriptor(handle->data[i]);
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err != NO_ERROR) {
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGD("write native handle, write dup fd failed");
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return err;
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
709dfece80c790934e4413def863070ac0dd21f6e29Mathias Agopian    err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
71022f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project    return err;
71122f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project}
71222f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project
7135462bc6318b4b70e7a58c66994e2bd79f59d9739Jeff Brownstatus_t Parcel::writeFileDescriptor(int fd, bool takeOwnership)
71454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
71554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    flat_binder_object obj;
71654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    obj.type = BINDER_TYPE_FD;
71754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
71854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    obj.handle = fd;
7195462bc6318b4b70e7a58c66994e2bd79f59d9739Jeff Brown    obj.cookie = (void*) (takeOwnership ? 1 : 0);
72054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return writeObject(obj, true);
72154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
72254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
72354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::writeDupFileDescriptor(int fd)
72454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
7255462bc6318b4b70e7a58c66994e2bd79f59d9739Jeff Brown    return writeFileDescriptor(dup(fd), true /*takeOwnership*/);
72654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
72754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
7286579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brownstatus_t Parcel::writeBlob(size_t len, WritableBlob* outBlob)
7296579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown{
7306579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    status_t status;
7316579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown
7326579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    if (!mAllowFds || len <= IN_PLACE_BLOB_LIMIT) {
7336579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown        LOGV("writeBlob: write in place");
7346579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown        status = writeInt32(0);
7356579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown        if (status) return status;
7366579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown
7376579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown        void* ptr = writeInplace(len);
7386579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown        if (!ptr) return NO_MEMORY;
7396579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown
7406579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown        outBlob->init(false /*mapped*/, ptr, len);
7416579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown        return NO_ERROR;
7426579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    }
7436579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown
7446579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    LOGV("writeBlob: write to ashmem");
7456579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    int fd = ashmem_create_region("Parcel Blob", len);
7466579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    if (fd < 0) return NO_MEMORY;
7476579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown
7486579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
7496579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    if (result < 0) {
7500cde89f5f025b7826be009ebb9673b970e180e32Jeff Brown        status = result;
7516579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    } else {
7526579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown        void* ptr = ::mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
7536579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown        if (ptr == MAP_FAILED) {
7546579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown            status = -errno;
7556579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown        } else {
7566579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown            result = ashmem_set_prot_region(fd, PROT_READ);
7576579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown            if (result < 0) {
7580cde89f5f025b7826be009ebb9673b970e180e32Jeff Brown                status = result;
7596579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown            } else {
7606579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown                status = writeInt32(1);
7616579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown                if (!status) {
7625462bc6318b4b70e7a58c66994e2bd79f59d9739Jeff Brown                    status = writeFileDescriptor(fd, true /*takeOwnership*/);
7636579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown                    if (!status) {
7646579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown                        outBlob->init(true /*mapped*/, ptr, len);
7656579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown                        return NO_ERROR;
7666579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown                    }
7676579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown                }
7686579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown            }
7696579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown        }
7706579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown        ::munmap(ptr, len);
7716579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    }
7726579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    ::close(fd);
7736579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    return status;
7746579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown}
7756579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown
776c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopianstatus_t Parcel::write(const Flattenable& val)
777c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian{
778c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    status_t err;
779c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian
780c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    // size if needed
781c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    size_t len = val.getFlattenedSize();
782c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    size_t fd_count = val.getFdCount();
783c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian
784c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    err = this->writeInt32(len);
785c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    if (err) return err;
786c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian
787c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    err = this->writeInt32(fd_count);
788c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    if (err) return err;
789c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian
790c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    // payload
791c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    void* buf = this->writeInplace(PAD_SIZE(len));
792c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    if (buf == NULL)
793c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian        return BAD_VALUE;
794c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian
795c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    int* fds = NULL;
796c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    if (fd_count) {
797c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian        fds = new int[fd_count];
798c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    }
799c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian
800c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    err = val.flatten(buf, len, fds, fd_count);
801c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
802c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian        err = this->writeDupFileDescriptor( fds[i] );
803c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    }
804c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian
805c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    if (fd_count) {
806c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian        delete [] fds;
807c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    }
808c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian
809c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    return err;
810c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian}
811c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian
81254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
81354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
81454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
81554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const bool enoughObjects = mObjectsSize < mObjectsCapacity;
81654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (enoughData && enoughObjects) {
81754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectrestart_write:
81854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
81954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
82054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // Need to write meta-data?
82154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (nullMetaData || val.binder != NULL) {
82254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mObjects[mObjectsSize] = mDataPos;
82354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            acquire_object(ProcessState::self(), val, this);
82454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mObjectsSize++;
82554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
82654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
82754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // remember if it's a file descriptor
82854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (val.type == BINDER_TYPE_FD) {
8299ecebbfbf768fd63e9a6c9a09c86d81c7737ee2dDianne Hackborn            if (!mAllowFds) {
8309ecebbfbf768fd63e9a6c9a09c86d81c7737ee2dDianne Hackborn                return FDS_NOT_ALLOWED;
8319ecebbfbf768fd63e9a6c9a09c86d81c7737ee2dDianne Hackborn            }
83254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mHasFds = mFdsKnown = true;
83354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
83454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
83554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return finishWrite(sizeof(flat_binder_object));
83654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
83754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
83854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (!enoughData) {
83954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const status_t err = growData(sizeof(val));
84054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (err != NO_ERROR) return err;
84154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
84254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (!enoughObjects) {
84354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        size_t newSize = ((mObjectsSize+2)*3)/2;
84454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        size_t* objects = (size_t*)realloc(mObjects, newSize*sizeof(size_t));
84554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (objects == NULL) return NO_MEMORY;
84654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mObjects = objects;
84754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mObjectsCapacity = newSize;
84854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
84954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
85054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    goto restart_write;
85154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
85254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
853c0a7e690bfd32dd897ceccd04dd0fa6bf6e9cee6Brad Fitzpatrickstatus_t Parcel::writeNoException()
854c0a7e690bfd32dd897ceccd04dd0fa6bf6e9cee6Brad Fitzpatrick{
855c0a7e690bfd32dd897ceccd04dd0fa6bf6e9cee6Brad Fitzpatrick    return writeInt32(0);
856c0a7e690bfd32dd897ceccd04dd0fa6bf6e9cee6Brad Fitzpatrick}
857c0a7e690bfd32dd897ceccd04dd0fa6bf6e9cee6Brad Fitzpatrick
85854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid Parcel::remove(size_t start, size_t amt)
85954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
86054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
86154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
86254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
86354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::read(void* outData, size_t len) const
86454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
86554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
86654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        memcpy(outData, mData+mDataPos, len);
86754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mDataPos += PAD_SIZE(len);
86854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        LOGV("read Setting data pos of %p to %d\n", this, mDataPos);
86954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return NO_ERROR;
87054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
87154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return NOT_ENOUGH_DATA;
87254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
87354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
87454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectconst void* Parcel::readInplace(size_t len) const
87554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
87654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
87754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const void* data = mData+mDataPos;
87854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mDataPos += PAD_SIZE(len);
87954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        LOGV("readInplace Setting data pos of %p to %d\n", this, mDataPos);
88054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return data;
88154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
88254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return NULL;
88354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
88454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
8852f10ae08d435b12e1798d93e0b90605717c66081Andreas Hubertemplate<class T>
8862f10ae08d435b12e1798d93e0b90605717c66081Andreas Huberstatus_t Parcel::readAligned(T *pArg) const {
8872f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
8882f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber
8892f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    if ((mDataPos+sizeof(T)) <= mDataSize) {
89054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const void* data = mData+mDataPos;
8912f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber        mDataPos += sizeof(T);
8922f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber        *pArg =  *reinterpret_cast<const T*>(data);
89354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return NO_ERROR;
89454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    } else {
89554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return NOT_ENOUGH_DATA;
89654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
89754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
89854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
8992f10ae08d435b12e1798d93e0b90605717c66081Andreas Hubertemplate<class T>
9002f10ae08d435b12e1798d93e0b90605717c66081Andreas HuberT Parcel::readAligned() const {
9012f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    T result;
9022f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    if (readAligned(&result) != NO_ERROR) {
9032f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber        result = 0;
9042f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    }
9052f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber
9062f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    return result;
9072f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber}
9082f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber
9092f10ae08d435b12e1798d93e0b90605717c66081Andreas Hubertemplate<class T>
9102f10ae08d435b12e1798d93e0b90605717c66081Andreas Huberstatus_t Parcel::writeAligned(T val) {
9112f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
9122f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber
9132f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
9142f10ae08d435b12e1798d93e0b90605717c66081Andreas Huberrestart_write:
9152f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber        *reinterpret_cast<T*>(mData+mDataPos) = val;
9162f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber        return finishWrite(sizeof(val));
9172f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    }
9182f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber
9192f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    status_t err = growData(sizeof(val));
9202f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    if (err == NO_ERROR) goto restart_write;
9212f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    return err;
9222f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber}
9232f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber
9242f10ae08d435b12e1798d93e0b90605717c66081Andreas Huberstatus_t Parcel::readInt32(int32_t *pArg) const
9252f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber{
9262f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    return readAligned(pArg);
9272f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber}
9282f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber
92954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectint32_t Parcel::readInt32() const
93054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
9312f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    return readAligned<int32_t>();
93254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
93354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
93454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
93554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::readInt64(int64_t *pArg) const
93654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
9372f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    return readAligned(pArg);
93854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
93954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
94054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
94154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectint64_t Parcel::readInt64() const
94254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
9432f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    return readAligned<int64_t>();
94454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
94554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
94654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::readFloat(float *pArg) const
94754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
9482f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    return readAligned(pArg);
94954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
95054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
95154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
95254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectfloat Parcel::readFloat() const
95354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
9542f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    return readAligned<float>();
95554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
95654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
95754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::readDouble(double *pArg) const
95854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
9592f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    return readAligned(pArg);
96054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
96154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
96254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
96354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectdouble Parcel::readDouble() const
96454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
9652f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    return readAligned<double>();
9662f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber}
9672f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber
9682f10ae08d435b12e1798d93e0b90605717c66081Andreas Huberstatus_t Parcel::readIntPtr(intptr_t *pArg) const
9692f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber{
9702f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    return readAligned(pArg);
9712f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber}
9722f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber
9732f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber
9742f10ae08d435b12e1798d93e0b90605717c66081Andreas Huberintptr_t Parcel::readIntPtr() const
9752f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber{
9762f10ae08d435b12e1798d93e0b90605717c66081Andreas Huber    return readAligned<intptr_t>();
97754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
97854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
97954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
98054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectconst char* Parcel::readCString() const
98154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
98254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const size_t avail = mDataSize-mDataPos;
98354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (avail > 0) {
98454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const char* str = reinterpret_cast<const char*>(mData+mDataPos);
98554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // is the string's trailing NUL within the parcel's valid bounds?
98654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
98754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (eos) {
98854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const size_t len = eos - str;
98954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mDataPos += PAD_SIZE(len+1);
99054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            LOGV("readCString Setting data pos of %p to %d\n", this, mDataPos);
99154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return str;
99254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
99354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
99454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return NULL;
99554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
99654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
99754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectString8 Parcel::readString8() const
99854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
99954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int32_t size = readInt32();
100054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // watch for potential int overflow adding 1 for trailing NUL
100154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (size > 0 && size < INT32_MAX) {
100254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const char* str = (const char*)readInplace(size+1);
100354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (str) return String8(str, size);
100454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
100554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return String8();
100654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
100754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
100854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectString16 Parcel::readString16() const
100954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
101054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    size_t len;
101154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const char16_t* str = readString16Inplace(&len);
101254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (str) return String16(str, len);
101354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    LOGE("Reading a NULL string not supported here.");
101454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return String16();
101554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
101654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
101754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectconst char16_t* Parcel::readString16Inplace(size_t* outLen) const
101854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
101954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int32_t size = readInt32();
102054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // watch for potential int overflow from size+1
102154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (size >= 0 && size < INT32_MAX) {
102254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        *outLen = size;
102354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
102454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (str != NULL) {
102554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return str;
102654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
102754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
102854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    *outLen = 0;
102954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return NULL;
103054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
103154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
103254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectsp<IBinder> Parcel::readStrongBinder() const
103354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
103454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    sp<IBinder> val;
103554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    unflatten_binder(ProcessState::self(), *this, &val);
103654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return val;
103754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
103854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
103954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectwp<IBinder> Parcel::readWeakBinder() const
104054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
104154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    wp<IBinder> val;
104254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    unflatten_binder(ProcessState::self(), *this, &val);
104354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return val;
104454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
104554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
1046c0a7e690bfd32dd897ceccd04dd0fa6bf6e9cee6Brad Fitzpatrickint32_t Parcel::readExceptionCode() const
1047c0a7e690bfd32dd897ceccd04dd0fa6bf6e9cee6Brad Fitzpatrick{
1048c0a7e690bfd32dd897ceccd04dd0fa6bf6e9cee6Brad Fitzpatrick  int32_t exception_code = readAligned<int32_t>();
10495b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick  if (exception_code == EX_HAS_REPLY_HEADER) {
10505b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    int32_t header_size = readAligned<int32_t>();
10515b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    // Skip over fat responses headers.  Not used (or propagated) in
10525b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    // native code
10535b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    setDataPosition(dataPosition() + header_size);
10545b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    // And fat response headers are currently only used when there are no
10555b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    // exceptions, so return no error:
10565b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    return 0;
10575b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick  }
1058c0a7e690bfd32dd897ceccd04dd0fa6bf6e9cee6Brad Fitzpatrick  return exception_code;
1059c0a7e690bfd32dd897ceccd04dd0fa6bf6e9cee6Brad Fitzpatrick}
106022f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project
1061dfece80c790934e4413def863070ac0dd21f6e29Mathias Agopiannative_handle* Parcel::readNativeHandle() const
106222f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project{
106322f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project    int numFds, numInts;
106422f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project    status_t err;
106522f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project    err = readInt32(&numFds);
106622f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project    if (err != NO_ERROR) return 0;
106722f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project    err = readInt32(&numInts);
106822f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project    if (err != NO_ERROR) return 0;
106922f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project
1070dfece80c790934e4413def863070ac0dd21f6e29Mathias Agopian    native_handle* h = native_handle_create(numFds, numInts);
107122f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project    for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
1072bc4afde167513f7efe76012015f9fa3641c156cfRebecca Schultz Zavin        h->data[i] = dup(readFileDescriptor());
107322f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project        if (h->data[i] < 0) err = BAD_VALUE;
107422f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project    }
107522f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project    err = read(h->data + numFds, sizeof(int)*numInts);
107622f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project    if (err != NO_ERROR) {
1077dfece80c790934e4413def863070ac0dd21f6e29Mathias Agopian        native_handle_close(h);
1078dfece80c790934e4413def863070ac0dd21f6e29Mathias Agopian        native_handle_delete(h);
107922f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project        h = 0;
108022f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project    }
108122f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project    return h;
108222f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project}
108322f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project
108422f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project
108554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectint Parcel::readFileDescriptor() const
108654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
108754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const flat_binder_object* flat = readObject(true);
108854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (flat) {
108954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        switch (flat->type) {
109054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            case BINDER_TYPE_FD:
109154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                //LOGI("Returning file descriptor %ld from parcel %p\n", flat->handle, this);
109254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                return flat->handle;
109354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
109454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
109554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return BAD_TYPE;
109654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
109754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
10986579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brownstatus_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
10996579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown{
11006579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    int32_t useAshmem;
11016579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    status_t status = readInt32(&useAshmem);
11026579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    if (status) return status;
11036579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown
11046579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    if (!useAshmem) {
11056579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown        LOGV("readBlob: read in place");
11066579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown        const void* ptr = readInplace(len);
11076579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown        if (!ptr) return BAD_VALUE;
11086579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown
11096579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown        outBlob->init(false /*mapped*/, const_cast<void*>(ptr), len);
11106579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown        return NO_ERROR;
11116579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    }
11126579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown
11136579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    LOGV("readBlob: read from ashmem");
11146579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    int fd = readFileDescriptor();
11156579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    if (fd == int(BAD_TYPE)) return BAD_VALUE;
11166579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown
11176579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    void* ptr = ::mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
11186579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    if (!ptr) return NO_MEMORY;
11196579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown
11206579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    outBlob->init(true /*mapped*/, ptr, len);
11216579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    return NO_ERROR;
11226579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown}
11236579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown
1124c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopianstatus_t Parcel::read(Flattenable& val) const
1125c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian{
1126c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    // size
1127c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    const size_t len = this->readInt32();
1128c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    const size_t fd_count = this->readInt32();
1129c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian
1130c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    // payload
1131c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    void const* buf = this->readInplace(PAD_SIZE(len));
1132c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    if (buf == NULL)
1133c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian        return BAD_VALUE;
1134c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian
1135c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    int* fds = NULL;
1136c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    if (fd_count) {
1137c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian        fds = new int[fd_count];
1138c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    }
1139c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian
1140c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    status_t err = NO_ERROR;
1141c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
1142c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian        fds[i] = dup(this->readFileDescriptor());
1143c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian        if (fds[i] < 0) err = BAD_VALUE;
1144c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    }
1145c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian
1146c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    if (err == NO_ERROR) {
1147c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian        err = val.unflatten(buf, len, fds, fd_count);
1148c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    }
1149c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian
1150c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    if (fd_count) {
1151c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian        delete [] fds;
1152c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    }
1153c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian
1154c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian    return err;
1155c86727f5805f28fbd25da141c50fb6843f364f3aMathias Agopian}
115654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectconst flat_binder_object* Parcel::readObject(bool nullMetaData) const
115754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
115854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const size_t DPOS = mDataPos;
115954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
116054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const flat_binder_object* obj
116154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
116254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mDataPos = DPOS + sizeof(flat_binder_object);
116354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (!nullMetaData && (obj->cookie == NULL && obj->binder == NULL)) {
116422f7dfd23490a3de2f21ff96949ba47003aac8f8The Android Open Source Project            // When transferring a NULL object, we don't write it into
116554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // the object list, so we don't want to check for it when
116654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // reading.
116754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
116854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return obj;
116954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
117054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
117154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // Ensure that this object is valid...
117254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        size_t* const OBJS = mObjects;
117354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const size_t N = mObjectsSize;
117454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        size_t opos = mNextObjectHint;
117554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
117654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (N > 0) {
117754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            LOGV("Parcel %p looking for obj at %d, hint=%d\n",
117854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                 this, DPOS, opos);
117954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
118054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // Start at the current hint position, looking for an object at
118154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // the current data position.
118254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (opos < N) {
118354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                while (opos < (N-1) && OBJS[opos] < DPOS) {
118454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    opos++;
118554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
118654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            } else {
118754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                opos = N-1;
118854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
118954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (OBJS[opos] == DPOS) {
119054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                // Found it!
119154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                LOGV("Parcel found obj %d at index %d with forward search",
119254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                     this, DPOS, opos);
119354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mNextObjectHint = opos+1;
119454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
119554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                return obj;
119654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
119754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
119854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // Look backwards for it...
119954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            while (opos > 0 && OBJS[opos] > DPOS) {
120054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                opos--;
120154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
120254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (OBJS[opos] == DPOS) {
120354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                // Found it!
120454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                LOGV("Parcel found obj %d at index %d with backward search",
120554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                     this, DPOS, opos);
120654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mNextObjectHint = opos+1;
120754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
120854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                return obj;
120954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
121054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
121154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        LOGW("Attempt to read object from Parcel %p at offset %d that is not in the object list",
121254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project             this, DPOS);
121354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
121454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return NULL;
121554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
121654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
121754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid Parcel::closeFileDescriptors()
121854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
121954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    size_t i = mObjectsSize;
122054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (i > 0) {
122154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        //LOGI("Closing file descriptors for %d objects...", mObjectsSize);
122254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
122354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    while (i > 0) {
122454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        i--;
122554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const flat_binder_object* flat
122654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
122754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (flat->type == BINDER_TYPE_FD) {
122854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //LOGI("Closing fd: %ld\n", flat->handle);
122954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            close(flat->handle);
123054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
123154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
123254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
123354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
123454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectconst uint8_t* Parcel::ipcData() const
123554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
123654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return mData;
123754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
123854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
123954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectsize_t Parcel::ipcDataSize() const
124054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
124154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return (mDataSize > mDataPos ? mDataSize : mDataPos);
124254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
124354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
124454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectconst size_t* Parcel::ipcObjects() const
124554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
124654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return mObjects;
124754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
124854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
124954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectsize_t Parcel::ipcObjectsCount() const
125054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
125154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return mObjectsSize;
125254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
125354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
125454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
125554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
125654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
125754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    freeDataNoInit();
125854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mError = NO_ERROR;
125954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mData = const_cast<uint8_t*>(data);
126054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mDataSize = mDataCapacity = dataSize;
126154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    //LOGI("setDataReference Setting data size of %p to %lu (pid=%d)\n", this, mDataSize, getpid());
126254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mDataPos = 0;
126354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    LOGV("setDataReference Setting data pos of %p to %d\n", this, mDataPos);
126454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mObjects = const_cast<size_t*>(objects);
126554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mObjectsSize = mObjectsCapacity = objectsCount;
126654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mNextObjectHint = 0;
126754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mOwner = relFunc;
126854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mOwnerCookie = relCookie;
126954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    scanForFds();
127054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
127154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
127254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid Parcel::print(TextOutput& to, uint32_t flags) const
127354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
127454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    to << "Parcel(";
127554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
127654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (errorCheck() != NO_ERROR) {
127754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const status_t err = errorCheck();
127854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        to << "Error: " << (void*)err << " \"" << strerror(-err) << "\"";
127954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    } else if (dataSize() > 0) {
128054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const uint8_t* DATA = data();
128154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        to << indent << HexDump(DATA, dataSize()) << dedent;
128254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const size_t* OBJS = objects();
128354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const size_t N = objectsCount();
128454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        for (size_t i=0; i<N; i++) {
128554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const flat_binder_object* flat
128654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
128754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
128854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                << TypeCode(flat->type & 0x7f7f7f00)
128954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                << " = " << flat->binder;
129054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
129154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    } else {
129254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        to << "NULL";
129354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
129454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
129554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    to << ")";
129654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
129754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
129854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid Parcel::releaseObjects()
129954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
130054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const sp<ProcessState> proc(ProcessState::self());
130154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    size_t i = mObjectsSize;
130254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    uint8_t* const data = mData;
130354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    size_t* const objects = mObjects;
130454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    while (i > 0) {
130554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        i--;
130654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const flat_binder_object* flat
130754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
130854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        release_object(proc, *flat, this);
130954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
131054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
131154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
131254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid Parcel::acquireObjects()
131354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
131454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const sp<ProcessState> proc(ProcessState::self());
131554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    size_t i = mObjectsSize;
131654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    uint8_t* const data = mData;
131754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    size_t* const objects = mObjects;
131854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    while (i > 0) {
131954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        i--;
132054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const flat_binder_object* flat
132154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
132254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        acquire_object(proc, *flat, this);
132354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
132454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
132554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
132654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid Parcel::freeData()
132754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
132854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    freeDataNoInit();
132954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    initState();
133054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
133154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
133254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid Parcel::freeDataNoInit()
133354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
133454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (mOwner) {
133554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        //LOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
133654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
133754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    } else {
133854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        releaseObjects();
133954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (mData) free(mData);
134054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (mObjects) free(mObjects);
134154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
134254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
134354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
134454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::growData(size_t len)
134554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
134654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    size_t newSize = ((mDataSize+len)*3)/2;
134754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return (newSize <= mDataSize)
134854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            ? (status_t) NO_MEMORY
134954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            : continueWrite(newSize);
135054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
135154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
135254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::restartWrite(size_t desired)
135354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
135454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (mOwner) {
135554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        freeData();
135654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return continueWrite(desired);
135754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
135854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
135954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    uint8_t* data = (uint8_t*)realloc(mData, desired);
136054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (!data && desired > mDataCapacity) {
136154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mError = NO_MEMORY;
136254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return NO_MEMORY;
136354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
136454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
136554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    releaseObjects();
136654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
136754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (data) {
136854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mData = data;
136954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mDataCapacity = desired;
137054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
137154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
137254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mDataSize = mDataPos = 0;
137354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    LOGV("restartWrite Setting data size of %p to %d\n", this, mDataSize);
137454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    LOGV("restartWrite Setting data pos of %p to %d\n", this, mDataPos);
137554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
137654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    free(mObjects);
137754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mObjects = NULL;
137854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mObjectsSize = mObjectsCapacity = 0;
137954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mNextObjectHint = 0;
138054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mHasFds = false;
138154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mFdsKnown = true;
13829ecebbfbf768fd63e9a6c9a09c86d81c7737ee2dDianne Hackborn    mAllowFds = true;
138354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
138454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return NO_ERROR;
138554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
138654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
138754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatus_t Parcel::continueWrite(size_t desired)
138854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
138954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // If shrinking, first adjust for any objects that appear
139054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // after the new data size.
139154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    size_t objectsSize = mObjectsSize;
139254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (desired < mDataSize) {
139354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (desired == 0) {
139454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            objectsSize = 0;
139554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        } else {
139654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            while (objectsSize > 0) {
139754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                if (mObjects[objectsSize-1] < desired)
139854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    break;
139954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                objectsSize--;
140054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
140154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
140254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
140354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
140454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (mOwner) {
140554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // If the size is going to zero, just release the owner's data.
140654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (desired == 0) {
140754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            freeData();
140854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return NO_ERROR;
140954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
141054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
141154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // If there is a different owner, we need to take
141254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // posession.
141354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        uint8_t* data = (uint8_t*)malloc(desired);
141454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (!data) {
141554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mError = NO_MEMORY;
141654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return NO_MEMORY;
141754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
141854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        size_t* objects = NULL;
141954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
142054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (objectsSize) {
142154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            objects = (size_t*)malloc(objectsSize*sizeof(size_t));
142254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (!objects) {
142354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mError = NO_MEMORY;
142454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                return NO_MEMORY;
142554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
142654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
142754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // Little hack to only acquire references on objects
142854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // we will be keeping.
142954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            size_t oldObjectsSize = mObjectsSize;
143054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mObjectsSize = objectsSize;
143154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            acquireObjects();
143254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mObjectsSize = oldObjectsSize;
143354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
143454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
143554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (mData) {
143654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
143754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
143854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (objects && mObjects) {
143954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            memcpy(objects, mObjects, objectsSize*sizeof(size_t));
144054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
144154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        //LOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
144254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
144354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mOwner = NULL;
144454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
144554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mData = data;
144654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mObjects = objects;
144754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mDataSize = (mDataSize < desired) ? mDataSize : desired;
144854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
144954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mDataCapacity = desired;
145054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mObjectsSize = mObjectsCapacity = objectsSize;
145154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mNextObjectHint = 0;
145254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
145354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    } else if (mData) {
145454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (objectsSize < mObjectsSize) {
145554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // Need to release refs on any objects we are dropping.
145654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            const sp<ProcessState> proc(ProcessState::self());
145754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            for (size_t i=objectsSize; i<mObjectsSize; i++) {
145854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                const flat_binder_object* flat
145954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
146054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                if (flat->type == BINDER_TYPE_FD) {
146154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    // will need to rescan because we may have lopped off the only FDs
146254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    mFdsKnown = false;
146354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
146454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                release_object(proc, *flat, this);
146554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
146654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            size_t* objects =
146754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                (size_t*)realloc(mObjects, objectsSize*sizeof(size_t));
146854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (objects) {
146954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mObjects = objects;
147054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
147154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mObjectsSize = objectsSize;
147254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mNextObjectHint = 0;
147354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
147454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
147554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // We own the data, so we can just do a realloc().
147654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (desired > mDataCapacity) {
147754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            uint8_t* data = (uint8_t*)realloc(mData, desired);
147854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (data) {
147954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mData = data;
148054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mDataCapacity = desired;
148154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            } else if (desired > mDataCapacity) {
148254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mError = NO_MEMORY;
148354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                return NO_MEMORY;
148454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
148554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        } else {
14860ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn            if (mDataSize > desired) {
14870ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn                mDataSize = desired;
14880ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn                LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
14890ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn            }
149054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (mDataPos > desired) {
149154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mDataPos = desired;
149254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                LOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
149354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
149454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
149554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
149654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    } else {
149754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // This is the first data.  Easy!
149854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        uint8_t* data = (uint8_t*)malloc(desired);
149954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (!data) {
150054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mError = NO_MEMORY;
150154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return NO_MEMORY;
150254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
150354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
150454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if(!(mDataCapacity == 0 && mObjects == NULL
150554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project             && mObjectsCapacity == 0)) {
150654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            LOGE("continueWrite: %d/%p/%d/%d", mDataCapacity, mObjects, mObjectsCapacity, desired);
150754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
150854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
150954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mData = data;
151054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mDataSize = mDataPos = 0;
151154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
151254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        LOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
151354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mDataCapacity = desired;
151454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
151554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
151654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return NO_ERROR;
151754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
151854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
151954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid Parcel::initState()
152054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
152154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mError = NO_ERROR;
152254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mData = 0;
152354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mDataSize = 0;
152454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mDataCapacity = 0;
152554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mDataPos = 0;
152654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    LOGV("initState Setting data size of %p to %d\n", this, mDataSize);
152754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    LOGV("initState Setting data pos of %p to %d\n", this, mDataPos);
152854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mObjects = NULL;
152954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mObjectsSize = 0;
153054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mObjectsCapacity = 0;
153154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mNextObjectHint = 0;
153254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mHasFds = false;
153354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mFdsKnown = true;
15349ecebbfbf768fd63e9a6c9a09c86d81c7737ee2dDianne Hackborn    mAllowFds = true;
153554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mOwner = NULL;
153654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
153754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
153854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid Parcel::scanForFds() const
153954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
154054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    bool hasFds = false;
154154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    for (size_t i=0; i<mObjectsSize; i++) {
154254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const flat_binder_object* flat
154354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
154454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (flat->type == BINDER_TYPE_FD) {
154554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            hasFds = true;
154654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            break;
154754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
154854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
154954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mHasFds = hasFds;
155054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mFdsKnown = true;
155154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
155254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
15536579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown// --- Parcel::Blob ---
15546579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown
15556579a9d6fe2302fa149452f66c4062ebc60c2523Jeff BrownParcel::Blob::Blob() :
15566579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown        mMapped(false), mData(NULL), mSize(0) {
15576579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown}
15586579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown
15596579a9d6fe2302fa149452f66c4062ebc60c2523Jeff BrownParcel::Blob::~Blob() {
15606579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    release();
15616579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown}
15626579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown
15636579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brownvoid Parcel::Blob::release() {
15646579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    if (mMapped && mData) {
15656579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown        ::munmap(mData, mSize);
15666579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    }
15676579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    clear();
15686579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown}
15696579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown
15706579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brownvoid Parcel::Blob::init(bool mapped, void* data, size_t size) {
15716579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    mMapped = mapped;
15726579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    mData = data;
15736579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    mSize = size;
15746579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown}
15756579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown
15766579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brownvoid Parcel::Blob::clear() {
15776579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    mMapped = false;
15786579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    mData = NULL;
15796579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown    mSize = 0;
15806579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown}
15816579a9d6fe2302fa149452f66c4062ebc60c2523Jeff Brown
158254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}; // namespace android
1583