mirror of
https://github.com/infiniteCable2/openpilot.git
synced 2026-08-05 08:16:03 +08:00
phonelibs -> third_party (#22477)
* git mv to third_party * find and replace * fix release tests * update pre-commit * update tici bins * update eon bins Co-authored-by: Comma Device <device@comma.ai> old-commit-hash: 5b641379ae04d3408093381629b9d60dee81da27
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2011, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CUTILS_ANDROID_REBOOT_H__
|
||||
#define __CUTILS_ANDROID_REBOOT_H__
|
||||
|
||||
#include <mntent.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* Commands */
|
||||
#define ANDROID_RB_RESTART 0xDEAD0001
|
||||
#define ANDROID_RB_POWEROFF 0xDEAD0002
|
||||
#define ANDROID_RB_RESTART2 0xDEAD0003
|
||||
|
||||
/* Properties */
|
||||
#define ANDROID_RB_PROPERTY "sys.powerctl"
|
||||
|
||||
int android_reboot(int cmd, int flags, const char *arg);
|
||||
int android_reboot_with_callback(
|
||||
int cmd, int flags, const char *arg,
|
||||
void (*cb_on_remount)(const struct mntent*));
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* __CUTILS_ANDROID_REBOOT_H__ */
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _CUTILS_AREF_H_
|
||||
#define _CUTILS_AREF_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <cutils/atomic.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define AREF_TO_ITEM(aref, container, member) \
|
||||
(container *) (((char*) (aref)) - offsetof(container, member))
|
||||
|
||||
struct aref
|
||||
{
|
||||
volatile int32_t count;
|
||||
};
|
||||
|
||||
static inline void aref_init(struct aref *r)
|
||||
{
|
||||
r->count = 1;
|
||||
}
|
||||
|
||||
static inline int32_t aref_count(struct aref *r)
|
||||
{
|
||||
return r->count;
|
||||
}
|
||||
|
||||
static inline void aref_get(struct aref *r)
|
||||
{
|
||||
android_atomic_inc(&r->count);
|
||||
}
|
||||
|
||||
static inline void aref_put(struct aref *r, void (*release)(struct aref *))
|
||||
{
|
||||
if (android_atomic_dec(&r->count) == 1)
|
||||
release(r);
|
||||
}
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif // _CUTILS_AREF_H_
|
||||
@@ -0,0 +1,45 @@
|
||||
/* cutils/ashmem.h
|
||||
**
|
||||
** Copyright 2008 The Android Open Source Project
|
||||
**
|
||||
** This file is dual licensed. It may be redistributed and/or modified
|
||||
** under the terms of the Apache 2.0 License OR version 2 of the GNU
|
||||
** General Public License.
|
||||
*/
|
||||
|
||||
#ifndef _CUTILS_ASHMEM_H
|
||||
#define _CUTILS_ASHMEM_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int ashmem_create_region(const char *name, size_t size);
|
||||
int ashmem_set_prot_region(int fd, int prot);
|
||||
int ashmem_pin_region(int fd, size_t offset, size_t len);
|
||||
int ashmem_unpin_region(int fd, size_t offset, size_t len);
|
||||
int ashmem_get_size_region(int fd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ASHMEMIOC /* in case someone included <linux/ashmem.h> too */
|
||||
|
||||
#define ASHMEM_NAME_LEN 256
|
||||
|
||||
#define ASHMEM_NAME_DEF "dev/ashmem"
|
||||
|
||||
/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */
|
||||
#define ASHMEM_NOT_PURGED 0
|
||||
#define ASHMEM_WAS_PURGED 1
|
||||
|
||||
/* Return values from ASHMEM_UNPIN: Is the mapping now pinned or unpinned? */
|
||||
#define ASHMEM_IS_UNPINNED 0
|
||||
#define ASHMEM_IS_PINNED 1
|
||||
|
||||
#endif /* ! __ASHMEMIOC */
|
||||
|
||||
#endif /* _CUTILS_ASHMEM_H */
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_CUTILS_ATOMIC_H
|
||||
#define ANDROID_CUTILS_ATOMIC_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdatomic.h>
|
||||
|
||||
#ifndef ANDROID_ATOMIC_INLINE
|
||||
#define ANDROID_ATOMIC_INLINE static inline
|
||||
#endif
|
||||
|
||||
/*
|
||||
* A handful of basic atomic operations.
|
||||
* THESE ARE HERE FOR LEGACY REASONS ONLY. AVOID.
|
||||
*
|
||||
* PREFERRED ALTERNATIVES:
|
||||
* - Use C++/C/pthread locks/mutexes whenever there is not a
|
||||
* convincing reason to do otherwise. Note that very clever and
|
||||
* complicated, but correct, lock-free code is often slower than
|
||||
* using locks, especially where nontrivial data structures
|
||||
* are involved.
|
||||
* - C11 stdatomic.h.
|
||||
* - Where supported, C++11 std::atomic<T> .
|
||||
*
|
||||
* PLEASE STOP READING HERE UNLESS YOU ARE TRYING TO UNDERSTAND
|
||||
* OR UPDATE OLD CODE.
|
||||
*
|
||||
* The "acquire" and "release" terms can be defined intuitively in terms
|
||||
* of the placement of memory barriers in a simple lock implementation:
|
||||
* - wait until compare-and-swap(lock-is-free --> lock-is-held) succeeds
|
||||
* - barrier
|
||||
* - [do work]
|
||||
* - barrier
|
||||
* - store(lock-is-free)
|
||||
* In very crude terms, the initial (acquire) barrier prevents any of the
|
||||
* "work" from happening before the lock is held, and the later (release)
|
||||
* barrier ensures that all of the work happens before the lock is released.
|
||||
* (Think of cached writes, cache read-ahead, and instruction reordering
|
||||
* around the CAS and store instructions.)
|
||||
*
|
||||
* The barriers must apply to both the compiler and the CPU. Note it is
|
||||
* legal for instructions that occur before an "acquire" barrier to be
|
||||
* moved down below it, and for instructions that occur after a "release"
|
||||
* barrier to be moved up above it.
|
||||
*
|
||||
* The ARM-driven implementation we use here is short on subtlety,
|
||||
* and actually requests a full barrier from the compiler and the CPU.
|
||||
* The only difference between acquire and release is in whether they
|
||||
* are issued before or after the atomic operation with which they
|
||||
* are associated. To ease the transition to C/C++ atomic intrinsics,
|
||||
* you should not rely on this, and instead assume that only the minimal
|
||||
* acquire/release protection is provided.
|
||||
*
|
||||
* NOTE: all int32_t* values are expected to be aligned on 32-bit boundaries.
|
||||
* If they are not, atomicity is not guaranteed.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Basic arithmetic and bitwise operations. These all provide a
|
||||
* barrier with "release" ordering, and return the previous value.
|
||||
*
|
||||
* These have the same characteristics (e.g. what happens on overflow)
|
||||
* as the equivalent non-atomic C operations.
|
||||
*/
|
||||
ANDROID_ATOMIC_INLINE
|
||||
int32_t android_atomic_inc(volatile int32_t* addr)
|
||||
{
|
||||
volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;
|
||||
/* Int32_t, if it exists, is the same as int_least32_t. */
|
||||
return atomic_fetch_add_explicit(a, 1, memory_order_release);
|
||||
}
|
||||
|
||||
ANDROID_ATOMIC_INLINE
|
||||
int32_t android_atomic_dec(volatile int32_t* addr)
|
||||
{
|
||||
volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;
|
||||
return atomic_fetch_sub_explicit(a, 1, memory_order_release);
|
||||
}
|
||||
|
||||
ANDROID_ATOMIC_INLINE
|
||||
int32_t android_atomic_add(int32_t value, volatile int32_t* addr)
|
||||
{
|
||||
volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;
|
||||
return atomic_fetch_add_explicit(a, value, memory_order_release);
|
||||
}
|
||||
|
||||
ANDROID_ATOMIC_INLINE
|
||||
int32_t android_atomic_and(int32_t value, volatile int32_t* addr)
|
||||
{
|
||||
volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;
|
||||
return atomic_fetch_and_explicit(a, value, memory_order_release);
|
||||
}
|
||||
|
||||
ANDROID_ATOMIC_INLINE
|
||||
int32_t android_atomic_or(int32_t value, volatile int32_t* addr)
|
||||
{
|
||||
volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;
|
||||
return atomic_fetch_or_explicit(a, value, memory_order_release);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform an atomic load with "acquire" or "release" ordering.
|
||||
*
|
||||
* Note that the notion of a "release" ordering for a load does not
|
||||
* really fit into the C11 or C++11 memory model. The extra ordering
|
||||
* is normally observable only by code using memory_order_relaxed
|
||||
* atomics, or data races. In the rare cases in which such ordering
|
||||
* is called for, use memory_order_relaxed atomics and a leading
|
||||
* atomic_thread_fence (typically with memory_order_acquire,
|
||||
* not memory_order_release!) instead. If you do not understand
|
||||
* this comment, you are in the vast majority, and should not be
|
||||
* using release loads or replacing them with anything other than
|
||||
* locks or default sequentially consistent atomics.
|
||||
*/
|
||||
ANDROID_ATOMIC_INLINE
|
||||
int32_t android_atomic_acquire_load(volatile const int32_t* addr)
|
||||
{
|
||||
volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;
|
||||
return atomic_load_explicit(a, memory_order_acquire);
|
||||
}
|
||||
|
||||
ANDROID_ATOMIC_INLINE
|
||||
int32_t android_atomic_release_load(volatile const int32_t* addr)
|
||||
{
|
||||
volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;
|
||||
atomic_thread_fence(memory_order_seq_cst);
|
||||
/* Any reasonable clients of this interface would probably prefer */
|
||||
/* something weaker. But some remaining clients seem to be */
|
||||
/* abusing this API in strange ways, e.g. by using it as a fence. */
|
||||
/* Thus we are conservative until we can get rid of remaining */
|
||||
/* clients (and this function). */
|
||||
return atomic_load_explicit(a, memory_order_relaxed);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform an atomic store with "acquire" or "release" ordering.
|
||||
*
|
||||
* Note that the notion of an "acquire" ordering for a store does not
|
||||
* really fit into the C11 or C++11 memory model. The extra ordering
|
||||
* is normally observable only by code using memory_order_relaxed
|
||||
* atomics, or data races. In the rare cases in which such ordering
|
||||
* is called for, use memory_order_relaxed atomics and a trailing
|
||||
* atomic_thread_fence (typically with memory_order_release,
|
||||
* not memory_order_acquire!) instead.
|
||||
*/
|
||||
ANDROID_ATOMIC_INLINE
|
||||
void android_atomic_acquire_store(int32_t value, volatile int32_t* addr)
|
||||
{
|
||||
volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;
|
||||
atomic_store_explicit(a, value, memory_order_relaxed);
|
||||
atomic_thread_fence(memory_order_seq_cst);
|
||||
/* Again overly conservative to accomodate weird clients. */
|
||||
}
|
||||
|
||||
ANDROID_ATOMIC_INLINE
|
||||
void android_atomic_release_store(int32_t value, volatile int32_t* addr)
|
||||
{
|
||||
volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;
|
||||
atomic_store_explicit(a, value, memory_order_release);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare-and-set operation with "acquire" or "release" ordering.
|
||||
*
|
||||
* This returns zero if the new value was successfully stored, which will
|
||||
* only happen when *addr == oldvalue.
|
||||
*
|
||||
* (The return value is inverted from implementations on other platforms,
|
||||
* but matches the ARM ldrex/strex result.)
|
||||
*
|
||||
* Implementations that use the release CAS in a loop may be less efficient
|
||||
* than possible, because we re-issue the memory barrier on each iteration.
|
||||
*/
|
||||
ANDROID_ATOMIC_INLINE
|
||||
int android_atomic_acquire_cas(int32_t oldvalue, int32_t newvalue,
|
||||
volatile int32_t* addr)
|
||||
{
|
||||
volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;
|
||||
return (int)(!atomic_compare_exchange_strong_explicit(
|
||||
a, &oldvalue, newvalue,
|
||||
memory_order_acquire,
|
||||
memory_order_acquire));
|
||||
}
|
||||
|
||||
ANDROID_ATOMIC_INLINE
|
||||
int android_atomic_release_cas(int32_t oldvalue, int32_t newvalue,
|
||||
volatile int32_t* addr)
|
||||
{
|
||||
volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;
|
||||
return (int)(!atomic_compare_exchange_strong_explicit(
|
||||
a, &oldvalue, newvalue,
|
||||
memory_order_release,
|
||||
memory_order_relaxed));
|
||||
}
|
||||
|
||||
/*
|
||||
* Fence primitives.
|
||||
*/
|
||||
ANDROID_ATOMIC_INLINE
|
||||
void android_compiler_barrier(void)
|
||||
{
|
||||
__asm__ __volatile__ ("" : : : "memory");
|
||||
/* Could probably also be: */
|
||||
/* atomic_signal_fence(memory_order_seq_cst); */
|
||||
}
|
||||
|
||||
ANDROID_ATOMIC_INLINE
|
||||
void android_memory_barrier(void)
|
||||
{
|
||||
atomic_thread_fence(memory_order_seq_cst);
|
||||
}
|
||||
|
||||
/*
|
||||
* Aliases for code using an older version of this header. These are now
|
||||
* deprecated and should not be used. The definitions will be removed
|
||||
* in a future release.
|
||||
*/
|
||||
#define android_atomic_write android_atomic_release_store
|
||||
#define android_atomic_cmpxchg android_atomic_release_cas
|
||||
|
||||
#endif // ANDROID_CUTILS_ATOMIC_H
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CUTILS_BITOPS_H
|
||||
#define __CUTILS_BITOPS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*
|
||||
* Bitmask Operations
|
||||
*
|
||||
* Note this doesn't provide any locking/exclusion, and isn't atomic.
|
||||
* Additionally no bounds checking is done on the bitmask array.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* int num_resources;
|
||||
* unsigned int resource_bits[BITS_TO_WORDS(num_resources)];
|
||||
* bitmask_init(resource_bits, num_resources);
|
||||
* ...
|
||||
* int bit = bitmask_ffz(resource_bits, num_resources);
|
||||
* bitmask_set(resource_bits, bit);
|
||||
* ...
|
||||
* if (bitmask_test(resource_bits, bit)) { ... }
|
||||
* ...
|
||||
* bitmask_clear(resource_bits, bit);
|
||||
*
|
||||
*/
|
||||
|
||||
#define BITS_PER_WORD (sizeof(unsigned int) * 8)
|
||||
#define BITS_TO_WORDS(x) (((x) + BITS_PER_WORD - 1) / BITS_PER_WORD)
|
||||
#define BIT_IN_WORD(x) ((x) % BITS_PER_WORD)
|
||||
#define BIT_WORD(x) ((x) / BITS_PER_WORD)
|
||||
#define BIT_MASK(x) (1 << BIT_IN_WORD(x))
|
||||
|
||||
static inline void bitmask_init(unsigned int *bitmask, int num_bits)
|
||||
{
|
||||
memset(bitmask, 0, BITS_TO_WORDS(num_bits)*sizeof(unsigned int));
|
||||
}
|
||||
|
||||
static inline int bitmask_ffz(unsigned int *bitmask, int num_bits)
|
||||
{
|
||||
int bit, result;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < BITS_TO_WORDS(num_bits); i++) {
|
||||
bit = ffs(~bitmask[i]);
|
||||
if (bit) {
|
||||
// ffs is 1-indexed, return 0-indexed result
|
||||
bit--;
|
||||
result = BITS_PER_WORD * i + bit;
|
||||
if (result >= num_bits)
|
||||
return -1;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int bitmask_weight(unsigned int *bitmask, int num_bits)
|
||||
{
|
||||
size_t i;
|
||||
int weight = 0;
|
||||
|
||||
for (i = 0; i < BITS_TO_WORDS(num_bits); i++)
|
||||
weight += __builtin_popcount(bitmask[i]);
|
||||
return weight;
|
||||
}
|
||||
|
||||
static inline void bitmask_set(unsigned int *bitmask, int bit)
|
||||
{
|
||||
bitmask[BIT_WORD(bit)] |= BIT_MASK(bit);
|
||||
}
|
||||
|
||||
static inline void bitmask_clear(unsigned int *bitmask, int bit)
|
||||
{
|
||||
bitmask[BIT_WORD(bit)] &= ~BIT_MASK(bit);
|
||||
}
|
||||
|
||||
static inline bool bitmask_test(unsigned int *bitmask, int bit)
|
||||
{
|
||||
return bitmask[BIT_WORD(bit)] & BIT_MASK(bit);
|
||||
}
|
||||
|
||||
static inline int popcount(unsigned int x)
|
||||
{
|
||||
return __builtin_popcount(x);
|
||||
}
|
||||
|
||||
static inline int popcountl(unsigned long x)
|
||||
{
|
||||
return __builtin_popcountl(x);
|
||||
}
|
||||
|
||||
static inline int popcountll(unsigned long long x)
|
||||
{
|
||||
return __builtin_popcountll(x);
|
||||
}
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* __CUTILS_BITOPS_H */
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_CUTILS_COMPILER_H
|
||||
#define ANDROID_CUTILS_COMPILER_H
|
||||
|
||||
/*
|
||||
* helps the compiler's optimizer predicting branches
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define CC_LIKELY( exp ) (__builtin_expect( !!(exp), true ))
|
||||
# define CC_UNLIKELY( exp ) (__builtin_expect( !!(exp), false ))
|
||||
#else
|
||||
# define CC_LIKELY( exp ) (__builtin_expect( !!(exp), 1 ))
|
||||
# define CC_UNLIKELY( exp ) (__builtin_expect( !!(exp), 0 ))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* exports marked symbols
|
||||
*
|
||||
* if used on a C++ class declaration, this macro must be inserted
|
||||
* after the "class" keyword. For instance:
|
||||
*
|
||||
* template <typename TYPE>
|
||||
* class ANDROID_API Singleton { }
|
||||
*/
|
||||
|
||||
#define ANDROID_API __attribute__((visibility("default")))
|
||||
|
||||
#endif // ANDROID_CUTILS_COMPILER_H
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CUTILS_CONFIG_UTILS_H
|
||||
#define __CUTILS_CONFIG_UTILS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct cnode cnode;
|
||||
|
||||
|
||||
struct cnode
|
||||
{
|
||||
cnode *next;
|
||||
cnode *first_child;
|
||||
cnode *last_child;
|
||||
const char *name;
|
||||
const char *value;
|
||||
};
|
||||
|
||||
/* parse a text string into a config node tree */
|
||||
void config_load(cnode *root, char *data);
|
||||
|
||||
/* parse a file into a config node tree */
|
||||
void config_load_file(cnode *root, const char *fn);
|
||||
|
||||
/* create a single config node */
|
||||
cnode* config_node(const char *name, const char *value);
|
||||
|
||||
/* locate a named child of a config node */
|
||||
cnode* config_find(cnode *root, const char *name);
|
||||
|
||||
/* look up a child by name and return the boolean value */
|
||||
int config_bool(cnode *root, const char *name, int _default);
|
||||
|
||||
/* look up a child by name and return the string value */
|
||||
const char* config_str(cnode *root, const char *name, const char *_default);
|
||||
|
||||
/* add a named child to a config node (or modify it if it already exists) */
|
||||
void config_set(cnode *root, const char *name, const char *value);
|
||||
|
||||
/* free a config node tree */
|
||||
void config_free(cnode *root);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CUTILS_DEBUGGER_H
|
||||
#define __CUTILS_DEBUGGER_H
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define DEBUGGER_SOCKET_NAME "android:debuggerd"
|
||||
#define DEBUGGER32_SOCKET_NAME "android:debuggerd32"
|
||||
#define DEBUGGER64_SOCKET_NAME DEBUGGER_SOCKET_NAME
|
||||
|
||||
typedef enum {
|
||||
// dump a crash
|
||||
DEBUGGER_ACTION_CRASH,
|
||||
// dump a tombstone file
|
||||
DEBUGGER_ACTION_DUMP_TOMBSTONE,
|
||||
// dump a backtrace only back to the socket
|
||||
DEBUGGER_ACTION_DUMP_BACKTRACE,
|
||||
} debugger_action_t;
|
||||
|
||||
// Make sure that all values have a fixed size so that this structure
|
||||
// is the same for 32 bit and 64 bit processes.
|
||||
// NOTE: Any changes to this structure must also be reflected in
|
||||
// bionic/linker/debugger.cpp.
|
||||
typedef struct __attribute__((packed)) {
|
||||
int32_t action;
|
||||
pid_t tid;
|
||||
uint64_t abort_msg_address;
|
||||
int32_t original_si_code;
|
||||
} debugger_msg_t;
|
||||
|
||||
/* Dumps a process backtrace, registers, and stack to a tombstone file (requires root).
|
||||
* Stores the tombstone path in the provided buffer.
|
||||
* Returns 0 on success, -1 on error.
|
||||
*/
|
||||
int dump_tombstone(pid_t tid, char* pathbuf, size_t pathlen);
|
||||
|
||||
/* Dumps a process backtrace, registers, and stack to a tombstone file (requires root).
|
||||
* Stores the tombstone path in the provided buffer.
|
||||
* If reading debugger data from debuggerd ever takes longer than timeout_secs
|
||||
* seconds, then stop and return an error.
|
||||
* Returns 0 on success, -1 on error.
|
||||
*/
|
||||
int dump_tombstone_timeout(pid_t tid, char* pathbuf, size_t pathlen, int timeout_secs);
|
||||
|
||||
/* Dumps a process backtrace only to the specified file (requires root).
|
||||
* Returns 0 on success, -1 on error.
|
||||
*/
|
||||
int dump_backtrace_to_file(pid_t tid, int fd);
|
||||
|
||||
/* Dumps a process backtrace only to the specified file (requires root).
|
||||
* If reading debugger data from debuggerd ever takes longer than timeout_secs
|
||||
* seconds, then stop and return an error.
|
||||
* Returns 0 on success, -1 on error.
|
||||
*/
|
||||
int dump_backtrace_to_file_timeout(pid_t tid, int fd, int timeout_secs);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* __CUTILS_DEBUGGER_H */
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CUTILS_FS_H
|
||||
#define __CUTILS_FS_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* TEMP_FAILURE_RETRY is defined by some, but not all, versions of
|
||||
* <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
|
||||
* not already defined, then define it here.
|
||||
*/
|
||||
#ifndef TEMP_FAILURE_RETRY
|
||||
/* Used to retry syscalls that can return EINTR. */
|
||||
#define TEMP_FAILURE_RETRY(exp) ({ \
|
||||
typeof (exp) _rc; \
|
||||
do { \
|
||||
_rc = (exp); \
|
||||
} while (_rc == -1 && errno == EINTR); \
|
||||
_rc; })
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Ensure that directory exists with given mode and owners.
|
||||
*/
|
||||
extern int fs_prepare_dir(const char* path, mode_t mode, uid_t uid, gid_t gid);
|
||||
|
||||
/*
|
||||
* Read single plaintext integer from given file, correctly handling files
|
||||
* partially written with fs_write_atomic_int().
|
||||
*/
|
||||
extern int fs_read_atomic_int(const char* path, int* value);
|
||||
|
||||
/*
|
||||
* Write single plaintext integer to given file, creating backup while
|
||||
* in progress.
|
||||
*/
|
||||
extern int fs_write_atomic_int(const char* path, int value);
|
||||
|
||||
/*
|
||||
* Ensure that all directories along given path exist, creating parent
|
||||
* directories as needed. Validates that given path is absolute and that
|
||||
* it contains no relative "." or ".." paths or symlinks. Last path segment
|
||||
* is treated as filename and ignored, unless the path ends with "/".
|
||||
*/
|
||||
extern int fs_mkdirs(const char* path, mode_t mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CUTILS_FS_H */
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hash map.
|
||||
*/
|
||||
|
||||
#ifndef __HASHMAP_H
|
||||
#define __HASHMAP_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** A hash map. */
|
||||
typedef struct Hashmap Hashmap;
|
||||
|
||||
/**
|
||||
* Creates a new hash map. Returns NULL if memory allocation fails.
|
||||
*
|
||||
* @param initialCapacity number of expected entries
|
||||
* @param hash function which hashes keys
|
||||
* @param equals function which compares keys for equality
|
||||
*/
|
||||
Hashmap* hashmapCreate(size_t initialCapacity,
|
||||
int (*hash)(void* key), bool (*equals)(void* keyA, void* keyB));
|
||||
|
||||
/**
|
||||
* Frees the hash map. Does not free the keys or values themselves.
|
||||
*/
|
||||
void hashmapFree(Hashmap* map);
|
||||
|
||||
/**
|
||||
* Hashes the memory pointed to by key with the given size. Useful for
|
||||
* implementing hash functions.
|
||||
*/
|
||||
int hashmapHash(void* key, size_t keySize);
|
||||
|
||||
/**
|
||||
* Puts value for the given key in the map. Returns pre-existing value if
|
||||
* any.
|
||||
*
|
||||
* If memory allocation fails, this function returns NULL, the map's size
|
||||
* does not increase, and errno is set to ENOMEM.
|
||||
*/
|
||||
void* hashmapPut(Hashmap* map, void* key, void* value);
|
||||
|
||||
/**
|
||||
* Gets a value from the map. Returns NULL if no entry for the given key is
|
||||
* found or if the value itself is NULL.
|
||||
*/
|
||||
void* hashmapGet(Hashmap* map, void* key);
|
||||
|
||||
/**
|
||||
* Returns true if the map contains an entry for the given key.
|
||||
*/
|
||||
bool hashmapContainsKey(Hashmap* map, void* key);
|
||||
|
||||
/**
|
||||
* Gets the value for a key. If a value is not found, this function gets a
|
||||
* value and creates an entry using the given callback.
|
||||
*
|
||||
* If memory allocation fails, the callback is not called, this function
|
||||
* returns NULL, and errno is set to ENOMEM.
|
||||
*/
|
||||
void* hashmapMemoize(Hashmap* map, void* key,
|
||||
void* (*initialValue)(void* key, void* context), void* context);
|
||||
|
||||
/**
|
||||
* Removes an entry from the map. Returns the removed value or NULL if no
|
||||
* entry was present.
|
||||
*/
|
||||
void* hashmapRemove(Hashmap* map, void* key);
|
||||
|
||||
/**
|
||||
* Gets the number of entries in this map.
|
||||
*/
|
||||
size_t hashmapSize(Hashmap* map);
|
||||
|
||||
/**
|
||||
* Invokes the given callback on each entry in the map. Stops iterating if
|
||||
* the callback returns false.
|
||||
*/
|
||||
void hashmapForEach(Hashmap* map,
|
||||
bool (*callback)(void* key, void* value, void* context),
|
||||
void* context);
|
||||
|
||||
/**
|
||||
* Concurrency support.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Locks the hash map so only the current thread can access it.
|
||||
*/
|
||||
void hashmapLock(Hashmap* map);
|
||||
|
||||
/**
|
||||
* Unlocks the hash map so other threads can access it.
|
||||
*/
|
||||
void hashmapUnlock(Hashmap* map);
|
||||
|
||||
/**
|
||||
* Key utilities.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hashes int keys. 'key' is a pointer to int.
|
||||
*/
|
||||
int hashmapIntHash(void* key);
|
||||
|
||||
/**
|
||||
* Compares two int keys for equality.
|
||||
*/
|
||||
bool hashmapIntEquals(void* keyA, void* keyB);
|
||||
|
||||
/**
|
||||
* For debugging.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets current capacity.
|
||||
*/
|
||||
size_t hashmapCurrentCapacity(Hashmap* map);
|
||||
|
||||
/**
|
||||
* Counts the number of entry collisions.
|
||||
*/
|
||||
size_t hashmapCountCollisions(Hashmap* map);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HASHMAP_H */
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CUTILS_IOSCHED_POLICY_H
|
||||
#define __CUTILS_IOSCHED_POLICY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
IoSchedClass_NONE,
|
||||
IoSchedClass_RT,
|
||||
IoSchedClass_BE,
|
||||
IoSchedClass_IDLE,
|
||||
} IoSchedClass;
|
||||
|
||||
extern int android_set_ioprio(int pid, IoSchedClass clazz, int ioprio);
|
||||
extern int android_get_ioprio(int pid, IoSchedClass *clazz, int *ioprio);
|
||||
|
||||
extern int android_set_rt_ioprio(int pid, int rt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CUTILS_IOSCHED_POLICY_H */
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CUTILS_STRING16_H
|
||||
#define __CUTILS_STRING16_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if __STDC_VERSION__ < 201112L && __cplusplus < 201103L
|
||||
typedef uint16_t char16_t;
|
||||
#endif
|
||||
// otherwise char16_t is a keyword with the right semantics
|
||||
|
||||
extern char * strndup16to8 (const char16_t* s, size_t n);
|
||||
extern size_t strnlen16to8 (const char16_t* s, size_t n);
|
||||
extern char * strncpy16to8 (char *dest, const char16_t*s, size_t n);
|
||||
|
||||
extern char16_t * strdup8to16 (const char* s, size_t *out_len);
|
||||
extern size_t strlen8to16 (const char* utf8Str);
|
||||
extern char16_t * strcpy8to16 (char16_t *dest, const char*s, size_t *out_len);
|
||||
extern char16_t * strcpylen8to16 (char16_t *dest, const char*s, int length,
|
||||
size_t *out_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CUTILS_STRING16_H */
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _CUTILS_KLOG_H_
|
||||
#define _CUTILS_KLOG_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/uio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
void klog_init(void);
|
||||
int klog_get_level(void);
|
||||
void klog_set_level(int level);
|
||||
/* TODO: void klog_close(void); - and make klog_fd users thread safe. */
|
||||
|
||||
void klog_write(int level, const char *fmt, ...)
|
||||
__attribute__ ((format(printf, 2, 3)));
|
||||
void klog_writev(int level, const struct iovec* iov, int iov_count);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#define KLOG_ERROR_LEVEL 3
|
||||
#define KLOG_WARNING_LEVEL 4
|
||||
#define KLOG_NOTICE_LEVEL 5
|
||||
#define KLOG_INFO_LEVEL 6
|
||||
#define KLOG_DEBUG_LEVEL 7
|
||||
|
||||
#define KLOG_ERROR(tag,x...) klog_write(KLOG_ERROR_LEVEL, "<3>" tag ": " x)
|
||||
#define KLOG_WARNING(tag,x...) klog_write(KLOG_WARNING_LEVEL, "<4>" tag ": " x)
|
||||
#define KLOG_NOTICE(tag,x...) klog_write(KLOG_NOTICE_LEVEL, "<5>" tag ": " x)
|
||||
#define KLOG_INFO(tag,x...) klog_write(KLOG_INFO_LEVEL, "<6>" tag ": " x)
|
||||
#define KLOG_DEBUG(tag,x...) klog_write(KLOG_DEBUG_LEVEL, "<7>" tag ": " x)
|
||||
|
||||
#define KLOG_DEFAULT_LEVEL 3 /* messages <= this level are logged */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _CUTILS_LIST_H_
|
||||
#define _CUTILS_LIST_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
struct listnode
|
||||
{
|
||||
struct listnode *next;
|
||||
struct listnode *prev;
|
||||
};
|
||||
|
||||
#define node_to_item(node, container, member) \
|
||||
(container *) (((char*) (node)) - offsetof(container, member))
|
||||
|
||||
#define list_declare(name) \
|
||||
struct listnode name = { \
|
||||
.next = &name, \
|
||||
.prev = &name, \
|
||||
}
|
||||
|
||||
#define list_for_each(node, list) \
|
||||
for (node = (list)->next; node != (list); node = node->next)
|
||||
|
||||
#define list_for_each_reverse(node, list) \
|
||||
for (node = (list)->prev; node != (list); node = node->prev)
|
||||
|
||||
#define list_for_each_safe(node, n, list) \
|
||||
for (node = (list)->next, n = node->next; \
|
||||
node != (list); \
|
||||
node = n, n = node->next)
|
||||
|
||||
static inline void list_init(struct listnode *node)
|
||||
{
|
||||
node->next = node;
|
||||
node->prev = node;
|
||||
}
|
||||
|
||||
static inline void list_add_tail(struct listnode *head, struct listnode *item)
|
||||
{
|
||||
item->next = head;
|
||||
item->prev = head->prev;
|
||||
head->prev->next = item;
|
||||
head->prev = item;
|
||||
}
|
||||
|
||||
static inline void list_add_head(struct listnode *head, struct listnode *item)
|
||||
{
|
||||
item->next = head->next;
|
||||
item->prev = head;
|
||||
head->next->prev = item;
|
||||
head->next = item;
|
||||
}
|
||||
|
||||
static inline void list_remove(struct listnode *item)
|
||||
{
|
||||
item->next->prev = item->prev;
|
||||
item->prev->next = item->next;
|
||||
}
|
||||
|
||||
#define list_empty(list) ((list) == (list)->next)
|
||||
#define list_head(list) ((list)->next)
|
||||
#define list_tail(list) ((list)->prev)
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1 @@
|
||||
#include <log/log.h>
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_CUTILS_MEMORY_H
|
||||
#define ANDROID_CUTILS_MEMORY_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* size is given in bytes and must be multiple of 2 */
|
||||
void android_memset16(uint16_t* dst, uint16_t value, size_t size);
|
||||
|
||||
/* size is given in bytes and must be multiple of 4 */
|
||||
void android_memset32(uint32_t* dst, uint32_t value, size_t size);
|
||||
|
||||
#if defined(__GLIBC__) || defined(_WIN32)
|
||||
/* Declaration of strlcpy() for platforms that don't already have it. */
|
||||
size_t strlcpy(char *dst, const char *src, size_t size);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ANDROID_CUTILS_MEMORY_H
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CUTILS_MISC_H
|
||||
#define __CUTILS_MISC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Load an entire file into a malloc'd chunk of memory
|
||||
* that is length_of_file + 1 (null terminator). If
|
||||
* sz is non-zero, return the size of the file via sz.
|
||||
* Returns 0 on failure.
|
||||
*/
|
||||
extern void *load_file(const char *fn, unsigned *sz);
|
||||
|
||||
/* This is the range of UIDs (and GIDs) that are reserved
|
||||
* for assigning to applications.
|
||||
*/
|
||||
#define FIRST_APPLICATION_UID 10000
|
||||
#define LAST_APPLICATION_UID 99999
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CUTILS_MISC_H */
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CUTILS_MULTIUSER_H
|
||||
#define __CUTILS_MULTIUSER_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// NOTE: keep in sync with android.os.UserId
|
||||
|
||||
#define MULTIUSER_APP_PER_USER_RANGE 100000
|
||||
|
||||
typedef uid_t userid_t;
|
||||
typedef uid_t appid_t;
|
||||
|
||||
extern userid_t multiuser_get_user_id(uid_t uid);
|
||||
extern appid_t multiuser_get_app_id(uid_t uid);
|
||||
extern uid_t multiuser_get_uid(userid_t userId, appid_t appId);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CUTILS_MULTIUSER_H */
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef NATIVE_HANDLE_H_
|
||||
#define NATIVE_HANDLE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct native_handle
|
||||
{
|
||||
int version; /* sizeof(native_handle_t) */
|
||||
int numFds; /* number of file-descriptors at &data[0] */
|
||||
int numInts; /* number of ints at &data[numFds] */
|
||||
int data[0]; /* numFds + numInts ints */
|
||||
} native_handle_t;
|
||||
|
||||
/*
|
||||
* native_handle_close
|
||||
*
|
||||
* closes the file descriptors contained in this native_handle_t
|
||||
*
|
||||
* return 0 on success, or a negative error code on failure
|
||||
*
|
||||
*/
|
||||
int native_handle_close(const native_handle_t* h);
|
||||
|
||||
|
||||
/*
|
||||
* native_handle_create
|
||||
*
|
||||
* creates a native_handle_t and initializes it. must be destroyed with
|
||||
* native_handle_delete().
|
||||
*
|
||||
*/
|
||||
native_handle_t* native_handle_create(int numFds, int numInts);
|
||||
|
||||
/*
|
||||
* native_handle_delete
|
||||
*
|
||||
* frees a native_handle_t allocated with native_handle_create().
|
||||
* This ONLY frees the memory allocated for the native_handle_t, but doesn't
|
||||
* close the file descriptors; which can be achieved with native_handle_close().
|
||||
*
|
||||
* return 0 on success, or a negative error code on failure
|
||||
*
|
||||
*/
|
||||
int native_handle_delete(native_handle_t* h);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NATIVE_HANDLE_H_ */
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CUTILS_OPEN_MEMSTREAM_H__
|
||||
#define __CUTILS_OPEN_MEMSTREAM_H__
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
FILE* open_memstream(char** bufp, size_t* sizep);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
#endif /*__CUTILS_OPEN_MEMSTREAM_H__*/
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2011, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CUTILS_PARTITION_WIPED_H__
|
||||
#define __CUTILS_PARTITION_WIPED_H__
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
int partition_wiped(char *source);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* __CUTILS_PARTITION_WIPED_H__ */
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gives the current process a name.
|
||||
*/
|
||||
|
||||
#ifndef __PROCESS_NAME_H
|
||||
#define __PROCESS_NAME_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Sets the current process name.
|
||||
*
|
||||
* Warning: This leaks a string every time you call it. Use judiciously!
|
||||
*/
|
||||
void set_process_name(const char* process_name);
|
||||
|
||||
/** Gets the current process name. */
|
||||
const char* get_process_name(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __PROCESS_NAME_H */
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CUTILS_PROPERTIES_H
|
||||
#define __CUTILS_PROPERTIES_H
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/system_properties.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* System properties are *small* name value pairs managed by the
|
||||
** property service. If your data doesn't fit in the provided
|
||||
** space it is not appropriate for a system property.
|
||||
**
|
||||
** WARNING: system/bionic/include/sys/system_properties.h also defines
|
||||
** these, but with different names. (TODO: fix that)
|
||||
*/
|
||||
#define PROPERTY_KEY_MAX PROP_NAME_MAX
|
||||
#define PROPERTY_VALUE_MAX PROP_VALUE_MAX
|
||||
|
||||
/* property_get: returns the length of the value which will never be
|
||||
** greater than PROPERTY_VALUE_MAX - 1 and will always be zero terminated.
|
||||
** (the length does not include the terminating zero).
|
||||
**
|
||||
** If the property read fails or returns an empty value, the default
|
||||
** value is used (if nonnull).
|
||||
*/
|
||||
int property_get(const char *key, char *value, const char *default_value);
|
||||
|
||||
/* property_get_bool: returns the value of key coerced into a
|
||||
** boolean. If the property is not set, then the default value is returned.
|
||||
**
|
||||
* The following is considered to be true (1):
|
||||
** "1", "true", "y", "yes", "on"
|
||||
**
|
||||
** The following is considered to be false (0):
|
||||
** "0", "false", "n", "no", "off"
|
||||
**
|
||||
** The conversion is whitespace-sensitive (e.g. " off" will not be false).
|
||||
**
|
||||
** If no property with this key is set (or the key is NULL) or the boolean
|
||||
** conversion fails, the default value is returned.
|
||||
**/
|
||||
int8_t property_get_bool(const char *key, int8_t default_value);
|
||||
|
||||
/* property_get_int64: returns the value of key truncated and coerced into a
|
||||
** int64_t. If the property is not set, then the default value is used.
|
||||
**
|
||||
** The numeric conversion is identical to strtoimax with the base inferred:
|
||||
** - All digits up to the first non-digit characters are read
|
||||
** - The longest consecutive prefix of digits is converted to a long
|
||||
**
|
||||
** Valid strings of digits are:
|
||||
** - An optional sign character + or -
|
||||
** - An optional prefix indicating the base (otherwise base 10 is assumed)
|
||||
** -- 0 prefix is octal
|
||||
** -- 0x / 0X prefix is hex
|
||||
**
|
||||
** Leading/trailing whitespace is ignored. Overflow/underflow will cause
|
||||
** numeric conversion to fail.
|
||||
**
|
||||
** If no property with this key is set (or the key is NULL) or the numeric
|
||||
** conversion fails, the default value is returned.
|
||||
**/
|
||||
int64_t property_get_int64(const char *key, int64_t default_value);
|
||||
|
||||
/* property_get_int32: returns the value of key truncated and coerced into an
|
||||
** int32_t. If the property is not set, then the default value is used.
|
||||
**
|
||||
** The numeric conversion is identical to strtoimax with the base inferred:
|
||||
** - All digits up to the first non-digit characters are read
|
||||
** - The longest consecutive prefix of digits is converted to a long
|
||||
**
|
||||
** Valid strings of digits are:
|
||||
** - An optional sign character + or -
|
||||
** - An optional prefix indicating the base (otherwise base 10 is assumed)
|
||||
** -- 0 prefix is octal
|
||||
** -- 0x / 0X prefix is hex
|
||||
**
|
||||
** Leading/trailing whitespace is ignored. Overflow/underflow will cause
|
||||
** numeric conversion to fail.
|
||||
**
|
||||
** If no property with this key is set (or the key is NULL) or the numeric
|
||||
** conversion fails, the default value is returned.
|
||||
**/
|
||||
int32_t property_get_int32(const char *key, int32_t default_value);
|
||||
|
||||
/* property_set: returns 0 on success, < 0 on failure
|
||||
*/
|
||||
int property_set(const char *key, const char *value);
|
||||
|
||||
int property_list(void (*propfn)(const char *key, const char *value, void *cookie), void *cookie);
|
||||
|
||||
#if defined(__BIONIC_FORTIFY)
|
||||
|
||||
extern int __property_get_real(const char *, char *, const char *)
|
||||
__asm__(__USER_LABEL_PREFIX__ "property_get");
|
||||
__errordecl(__property_get_too_small_error, "property_get() called with too small of a buffer");
|
||||
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
int property_get(const char *key, char *value, const char *default_value) {
|
||||
size_t bos = __bos(value);
|
||||
if (bos < PROPERTY_VALUE_MAX) {
|
||||
__property_get_too_small_error();
|
||||
}
|
||||
return __property_get_real(key, value, default_value);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CUTILS_QTAGUID_H
|
||||
#define __CUTILS_QTAGUID_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set tags (and owning UIDs) for network sockets.
|
||||
*/
|
||||
extern int qtaguid_tagSocket(int sockfd, int tag, uid_t uid);
|
||||
|
||||
/*
|
||||
* Untag a network socket before closing.
|
||||
*/
|
||||
extern int qtaguid_untagSocket(int sockfd);
|
||||
|
||||
/*
|
||||
* For the given uid, switch counter sets.
|
||||
* The kernel only keeps a limited number of sets.
|
||||
* 2 for now.
|
||||
*/
|
||||
extern int qtaguid_setCounterSet(int counterSetNum, uid_t uid);
|
||||
|
||||
/*
|
||||
* Delete all tag info that relates to the given tag an uid.
|
||||
* If the tag is 0, then ALL info about the uid is freeded.
|
||||
* The delete data also affects active tagged socketd, which are
|
||||
* then untagged.
|
||||
* The calling process can only operate on its own tags.
|
||||
* Unless it is part of the happy AID_NET_BW_ACCT group.
|
||||
* In which case it can clobber everything.
|
||||
*/
|
||||
extern int qtaguid_deleteTagData(int tag, uid_t uid);
|
||||
|
||||
/*
|
||||
* Enable/disable qtaguid functionnality at a lower level.
|
||||
* When pacified, the kernel will accept commands but do nothing.
|
||||
*/
|
||||
extern int qtaguid_setPacifier(int on);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CUTILS_QTAG_UID_H */
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* A simple utility for reading fixed records out of a stream fd
|
||||
*/
|
||||
|
||||
#ifndef _CUTILS_RECORD_STREAM_H
|
||||
#define _CUTILS_RECORD_STREAM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct RecordStream RecordStream;
|
||||
|
||||
extern RecordStream *record_stream_new(int fd, size_t maxRecordLen);
|
||||
extern void record_stream_free(RecordStream *p_rs);
|
||||
|
||||
extern int record_stream_get_next (RecordStream *p_rs, void ** p_outRecord,
|
||||
size_t *p_outRecordLen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*_CUTILS_RECORD_STREAM_H*/
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CUTILS_SCHED_POLICY_H
|
||||
#define __CUTILS_SCHED_POLICY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Keep in sync with THREAD_GROUP_* in frameworks/base/core/java/android/os/Process.java */
|
||||
typedef enum {
|
||||
SP_DEFAULT = -1,
|
||||
SP_BACKGROUND = 0,
|
||||
SP_FOREGROUND = 1,
|
||||
SP_SYSTEM = 2, // can't be used with set_sched_policy()
|
||||
SP_AUDIO_APP = 3,
|
||||
SP_AUDIO_SYS = 4,
|
||||
SP_CNT,
|
||||
SP_MAX = SP_CNT - 1,
|
||||
SP_SYSTEM_DEFAULT = SP_FOREGROUND,
|
||||
} SchedPolicy;
|
||||
|
||||
extern int set_cpuset_policy(int tid, SchedPolicy policy);
|
||||
|
||||
/* Assign thread tid to the cgroup associated with the specified policy.
|
||||
* If the thread is a thread group leader, that is it's gettid() == getpid(),
|
||||
* then the other threads in the same thread group are _not_ affected.
|
||||
* On platforms which support gettid(), zero tid means current thread.
|
||||
* Return value: 0 for success, or -errno for error.
|
||||
*/
|
||||
extern int set_sched_policy(int tid, SchedPolicy policy);
|
||||
|
||||
/* Return the policy associated with the cgroup of thread tid via policy pointer.
|
||||
* On platforms which support gettid(), zero tid means current thread.
|
||||
* Return value: 0 for success, or -1 for error and set errno.
|
||||
*/
|
||||
extern int get_sched_policy(int tid, SchedPolicy *policy);
|
||||
|
||||
/* Return a displayable string corresponding to policy.
|
||||
* Return value: non-NULL NUL-terminated name of unspecified length;
|
||||
* the caller is responsible for displaying the useful part of the string.
|
||||
*/
|
||||
extern const char *get_sched_policy_name(SchedPolicy policy);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CUTILS_SCHED_POLICY_H */
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CUTILS_SOCKETS_H
|
||||
#define __CUTILS_SOCKETS_H
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef HAVE_WINSOCK
|
||||
#include <winsock2.h>
|
||||
typedef int socklen_t;
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#define ANDROID_SOCKET_ENV_PREFIX "ANDROID_SOCKET_"
|
||||
#define ANDROID_SOCKET_DIR "/dev/socket"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* android_get_control_socket - simple helper function to get the file
|
||||
* descriptor of our init-managed Unix domain socket. `name' is the name of the
|
||||
* socket, as given in init.rc. Returns -1 on error.
|
||||
*
|
||||
* This is inline and not in libcutils proper because we want to use this in
|
||||
* third-party daemons with minimal modification.
|
||||
*/
|
||||
static inline int android_get_control_socket(const char *name)
|
||||
{
|
||||
char key[64];
|
||||
snprintf(key, sizeof(key), ANDROID_SOCKET_ENV_PREFIX "%s", name);
|
||||
|
||||
const char* val = getenv(key);
|
||||
if (!val) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
int fd = strtol(val, NULL, 10);
|
||||
if (errno) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/*
|
||||
* See also android.os.LocalSocketAddress.Namespace
|
||||
*/
|
||||
// Linux "abstract" (non-filesystem) namespace
|
||||
#define ANDROID_SOCKET_NAMESPACE_ABSTRACT 0
|
||||
// Android "reserved" (/dev/socket) namespace
|
||||
#define ANDROID_SOCKET_NAMESPACE_RESERVED 1
|
||||
// Normal filesystem namespace
|
||||
#define ANDROID_SOCKET_NAMESPACE_FILESYSTEM 2
|
||||
|
||||
extern int socket_loopback_client(int port, int type);
|
||||
extern int socket_network_client(const char *host, int port, int type);
|
||||
extern int socket_network_client_timeout(const char *host, int port, int type,
|
||||
int timeout);
|
||||
extern int socket_loopback_server(int port, int type);
|
||||
extern int socket_local_server(const char *name, int namespaceId, int type);
|
||||
extern int socket_local_server_bind(int s, const char *name, int namespaceId);
|
||||
extern int socket_local_client_connect(int fd,
|
||||
const char *name, int namespaceId, int type);
|
||||
extern int socket_local_client(const char *name, int namespaceId, int type);
|
||||
extern int socket_inaddr_any_server(int port, int type);
|
||||
|
||||
/*
|
||||
* socket_peer_is_trusted - Takes a socket which is presumed to be a
|
||||
* connected local socket (e.g. AF_LOCAL) and returns whether the peer
|
||||
* (the userid that owns the process on the other end of that socket)
|
||||
* is one of the two trusted userids, root or shell.
|
||||
*
|
||||
* Note: This only works as advertised on the Android OS and always
|
||||
* just returns true when called on other operating systems.
|
||||
*/
|
||||
extern bool socket_peer_is_trusted(int fd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CUTILS_SOCKETS_H */
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CUTILS_STR_PARMS_H
|
||||
#define __CUTILS_STR_PARMS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct str_parms;
|
||||
|
||||
struct str_parms *str_parms_create(void);
|
||||
struct str_parms *str_parms_create_str(const char *_string);
|
||||
void str_parms_destroy(struct str_parms *str_parms);
|
||||
|
||||
void str_parms_del(struct str_parms *str_parms, const char *key);
|
||||
|
||||
int str_parms_add_str(struct str_parms *str_parms, const char *key,
|
||||
const char *value);
|
||||
int str_parms_add_int(struct str_parms *str_parms, const char *key, int value);
|
||||
|
||||
int str_parms_add_float(struct str_parms *str_parms, const char *key,
|
||||
float value);
|
||||
|
||||
// Returns non-zero if the str_parms contains the specified key.
|
||||
int str_parms_has_key(struct str_parms *str_parms, const char *key);
|
||||
|
||||
// Gets value associated with the specified key (if present), placing it in the buffer
|
||||
// pointed to by the out_val parameter. Returns the length of the returned string value.
|
||||
// If 'key' isn't in the parms, then return -ENOENT (-2) and leave 'out_val' untouched.
|
||||
int str_parms_get_str(struct str_parms *str_parms, const char *key,
|
||||
char *out_val, int len);
|
||||
int str_parms_get_int(struct str_parms *str_parms, const char *key,
|
||||
int *out_val);
|
||||
int str_parms_get_float(struct str_parms *str_parms, const char *key,
|
||||
float *out_val);
|
||||
|
||||
char *str_parms_to_str(struct str_parms *str_parms);
|
||||
|
||||
/* debug */
|
||||
void str_parms_dump(struct str_parms *str_parms);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* __CUTILS_STR_PARMS_H */
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _LIBS_CUTILS_THREADS_H
|
||||
#define _LIBS_CUTILS_THREADS_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <pthread.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***********************************************************************/
|
||||
/***********************************************************************/
|
||||
/***** *****/
|
||||
/***** local thread storage *****/
|
||||
/***** *****/
|
||||
/***********************************************************************/
|
||||
/***********************************************************************/
|
||||
|
||||
extern pid_t gettid();
|
||||
|
||||
#if !defined(_WIN32)
|
||||
|
||||
typedef struct {
|
||||
pthread_mutex_t lock;
|
||||
int has_tls;
|
||||
pthread_key_t tls;
|
||||
} thread_store_t;
|
||||
|
||||
#define THREAD_STORE_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0 }
|
||||
|
||||
#else // !defined(_WIN32)
|
||||
|
||||
typedef struct {
|
||||
int lock_init;
|
||||
int has_tls;
|
||||
DWORD tls;
|
||||
CRITICAL_SECTION lock;
|
||||
} thread_store_t;
|
||||
|
||||
#define THREAD_STORE_INITIALIZER { 0, 0, 0, {0, 0, 0, 0, 0, 0} }
|
||||
|
||||
#endif // !defined(_WIN32)
|
||||
|
||||
typedef void (*thread_store_destruct_t)(void* value);
|
||||
|
||||
extern void* thread_store_get(thread_store_t* store);
|
||||
|
||||
extern void thread_store_set(thread_store_t* store,
|
||||
void* value,
|
||||
thread_store_destruct_t destroy);
|
||||
|
||||
/***********************************************************************/
|
||||
/***********************************************************************/
|
||||
/***** *****/
|
||||
/***** mutexes *****/
|
||||
/***** *****/
|
||||
/***********************************************************************/
|
||||
/***********************************************************************/
|
||||
|
||||
#if !defined(_WIN32)
|
||||
|
||||
typedef pthread_mutex_t mutex_t;
|
||||
|
||||
#define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||
|
||||
static __inline__ void mutex_lock(mutex_t* lock)
|
||||
{
|
||||
pthread_mutex_lock(lock);
|
||||
}
|
||||
static __inline__ void mutex_unlock(mutex_t* lock)
|
||||
{
|
||||
pthread_mutex_unlock(lock);
|
||||
}
|
||||
static __inline__ int mutex_init(mutex_t* lock)
|
||||
{
|
||||
return pthread_mutex_init(lock, NULL);
|
||||
}
|
||||
static __inline__ void mutex_destroy(mutex_t* lock)
|
||||
{
|
||||
pthread_mutex_destroy(lock);
|
||||
}
|
||||
|
||||
#else // !defined(_WIN32)
|
||||
|
||||
typedef struct {
|
||||
int init;
|
||||
CRITICAL_SECTION lock[1];
|
||||
} mutex_t;
|
||||
|
||||
#define MUTEX_INITIALIZER { 0, {{ NULL, 0, 0, NULL, NULL, 0 }} }
|
||||
|
||||
static __inline__ void mutex_lock(mutex_t* lock)
|
||||
{
|
||||
if (!lock->init) {
|
||||
lock->init = 1;
|
||||
InitializeCriticalSection( lock->lock );
|
||||
lock->init = 2;
|
||||
} else while (lock->init != 2)
|
||||
Sleep(10);
|
||||
|
||||
EnterCriticalSection(lock->lock);
|
||||
}
|
||||
|
||||
static __inline__ void mutex_unlock(mutex_t* lock)
|
||||
{
|
||||
LeaveCriticalSection(lock->lock);
|
||||
}
|
||||
static __inline__ int mutex_init(mutex_t* lock)
|
||||
{
|
||||
InitializeCriticalSection(lock->lock);
|
||||
lock->init = 2;
|
||||
return 0;
|
||||
}
|
||||
static __inline__ void mutex_destroy(mutex_t* lock)
|
||||
{
|
||||
if (lock->init) {
|
||||
lock->init = 0;
|
||||
DeleteCriticalSection(lock->lock);
|
||||
}
|
||||
}
|
||||
#endif // !defined(_WIN32)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIBS_CUTILS_THREADS_H */
|
||||
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _LIBS_CUTILS_TRACE_H
|
||||
#define _LIBS_CUTILS_TRACE_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cutils/compiler.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* The ATRACE_TAG macro can be defined before including this header to trace
|
||||
* using one of the tags defined below. It must be defined to one of the
|
||||
* following ATRACE_TAG_* macros. The trace tag is used to filter tracing in
|
||||
* userland to avoid some of the runtime cost of tracing when it is not desired.
|
||||
*
|
||||
* Defining ATRACE_TAG to be ATRACE_TAG_ALWAYS will result in the tracing always
|
||||
* being enabled - this should ONLY be done for debug code, as userland tracing
|
||||
* has a performance cost even when the trace is not being recorded. Defining
|
||||
* ATRACE_TAG to be ATRACE_TAG_NEVER or leaving ATRACE_TAG undefined will result
|
||||
* in the tracing always being disabled.
|
||||
*
|
||||
* ATRACE_TAG_HAL should be bitwise ORed with the relevant tags for tracing
|
||||
* within a hardware module. For example a camera hardware module would set:
|
||||
* #define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
|
||||
*
|
||||
* Keep these in sync with frameworks/base/core/java/android/os/Trace.java.
|
||||
*/
|
||||
#define ATRACE_TAG_NEVER 0 // This tag is never enabled.
|
||||
#define ATRACE_TAG_ALWAYS (1<<0) // This tag is always enabled.
|
||||
#define ATRACE_TAG_GRAPHICS (1<<1)
|
||||
#define ATRACE_TAG_INPUT (1<<2)
|
||||
#define ATRACE_TAG_VIEW (1<<3)
|
||||
#define ATRACE_TAG_WEBVIEW (1<<4)
|
||||
#define ATRACE_TAG_WINDOW_MANAGER (1<<5)
|
||||
#define ATRACE_TAG_ACTIVITY_MANAGER (1<<6)
|
||||
#define ATRACE_TAG_SYNC_MANAGER (1<<7)
|
||||
#define ATRACE_TAG_AUDIO (1<<8)
|
||||
#define ATRACE_TAG_VIDEO (1<<9)
|
||||
#define ATRACE_TAG_CAMERA (1<<10)
|
||||
#define ATRACE_TAG_HAL (1<<11)
|
||||
#define ATRACE_TAG_APP (1<<12)
|
||||
#define ATRACE_TAG_RESOURCES (1<<13)
|
||||
#define ATRACE_TAG_DALVIK (1<<14)
|
||||
#define ATRACE_TAG_RS (1<<15)
|
||||
#define ATRACE_TAG_BIONIC (1<<16)
|
||||
#define ATRACE_TAG_POWER (1<<17)
|
||||
#define ATRACE_TAG_LAST ATRACE_TAG_POWER
|
||||
|
||||
// Reserved for initialization.
|
||||
#define ATRACE_TAG_NOT_READY (1LL<<63)
|
||||
|
||||
#define ATRACE_TAG_VALID_MASK ((ATRACE_TAG_LAST - 1) | ATRACE_TAG_LAST)
|
||||
|
||||
#ifndef ATRACE_TAG
|
||||
#define ATRACE_TAG ATRACE_TAG_NEVER
|
||||
#elif ATRACE_TAG > ATRACE_TAG_VALID_MASK
|
||||
#error ATRACE_TAG must be defined to be one of the tags defined in cutils/trace.h
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Opens the trace file for writing and reads the property for initial tags.
|
||||
* The atrace.tags.enableflags property sets the tags to trace.
|
||||
* This function should not be explicitly called, the first call to any normal
|
||||
* trace function will cause it to be run safely.
|
||||
*/
|
||||
void atrace_setup();
|
||||
|
||||
/**
|
||||
* If tracing is ready, set atrace_enabled_tags to the system property
|
||||
* debug.atrace.tags.enableflags. Can be used as a sysprop change callback.
|
||||
*/
|
||||
void atrace_update_tags();
|
||||
|
||||
/**
|
||||
* Set whether the process is debuggable. By default the process is not
|
||||
* considered debuggable. If the process is not debuggable then application-
|
||||
* level tracing is not allowed unless the ro.debuggable system property is
|
||||
* set to '1'.
|
||||
*/
|
||||
void atrace_set_debuggable(bool debuggable);
|
||||
|
||||
/**
|
||||
* Set whether tracing is enabled for the current process. This is used to
|
||||
* prevent tracing within the Zygote process.
|
||||
*/
|
||||
void atrace_set_tracing_enabled(bool enabled);
|
||||
|
||||
/**
|
||||
* Flag indicating whether setup has been completed, initialized to 0.
|
||||
* Nonzero indicates setup has completed.
|
||||
* Note: This does NOT indicate whether or not setup was successful.
|
||||
*/
|
||||
extern atomic_bool atrace_is_ready;
|
||||
|
||||
/**
|
||||
* Set of ATRACE_TAG flags to trace for, initialized to ATRACE_TAG_NOT_READY.
|
||||
* A value of zero indicates setup has failed.
|
||||
* Any other nonzero value indicates setup has succeeded, and tracing is on.
|
||||
*/
|
||||
extern uint64_t atrace_enabled_tags;
|
||||
|
||||
/**
|
||||
* Handle to the kernel's trace buffer, initialized to -1.
|
||||
* Any other value indicates setup has succeeded, and is a valid fd for tracing.
|
||||
*/
|
||||
extern int atrace_marker_fd;
|
||||
|
||||
/**
|
||||
* atrace_init readies the process for tracing by opening the trace_marker file.
|
||||
* Calling any trace function causes this to be run, so calling it is optional.
|
||||
* This can be explicitly run to avoid setup delay on first trace function.
|
||||
*/
|
||||
#define ATRACE_INIT() atrace_init()
|
||||
static inline void atrace_init()
|
||||
{
|
||||
if (CC_UNLIKELY(!atomic_load_explicit(&atrace_is_ready, memory_order_acquire))) {
|
||||
atrace_setup();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mask of all tags currently enabled.
|
||||
* It can be used as a guard condition around more expensive trace calculations.
|
||||
* Every trace function calls this, which ensures atrace_init is run.
|
||||
*/
|
||||
#define ATRACE_GET_ENABLED_TAGS() atrace_get_enabled_tags()
|
||||
static inline uint64_t atrace_get_enabled_tags()
|
||||
{
|
||||
atrace_init();
|
||||
return atrace_enabled_tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a given tag is currently enabled.
|
||||
* Returns nonzero if the tag is enabled, otherwise zero.
|
||||
* It can be used as a guard condition around more expensive trace calculations.
|
||||
*/
|
||||
#define ATRACE_ENABLED() atrace_is_tag_enabled(ATRACE_TAG)
|
||||
static inline uint64_t atrace_is_tag_enabled(uint64_t tag)
|
||||
{
|
||||
return atrace_get_enabled_tags() & tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trace the beginning of a context. name is used to identify the context.
|
||||
* This is often used to time function execution.
|
||||
*/
|
||||
#define ATRACE_BEGIN(name) atrace_begin(ATRACE_TAG, name)
|
||||
static inline void atrace_begin(uint64_t tag, const char* name)
|
||||
{
|
||||
if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
|
||||
void atrace_begin_body(const char*);
|
||||
atrace_begin_body(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trace the end of a context.
|
||||
* This should match up (and occur after) a corresponding ATRACE_BEGIN.
|
||||
*/
|
||||
#define ATRACE_END() atrace_end(ATRACE_TAG)
|
||||
static inline void atrace_end(uint64_t tag)
|
||||
{
|
||||
if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
|
||||
char c = 'E';
|
||||
write(atrace_marker_fd, &c, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trace the beginning of an asynchronous event. Unlike ATRACE_BEGIN/ATRACE_END
|
||||
* contexts, asynchronous events do not need to be nested. The name describes
|
||||
* the event, and the cookie provides a unique identifier for distinguishing
|
||||
* simultaneous events. The name and cookie used to begin an event must be
|
||||
* used to end it.
|
||||
*/
|
||||
#define ATRACE_ASYNC_BEGIN(name, cookie) \
|
||||
atrace_async_begin(ATRACE_TAG, name, cookie)
|
||||
static inline void atrace_async_begin(uint64_t tag, const char* name,
|
||||
int32_t cookie)
|
||||
{
|
||||
if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
|
||||
void atrace_async_begin_body(const char*, int32_t);
|
||||
atrace_async_begin_body(name, cookie);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trace the end of an asynchronous event.
|
||||
* This should have a corresponding ATRACE_ASYNC_BEGIN.
|
||||
*/
|
||||
#define ATRACE_ASYNC_END(name, cookie) atrace_async_end(ATRACE_TAG, name, cookie)
|
||||
static inline void atrace_async_end(uint64_t tag, const char* name, int32_t cookie)
|
||||
{
|
||||
if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
|
||||
void atrace_async_end_body(const char*, int32_t);
|
||||
atrace_async_end_body(name, cookie);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Traces an integer counter value. name is used to identify the counter.
|
||||
* This can be used to track how a value changes over time.
|
||||
*/
|
||||
#define ATRACE_INT(name, value) atrace_int(ATRACE_TAG, name, value)
|
||||
static inline void atrace_int(uint64_t tag, const char* name, int32_t value)
|
||||
{
|
||||
if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
|
||||
void atrace_int_body(const char*, int32_t);
|
||||
atrace_int_body(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Traces a 64-bit integer counter value. name is used to identify the
|
||||
* counter. This can be used to track how a value changes over time.
|
||||
*/
|
||||
#define ATRACE_INT64(name, value) atrace_int64(ATRACE_TAG, name, value)
|
||||
static inline void atrace_int64(uint64_t tag, const char* name, int64_t value)
|
||||
{
|
||||
if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
|
||||
void atrace_int64_body(const char*, int64_t);
|
||||
atrace_int64_body(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif // _LIBS_CUTILS_TRACE_H
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CUTILS_UEVENT_H
|
||||
#define __CUTILS_UEVENT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int uevent_open_socket(int buf_sz, bool passcred);
|
||||
ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length);
|
||||
ssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer, size_t length, uid_t *uid);
|
||||
ssize_t uevent_kernel_recv(int socket, void *buffer, size_t length, bool require_group, uid_t *uid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CUTILS_UEVENT_H */
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _LIBS_CUTILS_EVENTTAGMAP_H
|
||||
#define _LIBS_CUTILS_EVENTTAGMAP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define EVENT_TAG_MAP_FILE "/system/etc/event-log-tags"
|
||||
|
||||
struct EventTagMap;
|
||||
typedef struct EventTagMap EventTagMap;
|
||||
|
||||
/*
|
||||
* Open the specified file as an event log tag map.
|
||||
*
|
||||
* Returns NULL on failure.
|
||||
*/
|
||||
EventTagMap* android_openEventTagMap(const char* fileName);
|
||||
|
||||
/*
|
||||
* Close the map.
|
||||
*/
|
||||
void android_closeEventTagMap(EventTagMap* map);
|
||||
|
||||
/*
|
||||
* Look up a tag by index. Returns the tag string, or NULL if not found.
|
||||
*/
|
||||
const char* android_lookupEventTag(const EventTagMap* map, int tag);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_LIBS_CUTILS_EVENTTAGMAP_H*/
|
||||
+642
@@ -0,0 +1,642 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//
|
||||
// C/C++ logging functions. See the logging documentation for API details.
|
||||
//
|
||||
// We'd like these to be available from C code (in case we import some from
|
||||
// somewhere), so this has a C interface.
|
||||
//
|
||||
// The output will be correct when the log file is shared between multiple
|
||||
// threads and/or multiple processes so long as the operating system
|
||||
// supports O_APPEND. These calls have mutex-protected data structures
|
||||
// and so are NOT reentrant. Do not use LOG in a signal handler.
|
||||
//
|
||||
#ifndef _LIBS_LOG_LOG_H
|
||||
#define _LIBS_LOG_LOG_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <log/logd.h>
|
||||
#include <log/uio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Normally we strip ALOGV (VERBOSE messages) from release builds.
|
||||
* You can modify this (for example with "#define LOG_NDEBUG 0"
|
||||
* at the top of your source file) to change that behavior.
|
||||
*/
|
||||
#ifndef LOG_NDEBUG
|
||||
#ifdef NDEBUG
|
||||
#define LOG_NDEBUG 1
|
||||
#else
|
||||
#define LOG_NDEBUG 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is the local tag used for the following simplified
|
||||
* logging macros. You can change this preprocessor definition
|
||||
* before using the other macros to change the tag.
|
||||
*/
|
||||
#ifndef LOG_TAG
|
||||
#define LOG_TAG NULL
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
#ifndef __predict_false
|
||||
#define __predict_false(exp) __builtin_expect((exp) != 0, 0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* -DLINT_RLOG in sources that you want to enforce that all logging
|
||||
* goes to the radio log buffer. If any logging goes to any of the other
|
||||
* log buffers, there will be a compile or link error to highlight the
|
||||
* problem. This is not a replacement for a full audit of the code since
|
||||
* this only catches compiled code, not ifdef'd debug code. Options to
|
||||
* defining this, either temporarily to do a spot check, or permanently
|
||||
* to enforce, in all the communications trees; We have hopes to ensure
|
||||
* that by supplying just the radio log buffer that the communications
|
||||
* teams will have their one-stop shop for triaging issues.
|
||||
*/
|
||||
#ifndef LINT_RLOG
|
||||
|
||||
/*
|
||||
* Simplified macro to send a verbose log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef ALOGV
|
||||
#define __ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
|
||||
#if LOG_NDEBUG
|
||||
#define ALOGV(...) do { if (0) { __ALOGV(__VA_ARGS__); } } while (0)
|
||||
#else
|
||||
#define ALOGV(...) __ALOGV(__VA_ARGS__)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ALOGV_IF
|
||||
#if LOG_NDEBUG
|
||||
#define ALOGV_IF(cond, ...) ((void)0)
|
||||
#else
|
||||
#define ALOGV_IF(cond, ...) \
|
||||
( (__predict_false(cond)) \
|
||||
? ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send a debug log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef ALOGD
|
||||
#define ALOGD(...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#ifndef ALOGD_IF
|
||||
#define ALOGD_IF(cond, ...) \
|
||||
( (__predict_false(cond)) \
|
||||
? ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send an info log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef ALOGI
|
||||
#define ALOGI(...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#ifndef ALOGI_IF
|
||||
#define ALOGI_IF(cond, ...) \
|
||||
( (__predict_false(cond)) \
|
||||
? ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send a warning log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef ALOGW
|
||||
#define ALOGW(...) ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#ifndef ALOGW_IF
|
||||
#define ALOGW_IF(cond, ...) \
|
||||
( (__predict_false(cond)) \
|
||||
? ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send an error log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef ALOGE
|
||||
#define ALOGE(...) ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#ifndef ALOGE_IF
|
||||
#define ALOGE_IF(cond, ...) \
|
||||
( (__predict_false(cond)) \
|
||||
? ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Conditional based on whether the current LOG_TAG is enabled at
|
||||
* verbose priority.
|
||||
*/
|
||||
#ifndef IF_ALOGV
|
||||
#if LOG_NDEBUG
|
||||
#define IF_ALOGV() if (false)
|
||||
#else
|
||||
#define IF_ALOGV() IF_ALOG(LOG_VERBOSE, LOG_TAG)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Conditional based on whether the current LOG_TAG is enabled at
|
||||
* debug priority.
|
||||
*/
|
||||
#ifndef IF_ALOGD
|
||||
#define IF_ALOGD() IF_ALOG(LOG_DEBUG, LOG_TAG)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Conditional based on whether the current LOG_TAG is enabled at
|
||||
* info priority.
|
||||
*/
|
||||
#ifndef IF_ALOGI
|
||||
#define IF_ALOGI() IF_ALOG(LOG_INFO, LOG_TAG)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Conditional based on whether the current LOG_TAG is enabled at
|
||||
* warn priority.
|
||||
*/
|
||||
#ifndef IF_ALOGW
|
||||
#define IF_ALOGW() IF_ALOG(LOG_WARN, LOG_TAG)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Conditional based on whether the current LOG_TAG is enabled at
|
||||
* error priority.
|
||||
*/
|
||||
#ifndef IF_ALOGE
|
||||
#define IF_ALOGE() IF_ALOG(LOG_ERROR, LOG_TAG)
|
||||
#endif
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Simplified macro to send a verbose system log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef SLOGV
|
||||
#define __SLOGV(...) \
|
||||
((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
|
||||
#if LOG_NDEBUG
|
||||
#define SLOGV(...) do { if (0) { __SLOGV(__VA_ARGS__); } } while (0)
|
||||
#else
|
||||
#define SLOGV(...) __SLOGV(__VA_ARGS__)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SLOGV_IF
|
||||
#if LOG_NDEBUG
|
||||
#define SLOGV_IF(cond, ...) ((void)0)
|
||||
#else
|
||||
#define SLOGV_IF(cond, ...) \
|
||||
( (__predict_false(cond)) \
|
||||
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send a debug system log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef SLOGD
|
||||
#define SLOGD(...) \
|
||||
((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#ifndef SLOGD_IF
|
||||
#define SLOGD_IF(cond, ...) \
|
||||
( (__predict_false(cond)) \
|
||||
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send an info system log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef SLOGI
|
||||
#define SLOGI(...) \
|
||||
((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#ifndef SLOGI_IF
|
||||
#define SLOGI_IF(cond, ...) \
|
||||
( (__predict_false(cond)) \
|
||||
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send a warning system log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef SLOGW
|
||||
#define SLOGW(...) \
|
||||
((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#ifndef SLOGW_IF
|
||||
#define SLOGW_IF(cond, ...) \
|
||||
( (__predict_false(cond)) \
|
||||
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send an error system log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef SLOGE
|
||||
#define SLOGE(...) \
|
||||
((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#ifndef SLOGE_IF
|
||||
#define SLOGE_IF(cond, ...) \
|
||||
( (__predict_false(cond)) \
|
||||
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
|
||||
#endif /* !LINT_RLOG */
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Simplified macro to send a verbose radio log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef RLOGV
|
||||
#define __RLOGV(...) \
|
||||
((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
|
||||
#if LOG_NDEBUG
|
||||
#define RLOGV(...) do { if (0) { __RLOGV(__VA_ARGS__); } } while (0)
|
||||
#else
|
||||
#define RLOGV(...) __RLOGV(__VA_ARGS__)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef RLOGV_IF
|
||||
#if LOG_NDEBUG
|
||||
#define RLOGV_IF(cond, ...) ((void)0)
|
||||
#else
|
||||
#define RLOGV_IF(cond, ...) \
|
||||
( (__predict_false(cond)) \
|
||||
? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send a debug radio log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef RLOGD
|
||||
#define RLOGD(...) \
|
||||
((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#ifndef RLOGD_IF
|
||||
#define RLOGD_IF(cond, ...) \
|
||||
( (__predict_false(cond)) \
|
||||
? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send an info radio log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef RLOGI
|
||||
#define RLOGI(...) \
|
||||
((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#ifndef RLOGI_IF
|
||||
#define RLOGI_IF(cond, ...) \
|
||||
( (__predict_false(cond)) \
|
||||
? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send a warning radio log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef RLOGW
|
||||
#define RLOGW(...) \
|
||||
((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#ifndef RLOGW_IF
|
||||
#define RLOGW_IF(cond, ...) \
|
||||
( (__predict_false(cond)) \
|
||||
? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simplified macro to send an error radio log message using the current LOG_TAG.
|
||||
*/
|
||||
#ifndef RLOGE
|
||||
#define RLOGE(...) \
|
||||
((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#ifndef RLOGE_IF
|
||||
#define RLOGE_IF(cond, ...) \
|
||||
( (__predict_false(cond)) \
|
||||
? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Log a fatal error. If the given condition fails, this stops program
|
||||
* execution like a normal assertion, but also generating the given message.
|
||||
* It is NOT stripped from release builds. Note that the condition test
|
||||
* is -inverted- from the normal assert() semantics.
|
||||
*/
|
||||
#ifndef LOG_ALWAYS_FATAL_IF
|
||||
#define LOG_ALWAYS_FATAL_IF(cond, ...) \
|
||||
( (__predict_false(cond)) \
|
||||
? ((void)android_printAssert(#cond, LOG_TAG, ## __VA_ARGS__)) \
|
||||
: (void)0 )
|
||||
#endif
|
||||
|
||||
#ifndef LOG_ALWAYS_FATAL
|
||||
#define LOG_ALWAYS_FATAL(...) \
|
||||
( ((void)android_printAssert(NULL, LOG_TAG, ## __VA_ARGS__)) )
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Versions of LOG_ALWAYS_FATAL_IF and LOG_ALWAYS_FATAL that
|
||||
* are stripped out of release builds.
|
||||
*/
|
||||
#if LOG_NDEBUG
|
||||
|
||||
#ifndef LOG_FATAL_IF
|
||||
#define LOG_FATAL_IF(cond, ...) ((void)0)
|
||||
#endif
|
||||
#ifndef LOG_FATAL
|
||||
#define LOG_FATAL(...) ((void)0)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifndef LOG_FATAL_IF
|
||||
#define LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, ## __VA_ARGS__)
|
||||
#endif
|
||||
#ifndef LOG_FATAL
|
||||
#define LOG_FATAL(...) LOG_ALWAYS_FATAL(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Assertion that generates a log message when the assertion fails.
|
||||
* Stripped out of release builds. Uses the current LOG_TAG.
|
||||
*/
|
||||
#ifndef ALOG_ASSERT
|
||||
#define ALOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), ## __VA_ARGS__)
|
||||
//#define ALOG_ASSERT(cond) LOG_FATAL_IF(!(cond), "Assertion failed: " #cond)
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Basic log message macro.
|
||||
*
|
||||
* Example:
|
||||
* ALOG(LOG_WARN, NULL, "Failed with error %d", errno);
|
||||
*
|
||||
* The second argument may be NULL or "" to indicate the "global" tag.
|
||||
*/
|
||||
#ifndef ALOG
|
||||
#define ALOG(priority, tag, ...) \
|
||||
LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Log macro that allows you to specify a number for the priority.
|
||||
*/
|
||||
#ifndef LOG_PRI
|
||||
#define LOG_PRI(priority, tag, ...) \
|
||||
android_printLog(priority, tag, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Log macro that allows you to pass in a varargs ("args" is a va_list).
|
||||
*/
|
||||
#ifndef LOG_PRI_VA
|
||||
#define LOG_PRI_VA(priority, tag, fmt, args) \
|
||||
android_vprintLog(priority, NULL, tag, fmt, args)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Conditional given a desired logging priority and tag.
|
||||
*/
|
||||
#ifndef IF_ALOG
|
||||
#define IF_ALOG(priority, tag) \
|
||||
if (android_testLog(ANDROID_##priority, tag))
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Event logging.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Event log entry types. These must match up with the declarations in
|
||||
* java/android/android/util/EventLog.java.
|
||||
*/
|
||||
typedef enum {
|
||||
EVENT_TYPE_INT = 0,
|
||||
EVENT_TYPE_LONG = 1,
|
||||
EVENT_TYPE_STRING = 2,
|
||||
EVENT_TYPE_LIST = 3,
|
||||
EVENT_TYPE_FLOAT = 4,
|
||||
} AndroidEventLogType;
|
||||
#define sizeof_AndroidEventLogType sizeof(typeof_AndroidEventLogType)
|
||||
#define typeof_AndroidEventLogType unsigned char
|
||||
|
||||
#ifndef LOG_EVENT_INT
|
||||
#define LOG_EVENT_INT(_tag, _value) { \
|
||||
int intBuf = _value; \
|
||||
(void) android_btWriteLog(_tag, EVENT_TYPE_INT, &intBuf, \
|
||||
sizeof(intBuf)); \
|
||||
}
|
||||
#endif
|
||||
#ifndef LOG_EVENT_LONG
|
||||
#define LOG_EVENT_LONG(_tag, _value) { \
|
||||
long long longBuf = _value; \
|
||||
(void) android_btWriteLog(_tag, EVENT_TYPE_LONG, &longBuf, \
|
||||
sizeof(longBuf)); \
|
||||
}
|
||||
#endif
|
||||
#ifndef LOG_EVENT_FLOAT
|
||||
#define LOG_EVENT_FLOAT(_tag, _value) { \
|
||||
float floatBuf = _value; \
|
||||
(void) android_btWriteLog(_tag, EVENT_TYPE_FLOAT, &floatBuf, \
|
||||
sizeof(floatBuf)); \
|
||||
}
|
||||
#endif
|
||||
#ifndef LOG_EVENT_STRING
|
||||
#define LOG_EVENT_STRING(_tag, _value) \
|
||||
(void) __android_log_bswrite(_tag, _value);
|
||||
#endif
|
||||
/* TODO: something for LIST */
|
||||
|
||||
/*
|
||||
* ===========================================================================
|
||||
*
|
||||
* The stuff in the rest of this file should not be used directly.
|
||||
*/
|
||||
|
||||
#define android_printLog(prio, tag, fmt...) \
|
||||
__android_log_print(prio, tag, fmt)
|
||||
|
||||
#define android_vprintLog(prio, cond, tag, fmt...) \
|
||||
__android_log_vprint(prio, tag, fmt)
|
||||
|
||||
/* XXX Macros to work around syntax errors in places where format string
|
||||
* arg is not passed to ALOG_ASSERT, LOG_ALWAYS_FATAL or LOG_ALWAYS_FATAL_IF
|
||||
* (happens only in debug builds).
|
||||
*/
|
||||
|
||||
/* Returns 2nd arg. Used to substitute default value if caller's vararg list
|
||||
* is empty.
|
||||
*/
|
||||
#define __android_second(dummy, second, ...) second
|
||||
|
||||
/* If passed multiple args, returns ',' followed by all but 1st arg, otherwise
|
||||
* returns nothing.
|
||||
*/
|
||||
#define __android_rest(first, ...) , ## __VA_ARGS__
|
||||
|
||||
#define android_printAssert(cond, tag, fmt...) \
|
||||
__android_log_assert(cond, tag, \
|
||||
__android_second(0, ## fmt, NULL) __android_rest(fmt))
|
||||
|
||||
#define android_writeLog(prio, tag, text) \
|
||||
__android_log_write(prio, tag, text)
|
||||
|
||||
#define android_bWriteLog(tag, payload, len) \
|
||||
__android_log_bwrite(tag, payload, len)
|
||||
#define android_btWriteLog(tag, type, payload, len) \
|
||||
__android_log_btwrite(tag, type, payload, len)
|
||||
|
||||
#define android_errorWriteLog(tag, subTag) \
|
||||
__android_log_error_write(tag, subTag, -1, NULL, 0)
|
||||
|
||||
#define android_errorWriteWithInfoLog(tag, subTag, uid, data, dataLen) \
|
||||
__android_log_error_write(tag, subTag, uid, data, dataLen)
|
||||
|
||||
/*
|
||||
* IF_ALOG uses android_testLog, but IF_ALOG can be overridden.
|
||||
* android_testLog will remain constant in its purpose as a wrapper
|
||||
* for Android logging filter policy, and can be subject to
|
||||
* change. It can be reused by the developers that override
|
||||
* IF_ALOG as a convenient means to reimplement their policy
|
||||
* over Android.
|
||||
*/
|
||||
#if LOG_NDEBUG /* Production */
|
||||
#define android_testLog(prio, tag) \
|
||||
(__android_log_is_loggable(prio, tag, ANDROID_LOG_DEBUG) != 0)
|
||||
#else
|
||||
#define android_testLog(prio, tag) \
|
||||
(__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE) != 0)
|
||||
#endif
|
||||
|
||||
// TODO: remove these prototypes and their users
|
||||
#define android_writevLog(vec,num) do{}while(0)
|
||||
#define android_write1Log(str,len) do{}while (0)
|
||||
#define android_setMinPriority(tag, prio) do{}while(0)
|
||||
//#define android_logToCallback(func) do{}while(0)
|
||||
#define android_logToFile(tag, file) (0)
|
||||
#define android_logToFd(tag, fd) (0)
|
||||
|
||||
#ifndef log_id_t_defined
|
||||
#define log_id_t_defined
|
||||
|
||||
typedef enum log_id {
|
||||
LOG_ID_MIN = 0,
|
||||
|
||||
#ifndef LINT_RLOG
|
||||
LOG_ID_MAIN = 0,
|
||||
#endif
|
||||
LOG_ID_RADIO = 1,
|
||||
#ifndef LINT_RLOG
|
||||
LOG_ID_EVENTS = 2,
|
||||
LOG_ID_SYSTEM = 3,
|
||||
LOG_ID_CRASH = 4,
|
||||
LOG_ID_KERNEL = 5,
|
||||
#endif
|
||||
|
||||
LOG_ID_MAX
|
||||
} log_id_t;
|
||||
#endif
|
||||
#define sizeof_log_id_t sizeof(typeof_log_id_t)
|
||||
#define typeof_log_id_t unsigned char
|
||||
|
||||
/*
|
||||
* Use the per-tag properties "log.tag.<tagname>" to generate a runtime
|
||||
* result of non-zero to expose a log.
|
||||
*/
|
||||
int __android_log_is_loggable(int prio, const char *tag, int def);
|
||||
|
||||
int __android_log_error_write(int tag, const char *subTag, int32_t uid, const char *data,
|
||||
uint32_t dataLen);
|
||||
|
||||
/*
|
||||
* Send a simple string to the log.
|
||||
*/
|
||||
int __android_log_buf_write(int bufID, int prio, const char *tag, const char *text);
|
||||
int __android_log_buf_print(int bufID, int prio, const char *tag, const char *fmt, ...)
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((__format__(printf, 4, 5)))
|
||||
#endif
|
||||
;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIBS_LOG_LOG_H */
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (C) 2013-2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _LIBS_LOG_LOG_READ_H
|
||||
#define _LIBS_LOG_LOG_READ_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
/* struct log_time is a wire-format variant of struct timespec */
|
||||
#define NS_PER_SEC 1000000000ULL
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
// NB: do NOT define a copy constructor. This will result in structure
|
||||
// no longer being compatible with pass-by-value which is desired
|
||||
// efficient behavior. Also, pass-by-reference breaks C/C++ ABI.
|
||||
struct log_time {
|
||||
public:
|
||||
uint32_t tv_sec; // good to Feb 5 2106
|
||||
uint32_t tv_nsec;
|
||||
|
||||
static const uint32_t tv_sec_max = 0xFFFFFFFFUL;
|
||||
static const uint32_t tv_nsec_max = 999999999UL;
|
||||
|
||||
log_time(const timespec &T)
|
||||
{
|
||||
tv_sec = T.tv_sec;
|
||||
tv_nsec = T.tv_nsec;
|
||||
}
|
||||
log_time(uint32_t sec, uint32_t nsec)
|
||||
{
|
||||
tv_sec = sec;
|
||||
tv_nsec = nsec;
|
||||
}
|
||||
static const timespec EPOCH;
|
||||
log_time()
|
||||
{
|
||||
}
|
||||
log_time(clockid_t id)
|
||||
{
|
||||
timespec T;
|
||||
clock_gettime(id, &T);
|
||||
tv_sec = T.tv_sec;
|
||||
tv_nsec = T.tv_nsec;
|
||||
}
|
||||
log_time(const char *T)
|
||||
{
|
||||
const uint8_t *c = (const uint8_t *) T;
|
||||
tv_sec = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
|
||||
tv_nsec = c[4] | (c[5] << 8) | (c[6] << 16) | (c[7] << 24);
|
||||
}
|
||||
|
||||
// timespec
|
||||
bool operator== (const timespec &T) const
|
||||
{
|
||||
return (tv_sec == static_cast<uint32_t>(T.tv_sec))
|
||||
&& (tv_nsec == static_cast<uint32_t>(T.tv_nsec));
|
||||
}
|
||||
bool operator!= (const timespec &T) const
|
||||
{
|
||||
return !(*this == T);
|
||||
}
|
||||
bool operator< (const timespec &T) const
|
||||
{
|
||||
return (tv_sec < static_cast<uint32_t>(T.tv_sec))
|
||||
|| ((tv_sec == static_cast<uint32_t>(T.tv_sec))
|
||||
&& (tv_nsec < static_cast<uint32_t>(T.tv_nsec)));
|
||||
}
|
||||
bool operator>= (const timespec &T) const
|
||||
{
|
||||
return !(*this < T);
|
||||
}
|
||||
bool operator> (const timespec &T) const
|
||||
{
|
||||
return (tv_sec > static_cast<uint32_t>(T.tv_sec))
|
||||
|| ((tv_sec == static_cast<uint32_t>(T.tv_sec))
|
||||
&& (tv_nsec > static_cast<uint32_t>(T.tv_nsec)));
|
||||
}
|
||||
bool operator<= (const timespec &T) const
|
||||
{
|
||||
return !(*this > T);
|
||||
}
|
||||
log_time operator-= (const timespec &T);
|
||||
log_time operator- (const timespec &T) const
|
||||
{
|
||||
log_time local(*this);
|
||||
return local -= T;
|
||||
}
|
||||
log_time operator+= (const timespec &T);
|
||||
log_time operator+ (const timespec &T) const
|
||||
{
|
||||
log_time local(*this);
|
||||
return local += T;
|
||||
}
|
||||
|
||||
// log_time
|
||||
bool operator== (const log_time &T) const
|
||||
{
|
||||
return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec);
|
||||
}
|
||||
bool operator!= (const log_time &T) const
|
||||
{
|
||||
return !(*this == T);
|
||||
}
|
||||
bool operator< (const log_time &T) const
|
||||
{
|
||||
return (tv_sec < T.tv_sec)
|
||||
|| ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec));
|
||||
}
|
||||
bool operator>= (const log_time &T) const
|
||||
{
|
||||
return !(*this < T);
|
||||
}
|
||||
bool operator> (const log_time &T) const
|
||||
{
|
||||
return (tv_sec > T.tv_sec)
|
||||
|| ((tv_sec == T.tv_sec) && (tv_nsec > T.tv_nsec));
|
||||
}
|
||||
bool operator<= (const log_time &T) const
|
||||
{
|
||||
return !(*this > T);
|
||||
}
|
||||
log_time operator-= (const log_time &T);
|
||||
log_time operator- (const log_time &T) const
|
||||
{
|
||||
log_time local(*this);
|
||||
return local -= T;
|
||||
}
|
||||
log_time operator+= (const log_time &T);
|
||||
log_time operator+ (const log_time &T) const
|
||||
{
|
||||
log_time local(*this);
|
||||
return local += T;
|
||||
}
|
||||
|
||||
uint64_t nsec() const
|
||||
{
|
||||
return static_cast<uint64_t>(tv_sec) * NS_PER_SEC + tv_nsec;
|
||||
}
|
||||
|
||||
static const char default_format[];
|
||||
|
||||
// Add %#q for the fraction of a second to the standard library functions
|
||||
char *strptime(const char *s, const char *format = default_format);
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#else
|
||||
|
||||
typedef struct log_time {
|
||||
uint32_t tv_sec;
|
||||
uint32_t tv_nsec;
|
||||
} __attribute__((__packed__)) log_time;
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* define _LIBS_LOG_LOG_READ_H */
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _ANDROID_CUTILS_LOGD_H
|
||||
#define _ANDROID_CUTILS_LOGD_H
|
||||
|
||||
/* the stable/frozen log-related definitions have been
|
||||
* moved to this header, which is exposed by the NDK
|
||||
*/
|
||||
#include <android/log.h>
|
||||
|
||||
/* the rest is only used internally by the system */
|
||||
#if !defined(_WIN32)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <log/uio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int __android_log_bwrite(int32_t tag, const void *payload, size_t len);
|
||||
int __android_log_btwrite(int32_t tag, char type, const void *payload,
|
||||
size_t len);
|
||||
int __android_log_bswrite(int32_t tag, const char *payload);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LOGD_H */
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
**
|
||||
** Copyright 2007-2014, The Android Open Source Project
|
||||
**
|
||||
** This file is dual licensed. It may be redistributed and/or modified
|
||||
** under the terms of the Apache 2.0 License OR version 2 of the GNU
|
||||
** General Public License.
|
||||
*/
|
||||
|
||||
#ifndef _LIBS_LOG_LOGGER_H
|
||||
#define _LIBS_LOG_LOGGER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <log/log.h>
|
||||
#include <log/log_read.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The userspace structure for version 1 of the logger_entry ABI.
|
||||
* This structure is returned to userspace by the kernel logger
|
||||
* driver unless an upgrade to a newer ABI version is requested.
|
||||
*/
|
||||
struct logger_entry {
|
||||
uint16_t len; /* length of the payload */
|
||||
uint16_t __pad; /* no matter what, we get 2 bytes of padding */
|
||||
int32_t pid; /* generating process's pid */
|
||||
int32_t tid; /* generating process's tid */
|
||||
int32_t sec; /* seconds since Epoch */
|
||||
int32_t nsec; /* nanoseconds */
|
||||
char msg[0]; /* the entry's payload */
|
||||
} __attribute__((__packed__));
|
||||
|
||||
/*
|
||||
* The userspace structure for version 2 of the logger_entry ABI.
|
||||
* This structure is returned to userspace if ioctl(LOGGER_SET_VERSION)
|
||||
* is called with version==2; or used with the user space log daemon.
|
||||
*/
|
||||
struct logger_entry_v2 {
|
||||
uint16_t len; /* length of the payload */
|
||||
uint16_t hdr_size; /* sizeof(struct logger_entry_v2) */
|
||||
int32_t pid; /* generating process's pid */
|
||||
int32_t tid; /* generating process's tid */
|
||||
int32_t sec; /* seconds since Epoch */
|
||||
int32_t nsec; /* nanoseconds */
|
||||
uint32_t euid; /* effective UID of logger */
|
||||
char msg[0]; /* the entry's payload */
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct logger_entry_v3 {
|
||||
uint16_t len; /* length of the payload */
|
||||
uint16_t hdr_size; /* sizeof(struct logger_entry_v3) */
|
||||
int32_t pid; /* generating process's pid */
|
||||
int32_t tid; /* generating process's tid */
|
||||
int32_t sec; /* seconds since Epoch */
|
||||
int32_t nsec; /* nanoseconds */
|
||||
uint32_t lid; /* log id of the payload */
|
||||
char msg[0]; /* the entry's payload */
|
||||
} __attribute__((__packed__));
|
||||
|
||||
/*
|
||||
* The maximum size of the log entry payload that can be
|
||||
* written to the logger. An attempt to write more than
|
||||
* this amount will result in a truncated log entry.
|
||||
*/
|
||||
#define LOGGER_ENTRY_MAX_PAYLOAD 4076
|
||||
|
||||
/*
|
||||
* The maximum size of a log entry which can be read from the
|
||||
* kernel logger driver. An attempt to read less than this amount
|
||||
* may result in read() returning EINVAL.
|
||||
*/
|
||||
#define LOGGER_ENTRY_MAX_LEN (5*1024)
|
||||
|
||||
#define NS_PER_SEC 1000000000ULL
|
||||
|
||||
struct log_msg {
|
||||
union {
|
||||
unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1];
|
||||
struct logger_entry_v3 entry;
|
||||
struct logger_entry_v3 entry_v3;
|
||||
struct logger_entry_v2 entry_v2;
|
||||
struct logger_entry entry_v1;
|
||||
} __attribute__((aligned(4)));
|
||||
#ifdef __cplusplus
|
||||
/* Matching log_time operators */
|
||||
bool operator== (const log_msg &T) const
|
||||
{
|
||||
return (entry.sec == T.entry.sec) && (entry.nsec == T.entry.nsec);
|
||||
}
|
||||
bool operator!= (const log_msg &T) const
|
||||
{
|
||||
return !(*this == T);
|
||||
}
|
||||
bool operator< (const log_msg &T) const
|
||||
{
|
||||
return (entry.sec < T.entry.sec)
|
||||
|| ((entry.sec == T.entry.sec)
|
||||
&& (entry.nsec < T.entry.nsec));
|
||||
}
|
||||
bool operator>= (const log_msg &T) const
|
||||
{
|
||||
return !(*this < T);
|
||||
}
|
||||
bool operator> (const log_msg &T) const
|
||||
{
|
||||
return (entry.sec > T.entry.sec)
|
||||
|| ((entry.sec == T.entry.sec)
|
||||
&& (entry.nsec > T.entry.nsec));
|
||||
}
|
||||
bool operator<= (const log_msg &T) const
|
||||
{
|
||||
return !(*this > T);
|
||||
}
|
||||
uint64_t nsec() const
|
||||
{
|
||||
return static_cast<uint64_t>(entry.sec) * NS_PER_SEC + entry.nsec;
|
||||
}
|
||||
|
||||
/* packet methods */
|
||||
log_id_t id()
|
||||
{
|
||||
return (log_id_t) entry.lid;
|
||||
}
|
||||
char *msg()
|
||||
{
|
||||
return entry.hdr_size ? (char *) buf + entry.hdr_size : entry_v1.msg;
|
||||
}
|
||||
unsigned int len()
|
||||
{
|
||||
return (entry.hdr_size ? entry.hdr_size : sizeof(entry_v1)) + entry.len;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
struct logger;
|
||||
|
||||
log_id_t android_logger_get_id(struct logger *logger);
|
||||
|
||||
int android_logger_clear(struct logger *logger);
|
||||
long android_logger_get_log_size(struct logger *logger);
|
||||
int android_logger_set_log_size(struct logger *logger, unsigned long size);
|
||||
long android_logger_get_log_readable_size(struct logger *logger);
|
||||
int android_logger_get_log_version(struct logger *logger);
|
||||
|
||||
struct logger_list;
|
||||
|
||||
ssize_t android_logger_get_statistics(struct logger_list *logger_list,
|
||||
char *buf, size_t len);
|
||||
ssize_t android_logger_get_prune_list(struct logger_list *logger_list,
|
||||
char *buf, size_t len);
|
||||
int android_logger_set_prune_list(struct logger_list *logger_list,
|
||||
char *buf, size_t len);
|
||||
|
||||
#define ANDROID_LOG_RDONLY O_RDONLY
|
||||
#define ANDROID_LOG_WRONLY O_WRONLY
|
||||
#define ANDROID_LOG_RDWR O_RDWR
|
||||
#define ANDROID_LOG_ACCMODE O_ACCMODE
|
||||
#define ANDROID_LOG_NONBLOCK O_NONBLOCK
|
||||
#define ANDROID_LOG_PSTORE 0x80000000
|
||||
|
||||
struct logger_list *android_logger_list_alloc(int mode,
|
||||
unsigned int tail,
|
||||
pid_t pid);
|
||||
struct logger_list *android_logger_list_alloc_time(int mode,
|
||||
log_time start,
|
||||
pid_t pid);
|
||||
void android_logger_list_free(struct logger_list *logger_list);
|
||||
/* In the purest sense, the following two are orthogonal interfaces */
|
||||
int android_logger_list_read(struct logger_list *logger_list,
|
||||
struct log_msg *log_msg);
|
||||
|
||||
/* Multiple log_id_t opens */
|
||||
struct logger *android_logger_open(struct logger_list *logger_list,
|
||||
log_id_t id);
|
||||
#define android_logger_close android_logger_free
|
||||
/* Single log_id_t open */
|
||||
struct logger_list *android_logger_list_open(log_id_t id,
|
||||
int mode,
|
||||
unsigned int tail,
|
||||
pid_t pid);
|
||||
#define android_logger_list_close android_logger_list_free
|
||||
|
||||
/*
|
||||
* log_id_t helpers
|
||||
*/
|
||||
log_id_t android_name_to_log_id(const char *logName);
|
||||
const char *android_log_id_to_name(log_id_t log_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIBS_LOG_LOGGER_H */
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _LOGPRINT_H
|
||||
#define _LOGPRINT_H
|
||||
|
||||
#include <log/log.h>
|
||||
#include <log/logger.h>
|
||||
#include <log/event_tag_map.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
FORMAT_OFF = 0,
|
||||
FORMAT_BRIEF,
|
||||
FORMAT_PROCESS,
|
||||
FORMAT_TAG,
|
||||
FORMAT_THREAD,
|
||||
FORMAT_RAW,
|
||||
FORMAT_TIME,
|
||||
FORMAT_THREADTIME,
|
||||
FORMAT_LONG,
|
||||
/* The following three are modifiers to above formats */
|
||||
FORMAT_MODIFIER_COLOR, /* converts priority to color */
|
||||
FORMAT_MODIFIER_TIME_USEC, /* switches from msec to usec time precision */
|
||||
FORMAT_MODIFIER_PRINTABLE, /* converts non-printable to printable escapes */
|
||||
} AndroidLogPrintFormat;
|
||||
|
||||
typedef struct AndroidLogFormat_t AndroidLogFormat;
|
||||
|
||||
typedef struct AndroidLogEntry_t {
|
||||
time_t tv_sec;
|
||||
long tv_nsec;
|
||||
android_LogPriority priority;
|
||||
int32_t pid;
|
||||
int32_t tid;
|
||||
const char * tag;
|
||||
size_t messageLen;
|
||||
const char * message;
|
||||
} AndroidLogEntry;
|
||||
|
||||
AndroidLogFormat *android_log_format_new();
|
||||
|
||||
void android_log_format_free(AndroidLogFormat *p_format);
|
||||
|
||||
/* currently returns 0 if format is a modifier, 1 if not */
|
||||
int android_log_setPrintFormat(AndroidLogFormat *p_format,
|
||||
AndroidLogPrintFormat format);
|
||||
|
||||
/**
|
||||
* Returns FORMAT_OFF on invalid string
|
||||
*/
|
||||
AndroidLogPrintFormat android_log_formatFromString(const char *s);
|
||||
|
||||
/**
|
||||
* filterExpression: a single filter expression
|
||||
* eg "AT:d"
|
||||
*
|
||||
* returns 0 on success and -1 on invalid expression
|
||||
*
|
||||
* Assumes single threaded execution
|
||||
*
|
||||
*/
|
||||
|
||||
int android_log_addFilterRule(AndroidLogFormat *p_format,
|
||||
const char *filterExpression);
|
||||
|
||||
|
||||
/**
|
||||
* filterString: a whitespace-separated set of filter expressions
|
||||
* eg "AT:d *:i"
|
||||
*
|
||||
* returns 0 on success and -1 on invalid expression
|
||||
*
|
||||
* Assumes single threaded execution
|
||||
*
|
||||
*/
|
||||
|
||||
int android_log_addFilterString(AndroidLogFormat *p_format,
|
||||
const char *filterString);
|
||||
|
||||
|
||||
/**
|
||||
* returns 1 if this log line should be printed based on its priority
|
||||
* and tag, and 0 if it should not
|
||||
*/
|
||||
int android_log_shouldPrintLine (
|
||||
AndroidLogFormat *p_format, const char *tag, android_LogPriority pri);
|
||||
|
||||
|
||||
/**
|
||||
* Splits a wire-format buffer into an AndroidLogEntry
|
||||
* entry allocated by caller. Pointers will point directly into buf
|
||||
*
|
||||
* Returns 0 on success and -1 on invalid wire format (entry will be
|
||||
* in unspecified state)
|
||||
*/
|
||||
int android_log_processLogBuffer(struct logger_entry *buf,
|
||||
AndroidLogEntry *entry);
|
||||
|
||||
/**
|
||||
* Like android_log_processLogBuffer, but for binary logs.
|
||||
*
|
||||
* If "map" is non-NULL, it will be used to convert the log tag number
|
||||
* into a string.
|
||||
*/
|
||||
int android_log_processBinaryLogBuffer(struct logger_entry *buf,
|
||||
AndroidLogEntry *entry, const EventTagMap* map, char* messageBuf,
|
||||
int messageBufLen);
|
||||
|
||||
|
||||
/**
|
||||
* Formats a log message into a buffer
|
||||
*
|
||||
* Uses defaultBuffer if it can, otherwise malloc()'s a new buffer
|
||||
* If return value != defaultBuffer, caller must call free()
|
||||
* Returns NULL on malloc error
|
||||
*/
|
||||
|
||||
char *android_log_formatLogLine (
|
||||
AndroidLogFormat *p_format,
|
||||
char *defaultBuffer,
|
||||
size_t defaultBufferSize,
|
||||
const AndroidLogEntry *p_line,
|
||||
size_t *p_outLength);
|
||||
|
||||
|
||||
/**
|
||||
* Either print or do not print log line, based on filter
|
||||
*
|
||||
* Assumes single threaded execution
|
||||
*
|
||||
*/
|
||||
int android_log_printLogLine(
|
||||
AndroidLogFormat *p_format,
|
||||
int fd,
|
||||
const AndroidLogEntry *entry);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*_LOGPRINT_H*/
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2007-2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _LIBS_CUTILS_UIO_H
|
||||
#define _LIBS_CUTILS_UIO_H
|
||||
|
||||
#if !defined(_WIN32)
|
||||
|
||||
#include <sys/uio.h>
|
||||
|
||||
#else
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//
|
||||
// Implementation of sys/uio.h for Win32.
|
||||
//
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct iovec {
|
||||
void* iov_base;
|
||||
size_t iov_len;
|
||||
};
|
||||
|
||||
extern int readv( int fd, struct iovec* vecs, int count );
|
||||
extern int writev( int fd, const struct iovec* vecs, int count );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _LIBS_UTILS_UIO_H */
|
||||
|
||||
@@ -0,0 +1,365 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SYSTEM_CORE_INCLUDE_ANDROID_CAMERA_H
|
||||
#define SYSTEM_CORE_INCLUDE_ANDROID_CAMERA_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
#include <cutils/native_handle.h>
|
||||
#include <hardware/hardware.h>
|
||||
#include <hardware/gralloc.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* A set of bit masks for specifying how the received preview frames are
|
||||
* handled before the previewCallback() call.
|
||||
*
|
||||
* The least significant 3 bits of an "int" value are used for this purpose:
|
||||
*
|
||||
* ..... 0 0 0
|
||||
* ^ ^ ^
|
||||
* | | |---------> determine whether the callback is enabled or not
|
||||
* | |-----------> determine whether the callback is one-shot or not
|
||||
* |-------------> determine whether the frame is copied out or not
|
||||
*
|
||||
* WARNING: When a frame is sent directly without copying, it is the frame
|
||||
* receiver's responsiblity to make sure that the frame data won't get
|
||||
* corrupted by subsequent preview frames filled by the camera. This flag is
|
||||
* recommended only when copying out data brings significant performance price
|
||||
* and the handling/processing of the received frame data is always faster than
|
||||
* the preview frame rate so that data corruption won't occur.
|
||||
*
|
||||
* For instance,
|
||||
* 1. 0x00 disables the callback. In this case, copy out and one shot bits
|
||||
* are ignored.
|
||||
* 2. 0x01 enables a callback without copying out the received frames. A
|
||||
* typical use case is the Camcorder application to avoid making costly
|
||||
* frame copies.
|
||||
* 3. 0x05 is enabling a callback with frame copied out repeatedly. A typical
|
||||
* use case is the Camera application.
|
||||
* 4. 0x07 is enabling a callback with frame copied out only once. A typical
|
||||
* use case is the Barcode scanner application.
|
||||
*/
|
||||
|
||||
enum {
|
||||
CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK = 0x01,
|
||||
CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK = 0x02,
|
||||
CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK = 0x04,
|
||||
/** Typical use cases */
|
||||
CAMERA_FRAME_CALLBACK_FLAG_NOOP = 0x00,
|
||||
CAMERA_FRAME_CALLBACK_FLAG_CAMCORDER = 0x01,
|
||||
CAMERA_FRAME_CALLBACK_FLAG_CAMERA = 0x05,
|
||||
CAMERA_FRAME_CALLBACK_FLAG_BARCODE_SCANNER = 0x07
|
||||
};
|
||||
|
||||
/** msgType in notifyCallback and dataCallback functions */
|
||||
enum {
|
||||
CAMERA_MSG_ERROR = 0x0001, // notifyCallback
|
||||
CAMERA_MSG_SHUTTER = 0x0002, // notifyCallback
|
||||
CAMERA_MSG_FOCUS = 0x0004, // notifyCallback
|
||||
CAMERA_MSG_ZOOM = 0x0008, // notifyCallback
|
||||
CAMERA_MSG_PREVIEW_FRAME = 0x0010, // dataCallback
|
||||
CAMERA_MSG_VIDEO_FRAME = 0x0020, // data_timestamp_callback
|
||||
CAMERA_MSG_POSTVIEW_FRAME = 0x0040, // dataCallback
|
||||
CAMERA_MSG_RAW_IMAGE = 0x0080, // dataCallback
|
||||
CAMERA_MSG_COMPRESSED_IMAGE = 0x0100, // dataCallback
|
||||
CAMERA_MSG_RAW_IMAGE_NOTIFY = 0x0200, // dataCallback
|
||||
// Preview frame metadata. This can be combined with
|
||||
// CAMERA_MSG_PREVIEW_FRAME in dataCallback. For example, the apps can
|
||||
// request FRAME and METADATA. Or the apps can request only FRAME or only
|
||||
// METADATA.
|
||||
CAMERA_MSG_PREVIEW_METADATA = 0x0400, // dataCallback
|
||||
// Notify on autofocus start and stop. This is useful in continuous
|
||||
// autofocus - FOCUS_MODE_CONTINUOUS_VIDEO and FOCUS_MODE_CONTINUOUS_PICTURE.
|
||||
CAMERA_MSG_FOCUS_MOVE = 0x0800, // notifyCallback
|
||||
CAMERA_MSG_VENDOR_START = 0x1000,
|
||||
CAMERA_MSG_STATS_DATA = CAMERA_MSG_VENDOR_START,
|
||||
CAMERA_MSG_META_DATA = 0x2000,
|
||||
CAMERA_MSG_VENDOR_END = 0x8000,
|
||||
CAMERA_MSG_ALL_MSGS = 0xFFFF
|
||||
};
|
||||
|
||||
/** meta data type in CameraMetaDataCallback */
|
||||
enum {
|
||||
CAMERA_META_DATA_ASD = 0x001, //ASD data
|
||||
CAMERA_META_DATA_FD = 0x002, //FD/FP data
|
||||
CAMERA_META_DATA_HDR = 0x003, //Auto HDR data
|
||||
};
|
||||
|
||||
/** cmdType in sendCommand functions */
|
||||
enum {
|
||||
CAMERA_CMD_START_SMOOTH_ZOOM = 1,
|
||||
CAMERA_CMD_STOP_SMOOTH_ZOOM = 2,
|
||||
|
||||
/**
|
||||
* Set the clockwise rotation of preview display (setPreviewDisplay) in
|
||||
* degrees. This affects the preview frames and the picture displayed after
|
||||
* snapshot. This method is useful for portrait mode applications. Note
|
||||
* that preview display of front-facing cameras is flipped horizontally
|
||||
* before the rotation, that is, the image is reflected along the central
|
||||
* vertical axis of the camera sensor. So the users can see themselves as
|
||||
* looking into a mirror.
|
||||
*
|
||||
* This does not affect the order of byte array of
|
||||
* CAMERA_MSG_PREVIEW_FRAME, CAMERA_MSG_VIDEO_FRAME,
|
||||
* CAMERA_MSG_POSTVIEW_FRAME, CAMERA_MSG_RAW_IMAGE, or
|
||||
* CAMERA_MSG_COMPRESSED_IMAGE. This is allowed to be set during preview
|
||||
* since API level 14.
|
||||
*/
|
||||
CAMERA_CMD_SET_DISPLAY_ORIENTATION = 3,
|
||||
|
||||
/**
|
||||
* cmdType to disable/enable shutter sound. In sendCommand passing arg1 =
|
||||
* 0 will disable, while passing arg1 = 1 will enable the shutter sound.
|
||||
*/
|
||||
CAMERA_CMD_ENABLE_SHUTTER_SOUND = 4,
|
||||
|
||||
/* cmdType to play recording sound */
|
||||
CAMERA_CMD_PLAY_RECORDING_SOUND = 5,
|
||||
|
||||
/**
|
||||
* Start the face detection. This should be called after preview is started.
|
||||
* The camera will notify the listener of CAMERA_MSG_FACE and the detected
|
||||
* faces in the preview frame. The detected faces may be the same as the
|
||||
* previous ones. Apps should call CAMERA_CMD_STOP_FACE_DETECTION to stop
|
||||
* the face detection. This method is supported if CameraParameters
|
||||
* KEY_MAX_NUM_HW_DETECTED_FACES or KEY_MAX_NUM_SW_DETECTED_FACES is
|
||||
* bigger than 0. Hardware and software face detection should not be running
|
||||
* at the same time. If the face detection has started, apps should not send
|
||||
* this again.
|
||||
*
|
||||
* In hardware face detection mode, CameraParameters KEY_WHITE_BALANCE,
|
||||
* KEY_FOCUS_AREAS and KEY_METERING_AREAS have no effect.
|
||||
*
|
||||
* arg1 is the face detection type. It can be CAMERA_FACE_DETECTION_HW or
|
||||
* CAMERA_FACE_DETECTION_SW. If the type of face detection requested is not
|
||||
* supported, the HAL must return BAD_VALUE.
|
||||
*/
|
||||
CAMERA_CMD_START_FACE_DETECTION = 6,
|
||||
|
||||
/**
|
||||
* Stop the face detection.
|
||||
*/
|
||||
CAMERA_CMD_STOP_FACE_DETECTION = 7,
|
||||
|
||||
/**
|
||||
* Enable/disable focus move callback (CAMERA_MSG_FOCUS_MOVE). Passing
|
||||
* arg1 = 0 will disable, while passing arg1 = 1 will enable the callback.
|
||||
*/
|
||||
CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG = 8,
|
||||
|
||||
/**
|
||||
* Ping camera service to see if camera hardware is released.
|
||||
*
|
||||
* When any camera method returns error, the client can use ping command
|
||||
* to see if the camera has been taken away by other clients. If the result
|
||||
* is NO_ERROR, it means the camera hardware is not released. If the result
|
||||
* is not NO_ERROR, the camera has been released and the existing client
|
||||
* can silently finish itself or show a dialog.
|
||||
*/
|
||||
CAMERA_CMD_PING = 9,
|
||||
|
||||
/**
|
||||
* Configure the number of video buffers used for recording. The intended
|
||||
* video buffer count for recording is passed as arg1, which must be
|
||||
* greater than 0. This command must be sent before recording is started.
|
||||
* This command returns INVALID_OPERATION error if it is sent after video
|
||||
* recording is started, or the command is not supported at all. This
|
||||
* command also returns a BAD_VALUE error if the intended video buffer
|
||||
* count is non-positive or too big to be realized.
|
||||
*/
|
||||
CAMERA_CMD_SET_VIDEO_BUFFER_COUNT = 10,
|
||||
|
||||
/**
|
||||
* Configure an explicit format to use for video recording metadata mode.
|
||||
* This can be used to switch the format from the
|
||||
* default IMPLEMENTATION_DEFINED gralloc format to some other
|
||||
* device-supported format, and the default dataspace from the BT_709 color
|
||||
* space to some other device-supported dataspace. arg1 is the HAL pixel
|
||||
* format, and arg2 is the HAL dataSpace. This command returns
|
||||
* INVALID_OPERATION error if it is sent after video recording is started,
|
||||
* or the command is not supported at all.
|
||||
*
|
||||
* If the gralloc format is set to a format other than
|
||||
* IMPLEMENTATION_DEFINED, then HALv3 devices will use gralloc usage flags
|
||||
* of SW_READ_OFTEN.
|
||||
*/
|
||||
#ifndef CAMERA_VENDOR_L_COMPAT
|
||||
CAMERA_CMD_SET_VIDEO_FORMAT = 11,
|
||||
|
||||
CAMERA_CMD_VENDOR_START = 20,
|
||||
/**
|
||||
* Commands to enable/disable preview histogram
|
||||
*
|
||||
* Based on user's input to enable/disable histogram from the camera
|
||||
* UI, send the appropriate command to the HAL to turn on/off the histogram
|
||||
* stats and start sending the data to the application.
|
||||
*/
|
||||
CAMERA_CMD_HISTOGRAM_ON = CAMERA_CMD_VENDOR_START,
|
||||
CAMERA_CMD_HISTOGRAM_OFF = CAMERA_CMD_VENDOR_START + 1,
|
||||
CAMERA_CMD_HISTOGRAM_SEND_DATA = CAMERA_CMD_VENDOR_START + 2,
|
||||
CAMERA_CMD_LONGSHOT_ON = CAMERA_CMD_VENDOR_START + 3,
|
||||
CAMERA_CMD_LONGSHOT_OFF = CAMERA_CMD_VENDOR_START + 4,
|
||||
CAMERA_CMD_STOP_LONGSHOT = CAMERA_CMD_VENDOR_START + 5,
|
||||
CAMERA_CMD_METADATA_ON = CAMERA_CMD_VENDOR_START + 6,
|
||||
CAMERA_CMD_METADATA_OFF = CAMERA_CMD_VENDOR_START + 7,
|
||||
CAMERA_CMD_VENDOR_END = 200,
|
||||
#else
|
||||
|
||||
/**
|
||||
* Values used by older HALs, provided as an option for compatibility
|
||||
*/
|
||||
CAMERA_CMD_HISTOGRAM_ON = 11,
|
||||
CAMERA_CMD_HISTOGRAM_OFF = 12,
|
||||
CAMERA_CMD_HISTOGRAM_SEND_DATA = 13,
|
||||
CAMERA_CMD_LONGSHOT_ON = 14,
|
||||
CAMERA_CMD_LONGSHOT_OFF = 15,
|
||||
CAMERA_CMD_STOP_LONGSHOT = 16,
|
||||
CAMERA_CMD_METADATA_ON = 100,
|
||||
CAMERA_CMD_METADATA_OFF = 101,
|
||||
CAMERA_CMD_SET_VIDEO_FORMAT = 102,
|
||||
#endif
|
||||
};
|
||||
|
||||
/** camera fatal errors */
|
||||
enum {
|
||||
CAMERA_ERROR_UNKNOWN = 1,
|
||||
/**
|
||||
* Camera was released because another client has connected to the camera.
|
||||
* The original client should call Camera::disconnect immediately after
|
||||
* getting this notification. Otherwise, the camera will be released by
|
||||
* camera service in a short time. The client should not call any method
|
||||
* (except disconnect and sending CAMERA_CMD_PING) after getting this.
|
||||
*/
|
||||
CAMERA_ERROR_RELEASED = 2,
|
||||
CAMERA_ERROR_SERVER_DIED = 100
|
||||
};
|
||||
|
||||
enum {
|
||||
/** The facing of the camera is opposite to that of the screen. */
|
||||
CAMERA_FACING_BACK = 0,
|
||||
/** The facing of the camera is the same as that of the screen. */
|
||||
CAMERA_FACING_FRONT = 1,
|
||||
/**
|
||||
* The facing of the camera is not fixed relative to the screen.
|
||||
* The cameras with this facing are external cameras, e.g. USB cameras.
|
||||
*/
|
||||
CAMERA_FACING_EXTERNAL = 2
|
||||
};
|
||||
|
||||
enum {
|
||||
/** Hardware face detection. It does not use much CPU. */
|
||||
CAMERA_FACE_DETECTION_HW = 0,
|
||||
/**
|
||||
* Software face detection. It uses some CPU. Applications must use
|
||||
* Camera.setPreviewTexture for preview in this mode.
|
||||
*/
|
||||
CAMERA_FACE_DETECTION_SW = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* The information of a face from camera face detection.
|
||||
*/
|
||||
typedef struct camera_face {
|
||||
/**
|
||||
* Bounds of the face [left, top, right, bottom]. (-1000, -1000) represents
|
||||
* the top-left of the camera field of view, and (1000, 1000) represents the
|
||||
* bottom-right of the field of view. The width and height cannot be 0 or
|
||||
* negative. This is supported by both hardware and software face detection.
|
||||
*
|
||||
* The direction is relative to the sensor orientation, that is, what the
|
||||
* sensor sees. The direction is not affected by the rotation or mirroring
|
||||
* of CAMERA_CMD_SET_DISPLAY_ORIENTATION.
|
||||
*/
|
||||
int32_t rect[4];
|
||||
|
||||
/**
|
||||
* The confidence level of the face. The range is 1 to 100. 100 is the
|
||||
* highest confidence. This is supported by both hardware and software
|
||||
* face detection.
|
||||
*/
|
||||
int32_t score;
|
||||
|
||||
/**
|
||||
* An unique id per face while the face is visible to the tracker. If
|
||||
* the face leaves the field-of-view and comes back, it will get a new
|
||||
* id. If the value is 0, id is not supported.
|
||||
*/
|
||||
int32_t id;
|
||||
|
||||
/**
|
||||
* The coordinates of the center of the left eye. The range is -1000 to
|
||||
* 1000. -2000, -2000 if this is not supported.
|
||||
*/
|
||||
int32_t left_eye[2];
|
||||
|
||||
/**
|
||||
* The coordinates of the center of the right eye. The range is -1000 to
|
||||
* 1000. -2000, -2000 if this is not supported.
|
||||
*/
|
||||
int32_t right_eye[2];
|
||||
|
||||
/**
|
||||
* The coordinates of the center of the mouth. The range is -1000 to 1000.
|
||||
* -2000, -2000 if this is not supported.
|
||||
*/
|
||||
int32_t mouth[2];
|
||||
int32_t smile_degree;
|
||||
int32_t smile_score;
|
||||
int32_t blink_detected;
|
||||
int32_t face_recognised;
|
||||
int32_t gaze_angle;
|
||||
int32_t updown_dir;
|
||||
int32_t leftright_dir;
|
||||
int32_t roll_dir;
|
||||
int32_t left_right_gaze;
|
||||
int32_t top_bottom_gaze;
|
||||
int32_t leye_blink;
|
||||
int32_t reye_blink;
|
||||
|
||||
} camera_face_t;
|
||||
|
||||
/**
|
||||
* The information of a data type received in a camera frame.
|
||||
*/
|
||||
typedef enum {
|
||||
/** Data buffer */
|
||||
CAMERA_FRAME_DATA_BUF = 0x000,
|
||||
/** File descriptor */
|
||||
CAMERA_FRAME_DATA_FD = 0x100
|
||||
} camera_frame_data_type_t;
|
||||
|
||||
/**
|
||||
* The metadata of the frame data.
|
||||
*/
|
||||
typedef struct camera_frame_metadata {
|
||||
/**
|
||||
* The number of detected faces in the frame.
|
||||
*/
|
||||
int32_t number_of_faces;
|
||||
|
||||
/**
|
||||
* An array of the detected faces. The length is number_of_faces.
|
||||
*/
|
||||
camera_face_t *faces;
|
||||
} camera_frame_metadata_t;
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* SYSTEM_CORE_INCLUDE_ANDROID_CAMERA_H */
|
||||
@@ -0,0 +1,763 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SYSTEM_CORE_INCLUDE_ANDROID_GRAPHICS_H
|
||||
#define SYSTEM_CORE_INCLUDE_ANDROID_GRAPHICS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If the HAL needs to create service threads to handle graphics related
|
||||
* tasks, these threads need to run at HAL_PRIORITY_URGENT_DISPLAY priority
|
||||
* if they can block the main rendering thread in any way.
|
||||
*
|
||||
* the priority of the current thread can be set with:
|
||||
*
|
||||
* #include <sys/resource.h>
|
||||
* setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
|
||||
*
|
||||
*/
|
||||
|
||||
#define HAL_PRIORITY_URGENT_DISPLAY (-8)
|
||||
|
||||
/**
|
||||
* pixel format definitions
|
||||
*/
|
||||
|
||||
enum {
|
||||
/*
|
||||
* "linear" color pixel formats:
|
||||
*
|
||||
* When used with ANativeWindow, the dataSpace field describes the color
|
||||
* space of the buffer.
|
||||
*
|
||||
* The color space determines, for example, if the formats are linear or
|
||||
* gamma-corrected; or whether any special operations are performed when
|
||||
* reading or writing into a buffer in one of these formats.
|
||||
*/
|
||||
HAL_PIXEL_FORMAT_RGBA_8888 = 1,
|
||||
HAL_PIXEL_FORMAT_RGBX_8888 = 2,
|
||||
HAL_PIXEL_FORMAT_RGB_888 = 3,
|
||||
HAL_PIXEL_FORMAT_RGB_565 = 4,
|
||||
HAL_PIXEL_FORMAT_BGRA_8888 = 5,
|
||||
|
||||
/*
|
||||
* 0x100 - 0x1FF
|
||||
*
|
||||
* This range is reserved for pixel formats that are specific to the HAL
|
||||
* implementation. Implementations can use any value in this range to
|
||||
* communicate video pixel formats between their HAL modules. These formats
|
||||
* must not have an alpha channel. Additionally, an EGLimage created from a
|
||||
* gralloc buffer of one of these formats must be supported for use with the
|
||||
* GL_OES_EGL_image_external OpenGL ES extension.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Android YUV format:
|
||||
*
|
||||
* This format is exposed outside of the HAL to software decoders and
|
||||
* applications. EGLImageKHR must support it in conjunction with the
|
||||
* OES_EGL_image_external extension.
|
||||
*
|
||||
* YV12 is a 4:2:0 YCrCb planar format comprised of a WxH Y plane followed
|
||||
* by (W/2) x (H/2) Cr and Cb planes.
|
||||
*
|
||||
* This format assumes
|
||||
* - an even width
|
||||
* - an even height
|
||||
* - a horizontal stride multiple of 16 pixels
|
||||
* - a vertical stride equal to the height
|
||||
*
|
||||
* y_size = stride * height
|
||||
* c_stride = ALIGN(stride/2, 16)
|
||||
* c_size = c_stride * height/2
|
||||
* size = y_size + c_size * 2
|
||||
* cr_offset = y_size
|
||||
* cb_offset = y_size + c_size
|
||||
*
|
||||
* When used with ANativeWindow, the dataSpace field describes the color
|
||||
* space of the buffer.
|
||||
*/
|
||||
HAL_PIXEL_FORMAT_YV12 = 0x32315659, // YCrCb 4:2:0 Planar
|
||||
|
||||
|
||||
/*
|
||||
* Android Y8 format:
|
||||
*
|
||||
* This format is exposed outside of the HAL to the framework.
|
||||
* The expected gralloc usage flags are SW_* and HW_CAMERA_*,
|
||||
* and no other HW_ flags will be used.
|
||||
*
|
||||
* Y8 is a YUV planar format comprised of a WxH Y plane,
|
||||
* with each pixel being represented by 8 bits.
|
||||
*
|
||||
* It is equivalent to just the Y plane from YV12.
|
||||
*
|
||||
* This format assumes
|
||||
* - an even width
|
||||
* - an even height
|
||||
* - a horizontal stride multiple of 16 pixels
|
||||
* - a vertical stride equal to the height
|
||||
*
|
||||
* size = stride * height
|
||||
*
|
||||
* When used with ANativeWindow, the dataSpace field describes the color
|
||||
* space of the buffer.
|
||||
*/
|
||||
HAL_PIXEL_FORMAT_Y8 = 0x20203859,
|
||||
|
||||
/*
|
||||
* Android Y16 format:
|
||||
*
|
||||
* This format is exposed outside of the HAL to the framework.
|
||||
* The expected gralloc usage flags are SW_* and HW_CAMERA_*,
|
||||
* and no other HW_ flags will be used.
|
||||
*
|
||||
* Y16 is a YUV planar format comprised of a WxH Y plane,
|
||||
* with each pixel being represented by 16 bits.
|
||||
*
|
||||
* It is just like Y8, but has double the bits per pixel (little endian).
|
||||
*
|
||||
* This format assumes
|
||||
* - an even width
|
||||
* - an even height
|
||||
* - a horizontal stride multiple of 16 pixels
|
||||
* - a vertical stride equal to the height
|
||||
* - strides are specified in pixels, not in bytes
|
||||
*
|
||||
* size = stride * height * 2
|
||||
*
|
||||
* When used with ANativeWindow, the dataSpace field describes the color
|
||||
* space of the buffer, except that dataSpace field
|
||||
* HAL_DATASPACE_DEPTH indicates that this buffer contains a depth
|
||||
* image where each sample is a distance value measured by a depth camera,
|
||||
* plus an associated confidence value.
|
||||
*/
|
||||
HAL_PIXEL_FORMAT_Y16 = 0x20363159,
|
||||
|
||||
/*
|
||||
* Android RAW sensor format:
|
||||
*
|
||||
* This format is exposed outside of the camera HAL to applications.
|
||||
*
|
||||
* RAW16 is a single-channel, 16-bit, little endian format, typically
|
||||
* representing raw Bayer-pattern images from an image sensor, with minimal
|
||||
* processing.
|
||||
*
|
||||
* The exact pixel layout of the data in the buffer is sensor-dependent, and
|
||||
* needs to be queried from the camera device.
|
||||
*
|
||||
* Generally, not all 16 bits are used; more common values are 10 or 12
|
||||
* bits. If not all bits are used, the lower-order bits are filled first.
|
||||
* All parameters to interpret the raw data (black and white points,
|
||||
* color space, etc) must be queried from the camera device.
|
||||
*
|
||||
* This format assumes
|
||||
* - an even width
|
||||
* - an even height
|
||||
* - a horizontal stride multiple of 16 pixels
|
||||
* - a vertical stride equal to the height
|
||||
* - strides are specified in pixels, not in bytes
|
||||
*
|
||||
* size = stride * height * 2
|
||||
*
|
||||
* This format must be accepted by the gralloc module when used with the
|
||||
* following usage flags:
|
||||
* - GRALLOC_USAGE_HW_CAMERA_*
|
||||
* - GRALLOC_USAGE_SW_*
|
||||
* - GRALLOC_USAGE_RENDERSCRIPT
|
||||
*
|
||||
* When used with ANativeWindow, the dataSpace should be
|
||||
* HAL_DATASPACE_ARBITRARY, as raw image sensor buffers require substantial
|
||||
* extra metadata to define.
|
||||
*/
|
||||
HAL_PIXEL_FORMAT_RAW16 = 0x20,
|
||||
|
||||
/*
|
||||
* Android RAW10 format:
|
||||
*
|
||||
* This format is exposed outside of the camera HAL to applications.
|
||||
*
|
||||
* RAW10 is a single-channel, 10-bit per pixel, densely packed in each row,
|
||||
* unprocessed format, usually representing raw Bayer-pattern images coming from
|
||||
* an image sensor.
|
||||
*
|
||||
* In an image buffer with this format, starting from the first pixel of each
|
||||
* row, each 4 consecutive pixels are packed into 5 bytes (40 bits). Each one
|
||||
* of the first 4 bytes contains the top 8 bits of each pixel, The fifth byte
|
||||
* contains the 2 least significant bits of the 4 pixels, the exact layout data
|
||||
* for each 4 consecutive pixels is illustrated below (Pi[j] stands for the jth
|
||||
* bit of the ith pixel):
|
||||
*
|
||||
* bit 7 bit 0
|
||||
* =====|=====|=====|=====|=====|=====|=====|=====|
|
||||
* Byte 0: |P0[9]|P0[8]|P0[7]|P0[6]|P0[5]|P0[4]|P0[3]|P0[2]|
|
||||
* |-----|-----|-----|-----|-----|-----|-----|-----|
|
||||
* Byte 1: |P1[9]|P1[8]|P1[7]|P1[6]|P1[5]|P1[4]|P1[3]|P1[2]|
|
||||
* |-----|-----|-----|-----|-----|-----|-----|-----|
|
||||
* Byte 2: |P2[9]|P2[8]|P2[7]|P2[6]|P2[5]|P2[4]|P2[3]|P2[2]|
|
||||
* |-----|-----|-----|-----|-----|-----|-----|-----|
|
||||
* Byte 3: |P3[9]|P3[8]|P3[7]|P3[6]|P3[5]|P3[4]|P3[3]|P3[2]|
|
||||
* |-----|-----|-----|-----|-----|-----|-----|-----|
|
||||
* Byte 4: |P3[1]|P3[0]|P2[1]|P2[0]|P1[1]|P1[0]|P0[1]|P0[0]|
|
||||
* ===============================================
|
||||
*
|
||||
* This format assumes
|
||||
* - a width multiple of 4 pixels
|
||||
* - an even height
|
||||
* - a vertical stride equal to the height
|
||||
* - strides are specified in bytes, not in pixels
|
||||
*
|
||||
* size = stride * height
|
||||
*
|
||||
* When stride is equal to width * (10 / 8), there will be no padding bytes at
|
||||
* the end of each row, the entire image data is densely packed. When stride is
|
||||
* larger than width * (10 / 8), padding bytes will be present at the end of each
|
||||
* row (including the last row).
|
||||
*
|
||||
* This format must be accepted by the gralloc module when used with the
|
||||
* following usage flags:
|
||||
* - GRALLOC_USAGE_HW_CAMERA_*
|
||||
* - GRALLOC_USAGE_SW_*
|
||||
* - GRALLOC_USAGE_RENDERSCRIPT
|
||||
*
|
||||
* When used with ANativeWindow, the dataSpace field should be
|
||||
* HAL_DATASPACE_ARBITRARY, as raw image sensor buffers require substantial
|
||||
* extra metadata to define.
|
||||
*/
|
||||
HAL_PIXEL_FORMAT_RAW10 = 0x25,
|
||||
|
||||
/*
|
||||
* Android RAW12 format:
|
||||
*
|
||||
* This format is exposed outside of camera HAL to applications.
|
||||
*
|
||||
* RAW12 is a single-channel, 12-bit per pixel, densely packed in each row,
|
||||
* unprocessed format, usually representing raw Bayer-pattern images coming from
|
||||
* an image sensor.
|
||||
*
|
||||
* In an image buffer with this format, starting from the first pixel of each
|
||||
* row, each two consecutive pixels are packed into 3 bytes (24 bits). The first
|
||||
* and second byte contains the top 8 bits of first and second pixel. The third
|
||||
* byte contains the 4 least significant bits of the two pixels, the exact layout
|
||||
* data for each two consecutive pixels is illustrated below (Pi[j] stands for
|
||||
* the jth bit of the ith pixel):
|
||||
*
|
||||
* bit 7 bit 0
|
||||
* ======|======|======|======|======|======|======|======|
|
||||
* Byte 0: |P0[11]|P0[10]|P0[ 9]|P0[ 8]|P0[ 7]|P0[ 6]|P0[ 5]|P0[ 4]|
|
||||
* |------|------|------|------|------|------|------|------|
|
||||
* Byte 1: |P1[11]|P1[10]|P1[ 9]|P1[ 8]|P1[ 7]|P1[ 6]|P1[ 5]|P1[ 4]|
|
||||
* |------|------|------|------|------|------|------|------|
|
||||
* Byte 2: |P1[ 3]|P1[ 2]|P1[ 1]|P1[ 0]|P0[ 3]|P0[ 2]|P0[ 1]|P0[ 0]|
|
||||
* =======================================================
|
||||
*
|
||||
* This format assumes:
|
||||
* - a width multiple of 4 pixels
|
||||
* - an even height
|
||||
* - a vertical stride equal to the height
|
||||
* - strides are specified in bytes, not in pixels
|
||||
*
|
||||
* size = stride * height
|
||||
*
|
||||
* When stride is equal to width * (12 / 8), there will be no padding bytes at
|
||||
* the end of each row, the entire image data is densely packed. When stride is
|
||||
* larger than width * (12 / 8), padding bytes will be present at the end of
|
||||
* each row (including the last row).
|
||||
*
|
||||
* This format must be accepted by the gralloc module when used with the
|
||||
* following usage flags:
|
||||
* - GRALLOC_USAGE_HW_CAMERA_*
|
||||
* - GRALLOC_USAGE_SW_*
|
||||
* - GRALLOC_USAGE_RENDERSCRIPT
|
||||
*
|
||||
* When used with ANativeWindow, the dataSpace field should be
|
||||
* HAL_DATASPACE_ARBITRARY, as raw image sensor buffers require substantial
|
||||
* extra metadata to define.
|
||||
*/
|
||||
HAL_PIXEL_FORMAT_RAW12 = 0x26,
|
||||
|
||||
/*
|
||||
* Android opaque RAW format:
|
||||
*
|
||||
* This format is exposed outside of the camera HAL to applications.
|
||||
*
|
||||
* RAW_OPAQUE is a format for unprocessed raw image buffers coming from an
|
||||
* image sensor. The actual structure of buffers of this format is
|
||||
* implementation-dependent.
|
||||
*
|
||||
* This format must be accepted by the gralloc module when used with the
|
||||
* following usage flags:
|
||||
* - GRALLOC_USAGE_HW_CAMERA_*
|
||||
* - GRALLOC_USAGE_SW_*
|
||||
* - GRALLOC_USAGE_RENDERSCRIPT
|
||||
*
|
||||
* When used with ANativeWindow, the dataSpace field should be
|
||||
* HAL_DATASPACE_ARBITRARY, as raw image sensor buffers require substantial
|
||||
* extra metadata to define.
|
||||
*/
|
||||
HAL_PIXEL_FORMAT_RAW_OPAQUE = 0x24,
|
||||
|
||||
/*
|
||||
* Android binary blob graphics buffer format:
|
||||
*
|
||||
* This format is used to carry task-specific data which does not have a
|
||||
* standard image structure. The details of the format are left to the two
|
||||
* endpoints.
|
||||
*
|
||||
* A typical use case is for transporting JPEG-compressed images from the
|
||||
* Camera HAL to the framework or to applications.
|
||||
*
|
||||
* Buffers of this format must have a height of 1, and width equal to their
|
||||
* size in bytes.
|
||||
*
|
||||
* When used with ANativeWindow, the mapping of the dataSpace field to
|
||||
* buffer contents for BLOB is as follows:
|
||||
*
|
||||
* dataSpace value | Buffer contents
|
||||
* -------------------------------+-----------------------------------------
|
||||
* HAL_DATASPACE_JFIF | An encoded JPEG image
|
||||
* HAL_DATASPACE_DEPTH | An android_depth_points buffer
|
||||
* Other | Unsupported
|
||||
*
|
||||
*/
|
||||
HAL_PIXEL_FORMAT_BLOB = 0x21,
|
||||
|
||||
/*
|
||||
* Android format indicating that the choice of format is entirely up to the
|
||||
* device-specific Gralloc implementation.
|
||||
*
|
||||
* The Gralloc implementation should examine the usage bits passed in when
|
||||
* allocating a buffer with this format, and it should derive the pixel
|
||||
* format from those usage flags. This format will never be used with any
|
||||
* of the GRALLOC_USAGE_SW_* usage flags.
|
||||
*
|
||||
* If a buffer of this format is to be used as an OpenGL ES texture, the
|
||||
* framework will assume that sampling the texture will always return an
|
||||
* alpha value of 1.0 (i.e. the buffer contains only opaque pixel values).
|
||||
*
|
||||
* When used with ANativeWindow, the dataSpace field describes the color
|
||||
* space of the buffer.
|
||||
*/
|
||||
HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED = 0x22,
|
||||
|
||||
/*
|
||||
* Android flexible YCbCr 4:2:0 formats
|
||||
*
|
||||
* This format allows platforms to use an efficient YCbCr/YCrCb 4:2:0
|
||||
* buffer layout, while still describing the general format in a
|
||||
* layout-independent manner. While called YCbCr, it can be
|
||||
* used to describe formats with either chromatic ordering, as well as
|
||||
* whole planar or semiplanar layouts.
|
||||
*
|
||||
* struct android_ycbcr (below) is the the struct used to describe it.
|
||||
*
|
||||
* This format must be accepted by the gralloc module when
|
||||
* USAGE_SW_WRITE_* or USAGE_SW_READ_* are set.
|
||||
*
|
||||
* This format is locked for use by gralloc's (*lock_ycbcr) method, and
|
||||
* locking with the (*lock) method will return an error.
|
||||
*
|
||||
* When used with ANativeWindow, the dataSpace field describes the color
|
||||
* space of the buffer.
|
||||
*/
|
||||
HAL_PIXEL_FORMAT_YCbCr_420_888 = 0x23,
|
||||
|
||||
/*
|
||||
* Android flexible YCbCr 4:2:2 formats
|
||||
*
|
||||
* This format allows platforms to use an efficient YCbCr/YCrCb 4:2:2
|
||||
* buffer layout, while still describing the general format in a
|
||||
* layout-independent manner. While called YCbCr, it can be
|
||||
* used to describe formats with either chromatic ordering, as well as
|
||||
* whole planar or semiplanar layouts.
|
||||
*
|
||||
* This format is currently only used by SW readable buffers
|
||||
* produced by MediaCodecs, so the gralloc module can ignore this format.
|
||||
*/
|
||||
HAL_PIXEL_FORMAT_YCbCr_422_888 = 0x27,
|
||||
|
||||
/*
|
||||
* Android flexible YCbCr 4:4:4 formats
|
||||
*
|
||||
* This format allows platforms to use an efficient YCbCr/YCrCb 4:4:4
|
||||
* buffer layout, while still describing the general format in a
|
||||
* layout-independent manner. While called YCbCr, it can be
|
||||
* used to describe formats with either chromatic ordering, as well as
|
||||
* whole planar or semiplanar layouts.
|
||||
*
|
||||
* This format is currently only used by SW readable buffers
|
||||
* produced by MediaCodecs, so the gralloc module can ignore this format.
|
||||
*/
|
||||
HAL_PIXEL_FORMAT_YCbCr_444_888 = 0x28,
|
||||
|
||||
/*
|
||||
* Android flexible RGB 888 formats
|
||||
*
|
||||
* This format allows platforms to use an efficient RGB/BGR/RGBX/BGRX
|
||||
* buffer layout, while still describing the general format in a
|
||||
* layout-independent manner. While called RGB, it can be
|
||||
* used to describe formats with either color ordering and optional
|
||||
* padding, as well as whole planar layout.
|
||||
*
|
||||
* This format is currently only used by SW readable buffers
|
||||
* produced by MediaCodecs, so the gralloc module can ignore this format.
|
||||
*/
|
||||
HAL_PIXEL_FORMAT_FLEX_RGB_888 = 0x29,
|
||||
|
||||
/*
|
||||
* Android flexible RGBA 8888 formats
|
||||
*
|
||||
* This format allows platforms to use an efficient RGBA/BGRA/ARGB/ABGR
|
||||
* buffer layout, while still describing the general format in a
|
||||
* layout-independent manner. While called RGBA, it can be
|
||||
* used to describe formats with any of the component orderings, as
|
||||
* well as whole planar layout.
|
||||
*
|
||||
* This format is currently only used by SW readable buffers
|
||||
* produced by MediaCodecs, so the gralloc module can ignore this format.
|
||||
*/
|
||||
HAL_PIXEL_FORMAT_FLEX_RGBA_8888 = 0x2A,
|
||||
|
||||
/* Legacy formats (deprecated), used by ImageFormat.java */
|
||||
HAL_PIXEL_FORMAT_YCbCr_422_SP = 0x10, // NV16
|
||||
HAL_PIXEL_FORMAT_YCrCb_420_SP = 0x11, // NV21
|
||||
HAL_PIXEL_FORMAT_YCbCr_422_I = 0x14, // YUY2
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure for describing YCbCr formats for consumption by applications.
|
||||
* This is used with HAL_PIXEL_FORMAT_YCbCr_*_888.
|
||||
*
|
||||
* Buffer chroma subsampling is defined in the format.
|
||||
* e.g. HAL_PIXEL_FORMAT_YCbCr_420_888 has subsampling 4:2:0.
|
||||
*
|
||||
* Buffers must have a 8 bit depth.
|
||||
*
|
||||
* @y, @cb, and @cr point to the first byte of their respective planes.
|
||||
*
|
||||
* Stride describes the distance in bytes from the first value of one row of
|
||||
* the image to the first value of the next row. It includes the width of the
|
||||
* image plus padding.
|
||||
* @ystride is the stride of the luma plane.
|
||||
* @cstride is the stride of the chroma planes.
|
||||
*
|
||||
* @chroma_step is the distance in bytes from one chroma pixel value to the
|
||||
* next. This is 2 bytes for semiplanar (because chroma values are interleaved
|
||||
* and each chroma value is one byte) and 1 for planar.
|
||||
*/
|
||||
|
||||
struct android_ycbcr {
|
||||
void *y;
|
||||
void *cb;
|
||||
void *cr;
|
||||
size_t ystride;
|
||||
size_t cstride;
|
||||
size_t chroma_step;
|
||||
|
||||
/** reserved for future use, set to 0 by gralloc's (*lock_ycbcr)() */
|
||||
uint32_t reserved[8];
|
||||
};
|
||||
|
||||
/**
|
||||
* Structure used to define depth point clouds for format HAL_PIXEL_FORMAT_BLOB
|
||||
* with dataSpace value of HAL_DATASPACE_DEPTH.
|
||||
* When locking a native buffer of the above format and dataSpace value,
|
||||
* the vaddr pointer can be cast to this structure.
|
||||
*
|
||||
* A variable-length list of (x,y,z, confidence) 3D points, as floats. (x, y,
|
||||
* z) represents a measured point's position, with the coordinate system defined
|
||||
* by the data source. Confidence represents the estimated likelihood that this
|
||||
* measurement is correct. It is between 0.f and 1.f, inclusive, with 1.f ==
|
||||
* 100% confidence.
|
||||
*
|
||||
* @num_points is the number of points in the list
|
||||
*
|
||||
* @xyz_points is the flexible array of floating-point values.
|
||||
* It contains (num_points) * 4 floats.
|
||||
*
|
||||
* For example:
|
||||
* android_depth_points d = get_depth_buffer();
|
||||
* struct {
|
||||
* float x; float y; float z; float confidence;
|
||||
* } firstPoint, lastPoint;
|
||||
*
|
||||
* firstPoint.x = d.xyzc_points[0];
|
||||
* firstPoint.y = d.xyzc_points[1];
|
||||
* firstPoint.z = d.xyzc_points[2];
|
||||
* firstPoint.confidence = d.xyzc_points[3];
|
||||
* lastPoint.x = d.xyzc_points[(d.num_points - 1) * 4 + 0];
|
||||
* lastPoint.y = d.xyzc_points[(d.num_points - 1) * 4 + 1];
|
||||
* lastPoint.z = d.xyzc_points[(d.num_points - 1) * 4 + 2];
|
||||
* lastPoint.confidence = d.xyzc_points[(d.num_points - 1) * 4 + 3];
|
||||
*/
|
||||
|
||||
struct android_depth_points {
|
||||
uint32_t num_points;
|
||||
|
||||
/** reserved for future use, set to 0 by gralloc's (*lock)() */
|
||||
uint32_t reserved[8];
|
||||
|
||||
float xyzc_points[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Transformation definitions
|
||||
*
|
||||
* IMPORTANT NOTE:
|
||||
* HAL_TRANSFORM_ROT_90 is applied CLOCKWISE and AFTER HAL_TRANSFORM_FLIP_{H|V}.
|
||||
*
|
||||
*/
|
||||
|
||||
enum {
|
||||
/* flip source image horizontally (around the vertical axis) */
|
||||
HAL_TRANSFORM_FLIP_H = 0x01,
|
||||
/* flip source image vertically (around the horizontal axis)*/
|
||||
HAL_TRANSFORM_FLIP_V = 0x02,
|
||||
/* rotate source image 90 degrees clockwise */
|
||||
HAL_TRANSFORM_ROT_90 = 0x04,
|
||||
/* rotate source image 180 degrees */
|
||||
HAL_TRANSFORM_ROT_180 = 0x03,
|
||||
/* rotate source image 270 degrees clockwise */
|
||||
HAL_TRANSFORM_ROT_270 = 0x07,
|
||||
/* don't use. see system/window.h */
|
||||
HAL_TRANSFORM_RESERVED = 0x08,
|
||||
};
|
||||
|
||||
/**
|
||||
* Dataspace Definitions
|
||||
* ======================
|
||||
*
|
||||
* Dataspace is the definition of how pixel values should be interpreted.
|
||||
*
|
||||
* For many formats, this is the colorspace of the image data, which includes
|
||||
* primaries (including white point) and the transfer characteristic function,
|
||||
* which describes both gamma curve and numeric range (within the bit depth).
|
||||
*
|
||||
* Other dataspaces include depth measurement data from a depth camera.
|
||||
*/
|
||||
|
||||
typedef enum android_dataspace {
|
||||
/*
|
||||
* Default-assumption data space, when not explicitly specified.
|
||||
*
|
||||
* It is safest to assume the buffer is an image with sRGB primaries and
|
||||
* encoding ranges, but the consumer and/or the producer of the data may
|
||||
* simply be using defaults. No automatic gamma transform should be
|
||||
* expected, except for a possible display gamma transform when drawn to a
|
||||
* screen.
|
||||
*/
|
||||
HAL_DATASPACE_UNKNOWN = 0x0,
|
||||
|
||||
/*
|
||||
* Arbitrary dataspace with manually defined characteristics. Definition
|
||||
* for colorspaces or other meaning must be communicated separately.
|
||||
*
|
||||
* This is used when specifying primaries, transfer characteristics,
|
||||
* etc. separately.
|
||||
*
|
||||
* A typical use case is in video encoding parameters (e.g. for H.264),
|
||||
* where a colorspace can have separately defined primaries, transfer
|
||||
* characteristics, etc.
|
||||
*/
|
||||
HAL_DATASPACE_ARBITRARY = 0x1,
|
||||
|
||||
/*
|
||||
* RGB Colorspaces
|
||||
* -----------------
|
||||
*
|
||||
* Primaries are given using (x,y) coordinates in the CIE 1931 definition
|
||||
* of x and y specified by ISO 11664-1.
|
||||
*
|
||||
* Transfer characteristics are the opto-electronic transfer characteristic
|
||||
* at the source as a function of linear optical intensity (luminance).
|
||||
*/
|
||||
|
||||
/*
|
||||
* sRGB linear encoding:
|
||||
*
|
||||
* The red, green, and blue components are stored in sRGB space, but
|
||||
* are linear, not gamma-encoded.
|
||||
* The RGB primaries and the white point are the same as BT.709.
|
||||
*
|
||||
* The values are encoded using the full range ([0,255] for 8-bit) for all
|
||||
* components.
|
||||
*/
|
||||
HAL_DATASPACE_SRGB_LINEAR = 0x200,
|
||||
|
||||
/*
|
||||
* sRGB gamma encoding:
|
||||
*
|
||||
* The red, green and blue components are stored in sRGB space, and
|
||||
* converted to linear space when read, using the standard sRGB to linear
|
||||
* equation:
|
||||
*
|
||||
* Clinear = Csrgb / 12.92 for Csrgb <= 0.04045
|
||||
* = (Csrgb + 0.055 / 1.055)^2.4 for Csrgb > 0.04045
|
||||
*
|
||||
* When written the inverse transformation is performed:
|
||||
*
|
||||
* Csrgb = 12.92 * Clinear for Clinear <= 0.0031308
|
||||
* = 1.055 * Clinear^(1/2.4) - 0.055 for Clinear > 0.0031308
|
||||
*
|
||||
*
|
||||
* The alpha component, if present, is always stored in linear space and
|
||||
* is left unmodified when read or written.
|
||||
*
|
||||
* The RGB primaries and the white point are the same as BT.709.
|
||||
*
|
||||
* The values are encoded using the full range ([0,255] for 8-bit) for all
|
||||
* components.
|
||||
*
|
||||
*/
|
||||
HAL_DATASPACE_SRGB = 0x201,
|
||||
|
||||
/*
|
||||
* YCbCr Colorspaces
|
||||
* -----------------
|
||||
*
|
||||
* Primaries are given using (x,y) coordinates in the CIE 1931 definition
|
||||
* of x and y specified by ISO 11664-1.
|
||||
*
|
||||
* Transfer characteristics are the opto-electronic transfer characteristic
|
||||
* at the source as a function of linear optical intensity (luminance).
|
||||
*/
|
||||
|
||||
/*
|
||||
* JPEG File Interchange Format (JFIF)
|
||||
*
|
||||
* Same model as BT.601-625, but all values (Y, Cb, Cr) range from 0 to 255
|
||||
*
|
||||
* Transfer characteristic curve:
|
||||
* E = 1.099 * L ^ 0.45 - 0.099, 1.00 >= L >= 0.018
|
||||
* E = 4.500 L, 0.018 > L >= 0
|
||||
* L - luminance of image 0 <= L <= 1 for conventional colorimetry
|
||||
* E - corresponding electrical signal
|
||||
*
|
||||
* Primaries: x y
|
||||
* green 0.290 0.600
|
||||
* blue 0.150 0.060
|
||||
* red 0.640 0.330
|
||||
* white (D65) 0.3127 0.3290
|
||||
*/
|
||||
HAL_DATASPACE_JFIF = 0x101,
|
||||
|
||||
/*
|
||||
* ITU-R Recommendation 601 (BT.601) - 625-line
|
||||
*
|
||||
* Standard-definition television, 625 Lines (PAL)
|
||||
*
|
||||
* For 8-bit-depth formats:
|
||||
* Luma (Y) samples should range from 16 to 235, inclusive
|
||||
* Chroma (Cb, Cr) samples should range from 16 to 240, inclusive
|
||||
*
|
||||
* For 10-bit-depth formats:
|
||||
* Luma (Y) samples should range from 64 to 940, inclusive
|
||||
* Chroma (Cb, Cr) samples should range from 64 to 960, inclusive
|
||||
*
|
||||
* Transfer characteristic curve:
|
||||
* E = 1.099 * L ^ 0.45 - 0.099, 1.00 >= L >= 0.018
|
||||
* E = 4.500 L, 0.018 > L >= 0
|
||||
* L - luminance of image 0 <= L <= 1 for conventional colorimetry
|
||||
* E - corresponding electrical signal
|
||||
*
|
||||
* Primaries: x y
|
||||
* green 0.290 0.600
|
||||
* blue 0.150 0.060
|
||||
* red 0.640 0.330
|
||||
* white (D65) 0.3127 0.3290
|
||||
*/
|
||||
HAL_DATASPACE_BT601_625 = 0x102,
|
||||
|
||||
/*
|
||||
* ITU-R Recommendation 601 (BT.601) - 525-line
|
||||
*
|
||||
* Standard-definition television, 525 Lines (NTSC)
|
||||
*
|
||||
* For 8-bit-depth formats:
|
||||
* Luma (Y) samples should range from 16 to 235, inclusive
|
||||
* Chroma (Cb, Cr) samples should range from 16 to 240, inclusive
|
||||
*
|
||||
* For 10-bit-depth formats:
|
||||
* Luma (Y) samples should range from 64 to 940, inclusive
|
||||
* Chroma (Cb, Cr) samples should range from 64 to 960, inclusive
|
||||
*
|
||||
* Transfer characteristic curve:
|
||||
* E = 1.099 * L ^ 0.45 - 0.099, 1.00 >= L >= 0.018
|
||||
* E = 4.500 L, 0.018 > L >= 0
|
||||
* L - luminance of image 0 <= L <= 1 for conventional colorimetry
|
||||
* E - corresponding electrical signal
|
||||
*
|
||||
* Primaries: x y
|
||||
* green 0.310 0.595
|
||||
* blue 0.155 0.070
|
||||
* red 0.630 0.340
|
||||
* white (D65) 0.3127 0.3290
|
||||
*/
|
||||
HAL_DATASPACE_BT601_525 = 0x103,
|
||||
|
||||
/*
|
||||
* ITU-R Recommendation 709 (BT.709)
|
||||
*
|
||||
* High-definition television
|
||||
*
|
||||
* For 8-bit-depth formats:
|
||||
* Luma (Y) samples should range from 16 to 235, inclusive
|
||||
* Chroma (Cb, Cr) samples should range from 16 to 240, inclusive
|
||||
*
|
||||
* For 10-bit-depth formats:
|
||||
* Luma (Y) samples should range from 64 to 940, inclusive
|
||||
* Chroma (Cb, Cr) samples should range from 64 to 960, inclusive
|
||||
*
|
||||
* Primaries: x y
|
||||
* green 0.300 0.600
|
||||
* blue 0.150 0.060
|
||||
* red 0.640 0.330
|
||||
* white (D65) 0.3127 0.3290
|
||||
*/
|
||||
HAL_DATASPACE_BT709 = 0x104,
|
||||
|
||||
/*
|
||||
* The buffer contains depth ranging measurements from a depth camera.
|
||||
* This value is valid with formats:
|
||||
* HAL_PIXEL_FORMAT_Y16: 16-bit samples, consisting of a depth measurement
|
||||
* and an associated confidence value. The 3 MSBs of the sample make
|
||||
* up the confidence value, and the low 13 LSBs of the sample make up
|
||||
* the depth measurement.
|
||||
* For the confidence section, 0 means 100% confidence, 1 means 0%
|
||||
* confidence. The mapping to a linear float confidence value between
|
||||
* 0.f and 1.f can be obtained with
|
||||
* float confidence = (((depthSample >> 13) - 1) & 0x7) / 7.0f;
|
||||
* The depth measurement can be extracted simply with
|
||||
* uint16_t range = (depthSample & 0x1FFF);
|
||||
* HAL_PIXEL_FORMAT_BLOB: A depth point cloud, as
|
||||
* a variable-length float (x,y,z, confidence) coordinate point list.
|
||||
* The point cloud will be represented with the android_depth_points
|
||||
* structure.
|
||||
*/
|
||||
HAL_DATASPACE_DEPTH = 0x1000
|
||||
|
||||
} android_dataspace_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SYSTEM_CORE_INCLUDE_ANDROID_GRAPHICS_H */
|
||||
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_RADIO_H
|
||||
#define ANDROID_RADIO_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
#define RADIO_NUM_BANDS_MAX 16
|
||||
#define RADIO_NUM_SPACINGS_MAX 16
|
||||
#define RADIO_STRING_LEN_MAX 128
|
||||
|
||||
/*
|
||||
* Radio hardware module class. A given radio hardware module HAL is of one class
|
||||
* only. The platform can not have more than one hardware module of each class.
|
||||
* Current version of the framework only supports RADIO_CLASS_AM_FM.
|
||||
*/
|
||||
typedef enum {
|
||||
RADIO_CLASS_AM_FM = 0, /* FM (including HD radio) and AM */
|
||||
RADIO_CLASS_SAT = 1, /* Satellite Radio */
|
||||
RADIO_CLASS_DT = 2, /* Digital Radio (DAB) */
|
||||
} radio_class_t;
|
||||
|
||||
/* value for field "type" of radio band described in struct radio_hal_band_config */
|
||||
typedef enum {
|
||||
RADIO_BAND_AM = 0, /* Amplitude Modulation band: LW, MW, SW */
|
||||
RADIO_BAND_FM = 1, /* Frequency Modulation band: FM */
|
||||
RADIO_BAND_FM_HD = 2, /* FM HD Radio / DRM (IBOC) */
|
||||
RADIO_BAND_AM_HD = 3, /* AM HD Radio / DRM (IBOC) */
|
||||
} radio_band_t;
|
||||
|
||||
/* RDS variant implemented. A struct radio_hal_fm_band_config can list none or several. */
|
||||
enum {
|
||||
RADIO_RDS_NONE = 0x0,
|
||||
RADIO_RDS_WORLD = 0x01,
|
||||
RADIO_RDS_US = 0x02,
|
||||
};
|
||||
typedef unsigned int radio_rds_t;
|
||||
|
||||
/* FM deemphasis variant implemented. A struct radio_hal_fm_band_config can list one or more. */
|
||||
enum {
|
||||
RADIO_DEEMPHASIS_50 = 0x1,
|
||||
RADIO_DEEMPHASIS_75 = 0x2,
|
||||
};
|
||||
typedef unsigned int radio_deemphasis_t;
|
||||
|
||||
/* Region a particular radio band configuration corresponds to. Not used at the HAL.
|
||||
* Derived by the framework when converting the band descriptors retrieved from the HAL to
|
||||
* individual band descriptors for each supported region. */
|
||||
typedef enum {
|
||||
RADIO_REGION_NONE = -1,
|
||||
RADIO_REGION_ITU_1 = 0,
|
||||
RADIO_REGION_ITU_2 = 1,
|
||||
RADIO_REGION_OIRT = 2,
|
||||
RADIO_REGION_JAPAN = 3,
|
||||
RADIO_REGION_KOREA = 4,
|
||||
} radio_region_t;
|
||||
|
||||
/* scanning direction for scan() and step() tuner APIs */
|
||||
typedef enum {
|
||||
RADIO_DIRECTION_UP,
|
||||
RADIO_DIRECTION_DOWN
|
||||
} radio_direction_t;
|
||||
|
||||
/* unique handle allocated to a radio module */
|
||||
typedef unsigned int radio_handle_t;
|
||||
|
||||
/* Opaque meta data structure used by radio meta data API (see system/radio_metadata.h) */
|
||||
typedef struct radio_medtadata radio_metadata_t;
|
||||
|
||||
|
||||
/* Additional attributes for an FM band configuration */
|
||||
typedef struct radio_hal_fm_band_config {
|
||||
radio_deemphasis_t deemphasis; /* deemphasis variant */
|
||||
bool stereo; /* stereo supported */
|
||||
radio_rds_t rds; /* RDS variants supported */
|
||||
bool ta; /* Traffic Announcement supported */
|
||||
bool af; /* Alternate Frequency supported */
|
||||
} radio_hal_fm_band_config_t;
|
||||
|
||||
/* Additional attributes for an AM band configuration */
|
||||
typedef struct radio_hal_am_band_config {
|
||||
bool stereo; /* stereo supported */
|
||||
} radio_hal_am_band_config_t;
|
||||
|
||||
/* Radio band configuration. Describes a given band supported by the radio module.
|
||||
* The HAL can expose only one band per type with the the maximum range supported and all options.
|
||||
* THe framework will derive the actual regions were this module can operate and expose separate
|
||||
* band configurations for applications to chose from. */
|
||||
typedef struct radio_hal_band_config {
|
||||
radio_band_t type;
|
||||
bool antenna_connected;
|
||||
unsigned int lower_limit;
|
||||
unsigned int upper_limit;
|
||||
unsigned int num_spacings;
|
||||
unsigned int spacings[RADIO_NUM_SPACINGS_MAX];
|
||||
union {
|
||||
radio_hal_fm_band_config_t fm;
|
||||
radio_hal_am_band_config_t am;
|
||||
};
|
||||
} radio_hal_band_config_t;
|
||||
|
||||
/* Used internally by the framework to represent a band for s specific region */
|
||||
typedef struct radio_band_config {
|
||||
radio_region_t region;
|
||||
radio_hal_band_config_t band;
|
||||
} radio_band_config_t;
|
||||
|
||||
|
||||
/* Exposes properties of a given hardware radio module.
|
||||
* NOTE: current framework implementation supports only one audio source (num_audio_sources = 1).
|
||||
* The source corresponds to AUDIO_DEVICE_IN_FM_TUNER.
|
||||
* If more than one tuner is supported (num_tuners > 1), only one can be connected to the audio
|
||||
* source. */
|
||||
typedef struct radio_hal_properties {
|
||||
radio_class_t class_id; /* Class of this module. E.g RADIO_CLASS_AM_FM */
|
||||
char implementor[RADIO_STRING_LEN_MAX]; /* implementor name */
|
||||
char product[RADIO_STRING_LEN_MAX]; /* product name */
|
||||
char version[RADIO_STRING_LEN_MAX]; /* product version */
|
||||
char serial[RADIO_STRING_LEN_MAX]; /* serial number (for subscription services) */
|
||||
unsigned int num_tuners; /* number of tuners controllable independently */
|
||||
unsigned int num_audio_sources; /* number of audio sources driven simultaneously */
|
||||
bool supports_capture; /* the hardware supports capture of audio source audio HAL */
|
||||
unsigned int num_bands; /* number of band descriptors */
|
||||
radio_hal_band_config_t bands[RADIO_NUM_BANDS_MAX]; /* band descriptors */
|
||||
} radio_hal_properties_t;
|
||||
|
||||
/* Used internally by the framework. Same information as in struct radio_hal_properties plus a
|
||||
* unique handle and one band configuration per region. */
|
||||
typedef struct radio_properties {
|
||||
radio_handle_t handle;
|
||||
radio_class_t class_id;
|
||||
char implementor[RADIO_STRING_LEN_MAX];
|
||||
char product[RADIO_STRING_LEN_MAX];
|
||||
char version[RADIO_STRING_LEN_MAX];
|
||||
char serial[RADIO_STRING_LEN_MAX];
|
||||
unsigned int num_tuners;
|
||||
unsigned int num_audio_sources;
|
||||
bool supports_capture;
|
||||
unsigned int num_bands;
|
||||
radio_band_config_t bands[RADIO_NUM_BANDS_MAX];
|
||||
} radio_properties_t;
|
||||
|
||||
/* Radio program information. Returned by the HAL with event RADIO_EVENT_TUNED.
|
||||
* Contains information on currently tuned channel.
|
||||
*/
|
||||
typedef struct radio_program_info {
|
||||
unsigned int channel; /* current channel. (e.g kHz for band type RADIO_BAND_FM) */
|
||||
unsigned int sub_channel; /* current sub channel. (used for RADIO_BAND_FM_HD) */
|
||||
bool tuned; /* tuned to a program or not */
|
||||
bool stereo; /* program is stereo or not */
|
||||
bool digital; /* digital program or not (e.g HD Radio program) */
|
||||
unsigned int signal_strength; /* signal strength from 0 to 100 */
|
||||
radio_metadata_t *metadata; /* non null if meta data are present (e.g PTY, song title ...) */
|
||||
} radio_program_info_t;
|
||||
|
||||
|
||||
/* Events sent to the framework via the HAL callback. An event can notify the completion of an
|
||||
* asynchronous command (configuration, tune, scan ...) or a spontaneous change (antenna connection,
|
||||
* failure, AF switching, meta data reception... */
|
||||
enum {
|
||||
RADIO_EVENT_HW_FAILURE = 0, /* hardware module failure. Requires reopening the tuner */
|
||||
RADIO_EVENT_CONFIG = 1, /* configuration change completed */
|
||||
RADIO_EVENT_ANTENNA = 2, /* Antenna connected, disconnected */
|
||||
RADIO_EVENT_TUNED = 3, /* tune, step, scan completed */
|
||||
RADIO_EVENT_METADATA = 4, /* New meta data received */
|
||||
RADIO_EVENT_TA = 5, /* Traffic announcement start or stop */
|
||||
RADIO_EVENT_AF_SWITCH = 6, /* Switch to Alternate Frequency */
|
||||
// begin framework only events
|
||||
RADIO_EVENT_CONTROL = 100, /* loss/gain of tuner control */
|
||||
RADIO_EVENT_SERVER_DIED = 101, /* radio service died */
|
||||
};
|
||||
typedef unsigned int radio_event_type_t;
|
||||
|
||||
/* Event passed to the framework by the HAL callback */
|
||||
typedef struct radio_hal_event {
|
||||
radio_event_type_t type; /* event type */
|
||||
int status; /* used by RADIO_EVENT_CONFIG, RADIO_EVENT_TUNED */
|
||||
union {
|
||||
bool on; /* RADIO_EVENT_ANTENNA, RADIO_EVENT_TA */
|
||||
radio_hal_band_config_t config; /* RADIO_EVENT_CONFIG */
|
||||
radio_program_info_t info; /* RADIO_EVENT_TUNED, RADIO_EVENT_AF_SWITCH */
|
||||
radio_metadata_t *metadata; /* RADIO_EVENT_METADATA */
|
||||
};
|
||||
} radio_hal_event_t;
|
||||
|
||||
/* Used internally by the framework. Same information as in struct radio_hal_event */
|
||||
typedef struct radio_event {
|
||||
radio_event_type_t type;
|
||||
int status;
|
||||
union {
|
||||
bool on;
|
||||
radio_band_config_t config;
|
||||
radio_program_info_t info;
|
||||
radio_metadata_t *metadata; /* offset from start of struct when in shared memory */
|
||||
};
|
||||
} radio_event_t;
|
||||
|
||||
|
||||
static radio_rds_t radio_rds_for_region(bool rds, radio_region_t region) {
|
||||
if (!rds)
|
||||
return RADIO_RDS_NONE;
|
||||
switch(region) {
|
||||
case RADIO_REGION_ITU_1:
|
||||
case RADIO_REGION_OIRT:
|
||||
case RADIO_REGION_JAPAN:
|
||||
case RADIO_REGION_KOREA:
|
||||
return RADIO_RDS_WORLD;
|
||||
case RADIO_REGION_ITU_2:
|
||||
return RADIO_RDS_US;
|
||||
default:
|
||||
return RADIO_REGION_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static radio_deemphasis_t radio_demephasis_for_region(radio_region_t region) {
|
||||
switch(region) {
|
||||
case RADIO_REGION_KOREA:
|
||||
case RADIO_REGION_ITU_2:
|
||||
return RADIO_DEEMPHASIS_75;
|
||||
case RADIO_REGION_ITU_1:
|
||||
case RADIO_REGION_OIRT:
|
||||
case RADIO_REGION_JAPAN:
|
||||
default:
|
||||
return RADIO_DEEMPHASIS_50;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ANDROID_RADIO_H
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_THREAD_DEFS_H
|
||||
#define ANDROID_THREAD_DEFS_H
|
||||
|
||||
#include "graphics.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
/*
|
||||
* ***********************************************
|
||||
* ** Keep in sync with android.os.Process.java **
|
||||
* ***********************************************
|
||||
*
|
||||
* This maps directly to the "nice" priorities we use in Android.
|
||||
* A thread priority should be chosen inverse-proportionally to
|
||||
* the amount of work the thread is expected to do. The more work
|
||||
* a thread will do, the less favorable priority it should get so that
|
||||
* it doesn't starve the system. Threads not behaving properly might
|
||||
* be "punished" by the kernel.
|
||||
* Use the levels below when appropriate. Intermediate values are
|
||||
* acceptable, preferably use the {MORE|LESS}_FAVORABLE constants below.
|
||||
*/
|
||||
ANDROID_PRIORITY_LOWEST = 19,
|
||||
|
||||
/* use for background tasks */
|
||||
ANDROID_PRIORITY_BACKGROUND = 10,
|
||||
|
||||
/* most threads run at normal priority */
|
||||
ANDROID_PRIORITY_NORMAL = 0,
|
||||
|
||||
/* threads currently running a UI that the user is interacting with */
|
||||
ANDROID_PRIORITY_FOREGROUND = -2,
|
||||
|
||||
/* the main UI thread has a slightly more favorable priority */
|
||||
ANDROID_PRIORITY_DISPLAY = -4,
|
||||
|
||||
/* ui service treads might want to run at a urgent display (uncommon) */
|
||||
ANDROID_PRIORITY_URGENT_DISPLAY = HAL_PRIORITY_URGENT_DISPLAY,
|
||||
|
||||
/* all normal audio threads */
|
||||
ANDROID_PRIORITY_AUDIO = -16,
|
||||
|
||||
/* service audio threads (uncommon) */
|
||||
ANDROID_PRIORITY_URGENT_AUDIO = -19,
|
||||
|
||||
/* should never be used in practice. regular process might not
|
||||
* be allowed to use this level */
|
||||
ANDROID_PRIORITY_HIGHEST = -20,
|
||||
|
||||
ANDROID_PRIORITY_DEFAULT = ANDROID_PRIORITY_NORMAL,
|
||||
ANDROID_PRIORITY_MORE_FAVORABLE = -1,
|
||||
ANDROID_PRIORITY_LESS_FAVORABLE = +1,
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ANDROID_THREAD_DEFS_H */
|
||||
@@ -0,0 +1,954 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SYSTEM_CORE_INCLUDE_ANDROID_WINDOW_H
|
||||
#define SYSTEM_CORE_INCLUDE_ANDROID_WINDOW_H
|
||||
|
||||
#include <cutils/native_handle.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <system/graphics.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef __UNUSED
|
||||
#define __UNUSED __attribute__((__unused__))
|
||||
#endif
|
||||
#ifndef __deprecated
|
||||
#define __deprecated __attribute__((__deprecated__))
|
||||
#endif
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define ANDROID_NATIVE_MAKE_CONSTANT(a,b,c,d) \
|
||||
(((unsigned)(a)<<24)|((unsigned)(b)<<16)|((unsigned)(c)<<8)|(unsigned)(d))
|
||||
|
||||
#define ANDROID_NATIVE_WINDOW_MAGIC \
|
||||
ANDROID_NATIVE_MAKE_CONSTANT('_','w','n','d')
|
||||
|
||||
#define ANDROID_NATIVE_BUFFER_MAGIC \
|
||||
ANDROID_NATIVE_MAKE_CONSTANT('_','b','f','r')
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// This #define may be used to conditionally compile device-specific code to
|
||||
// support either the prior ANativeWindow interface, which did not pass libsync
|
||||
// fences around, or the new interface that does. This #define is only present
|
||||
// when the ANativeWindow interface does include libsync support.
|
||||
#define ANDROID_NATIVE_WINDOW_HAS_SYNC 1
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
typedef const native_handle_t* buffer_handle_t;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
typedef struct android_native_rect_t
|
||||
{
|
||||
int32_t left;
|
||||
int32_t top;
|
||||
int32_t right;
|
||||
int32_t bottom;
|
||||
} android_native_rect_t;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
typedef struct android_native_base_t
|
||||
{
|
||||
/* a magic value defined by the actual EGL native type */
|
||||
int magic;
|
||||
|
||||
/* the sizeof() of the actual EGL native type */
|
||||
int version;
|
||||
|
||||
void* reserved[4];
|
||||
|
||||
/* reference-counting interface */
|
||||
void (*incRef)(struct android_native_base_t* base);
|
||||
void (*decRef)(struct android_native_base_t* base);
|
||||
} android_native_base_t;
|
||||
|
||||
typedef struct ANativeWindowBuffer
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
ANativeWindowBuffer() {
|
||||
common.magic = ANDROID_NATIVE_BUFFER_MAGIC;
|
||||
common.version = sizeof(ANativeWindowBuffer);
|
||||
memset(common.reserved, 0, sizeof(common.reserved));
|
||||
}
|
||||
|
||||
// Implement the methods that sp<ANativeWindowBuffer> expects so that it
|
||||
// can be used to automatically refcount ANativeWindowBuffer's.
|
||||
void incStrong(const void* /*id*/) const {
|
||||
common.incRef(const_cast<android_native_base_t*>(&common));
|
||||
}
|
||||
void decStrong(const void* /*id*/) const {
|
||||
common.decRef(const_cast<android_native_base_t*>(&common));
|
||||
}
|
||||
#endif
|
||||
|
||||
struct android_native_base_t common;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
int stride;
|
||||
int format;
|
||||
int usage;
|
||||
|
||||
void* reserved[2];
|
||||
|
||||
buffer_handle_t handle;
|
||||
|
||||
void* reserved_proc[8];
|
||||
} ANativeWindowBuffer_t;
|
||||
|
||||
// Old typedef for backwards compatibility.
|
||||
typedef ANativeWindowBuffer_t android_native_buffer_t;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/* attributes queriable with query() */
|
||||
enum {
|
||||
NATIVE_WINDOW_WIDTH = 0,
|
||||
NATIVE_WINDOW_HEIGHT = 1,
|
||||
NATIVE_WINDOW_FORMAT = 2,
|
||||
|
||||
/* The minimum number of buffers that must remain un-dequeued after a buffer
|
||||
* has been queued. This value applies only if set_buffer_count was used to
|
||||
* override the number of buffers and if a buffer has since been queued.
|
||||
* Users of the set_buffer_count ANativeWindow method should query this
|
||||
* value before calling set_buffer_count. If it is necessary to have N
|
||||
* buffers simultaneously dequeued as part of the steady-state operation,
|
||||
* and this query returns M then N+M buffers should be requested via
|
||||
* native_window_set_buffer_count.
|
||||
*
|
||||
* Note that this value does NOT apply until a single buffer has been
|
||||
* queued. In particular this means that it is possible to:
|
||||
*
|
||||
* 1. Query M = min undequeued buffers
|
||||
* 2. Set the buffer count to N + M
|
||||
* 3. Dequeue all N + M buffers
|
||||
* 4. Cancel M buffers
|
||||
* 5. Queue, dequeue, queue, dequeue, ad infinitum
|
||||
*/
|
||||
NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS = 3,
|
||||
|
||||
/* Check whether queueBuffer operations on the ANativeWindow send the buffer
|
||||
* to the window compositor. The query sets the returned 'value' argument
|
||||
* to 1 if the ANativeWindow DOES send queued buffers directly to the window
|
||||
* compositor and 0 if the buffers do not go directly to the window
|
||||
* compositor.
|
||||
*
|
||||
* This can be used to determine whether protected buffer content should be
|
||||
* sent to the ANativeWindow. Note, however, that a result of 1 does NOT
|
||||
* indicate that queued buffers will be protected from applications or users
|
||||
* capturing their contents. If that behavior is desired then some other
|
||||
* mechanism (e.g. the GRALLOC_USAGE_PROTECTED flag) should be used in
|
||||
* conjunction with this query.
|
||||
*/
|
||||
NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER = 4,
|
||||
|
||||
/* Get the concrete type of a ANativeWindow. See below for the list of
|
||||
* possible return values.
|
||||
*
|
||||
* This query should not be used outside the Android framework and will
|
||||
* likely be removed in the near future.
|
||||
*/
|
||||
NATIVE_WINDOW_CONCRETE_TYPE = 5,
|
||||
|
||||
|
||||
/*
|
||||
* Default width and height of ANativeWindow buffers, these are the
|
||||
* dimensions of the window buffers irrespective of the
|
||||
* NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS call and match the native window
|
||||
* size unless overridden by NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS.
|
||||
*/
|
||||
NATIVE_WINDOW_DEFAULT_WIDTH = 6,
|
||||
NATIVE_WINDOW_DEFAULT_HEIGHT = 7,
|
||||
|
||||
/*
|
||||
* transformation that will most-likely be applied to buffers. This is only
|
||||
* a hint, the actual transformation applied might be different.
|
||||
*
|
||||
* INTENDED USE:
|
||||
*
|
||||
* The transform hint can be used by a producer, for instance the GLES
|
||||
* driver, to pre-rotate the rendering such that the final transformation
|
||||
* in the composer is identity. This can be very useful when used in
|
||||
* conjunction with the h/w composer HAL, in situations where it
|
||||
* cannot handle arbitrary rotations.
|
||||
*
|
||||
* 1. Before dequeuing a buffer, the GL driver (or any other ANW client)
|
||||
* queries the ANW for NATIVE_WINDOW_TRANSFORM_HINT.
|
||||
*
|
||||
* 2. The GL driver overrides the width and height of the ANW to
|
||||
* account for NATIVE_WINDOW_TRANSFORM_HINT. This is done by querying
|
||||
* NATIVE_WINDOW_DEFAULT_{WIDTH | HEIGHT}, swapping the dimensions
|
||||
* according to NATIVE_WINDOW_TRANSFORM_HINT and calling
|
||||
* native_window_set_buffers_dimensions().
|
||||
*
|
||||
* 3. The GL driver dequeues a buffer of the new pre-rotated size.
|
||||
*
|
||||
* 4. The GL driver renders to the buffer such that the image is
|
||||
* already transformed, that is applying NATIVE_WINDOW_TRANSFORM_HINT
|
||||
* to the rendering.
|
||||
*
|
||||
* 5. The GL driver calls native_window_set_transform to apply
|
||||
* inverse transformation to the buffer it just rendered.
|
||||
* In order to do this, the GL driver needs
|
||||
* to calculate the inverse of NATIVE_WINDOW_TRANSFORM_HINT, this is
|
||||
* done easily:
|
||||
*
|
||||
* int hintTransform, inverseTransform;
|
||||
* query(..., NATIVE_WINDOW_TRANSFORM_HINT, &hintTransform);
|
||||
* inverseTransform = hintTransform;
|
||||
* if (hintTransform & HAL_TRANSFORM_ROT_90)
|
||||
* inverseTransform ^= HAL_TRANSFORM_ROT_180;
|
||||
*
|
||||
*
|
||||
* 6. The GL driver queues the pre-transformed buffer.
|
||||
*
|
||||
* 7. The composer combines the buffer transform with the display
|
||||
* transform. If the buffer transform happens to cancel out the
|
||||
* display transform then no rotation is needed.
|
||||
*
|
||||
*/
|
||||
NATIVE_WINDOW_TRANSFORM_HINT = 8,
|
||||
|
||||
/*
|
||||
* Boolean that indicates whether the consumer is running more than
|
||||
* one buffer behind the producer.
|
||||
*/
|
||||
NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND = 9,
|
||||
|
||||
/*
|
||||
* The consumer gralloc usage bits currently set by the consumer.
|
||||
* The values are defined in hardware/libhardware/include/gralloc.h.
|
||||
*/
|
||||
NATIVE_WINDOW_CONSUMER_USAGE_BITS = 10,
|
||||
|
||||
/**
|
||||
* Transformation that will by applied to buffers by the hwcomposer.
|
||||
* This must not be set or checked by producer endpoints, and will
|
||||
* disable the transform hint set in SurfaceFlinger (see
|
||||
* NATIVE_WINDOW_TRANSFORM_HINT).
|
||||
*
|
||||
* INTENDED USE:
|
||||
* Temporary - Please do not use this. This is intended only to be used
|
||||
* by the camera's LEGACY mode.
|
||||
*
|
||||
* In situations where a SurfaceFlinger client wishes to set a transform
|
||||
* that is not visible to the producer, and will always be applied in the
|
||||
* hardware composer, the client can set this flag with
|
||||
* native_window_set_buffers_sticky_transform. This can be used to rotate
|
||||
* and flip buffers consumed by hardware composer without actually changing
|
||||
* the aspect ratio of the buffers produced.
|
||||
*/
|
||||
NATIVE_WINDOW_STICKY_TRANSFORM = 11,
|
||||
|
||||
/**
|
||||
* The default data space for the buffers as set by the consumer.
|
||||
* The values are defined in graphics.h.
|
||||
*/
|
||||
NATIVE_WINDOW_DEFAULT_DATASPACE = 12,
|
||||
|
||||
/*
|
||||
* Returns the age of the contents of the most recently dequeued buffer as
|
||||
* the number of frames that have elapsed since it was last queued. For
|
||||
* example, if the window is double-buffered, the age of any given buffer in
|
||||
* steady state will be 2. If the dequeued buffer has never been queued, its
|
||||
* age will be 0.
|
||||
*/
|
||||
NATIVE_WINDOW_BUFFER_AGE = 13,
|
||||
};
|
||||
|
||||
/* Valid operations for the (*perform)() hook.
|
||||
*
|
||||
* Values marked as 'deprecated' are supported, but have been superceded by
|
||||
* other functionality.
|
||||
*
|
||||
* Values marked as 'private' should be considered private to the framework.
|
||||
* HAL implementation code with access to an ANativeWindow should not use these,
|
||||
* as it may not interact properly with the framework's use of the
|
||||
* ANativeWindow.
|
||||
*/
|
||||
enum {
|
||||
NATIVE_WINDOW_SET_USAGE = 0,
|
||||
NATIVE_WINDOW_CONNECT = 1, /* deprecated */
|
||||
NATIVE_WINDOW_DISCONNECT = 2, /* deprecated */
|
||||
NATIVE_WINDOW_SET_CROP = 3, /* private */
|
||||
NATIVE_WINDOW_SET_BUFFER_COUNT = 4,
|
||||
NATIVE_WINDOW_SET_BUFFERS_GEOMETRY = 5, /* deprecated */
|
||||
NATIVE_WINDOW_SET_BUFFERS_TRANSFORM = 6,
|
||||
NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP = 7,
|
||||
NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS = 8,
|
||||
NATIVE_WINDOW_SET_BUFFERS_FORMAT = 9,
|
||||
NATIVE_WINDOW_SET_SCALING_MODE = 10, /* private */
|
||||
NATIVE_WINDOW_LOCK = 11, /* private */
|
||||
NATIVE_WINDOW_UNLOCK_AND_POST = 12, /* private */
|
||||
NATIVE_WINDOW_API_CONNECT = 13, /* private */
|
||||
NATIVE_WINDOW_API_DISCONNECT = 14, /* private */
|
||||
NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS = 15, /* private */
|
||||
NATIVE_WINDOW_SET_POST_TRANSFORM_CROP = 16, /* private */
|
||||
NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM = 17,/* private */
|
||||
NATIVE_WINDOW_SET_SIDEBAND_STREAM = 18,
|
||||
NATIVE_WINDOW_SET_BUFFERS_DATASPACE = 19,
|
||||
NATIVE_WINDOW_SET_SURFACE_DAMAGE = 20, /* private */
|
||||
};
|
||||
|
||||
/* parameter for NATIVE_WINDOW_[API_][DIS]CONNECT */
|
||||
enum {
|
||||
/* Buffers will be queued by EGL via eglSwapBuffers after being filled using
|
||||
* OpenGL ES.
|
||||
*/
|
||||
NATIVE_WINDOW_API_EGL = 1,
|
||||
|
||||
/* Buffers will be queued after being filled using the CPU
|
||||
*/
|
||||
NATIVE_WINDOW_API_CPU = 2,
|
||||
|
||||
/* Buffers will be queued by Stagefright after being filled by a video
|
||||
* decoder. The video decoder can either be a software or hardware decoder.
|
||||
*/
|
||||
NATIVE_WINDOW_API_MEDIA = 3,
|
||||
|
||||
/* Buffers will be queued by the the camera HAL.
|
||||
*/
|
||||
NATIVE_WINDOW_API_CAMERA = 4,
|
||||
};
|
||||
|
||||
/* parameter for NATIVE_WINDOW_SET_BUFFERS_TRANSFORM */
|
||||
enum {
|
||||
/* flip source image horizontally */
|
||||
NATIVE_WINDOW_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H ,
|
||||
/* flip source image vertically */
|
||||
NATIVE_WINDOW_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V,
|
||||
/* rotate source image 90 degrees clock-wise, and is applied after TRANSFORM_FLIP_{H|V} */
|
||||
NATIVE_WINDOW_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90,
|
||||
/* rotate source image 180 degrees */
|
||||
NATIVE_WINDOW_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180,
|
||||
/* rotate source image 270 degrees clock-wise */
|
||||
NATIVE_WINDOW_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270,
|
||||
/* transforms source by the inverse transform of the screen it is displayed onto. This
|
||||
* transform is applied last */
|
||||
NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY = 0x08
|
||||
};
|
||||
|
||||
/* parameter for NATIVE_WINDOW_SET_SCALING_MODE */
|
||||
enum {
|
||||
/* the window content is not updated (frozen) until a buffer of
|
||||
* the window size is received (enqueued)
|
||||
*/
|
||||
NATIVE_WINDOW_SCALING_MODE_FREEZE = 0,
|
||||
/* the buffer is scaled in both dimensions to match the window size */
|
||||
NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW = 1,
|
||||
/* the buffer is scaled uniformly such that the smaller dimension
|
||||
* of the buffer matches the window size (cropping in the process)
|
||||
*/
|
||||
NATIVE_WINDOW_SCALING_MODE_SCALE_CROP = 2,
|
||||
/* the window is clipped to the size of the buffer's crop rectangle; pixels
|
||||
* outside the crop rectangle are treated as if they are completely
|
||||
* transparent.
|
||||
*/
|
||||
NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP = 3,
|
||||
};
|
||||
|
||||
/* values returned by the NATIVE_WINDOW_CONCRETE_TYPE query */
|
||||
enum {
|
||||
NATIVE_WINDOW_FRAMEBUFFER = 0, /* FramebufferNativeWindow */
|
||||
NATIVE_WINDOW_SURFACE = 1, /* Surface */
|
||||
};
|
||||
|
||||
/* parameter for NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP
|
||||
*
|
||||
* Special timestamp value to indicate that timestamps should be auto-generated
|
||||
* by the native window when queueBuffer is called. This is equal to INT64_MIN,
|
||||
* defined directly to avoid problems with C99/C++ inclusion of stdint.h.
|
||||
*/
|
||||
static const int64_t NATIVE_WINDOW_TIMESTAMP_AUTO = (-9223372036854775807LL-1);
|
||||
|
||||
struct ANativeWindow
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
ANativeWindow()
|
||||
: flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)
|
||||
{
|
||||
common.magic = ANDROID_NATIVE_WINDOW_MAGIC;
|
||||
common.version = sizeof(ANativeWindow);
|
||||
memset(common.reserved, 0, sizeof(common.reserved));
|
||||
}
|
||||
|
||||
/* Implement the methods that sp<ANativeWindow> expects so that it
|
||||
can be used to automatically refcount ANativeWindow's. */
|
||||
void incStrong(const void* /*id*/) const {
|
||||
common.incRef(const_cast<android_native_base_t*>(&common));
|
||||
}
|
||||
void decStrong(const void* /*id*/) const {
|
||||
common.decRef(const_cast<android_native_base_t*>(&common));
|
||||
}
|
||||
#endif
|
||||
|
||||
struct android_native_base_t common;
|
||||
|
||||
/* flags describing some attributes of this surface or its updater */
|
||||
const uint32_t flags;
|
||||
|
||||
/* min swap interval supported by this updated */
|
||||
const int minSwapInterval;
|
||||
|
||||
/* max swap interval supported by this updated */
|
||||
const int maxSwapInterval;
|
||||
|
||||
/* horizontal and vertical resolution in DPI */
|
||||
const float xdpi;
|
||||
const float ydpi;
|
||||
|
||||
/* Some storage reserved for the OEM's driver. */
|
||||
intptr_t oem[4];
|
||||
|
||||
/*
|
||||
* Set the swap interval for this surface.
|
||||
*
|
||||
* Returns 0 on success or -errno on error.
|
||||
*/
|
||||
int (*setSwapInterval)(struct ANativeWindow* window,
|
||||
int interval);
|
||||
|
||||
/*
|
||||
* Hook called by EGL to acquire a buffer. After this call, the buffer
|
||||
* is not locked, so its content cannot be modified. This call may block if
|
||||
* no buffers are available.
|
||||
*
|
||||
* The window holds a reference to the buffer between dequeueBuffer and
|
||||
* either queueBuffer or cancelBuffer, so clients only need their own
|
||||
* reference if they might use the buffer after queueing or canceling it.
|
||||
* Holding a reference to a buffer after queueing or canceling it is only
|
||||
* allowed if a specific buffer count has been set.
|
||||
*
|
||||
* Returns 0 on success or -errno on error.
|
||||
*
|
||||
* XXX: This function is deprecated. It will continue to work for some
|
||||
* time for binary compatibility, but the new dequeueBuffer function that
|
||||
* outputs a fence file descriptor should be used in its place.
|
||||
*/
|
||||
int (*dequeueBuffer_DEPRECATED)(struct ANativeWindow* window,
|
||||
struct ANativeWindowBuffer** buffer);
|
||||
|
||||
/*
|
||||
* hook called by EGL to lock a buffer. This MUST be called before modifying
|
||||
* the content of a buffer. The buffer must have been acquired with
|
||||
* dequeueBuffer first.
|
||||
*
|
||||
* Returns 0 on success or -errno on error.
|
||||
*
|
||||
* XXX: This function is deprecated. It will continue to work for some
|
||||
* time for binary compatibility, but it is essentially a no-op, and calls
|
||||
* to it should be removed.
|
||||
*/
|
||||
int (*lockBuffer_DEPRECATED)(struct ANativeWindow* window,
|
||||
struct ANativeWindowBuffer* buffer);
|
||||
|
||||
/*
|
||||
* Hook called by EGL when modifications to the render buffer are done.
|
||||
* This unlocks and post the buffer.
|
||||
*
|
||||
* The window holds a reference to the buffer between dequeueBuffer and
|
||||
* either queueBuffer or cancelBuffer, so clients only need their own
|
||||
* reference if they might use the buffer after queueing or canceling it.
|
||||
* Holding a reference to a buffer after queueing or canceling it is only
|
||||
* allowed if a specific buffer count has been set.
|
||||
*
|
||||
* Buffers MUST be queued in the same order than they were dequeued.
|
||||
*
|
||||
* Returns 0 on success or -errno on error.
|
||||
*
|
||||
* XXX: This function is deprecated. It will continue to work for some
|
||||
* time for binary compatibility, but the new queueBuffer function that
|
||||
* takes a fence file descriptor should be used in its place (pass a value
|
||||
* of -1 for the fence file descriptor if there is no valid one to pass).
|
||||
*/
|
||||
int (*queueBuffer_DEPRECATED)(struct ANativeWindow* window,
|
||||
struct ANativeWindowBuffer* buffer);
|
||||
|
||||
/*
|
||||
* hook used to retrieve information about the native window.
|
||||
*
|
||||
* Returns 0 on success or -errno on error.
|
||||
*/
|
||||
int (*query)(const struct ANativeWindow* window,
|
||||
int what, int* value);
|
||||
|
||||
/*
|
||||
* hook used to perform various operations on the surface.
|
||||
* (*perform)() is a generic mechanism to add functionality to
|
||||
* ANativeWindow while keeping backward binary compatibility.
|
||||
*
|
||||
* DO NOT CALL THIS HOOK DIRECTLY. Instead, use the helper functions
|
||||
* defined below.
|
||||
*
|
||||
* (*perform)() returns -ENOENT if the 'what' parameter is not supported
|
||||
* by the surface's implementation.
|
||||
*
|
||||
* See above for a list of valid operations, such as
|
||||
* NATIVE_WINDOW_SET_USAGE or NATIVE_WINDOW_CONNECT
|
||||
*/
|
||||
int (*perform)(struct ANativeWindow* window,
|
||||
int operation, ... );
|
||||
|
||||
/*
|
||||
* Hook used to cancel a buffer that has been dequeued.
|
||||
* No synchronization is performed between dequeue() and cancel(), so
|
||||
* either external synchronization is needed, or these functions must be
|
||||
* called from the same thread.
|
||||
*
|
||||
* The window holds a reference to the buffer between dequeueBuffer and
|
||||
* either queueBuffer or cancelBuffer, so clients only need their own
|
||||
* reference if they might use the buffer after queueing or canceling it.
|
||||
* Holding a reference to a buffer after queueing or canceling it is only
|
||||
* allowed if a specific buffer count has been set.
|
||||
*
|
||||
* XXX: This function is deprecated. It will continue to work for some
|
||||
* time for binary compatibility, but the new cancelBuffer function that
|
||||
* takes a fence file descriptor should be used in its place (pass a value
|
||||
* of -1 for the fence file descriptor if there is no valid one to pass).
|
||||
*/
|
||||
int (*cancelBuffer_DEPRECATED)(struct ANativeWindow* window,
|
||||
struct ANativeWindowBuffer* buffer);
|
||||
|
||||
/*
|
||||
* Hook called by EGL to acquire a buffer. This call may block if no
|
||||
* buffers are available.
|
||||
*
|
||||
* The window holds a reference to the buffer between dequeueBuffer and
|
||||
* either queueBuffer or cancelBuffer, so clients only need their own
|
||||
* reference if they might use the buffer after queueing or canceling it.
|
||||
* Holding a reference to a buffer after queueing or canceling it is only
|
||||
* allowed if a specific buffer count has been set.
|
||||
*
|
||||
* The libsync fence file descriptor returned in the int pointed to by the
|
||||
* fenceFd argument will refer to the fence that must signal before the
|
||||
* dequeued buffer may be written to. A value of -1 indicates that the
|
||||
* caller may access the buffer immediately without waiting on a fence. If
|
||||
* a valid file descriptor is returned (i.e. any value except -1) then the
|
||||
* caller is responsible for closing the file descriptor.
|
||||
*
|
||||
* Returns 0 on success or -errno on error.
|
||||
*/
|
||||
int (*dequeueBuffer)(struct ANativeWindow* window,
|
||||
struct ANativeWindowBuffer** buffer, int* fenceFd);
|
||||
|
||||
/*
|
||||
* Hook called by EGL when modifications to the render buffer are done.
|
||||
* This unlocks and post the buffer.
|
||||
*
|
||||
* The window holds a reference to the buffer between dequeueBuffer and
|
||||
* either queueBuffer or cancelBuffer, so clients only need their own
|
||||
* reference if they might use the buffer after queueing or canceling it.
|
||||
* Holding a reference to a buffer after queueing or canceling it is only
|
||||
* allowed if a specific buffer count has been set.
|
||||
*
|
||||
* The fenceFd argument specifies a libsync fence file descriptor for a
|
||||
* fence that must signal before the buffer can be accessed. If the buffer
|
||||
* can be accessed immediately then a value of -1 should be used. The
|
||||
* caller must not use the file descriptor after it is passed to
|
||||
* queueBuffer, and the ANativeWindow implementation is responsible for
|
||||
* closing it.
|
||||
*
|
||||
* Returns 0 on success or -errno on error.
|
||||
*/
|
||||
int (*queueBuffer)(struct ANativeWindow* window,
|
||||
struct ANativeWindowBuffer* buffer, int fenceFd);
|
||||
|
||||
/*
|
||||
* Hook used to cancel a buffer that has been dequeued.
|
||||
* No synchronization is performed between dequeue() and cancel(), so
|
||||
* either external synchronization is needed, or these functions must be
|
||||
* called from the same thread.
|
||||
*
|
||||
* The window holds a reference to the buffer between dequeueBuffer and
|
||||
* either queueBuffer or cancelBuffer, so clients only need their own
|
||||
* reference if they might use the buffer after queueing or canceling it.
|
||||
* Holding a reference to a buffer after queueing or canceling it is only
|
||||
* allowed if a specific buffer count has been set.
|
||||
*
|
||||
* The fenceFd argument specifies a libsync fence file decsriptor for a
|
||||
* fence that must signal before the buffer can be accessed. If the buffer
|
||||
* can be accessed immediately then a value of -1 should be used.
|
||||
*
|
||||
* Note that if the client has not waited on the fence that was returned
|
||||
* from dequeueBuffer, that same fence should be passed to cancelBuffer to
|
||||
* ensure that future uses of the buffer are preceded by a wait on that
|
||||
* fence. The caller must not use the file descriptor after it is passed
|
||||
* to cancelBuffer, and the ANativeWindow implementation is responsible for
|
||||
* closing it.
|
||||
*
|
||||
* Returns 0 on success or -errno on error.
|
||||
*/
|
||||
int (*cancelBuffer)(struct ANativeWindow* window,
|
||||
struct ANativeWindowBuffer* buffer, int fenceFd);
|
||||
};
|
||||
|
||||
/* Backwards compatibility: use ANativeWindow (struct ANativeWindow in C).
|
||||
* android_native_window_t is deprecated.
|
||||
*/
|
||||
typedef struct ANativeWindow ANativeWindow;
|
||||
typedef struct ANativeWindow android_native_window_t __deprecated;
|
||||
|
||||
/*
|
||||
* native_window_set_usage(..., usage)
|
||||
* Sets the intended usage flags for the next buffers
|
||||
* acquired with (*lockBuffer)() and on.
|
||||
* By default (if this function is never called), a usage of
|
||||
* GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE
|
||||
* is assumed.
|
||||
* Calling this function will usually cause following buffers to be
|
||||
* reallocated.
|
||||
*/
|
||||
|
||||
static inline int native_window_set_usage(
|
||||
struct ANativeWindow* window, int usage)
|
||||
{
|
||||
return window->perform(window, NATIVE_WINDOW_SET_USAGE, usage);
|
||||
}
|
||||
|
||||
/* deprecated. Always returns 0. Don't call. */
|
||||
static inline int native_window_connect(
|
||||
struct ANativeWindow* window __UNUSED, int api __UNUSED) __deprecated;
|
||||
|
||||
static inline int native_window_connect(
|
||||
struct ANativeWindow* window __UNUSED, int api __UNUSED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* deprecated. Always returns 0. Don't call. */
|
||||
static inline int native_window_disconnect(
|
||||
struct ANativeWindow* window __UNUSED, int api __UNUSED) __deprecated;
|
||||
|
||||
static inline int native_window_disconnect(
|
||||
struct ANativeWindow* window __UNUSED, int api __UNUSED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* native_window_set_crop(..., crop)
|
||||
* Sets which region of the next queued buffers needs to be considered.
|
||||
* Depending on the scaling mode, a buffer's crop region is scaled and/or
|
||||
* cropped to match the surface's size. This function sets the crop in
|
||||
* pre-transformed buffer pixel coordinates.
|
||||
*
|
||||
* The specified crop region applies to all buffers queued after it is called.
|
||||
*
|
||||
* If 'crop' is NULL, subsequently queued buffers won't be cropped.
|
||||
*
|
||||
* An error is returned if for instance the crop region is invalid, out of the
|
||||
* buffer's bound or if the window is invalid.
|
||||
*/
|
||||
static inline int native_window_set_crop(
|
||||
struct ANativeWindow* window,
|
||||
android_native_rect_t const * crop)
|
||||
{
|
||||
return window->perform(window, NATIVE_WINDOW_SET_CROP, crop);
|
||||
}
|
||||
|
||||
/*
|
||||
* native_window_set_post_transform_crop(..., crop)
|
||||
* Sets which region of the next queued buffers needs to be considered.
|
||||
* Depending on the scaling mode, a buffer's crop region is scaled and/or
|
||||
* cropped to match the surface's size. This function sets the crop in
|
||||
* post-transformed pixel coordinates.
|
||||
*
|
||||
* The specified crop region applies to all buffers queued after it is called.
|
||||
*
|
||||
* If 'crop' is NULL, subsequently queued buffers won't be cropped.
|
||||
*
|
||||
* An error is returned if for instance the crop region is invalid, out of the
|
||||
* buffer's bound or if the window is invalid.
|
||||
*/
|
||||
static inline int native_window_set_post_transform_crop(
|
||||
struct ANativeWindow* window,
|
||||
android_native_rect_t const * crop)
|
||||
{
|
||||
return window->perform(window, NATIVE_WINDOW_SET_POST_TRANSFORM_CROP, crop);
|
||||
}
|
||||
|
||||
/*
|
||||
* native_window_set_active_rect(..., active_rect)
|
||||
*
|
||||
* This function is deprecated and will be removed soon. For now it simply
|
||||
* sets the post-transform crop for compatibility while multi-project commits
|
||||
* get checked.
|
||||
*/
|
||||
static inline int native_window_set_active_rect(
|
||||
struct ANativeWindow* window,
|
||||
android_native_rect_t const * active_rect) __deprecated;
|
||||
|
||||
static inline int native_window_set_active_rect(
|
||||
struct ANativeWindow* window,
|
||||
android_native_rect_t const * active_rect)
|
||||
{
|
||||
return native_window_set_post_transform_crop(window, active_rect);
|
||||
}
|
||||
|
||||
/*
|
||||
* native_window_set_buffer_count(..., count)
|
||||
* Sets the number of buffers associated with this native window.
|
||||
*/
|
||||
static inline int native_window_set_buffer_count(
|
||||
struct ANativeWindow* window,
|
||||
size_t bufferCount)
|
||||
{
|
||||
return window->perform(window, NATIVE_WINDOW_SET_BUFFER_COUNT, bufferCount);
|
||||
}
|
||||
|
||||
/*
|
||||
* native_window_set_buffers_geometry(..., int w, int h, int format)
|
||||
* All buffers dequeued after this call will have the dimensions and format
|
||||
* specified. A successful call to this function has the same effect as calling
|
||||
* native_window_set_buffers_size and native_window_set_buffers_format.
|
||||
*
|
||||
* XXX: This function is deprecated. The native_window_set_buffers_dimensions
|
||||
* and native_window_set_buffers_format functions should be used instead.
|
||||
*/
|
||||
static inline int native_window_set_buffers_geometry(
|
||||
struct ANativeWindow* window,
|
||||
int w, int h, int format) __deprecated;
|
||||
|
||||
static inline int native_window_set_buffers_geometry(
|
||||
struct ANativeWindow* window,
|
||||
int w, int h, int format)
|
||||
{
|
||||
return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_GEOMETRY,
|
||||
w, h, format);
|
||||
}
|
||||
|
||||
/*
|
||||
* native_window_set_buffers_dimensions(..., int w, int h)
|
||||
* All buffers dequeued after this call will have the dimensions specified.
|
||||
* In particular, all buffers will have a fixed-size, independent from the
|
||||
* native-window size. They will be scaled according to the scaling mode
|
||||
* (see native_window_set_scaling_mode) upon window composition.
|
||||
*
|
||||
* If w and h are 0, the normal behavior is restored. That is, dequeued buffers
|
||||
* following this call will be sized to match the window's size.
|
||||
*
|
||||
* Calling this function will reset the window crop to a NULL value, which
|
||||
* disables cropping of the buffers.
|
||||
*/
|
||||
static inline int native_window_set_buffers_dimensions(
|
||||
struct ANativeWindow* window,
|
||||
int w, int h)
|
||||
{
|
||||
return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS,
|
||||
w, h);
|
||||
}
|
||||
|
||||
/*
|
||||
* native_window_set_buffers_user_dimensions(..., int w, int h)
|
||||
*
|
||||
* Sets the user buffer size for the window, which overrides the
|
||||
* window's size. All buffers dequeued after this call will have the
|
||||
* dimensions specified unless overridden by
|
||||
* native_window_set_buffers_dimensions. All buffers will have a
|
||||
* fixed-size, independent from the native-window size. They will be
|
||||
* scaled according to the scaling mode (see
|
||||
* native_window_set_scaling_mode) upon window composition.
|
||||
*
|
||||
* If w and h are 0, the normal behavior is restored. That is, the
|
||||
* default buffer size will match the windows's size.
|
||||
*
|
||||
* Calling this function will reset the window crop to a NULL value, which
|
||||
* disables cropping of the buffers.
|
||||
*/
|
||||
static inline int native_window_set_buffers_user_dimensions(
|
||||
struct ANativeWindow* window,
|
||||
int w, int h)
|
||||
{
|
||||
return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS,
|
||||
w, h);
|
||||
}
|
||||
|
||||
/*
|
||||
* native_window_set_buffers_format(..., int format)
|
||||
* All buffers dequeued after this call will have the format specified.
|
||||
*
|
||||
* If the specified format is 0, the default buffer format will be used.
|
||||
*/
|
||||
static inline int native_window_set_buffers_format(
|
||||
struct ANativeWindow* window,
|
||||
int format)
|
||||
{
|
||||
return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_FORMAT, format);
|
||||
}
|
||||
|
||||
/*
|
||||
* native_window_set_buffers_data_space(..., int dataSpace)
|
||||
* All buffers queued after this call will be associated with the dataSpace
|
||||
* parameter specified.
|
||||
*
|
||||
* dataSpace specifies additional information about the buffer that's dependent
|
||||
* on the buffer format and the endpoints. For example, it can be used to convey
|
||||
* the color space of the image data in the buffer, or it can be used to
|
||||
* indicate that the buffers contain depth measurement data instead of color
|
||||
* images. The default dataSpace is 0, HAL_DATASPACE_UNKNOWN, unless it has been
|
||||
* overridden by the consumer.
|
||||
*/
|
||||
static inline int native_window_set_buffers_data_space(
|
||||
struct ANativeWindow* window,
|
||||
android_dataspace_t dataSpace)
|
||||
{
|
||||
return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_DATASPACE,
|
||||
dataSpace);
|
||||
}
|
||||
|
||||
/*
|
||||
* native_window_set_buffers_transform(..., int transform)
|
||||
* All buffers queued after this call will be displayed transformed according
|
||||
* to the transform parameter specified.
|
||||
*/
|
||||
static inline int native_window_set_buffers_transform(
|
||||
struct ANativeWindow* window,
|
||||
int transform)
|
||||
{
|
||||
return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TRANSFORM,
|
||||
transform);
|
||||
}
|
||||
|
||||
/*
|
||||
* native_window_set_buffers_sticky_transform(..., int transform)
|
||||
* All buffers queued after this call will be displayed transformed according
|
||||
* to the transform parameter specified applied on top of the regular buffer
|
||||
* transform. Setting this transform will disable the transform hint.
|
||||
*
|
||||
* Temporary - This is only intended to be used by the LEGACY camera mode, do
|
||||
* not use this for anything else.
|
||||
*/
|
||||
static inline int native_window_set_buffers_sticky_transform(
|
||||
struct ANativeWindow* window,
|
||||
int transform)
|
||||
{
|
||||
return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM,
|
||||
transform);
|
||||
}
|
||||
|
||||
/*
|
||||
* native_window_set_buffers_timestamp(..., int64_t timestamp)
|
||||
* All buffers queued after this call will be associated with the timestamp
|
||||
* parameter specified. If the timestamp is set to NATIVE_WINDOW_TIMESTAMP_AUTO
|
||||
* (the default), timestamps will be generated automatically when queueBuffer is
|
||||
* called. The timestamp is measured in nanoseconds, and is normally monotonically
|
||||
* increasing. The timestamp should be unaffected by time-of-day adjustments,
|
||||
* and for a camera should be strictly monotonic but for a media player may be
|
||||
* reset when the position is set.
|
||||
*/
|
||||
static inline int native_window_set_buffers_timestamp(
|
||||
struct ANativeWindow* window,
|
||||
int64_t timestamp)
|
||||
{
|
||||
return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP,
|
||||
timestamp);
|
||||
}
|
||||
|
||||
/*
|
||||
* native_window_set_scaling_mode(..., int mode)
|
||||
* All buffers queued after this call will be associated with the scaling mode
|
||||
* specified.
|
||||
*/
|
||||
static inline int native_window_set_scaling_mode(
|
||||
struct ANativeWindow* window,
|
||||
int mode)
|
||||
{
|
||||
return window->perform(window, NATIVE_WINDOW_SET_SCALING_MODE,
|
||||
mode);
|
||||
}
|
||||
|
||||
/*
|
||||
* native_window_api_connect(..., int api)
|
||||
* connects an API to this window. only one API can be connected at a time.
|
||||
* Returns -EINVAL if for some reason the window cannot be connected, which
|
||||
* can happen if it's connected to some other API.
|
||||
*/
|
||||
static inline int native_window_api_connect(
|
||||
struct ANativeWindow* window, int api)
|
||||
{
|
||||
return window->perform(window, NATIVE_WINDOW_API_CONNECT, api);
|
||||
}
|
||||
|
||||
/*
|
||||
* native_window_api_disconnect(..., int api)
|
||||
* disconnect the API from this window.
|
||||
* An error is returned if for instance the window wasn't connected in the
|
||||
* first place.
|
||||
*/
|
||||
static inline int native_window_api_disconnect(
|
||||
struct ANativeWindow* window, int api)
|
||||
{
|
||||
return window->perform(window, NATIVE_WINDOW_API_DISCONNECT, api);
|
||||
}
|
||||
|
||||
/*
|
||||
* native_window_dequeue_buffer_and_wait(...)
|
||||
* Dequeue a buffer and wait on the fence associated with that buffer. The
|
||||
* buffer may safely be accessed immediately upon this function returning. An
|
||||
* error is returned if either of the dequeue or the wait operations fail.
|
||||
*/
|
||||
static inline int native_window_dequeue_buffer_and_wait(ANativeWindow *anw,
|
||||
struct ANativeWindowBuffer** anb) {
|
||||
return anw->dequeueBuffer_DEPRECATED(anw, anb);
|
||||
}
|
||||
|
||||
/*
|
||||
* native_window_set_sideband_stream(..., native_handle_t*)
|
||||
* Attach a sideband buffer stream to a native window.
|
||||
*/
|
||||
static inline int native_window_set_sideband_stream(
|
||||
struct ANativeWindow* window,
|
||||
native_handle_t* sidebandHandle)
|
||||
{
|
||||
return window->perform(window, NATIVE_WINDOW_SET_SIDEBAND_STREAM,
|
||||
sidebandHandle);
|
||||
}
|
||||
|
||||
/*
|
||||
* native_window_set_surface_damage(..., android_native_rect_t* rects, int numRects)
|
||||
* Set the surface damage (i.e., the region of the surface that has changed
|
||||
* since the previous frame). The damage set by this call will be reset (to the
|
||||
* default of full-surface damage) after calling queue, so this must be called
|
||||
* prior to every frame with damage that does not cover the whole surface if the
|
||||
* caller desires downstream consumers to use this optimization.
|
||||
*
|
||||
* The damage region is specified as an array of rectangles, with the important
|
||||
* caveat that the origin of the surface is considered to be the bottom-left
|
||||
* corner, as in OpenGL ES.
|
||||
*
|
||||
* If numRects is set to 0, rects may be NULL, and the surface damage will be
|
||||
* set to the full surface (the same as if this function had not been called for
|
||||
* this frame).
|
||||
*/
|
||||
static inline int native_window_set_surface_damage(
|
||||
struct ANativeWindow* window,
|
||||
const android_native_rect_t* rects, size_t numRects)
|
||||
{
|
||||
return window->perform(window, NATIVE_WINDOW_SET_SURFACE_DAMAGE,
|
||||
rects, numRects);
|
||||
}
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* SYSTEM_CORE_INCLUDE_ANDROID_WINDOW_H */
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _LIBS_UTILS_ANDROID_THREADS_H
|
||||
#define _LIBS_UTILS_ANDROID_THREADS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include <utils/ThreadDefs.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// C API
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Create and run a new thread.
|
||||
extern int androidCreateThread(android_thread_func_t, void *);
|
||||
|
||||
// Create thread with lots of parameters
|
||||
extern int androidCreateThreadEtc(android_thread_func_t entryFunction,
|
||||
void *userData,
|
||||
const char* threadName,
|
||||
int32_t threadPriority,
|
||||
size_t threadStackSize,
|
||||
android_thread_id_t *threadId);
|
||||
|
||||
// Get some sort of unique identifier for the current thread.
|
||||
extern android_thread_id_t androidGetThreadId();
|
||||
|
||||
// Low-level thread creation -- never creates threads that can
|
||||
// interact with the Java VM.
|
||||
extern int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
|
||||
void *userData,
|
||||
const char* threadName,
|
||||
int32_t threadPriority,
|
||||
size_t threadStackSize,
|
||||
android_thread_id_t *threadId);
|
||||
|
||||
// set the same of the running thread
|
||||
extern void androidSetThreadName(const char* name);
|
||||
|
||||
// Used by the Java Runtime to control how threads are created, so that
|
||||
// they can be proper and lovely Java threads.
|
||||
typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction,
|
||||
void *userData,
|
||||
const char* threadName,
|
||||
int32_t threadPriority,
|
||||
size_t threadStackSize,
|
||||
android_thread_id_t *threadId);
|
||||
|
||||
extern void androidSetCreateThreadFunc(android_create_thread_fn func);
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Extra functions working with raw pids.
|
||||
|
||||
#ifdef HAVE_ANDROID_OS
|
||||
// Change the priority AND scheduling group of a particular thread. The priority
|
||||
// should be one of the ANDROID_PRIORITY constants. Returns INVALID_OPERATION
|
||||
// if the priority set failed, else another value if just the group set failed;
|
||||
// in either case errno is set. Thread ID zero means current thread.
|
||||
extern int androidSetThreadPriority(pid_t tid, int prio);
|
||||
|
||||
// Get the current priority of a particular thread. Returns one of the
|
||||
// ANDROID_PRIORITY constants or a negative result in case of error.
|
||||
extern int androidGetThreadPriority(pid_t tid);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// C++ API
|
||||
#ifdef __cplusplus
|
||||
namespace android {
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Create and run a new thread.
|
||||
inline bool createThread(thread_func_t f, void *a) {
|
||||
return androidCreateThread(f, a) ? true : false;
|
||||
}
|
||||
|
||||
// Create thread with lots of parameters
|
||||
inline bool createThreadEtc(thread_func_t entryFunction,
|
||||
void *userData,
|
||||
const char* threadName = "android:unnamed_thread",
|
||||
int32_t threadPriority = PRIORITY_DEFAULT,
|
||||
size_t threadStackSize = 0,
|
||||
thread_id_t *threadId = 0)
|
||||
{
|
||||
return androidCreateThreadEtc(entryFunction, userData, threadName,
|
||||
threadPriority, threadStackSize, threadId) ? true : false;
|
||||
}
|
||||
|
||||
// Get some sort of unique identifier for the current thread.
|
||||
inline thread_id_t getThreadId() {
|
||||
return androidGetThreadId();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
}; // namespace android
|
||||
#endif // __cplusplus
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#endif // _LIBS_UTILS_ANDROID_THREADS_H
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_UTILS_ATOMIC_H
|
||||
#define ANDROID_UTILS_ATOMIC_H
|
||||
|
||||
#include <cutils/atomic.h>
|
||||
|
||||
#endif // ANDROID_UTILS_ATOMIC_H
|
||||
@@ -0,0 +1,402 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_BASIC_HASHTABLE_H
|
||||
#define ANDROID_BASIC_HASHTABLE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <utils/SharedBuffer.h>
|
||||
#include <utils/TypeHelpers.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
/* Implementation type. Nothing to see here. */
|
||||
class BasicHashtableImpl {
|
||||
protected:
|
||||
struct Bucket {
|
||||
// The collision flag indicates that the bucket is part of a collision chain
|
||||
// such that at least two entries both hash to this bucket. When true, we
|
||||
// may need to seek further along the chain to find the entry.
|
||||
static const uint32_t COLLISION = 0x80000000UL;
|
||||
|
||||
// The present flag indicates that the bucket contains an initialized entry value.
|
||||
static const uint32_t PRESENT = 0x40000000UL;
|
||||
|
||||
// Mask for 30 bits worth of the hash code that are stored within the bucket to
|
||||
// speed up lookups and rehashing by eliminating the need to recalculate the
|
||||
// hash code of the entry's key.
|
||||
static const uint32_t HASH_MASK = 0x3fffffffUL;
|
||||
|
||||
// Combined value that stores the collision and present flags as well as
|
||||
// a 30 bit hash code.
|
||||
uint32_t cookie;
|
||||
|
||||
// Storage for the entry begins here.
|
||||
char entry[0];
|
||||
};
|
||||
|
||||
BasicHashtableImpl(size_t entrySize, bool hasTrivialDestructor,
|
||||
size_t minimumInitialCapacity, float loadFactor);
|
||||
BasicHashtableImpl(const BasicHashtableImpl& other);
|
||||
virtual ~BasicHashtableImpl();
|
||||
|
||||
void dispose();
|
||||
|
||||
inline void edit() {
|
||||
if (mBuckets && !SharedBuffer::bufferFromData(mBuckets)->onlyOwner()) {
|
||||
clone();
|
||||
}
|
||||
}
|
||||
|
||||
void setTo(const BasicHashtableImpl& other);
|
||||
void clear();
|
||||
|
||||
ssize_t next(ssize_t index) const;
|
||||
ssize_t find(ssize_t index, hash_t hash, const void* __restrict__ key) const;
|
||||
size_t add(hash_t hash, const void* __restrict__ entry);
|
||||
void removeAt(size_t index);
|
||||
void rehash(size_t minimumCapacity, float loadFactor);
|
||||
|
||||
const size_t mBucketSize; // number of bytes per bucket including the entry
|
||||
const bool mHasTrivialDestructor; // true if the entry type does not require destruction
|
||||
size_t mCapacity; // number of buckets that can be filled before exceeding load factor
|
||||
float mLoadFactor; // load factor
|
||||
size_t mSize; // number of elements actually in the table
|
||||
size_t mFilledBuckets; // number of buckets for which collision or present is true
|
||||
size_t mBucketCount; // number of slots in the mBuckets array
|
||||
void* mBuckets; // array of buckets, as a SharedBuffer
|
||||
|
||||
inline const Bucket& bucketAt(const void* __restrict__ buckets, size_t index) const {
|
||||
return *reinterpret_cast<const Bucket*>(
|
||||
static_cast<const uint8_t*>(buckets) + index * mBucketSize);
|
||||
}
|
||||
|
||||
inline Bucket& bucketAt(void* __restrict__ buckets, size_t index) const {
|
||||
return *reinterpret_cast<Bucket*>(static_cast<uint8_t*>(buckets) + index * mBucketSize);
|
||||
}
|
||||
|
||||
virtual bool compareBucketKey(const Bucket& bucket, const void* __restrict__ key) const = 0;
|
||||
virtual void initializeBucketEntry(Bucket& bucket, const void* __restrict__ entry) const = 0;
|
||||
virtual void destroyBucketEntry(Bucket& bucket) const = 0;
|
||||
|
||||
private:
|
||||
void clone();
|
||||
|
||||
// Allocates a bucket array as a SharedBuffer.
|
||||
void* allocateBuckets(size_t count) const;
|
||||
|
||||
// Releases a bucket array's associated SharedBuffer.
|
||||
void releaseBuckets(void* __restrict__ buckets, size_t count) const;
|
||||
|
||||
// Destroys the contents of buckets (invokes destroyBucketEntry for each
|
||||
// populated bucket if needed).
|
||||
void destroyBuckets(void* __restrict__ buckets, size_t count) const;
|
||||
|
||||
// Copies the content of buckets (copies the cookie and invokes copyBucketEntry
|
||||
// for each populated bucket if needed).
|
||||
void copyBuckets(const void* __restrict__ fromBuckets,
|
||||
void* __restrict__ toBuckets, size_t count) const;
|
||||
|
||||
// Determines the appropriate size of a bucket array to store a certain minimum
|
||||
// number of entries and returns its effective capacity.
|
||||
static void determineCapacity(size_t minimumCapacity, float loadFactor,
|
||||
size_t* __restrict__ outBucketCount, size_t* __restrict__ outCapacity);
|
||||
|
||||
// Trim a hash code to 30 bits to match what we store in the bucket's cookie.
|
||||
inline static hash_t trimHash(hash_t hash) {
|
||||
return (hash & Bucket::HASH_MASK) ^ (hash >> 30);
|
||||
}
|
||||
|
||||
// Returns the index of the first bucket that is in the collision chain
|
||||
// for the specified hash code, given the total number of buckets.
|
||||
// (Primary hash)
|
||||
inline static size_t chainStart(hash_t hash, size_t count) {
|
||||
return hash % count;
|
||||
}
|
||||
|
||||
// Returns the increment to add to a bucket index to seek to the next bucket
|
||||
// in the collision chain for the specified hash code, given the total number of buckets.
|
||||
// (Secondary hash)
|
||||
inline static size_t chainIncrement(hash_t hash, size_t count) {
|
||||
return ((hash >> 7) | (hash << 25)) % (count - 1) + 1;
|
||||
}
|
||||
|
||||
// Returns the index of the next bucket that is in the collision chain
|
||||
// that is defined by the specified increment, given the total number of buckets.
|
||||
inline static size_t chainSeek(size_t index, size_t increment, size_t count) {
|
||||
return (index + increment) % count;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* A BasicHashtable stores entries that are indexed by hash code in place
|
||||
* within an array. The basic operations are finding entries by key,
|
||||
* adding new entries and removing existing entries.
|
||||
*
|
||||
* This class provides a very limited set of operations with simple semantics.
|
||||
* It is intended to be used as a building block to construct more complex
|
||||
* and interesting data structures such as HashMap. Think very hard before
|
||||
* adding anything extra to BasicHashtable, it probably belongs at a
|
||||
* higher level of abstraction.
|
||||
*
|
||||
* TKey: The key type.
|
||||
* TEntry: The entry type which is what is actually stored in the array.
|
||||
*
|
||||
* TKey must support the following contract:
|
||||
* bool operator==(const TKey& other) const; // return true if equal
|
||||
* bool operator!=(const TKey& other) const; // return true if unequal
|
||||
*
|
||||
* TEntry must support the following contract:
|
||||
* const TKey& getKey() const; // get the key from the entry
|
||||
*
|
||||
* This class supports storing entries with duplicate keys. Of course, it can't
|
||||
* tell them apart during removal so only the first entry will be removed.
|
||||
* We do this because it means that operations like add() can't fail.
|
||||
*/
|
||||
template <typename TKey, typename TEntry>
|
||||
class BasicHashtable : private BasicHashtableImpl {
|
||||
public:
|
||||
/* Creates a hashtable with the specified minimum initial capacity.
|
||||
* The underlying array will be created when the first entry is added.
|
||||
*
|
||||
* minimumInitialCapacity: The minimum initial capacity for the hashtable.
|
||||
* Default is 0.
|
||||
* loadFactor: The desired load factor for the hashtable, between 0 and 1.
|
||||
* Default is 0.75.
|
||||
*/
|
||||
BasicHashtable(size_t minimumInitialCapacity = 0, float loadFactor = 0.75f);
|
||||
|
||||
/* Copies a hashtable.
|
||||
* The underlying storage is shared copy-on-write.
|
||||
*/
|
||||
BasicHashtable(const BasicHashtable& other);
|
||||
|
||||
/* Clears and destroys the hashtable.
|
||||
*/
|
||||
virtual ~BasicHashtable();
|
||||
|
||||
/* Making this hashtable a copy of the other hashtable.
|
||||
* The underlying storage is shared copy-on-write.
|
||||
*
|
||||
* other: The hashtable to copy.
|
||||
*/
|
||||
inline BasicHashtable<TKey, TEntry>& operator =(const BasicHashtable<TKey, TEntry> & other) {
|
||||
setTo(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* Returns the number of entries in the hashtable.
|
||||
*/
|
||||
inline size_t size() const {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
/* Returns the capacity of the hashtable, which is the number of elements that can
|
||||
* added to the hashtable without requiring it to be grown.
|
||||
*/
|
||||
inline size_t capacity() const {
|
||||
return mCapacity;
|
||||
}
|
||||
|
||||
/* Returns the number of buckets that the hashtable has, which is the size of its
|
||||
* underlying array.
|
||||
*/
|
||||
inline size_t bucketCount() const {
|
||||
return mBucketCount;
|
||||
}
|
||||
|
||||
/* Returns the load factor of the hashtable. */
|
||||
inline float loadFactor() const {
|
||||
return mLoadFactor;
|
||||
};
|
||||
|
||||
/* Returns a const reference to the entry at the specified index.
|
||||
*
|
||||
* index: The index of the entry to retrieve. Must be a valid index within
|
||||
* the bounds of the hashtable.
|
||||
*/
|
||||
inline const TEntry& entryAt(size_t index) const {
|
||||
return entryFor(bucketAt(mBuckets, index));
|
||||
}
|
||||
|
||||
/* Returns a non-const reference to the entry at the specified index.
|
||||
*
|
||||
* index: The index of the entry to edit. Must be a valid index within
|
||||
* the bounds of the hashtable.
|
||||
*/
|
||||
inline TEntry& editEntryAt(size_t index) {
|
||||
edit();
|
||||
return entryFor(bucketAt(mBuckets, index));
|
||||
}
|
||||
|
||||
/* Clears the hashtable.
|
||||
* All entries in the hashtable are destroyed immediately.
|
||||
* If you need to do something special with the entries in the hashtable then iterate
|
||||
* over them and do what you need before clearing the hashtable.
|
||||
*/
|
||||
inline void clear() {
|
||||
BasicHashtableImpl::clear();
|
||||
}
|
||||
|
||||
/* Returns the index of the next entry in the hashtable given the index of a previous entry.
|
||||
* If the given index is -1, then returns the index of the first entry in the hashtable,
|
||||
* if there is one, or -1 otherwise.
|
||||
* If the given index is not -1, then returns the index of the next entry in the hashtable,
|
||||
* in strictly increasing order, or -1 if there are none left.
|
||||
*
|
||||
* index: The index of the previous entry that was iterated, or -1 to begin
|
||||
* iteration at the beginning of the hashtable.
|
||||
*/
|
||||
inline ssize_t next(ssize_t index) const {
|
||||
return BasicHashtableImpl::next(index);
|
||||
}
|
||||
|
||||
/* Finds the index of an entry with the specified key.
|
||||
* If the given index is -1, then returns the index of the first matching entry,
|
||||
* otherwise returns the index of the next matching entry.
|
||||
* If the hashtable contains multiple entries with keys that match the requested
|
||||
* key, then the sequence of entries returned is arbitrary.
|
||||
* Returns -1 if no entry was found.
|
||||
*
|
||||
* index: The index of the previous entry with the specified key, or -1 to
|
||||
* find the first matching entry.
|
||||
* hash: The hashcode of the key.
|
||||
* key: The key.
|
||||
*/
|
||||
inline ssize_t find(ssize_t index, hash_t hash, const TKey& key) const {
|
||||
return BasicHashtableImpl::find(index, hash, &key);
|
||||
}
|
||||
|
||||
/* Adds the entry to the hashtable.
|
||||
* Returns the index of the newly added entry.
|
||||
* If an entry with the same key already exists, then a duplicate entry is added.
|
||||
* If the entry will not fit, then the hashtable's capacity is increased and
|
||||
* its contents are rehashed. See rehash().
|
||||
*
|
||||
* hash: The hashcode of the key.
|
||||
* entry: The entry to add.
|
||||
*/
|
||||
inline size_t add(hash_t hash, const TEntry& entry) {
|
||||
return BasicHashtableImpl::add(hash, &entry);
|
||||
}
|
||||
|
||||
/* Removes the entry with the specified index from the hashtable.
|
||||
* The entry is destroyed immediately.
|
||||
* The index must be valid.
|
||||
*
|
||||
* The hashtable is not compacted after an item is removed, so it is legal
|
||||
* to continue iterating over the hashtable using next() or find().
|
||||
*
|
||||
* index: The index of the entry to remove. Must be a valid index within the
|
||||
* bounds of the hashtable, and it must refer to an existing entry.
|
||||
*/
|
||||
inline void removeAt(size_t index) {
|
||||
BasicHashtableImpl::removeAt(index);
|
||||
}
|
||||
|
||||
/* Rehashes the contents of the hashtable.
|
||||
* Grows the hashtable to at least the specified minimum capacity or the
|
||||
* current number of elements, whichever is larger.
|
||||
*
|
||||
* Rehashing causes all entries to be copied and the entry indices may change.
|
||||
* Although the hash codes are cached by the hashtable, rehashing can be an
|
||||
* expensive operation and should be avoided unless the hashtable's size
|
||||
* needs to be changed.
|
||||
*
|
||||
* Rehashing is the only way to change the capacity or load factor of the
|
||||
* hashtable once it has been created. It can be used to compact the
|
||||
* hashtable by choosing a minimum capacity that is smaller than the current
|
||||
* capacity (such as 0).
|
||||
*
|
||||
* minimumCapacity: The desired minimum capacity after rehashing.
|
||||
* loadFactor: The desired load factor after rehashing.
|
||||
*/
|
||||
inline void rehash(size_t minimumCapacity, float loadFactor) {
|
||||
BasicHashtableImpl::rehash(minimumCapacity, loadFactor);
|
||||
}
|
||||
|
||||
/* Determines whether there is room to add another entry without rehashing.
|
||||
* When this returns true, a subsequent add() operation is guaranteed to
|
||||
* complete without performing a rehash.
|
||||
*/
|
||||
inline bool hasMoreRoom() const {
|
||||
return mCapacity > mFilledBuckets;
|
||||
}
|
||||
|
||||
protected:
|
||||
static inline const TEntry& entryFor(const Bucket& bucket) {
|
||||
return reinterpret_cast<const TEntry&>(bucket.entry);
|
||||
}
|
||||
|
||||
static inline TEntry& entryFor(Bucket& bucket) {
|
||||
return reinterpret_cast<TEntry&>(bucket.entry);
|
||||
}
|
||||
|
||||
virtual bool compareBucketKey(const Bucket& bucket, const void* __restrict__ key) const;
|
||||
virtual void initializeBucketEntry(Bucket& bucket, const void* __restrict__ entry) const;
|
||||
virtual void destroyBucketEntry(Bucket& bucket) const;
|
||||
|
||||
private:
|
||||
// For dumping the raw contents of a hashtable during testing.
|
||||
friend class BasicHashtableTest;
|
||||
inline uint32_t cookieAt(size_t index) const {
|
||||
return bucketAt(mBuckets, index).cookie;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TKey, typename TEntry>
|
||||
BasicHashtable<TKey, TEntry>::BasicHashtable(size_t minimumInitialCapacity, float loadFactor) :
|
||||
BasicHashtableImpl(sizeof(TEntry), traits<TEntry>::has_trivial_dtor,
|
||||
minimumInitialCapacity, loadFactor) {
|
||||
}
|
||||
|
||||
template <typename TKey, typename TEntry>
|
||||
BasicHashtable<TKey, TEntry>::BasicHashtable(const BasicHashtable<TKey, TEntry>& other) :
|
||||
BasicHashtableImpl(other) {
|
||||
}
|
||||
|
||||
template <typename TKey, typename TEntry>
|
||||
BasicHashtable<TKey, TEntry>::~BasicHashtable() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
template <typename TKey, typename TEntry>
|
||||
bool BasicHashtable<TKey, TEntry>::compareBucketKey(const Bucket& bucket,
|
||||
const void* __restrict__ key) const {
|
||||
return entryFor(bucket).getKey() == *static_cast<const TKey*>(key);
|
||||
}
|
||||
|
||||
template <typename TKey, typename TEntry>
|
||||
void BasicHashtable<TKey, TEntry>::initializeBucketEntry(Bucket& bucket,
|
||||
const void* __restrict__ entry) const {
|
||||
if (!traits<TEntry>::has_trivial_copy) {
|
||||
new (&entryFor(bucket)) TEntry(*(static_cast<const TEntry*>(entry)));
|
||||
} else {
|
||||
memcpy(&entryFor(bucket), entry, sizeof(TEntry));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TKey, typename TEntry>
|
||||
void BasicHashtable<TKey, TEntry>::destroyBucketEntry(Bucket& bucket) const {
|
||||
if (!traits<TEntry>::has_trivial_dtor) {
|
||||
entryFor(bucket).~TEntry();
|
||||
}
|
||||
}
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#endif // ANDROID_BASIC_HASHTABLE_H
|
||||
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef UTILS_BITSET_H
|
||||
#define UTILS_BITSET_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <utils/TypeHelpers.h>
|
||||
|
||||
/*
|
||||
* Contains some bit manipulation helpers.
|
||||
*/
|
||||
|
||||
namespace android {
|
||||
|
||||
// A simple set of 32 bits that can be individually marked or cleared.
|
||||
struct BitSet32 {
|
||||
uint32_t value;
|
||||
|
||||
inline BitSet32() : value(0UL) { }
|
||||
explicit inline BitSet32(uint32_t value) : value(value) { }
|
||||
|
||||
// Gets the value associated with a particular bit index.
|
||||
static inline uint32_t valueForBit(uint32_t n) { return 0x80000000UL >> n; }
|
||||
|
||||
// Clears the bit set.
|
||||
inline void clear() { clear(value); }
|
||||
|
||||
static inline void clear(uint32_t& value) { value = 0UL; }
|
||||
|
||||
// Returns the number of marked bits in the set.
|
||||
inline uint32_t count() const { return count(value); }
|
||||
|
||||
static inline uint32_t count(uint32_t value) { return __builtin_popcountl(value); }
|
||||
|
||||
// Returns true if the bit set does not contain any marked bits.
|
||||
inline bool isEmpty() const { return isEmpty(value); }
|
||||
|
||||
static inline bool isEmpty(uint32_t value) { return ! value; }
|
||||
|
||||
// Returns true if the bit set does not contain any unmarked bits.
|
||||
inline bool isFull() const { return isFull(value); }
|
||||
|
||||
static inline bool isFull(uint32_t value) { return value == 0xffffffffUL; }
|
||||
|
||||
// Returns true if the specified bit is marked.
|
||||
inline bool hasBit(uint32_t n) const { return hasBit(value, n); }
|
||||
|
||||
static inline bool hasBit(uint32_t value, uint32_t n) { return value & valueForBit(n); }
|
||||
|
||||
// Marks the specified bit.
|
||||
inline void markBit(uint32_t n) { markBit(value, n); }
|
||||
|
||||
static inline void markBit (uint32_t& value, uint32_t n) { value |= valueForBit(n); }
|
||||
|
||||
// Clears the specified bit.
|
||||
inline void clearBit(uint32_t n) { clearBit(value, n); }
|
||||
|
||||
static inline void clearBit(uint32_t& value, uint32_t n) { value &= ~ valueForBit(n); }
|
||||
|
||||
// Finds the first marked bit in the set.
|
||||
// Result is undefined if all bits are unmarked.
|
||||
inline uint32_t firstMarkedBit() const { return firstMarkedBit(value); }
|
||||
|
||||
static uint32_t firstMarkedBit(uint32_t value) { return clz_checked(value); }
|
||||
|
||||
// Finds the first unmarked bit in the set.
|
||||
// Result is undefined if all bits are marked.
|
||||
inline uint32_t firstUnmarkedBit() const { return firstUnmarkedBit(value); }
|
||||
|
||||
static inline uint32_t firstUnmarkedBit(uint32_t value) { return clz_checked(~ value); }
|
||||
|
||||
// Finds the last marked bit in the set.
|
||||
// Result is undefined if all bits are unmarked.
|
||||
inline uint32_t lastMarkedBit() const { return lastMarkedBit(value); }
|
||||
|
||||
static inline uint32_t lastMarkedBit(uint32_t value) { return 31 - ctz_checked(value); }
|
||||
|
||||
// Finds the first marked bit in the set and clears it. Returns the bit index.
|
||||
// Result is undefined if all bits are unmarked.
|
||||
inline uint32_t clearFirstMarkedBit() { return clearFirstMarkedBit(value); }
|
||||
|
||||
static inline uint32_t clearFirstMarkedBit(uint32_t& value) {
|
||||
uint32_t n = firstMarkedBit(value);
|
||||
clearBit(value, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
// Finds the first unmarked bit in the set and marks it. Returns the bit index.
|
||||
// Result is undefined if all bits are marked.
|
||||
inline uint32_t markFirstUnmarkedBit() { return markFirstUnmarkedBit(value); }
|
||||
|
||||
static inline uint32_t markFirstUnmarkedBit(uint32_t& value) {
|
||||
uint32_t n = firstUnmarkedBit(value);
|
||||
markBit(value, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
// Finds the last marked bit in the set and clears it. Returns the bit index.
|
||||
// Result is undefined if all bits are unmarked.
|
||||
inline uint32_t clearLastMarkedBit() { return clearLastMarkedBit(value); }
|
||||
|
||||
static inline uint32_t clearLastMarkedBit(uint32_t& value) {
|
||||
uint32_t n = lastMarkedBit(value);
|
||||
clearBit(value, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
// Gets the index of the specified bit in the set, which is the number of
|
||||
// marked bits that appear before the specified bit.
|
||||
inline uint32_t getIndexOfBit(uint32_t n) const {
|
||||
return getIndexOfBit(value, n);
|
||||
}
|
||||
|
||||
static inline uint32_t getIndexOfBit(uint32_t value, uint32_t n) {
|
||||
return __builtin_popcountl(value & ~(0xffffffffUL >> n));
|
||||
}
|
||||
|
||||
inline bool operator== (const BitSet32& other) const { return value == other.value; }
|
||||
inline bool operator!= (const BitSet32& other) const { return value != other.value; }
|
||||
inline BitSet32 operator& (const BitSet32& other) const {
|
||||
return BitSet32(value & other.value);
|
||||
}
|
||||
inline BitSet32& operator&= (const BitSet32& other) {
|
||||
value &= other.value;
|
||||
return *this;
|
||||
}
|
||||
inline BitSet32 operator| (const BitSet32& other) const {
|
||||
return BitSet32(value | other.value);
|
||||
}
|
||||
inline BitSet32& operator|= (const BitSet32& other) {
|
||||
value |= other.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
// We use these helpers as the signature of __builtin_c{l,t}z has "unsigned int" for the
|
||||
// input, which is only guaranteed to be 16b, not 32. The compiler should optimize this away.
|
||||
static inline uint32_t clz_checked(uint32_t value) {
|
||||
if (sizeof(unsigned int) == sizeof(uint32_t)) {
|
||||
return __builtin_clz(value);
|
||||
} else {
|
||||
return __builtin_clzl(value);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t ctz_checked(uint32_t value) {
|
||||
if (sizeof(unsigned int) == sizeof(uint32_t)) {
|
||||
return __builtin_ctz(value);
|
||||
} else {
|
||||
return __builtin_ctzl(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ANDROID_BASIC_TYPES_TRAITS(BitSet32)
|
||||
|
||||
// A simple set of 64 bits that can be individually marked or cleared.
|
||||
struct BitSet64 {
|
||||
uint64_t value;
|
||||
|
||||
inline BitSet64() : value(0ULL) { }
|
||||
explicit inline BitSet64(uint64_t value) : value(value) { }
|
||||
|
||||
// Gets the value associated with a particular bit index.
|
||||
static inline uint64_t valueForBit(uint32_t n) { return 0x8000000000000000ULL >> n; }
|
||||
|
||||
// Clears the bit set.
|
||||
inline void clear() { clear(value); }
|
||||
|
||||
static inline void clear(uint64_t& value) { value = 0ULL; }
|
||||
|
||||
// Returns the number of marked bits in the set.
|
||||
inline uint32_t count() const { return count(value); }
|
||||
|
||||
static inline uint32_t count(uint64_t value) { return __builtin_popcountll(value); }
|
||||
|
||||
// Returns true if the bit set does not contain any marked bits.
|
||||
inline bool isEmpty() const { return isEmpty(value); }
|
||||
|
||||
static inline bool isEmpty(uint64_t value) { return ! value; }
|
||||
|
||||
// Returns true if the bit set does not contain any unmarked bits.
|
||||
inline bool isFull() const { return isFull(value); }
|
||||
|
||||
static inline bool isFull(uint64_t value) { return value == 0xffffffffffffffffULL; }
|
||||
|
||||
// Returns true if the specified bit is marked.
|
||||
inline bool hasBit(uint32_t n) const { return hasBit(value, n); }
|
||||
|
||||
static inline bool hasBit(uint64_t value, uint32_t n) { return value & valueForBit(n); }
|
||||
|
||||
// Marks the specified bit.
|
||||
inline void markBit(uint32_t n) { markBit(value, n); }
|
||||
|
||||
static inline void markBit(uint64_t& value, uint32_t n) { value |= valueForBit(n); }
|
||||
|
||||
// Clears the specified bit.
|
||||
inline void clearBit(uint32_t n) { clearBit(value, n); }
|
||||
|
||||
static inline void clearBit(uint64_t& value, uint32_t n) { value &= ~ valueForBit(n); }
|
||||
|
||||
// Finds the first marked bit in the set.
|
||||
// Result is undefined if all bits are unmarked.
|
||||
inline uint32_t firstMarkedBit() const { return firstMarkedBit(value); }
|
||||
|
||||
static inline uint32_t firstMarkedBit(uint64_t value) { return __builtin_clzll(value); }
|
||||
|
||||
// Finds the first unmarked bit in the set.
|
||||
// Result is undefined if all bits are marked.
|
||||
inline uint32_t firstUnmarkedBit() const { return firstUnmarkedBit(value); }
|
||||
|
||||
static inline uint32_t firstUnmarkedBit(uint64_t value) { return __builtin_clzll(~ value); }
|
||||
|
||||
// Finds the last marked bit in the set.
|
||||
// Result is undefined if all bits are unmarked.
|
||||
inline uint32_t lastMarkedBit() const { return lastMarkedBit(value); }
|
||||
|
||||
static inline uint32_t lastMarkedBit(uint64_t value) { return 63 - __builtin_ctzll(value); }
|
||||
|
||||
// Finds the first marked bit in the set and clears it. Returns the bit index.
|
||||
// Result is undefined if all bits are unmarked.
|
||||
inline uint32_t clearFirstMarkedBit() { return clearFirstMarkedBit(value); }
|
||||
|
||||
static inline uint32_t clearFirstMarkedBit(uint64_t& value) {
|
||||
uint64_t n = firstMarkedBit(value);
|
||||
clearBit(value, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
// Finds the first unmarked bit in the set and marks it. Returns the bit index.
|
||||
// Result is undefined if all bits are marked.
|
||||
inline uint32_t markFirstUnmarkedBit() { return markFirstUnmarkedBit(value); }
|
||||
|
||||
static inline uint32_t markFirstUnmarkedBit(uint64_t& value) {
|
||||
uint64_t n = firstUnmarkedBit(value);
|
||||
markBit(value, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
// Finds the last marked bit in the set and clears it. Returns the bit index.
|
||||
// Result is undefined if all bits are unmarked.
|
||||
inline uint32_t clearLastMarkedBit() { return clearLastMarkedBit(value); }
|
||||
|
||||
static inline uint32_t clearLastMarkedBit(uint64_t& value) {
|
||||
uint64_t n = lastMarkedBit(value);
|
||||
clearBit(value, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
// Gets the index of the specified bit in the set, which is the number of
|
||||
// marked bits that appear before the specified bit.
|
||||
inline uint32_t getIndexOfBit(uint32_t n) const { return getIndexOfBit(value, n); }
|
||||
|
||||
static inline uint32_t getIndexOfBit(uint64_t value, uint32_t n) {
|
||||
return __builtin_popcountll(value & ~(0xffffffffffffffffULL >> n));
|
||||
}
|
||||
|
||||
inline bool operator== (const BitSet64& other) const { return value == other.value; }
|
||||
inline bool operator!= (const BitSet64& other) const { return value != other.value; }
|
||||
inline BitSet64 operator& (const BitSet64& other) const {
|
||||
return BitSet64(value & other.value);
|
||||
}
|
||||
inline BitSet64& operator&= (const BitSet64& other) {
|
||||
value &= other.value;
|
||||
return *this;
|
||||
}
|
||||
inline BitSet64 operator| (const BitSet64& other) const {
|
||||
return BitSet64(value | other.value);
|
||||
}
|
||||
inline BitSet64& operator|= (const BitSet64& other) {
|
||||
value |= other.value;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
ANDROID_BASIC_TYPES_TRAITS(BitSet64)
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // UTILS_BITSET_H
|
||||
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
** Copyright 2011, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_BLOB_CACHE_H
|
||||
#define ANDROID_BLOB_CACHE_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <utils/Flattenable.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/SortedVector.h>
|
||||
#include <utils/threads.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
// A BlobCache is an in-memory cache for binary key/value pairs. A BlobCache
|
||||
// does NOT provide any thread-safety guarantees.
|
||||
//
|
||||
// The cache contents can be serialized to an in-memory buffer or mmap'd file
|
||||
// and then reloaded in a subsequent execution of the program. This
|
||||
// serialization is non-portable and the data should only be used by the device
|
||||
// that generated it.
|
||||
class BlobCache : public RefBase {
|
||||
|
||||
public:
|
||||
|
||||
// Create an empty blob cache. The blob cache will cache key/value pairs
|
||||
// with key and value sizes less than or equal to maxKeySize and
|
||||
// maxValueSize, respectively. The total combined size of ALL cache entries
|
||||
// (key sizes plus value sizes) will not exceed maxTotalSize.
|
||||
BlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxTotalSize);
|
||||
|
||||
// set inserts a new binary value into the cache and associates it with the
|
||||
// given binary key. If the key or value are too large for the cache then
|
||||
// the cache remains unchanged. This includes the case where a different
|
||||
// value was previously associated with the given key - the old value will
|
||||
// remain in the cache. If the given key and value are small enough to be
|
||||
// put in the cache (based on the maxKeySize, maxValueSize, and maxTotalSize
|
||||
// values specified to the BlobCache constructor), then the key/value pair
|
||||
// will be in the cache after set returns. Note, however, that a subsequent
|
||||
// call to set may evict old key/value pairs from the cache.
|
||||
//
|
||||
// Preconditions:
|
||||
// key != NULL
|
||||
// 0 < keySize
|
||||
// value != NULL
|
||||
// 0 < valueSize
|
||||
void set(const void* key, size_t keySize, const void* value,
|
||||
size_t valueSize);
|
||||
|
||||
// get retrieves from the cache the binary value associated with a given
|
||||
// binary key. If the key is present in the cache then the length of the
|
||||
// binary value associated with that key is returned. If the value argument
|
||||
// is non-NULL and the size of the cached value is less than valueSize bytes
|
||||
// then the cached value is copied into the buffer pointed to by the value
|
||||
// argument. If the key is not present in the cache then 0 is returned and
|
||||
// the buffer pointed to by the value argument is not modified.
|
||||
//
|
||||
// Note that when calling get multiple times with the same key, the later
|
||||
// calls may fail, returning 0, even if earlier calls succeeded. The return
|
||||
// value must be checked for each call.
|
||||
//
|
||||
// Preconditions:
|
||||
// key != NULL
|
||||
// 0 < keySize
|
||||
// 0 <= valueSize
|
||||
size_t get(const void* key, size_t keySize, void* value, size_t valueSize);
|
||||
|
||||
|
||||
// getFlattenedSize returns the number of bytes needed to store the entire
|
||||
// serialized cache.
|
||||
size_t getFlattenedSize() const;
|
||||
|
||||
// flatten serializes the current contents of the cache into the memory
|
||||
// pointed to by 'buffer'. The serialized cache contents can later be
|
||||
// loaded into a BlobCache object using the unflatten method. The contents
|
||||
// of the BlobCache object will not be modified.
|
||||
//
|
||||
// Preconditions:
|
||||
// size >= this.getFlattenedSize()
|
||||
status_t flatten(void* buffer, size_t size) const;
|
||||
|
||||
// unflatten replaces the contents of the cache with the serialized cache
|
||||
// contents in the memory pointed to by 'buffer'. The previous contents of
|
||||
// the BlobCache will be evicted from the cache. If an error occurs while
|
||||
// unflattening the serialized cache contents then the BlobCache will be
|
||||
// left in an empty state.
|
||||
//
|
||||
status_t unflatten(void const* buffer, size_t size);
|
||||
|
||||
private:
|
||||
// Copying is disallowed.
|
||||
BlobCache(const BlobCache&);
|
||||
void operator=(const BlobCache&);
|
||||
|
||||
// A random function helper to get around MinGW not having nrand48()
|
||||
long int blob_random();
|
||||
|
||||
// clean evicts a randomly chosen set of entries from the cache such that
|
||||
// the total size of all remaining entries is less than mMaxTotalSize/2.
|
||||
void clean();
|
||||
|
||||
// isCleanable returns true if the cache is full enough for the clean method
|
||||
// to have some effect, and false otherwise.
|
||||
bool isCleanable() const;
|
||||
|
||||
// A Blob is an immutable sized unstructured data blob.
|
||||
class Blob : public RefBase {
|
||||
public:
|
||||
Blob(const void* data, size_t size, bool copyData);
|
||||
~Blob();
|
||||
|
||||
bool operator<(const Blob& rhs) const;
|
||||
|
||||
const void* getData() const;
|
||||
size_t getSize() const;
|
||||
|
||||
private:
|
||||
// Copying is not allowed.
|
||||
Blob(const Blob&);
|
||||
void operator=(const Blob&);
|
||||
|
||||
// mData points to the buffer containing the blob data.
|
||||
const void* mData;
|
||||
|
||||
// mSize is the size of the blob data in bytes.
|
||||
size_t mSize;
|
||||
|
||||
// mOwnsData indicates whether or not this Blob object should free the
|
||||
// memory pointed to by mData when the Blob gets destructed.
|
||||
bool mOwnsData;
|
||||
};
|
||||
|
||||
// A CacheEntry is a single key/value pair in the cache.
|
||||
class CacheEntry {
|
||||
public:
|
||||
CacheEntry();
|
||||
CacheEntry(const sp<Blob>& key, const sp<Blob>& value);
|
||||
CacheEntry(const CacheEntry& ce);
|
||||
|
||||
bool operator<(const CacheEntry& rhs) const;
|
||||
const CacheEntry& operator=(const CacheEntry&);
|
||||
|
||||
sp<Blob> getKey() const;
|
||||
sp<Blob> getValue() const;
|
||||
|
||||
void setValue(const sp<Blob>& value);
|
||||
|
||||
private:
|
||||
|
||||
// mKey is the key that identifies the cache entry.
|
||||
sp<Blob> mKey;
|
||||
|
||||
// mValue is the cached data associated with the key.
|
||||
sp<Blob> mValue;
|
||||
};
|
||||
|
||||
// A Header is the header for the entire BlobCache serialization format. No
|
||||
// need to make this portable, so we simply write the struct out.
|
||||
struct Header {
|
||||
// mMagicNumber is the magic number that identifies the data as
|
||||
// serialized BlobCache contents. It must always contain 'Blb$'.
|
||||
uint32_t mMagicNumber;
|
||||
|
||||
// mBlobCacheVersion is the serialization format version.
|
||||
uint32_t mBlobCacheVersion;
|
||||
|
||||
// mDeviceVersion is the device-specific version of the cache. This can
|
||||
// be used to invalidate the cache.
|
||||
uint32_t mDeviceVersion;
|
||||
|
||||
// mNumEntries is number of cache entries following the header in the
|
||||
// data.
|
||||
size_t mNumEntries;
|
||||
|
||||
// mBuildId is the build id of the device when the cache was created.
|
||||
// When an update to the build happens (via an OTA or other update) this
|
||||
// is used to invalidate the cache.
|
||||
int mBuildIdLength;
|
||||
char mBuildId[];
|
||||
};
|
||||
|
||||
// An EntryHeader is the header for a serialized cache entry. No need to
|
||||
// make this portable, so we simply write the struct out. Each EntryHeader
|
||||
// is followed imediately by the key data and then the value data.
|
||||
//
|
||||
// The beginning of each serialized EntryHeader is 4-byte aligned, so the
|
||||
// number of bytes that a serialized cache entry will occupy is:
|
||||
//
|
||||
// ((sizeof(EntryHeader) + keySize + valueSize) + 3) & ~3
|
||||
//
|
||||
struct EntryHeader {
|
||||
// mKeySize is the size of the entry key in bytes.
|
||||
size_t mKeySize;
|
||||
|
||||
// mValueSize is the size of the entry value in bytes.
|
||||
size_t mValueSize;
|
||||
|
||||
// mData contains both the key and value data for the cache entry. The
|
||||
// key comes first followed immediately by the value.
|
||||
uint8_t mData[];
|
||||
};
|
||||
|
||||
// mMaxKeySize is the maximum key size that will be cached. Calls to
|
||||
// BlobCache::set with a keySize parameter larger than mMaxKeySize will
|
||||
// simply not add the key/value pair to the cache.
|
||||
const size_t mMaxKeySize;
|
||||
|
||||
// mMaxValueSize is the maximum value size that will be cached. Calls to
|
||||
// BlobCache::set with a valueSize parameter larger than mMaxValueSize will
|
||||
// simply not add the key/value pair to the cache.
|
||||
const size_t mMaxValueSize;
|
||||
|
||||
// mMaxTotalSize is the maximum size that all cache entries can occupy. This
|
||||
// includes space for both keys and values. When a call to BlobCache::set
|
||||
// would otherwise cause this limit to be exceeded, either the key/value
|
||||
// pair passed to BlobCache::set will not be cached or other cache entries
|
||||
// will be evicted from the cache to make room for the new entry.
|
||||
const size_t mMaxTotalSize;
|
||||
|
||||
// mTotalSize is the total combined size of all keys and values currently in
|
||||
// the cache.
|
||||
size_t mTotalSize;
|
||||
|
||||
// mRandState is the pseudo-random number generator state. It is passed to
|
||||
// nrand48 to generate random numbers when needed.
|
||||
unsigned short mRandState[3];
|
||||
|
||||
// mCacheEntries stores all the cache entries that are resident in memory.
|
||||
// Cache entries are added to it by the 'set' method.
|
||||
SortedVector<CacheEntry> mCacheEntries;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // ANDROID_BLOB_CACHE_H
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//
|
||||
|
||||
#ifndef _LIBS_UTILS_BYTE_ORDER_H
|
||||
#define _LIBS_UTILS_BYTE_ORDER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_WINSOCK
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These macros are like the hton/ntoh byte swapping macros,
|
||||
* except they allow you to swap to and from the "device" byte
|
||||
* order. The device byte order is the endianness of the target
|
||||
* device -- for the ARM CPUs we use today, this is little endian.
|
||||
*
|
||||
* Note that the byte swapping functions have not been optimized
|
||||
* much; performance is currently not an issue for them since the
|
||||
* intent is to allow us to avoid byte swapping on the device.
|
||||
*/
|
||||
|
||||
static inline uint32_t android_swap_long(uint32_t v)
|
||||
{
|
||||
return (v<<24) | ((v<<8)&0x00FF0000) | ((v>>8)&0x0000FF00) | (v>>24);
|
||||
}
|
||||
|
||||
static inline uint16_t android_swap_short(uint16_t v)
|
||||
{
|
||||
return (v<<8) | (v>>8);
|
||||
}
|
||||
|
||||
#define DEVICE_BYTE_ORDER LITTLE_ENDIAN
|
||||
|
||||
#if BYTE_ORDER == DEVICE_BYTE_ORDER
|
||||
|
||||
#define dtohl(x) (x)
|
||||
#define dtohs(x) (x)
|
||||
#define htodl(x) (x)
|
||||
#define htods(x) (x)
|
||||
|
||||
#else
|
||||
|
||||
#define dtohl(x) (android_swap_long(x))
|
||||
#define dtohs(x) (android_swap_short(x))
|
||||
#define htodl(x) (android_swap_long(x))
|
||||
#define htods(x) (android_swap_short(x))
|
||||
|
||||
#endif
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#define fromlel(x) (x)
|
||||
#define fromles(x) (x)
|
||||
#define tolel(x) (x)
|
||||
#define toles(x) (x)
|
||||
#else
|
||||
#define fromlel(x) (android_swap_long(x))
|
||||
#define fromles(x) (android_swap_short(x))
|
||||
#define tolel(x) (android_swap_long(x))
|
||||
#define toles(x) (android_swap_short(x))
|
||||
#endif
|
||||
|
||||
#endif // _LIBS_UTILS_BYTE_ORDER_H
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_CALLSTACK_H
|
||||
#define ANDROID_CALLSTACK_H
|
||||
|
||||
#include <android/log.h>
|
||||
#include <backtrace/backtrace_constants.h>
|
||||
#include <utils/String8.h>
|
||||
#include <utils/Vector.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
class Printer;
|
||||
|
||||
// Collect/print the call stack (function, file, line) traces for a single thread.
|
||||
class CallStack {
|
||||
public:
|
||||
// Create an empty call stack. No-op.
|
||||
CallStack();
|
||||
// Create a callstack with the current thread's stack trace.
|
||||
// Immediately dump it to logcat using the given logtag.
|
||||
CallStack(const char* logtag, int32_t ignoreDepth=1);
|
||||
~CallStack();
|
||||
|
||||
// Reset the stack frames (same as creating an empty call stack).
|
||||
void clear() { mFrameLines.clear(); }
|
||||
|
||||
// Immediately collect the stack traces for the specified thread.
|
||||
// The default is to dump the stack of the current call.
|
||||
void update(int32_t ignoreDepth=1, pid_t tid=BACKTRACE_CURRENT_THREAD);
|
||||
|
||||
// Dump a stack trace to the log using the supplied logtag.
|
||||
void log(const char* logtag,
|
||||
android_LogPriority priority = ANDROID_LOG_DEBUG,
|
||||
const char* prefix = 0) const;
|
||||
|
||||
// Dump a stack trace to the specified file descriptor.
|
||||
void dump(int fd, int indent = 0, const char* prefix = 0) const;
|
||||
|
||||
// Return a string (possibly very long) containing the complete stack trace.
|
||||
String8 toString(const char* prefix = 0) const;
|
||||
|
||||
// Dump a serialized representation of the stack trace to the specified printer.
|
||||
void print(Printer& printer) const;
|
||||
|
||||
// Get the count of stack frames that are in this call stack.
|
||||
size_t size() const { return mFrameLines.size(); }
|
||||
|
||||
private:
|
||||
Vector<String8> mFrameLines;
|
||||
};
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#endif // ANDROID_CALLSTACK_H
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __LIB_UTILS_COMPAT_H
|
||||
#define __LIB_UTILS_COMPAT_H
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
||||
/* Mac OS has always had a 64-bit off_t, so it doesn't have off64_t. */
|
||||
|
||||
typedef off_t off64_t;
|
||||
|
||||
static inline off64_t lseek64(int fd, off64_t offset, int whence) {
|
||||
return lseek(fd, offset, whence);
|
||||
}
|
||||
|
||||
static inline ssize_t pread64(int fd, void* buf, size_t nbytes, off64_t offset) {
|
||||
return pread(fd, buf, nbytes, offset);
|
||||
}
|
||||
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define O_CLOEXEC O_NOINHERIT
|
||||
#define O_NOFOLLOW 0
|
||||
#define DEFFILEMODE 0666
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define ZD "%ld"
|
||||
#define ZD_TYPE long
|
||||
#else
|
||||
#define ZD "%zd"
|
||||
#define ZD_TYPE ssize_t
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Needed for cases where something should be constexpr if possible, but not
|
||||
* being constexpr is fine if in pre-C++11 code (such as a const static float
|
||||
* member variable).
|
||||
*/
|
||||
#if __cplusplus >= 201103L
|
||||
#define CONSTEXPR constexpr
|
||||
#else
|
||||
#define CONSTEXPR
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TEMP_FAILURE_RETRY is defined by some, but not all, versions of
|
||||
* <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
|
||||
* not already defined, then define it here.
|
||||
*/
|
||||
#ifndef TEMP_FAILURE_RETRY
|
||||
/* Used to retry syscalls that can return EINTR. */
|
||||
#define TEMP_FAILURE_RETRY(exp) ({ \
|
||||
typeof (exp) _rc; \
|
||||
do { \
|
||||
_rc = (exp); \
|
||||
} while (_rc == -1 && errno == EINTR); \
|
||||
_rc; })
|
||||
#endif
|
||||
|
||||
#endif /* __LIB_UTILS_COMPAT_H */
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _LIBS_UTILS_CONDITION_H
|
||||
#define _LIBS_UTILS_CONDITION_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/Mutex.h>
|
||||
#include <utils/Timers.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
namespace android {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Condition variable class. The implementation is system-dependent.
|
||||
*
|
||||
* Condition variables are paired up with mutexes. Lock the mutex,
|
||||
* call wait(), then either re-wait() if things aren't quite what you want,
|
||||
* or unlock the mutex and continue. All threads calling wait() must
|
||||
* use the same mutex for a given Condition.
|
||||
*/
|
||||
class Condition {
|
||||
public:
|
||||
enum {
|
||||
PRIVATE = 0,
|
||||
SHARED = 1
|
||||
};
|
||||
|
||||
enum WakeUpType {
|
||||
WAKE_UP_ONE = 0,
|
||||
WAKE_UP_ALL = 1
|
||||
};
|
||||
|
||||
Condition();
|
||||
Condition(int type);
|
||||
~Condition();
|
||||
// Wait on the condition variable. Lock the mutex before calling.
|
||||
status_t wait(Mutex& mutex);
|
||||
// same with relative timeout
|
||||
status_t waitRelative(Mutex& mutex, nsecs_t reltime);
|
||||
// Signal the condition variable, allowing exactly one thread to continue.
|
||||
void signal();
|
||||
// Signal the condition variable, allowing one or all threads to continue.
|
||||
void signal(WakeUpType type) {
|
||||
if (type == WAKE_UP_ONE) {
|
||||
signal();
|
||||
} else {
|
||||
broadcast();
|
||||
}
|
||||
}
|
||||
// Signal the condition variable, allowing all threads to continue.
|
||||
void broadcast();
|
||||
|
||||
private:
|
||||
#if !defined(_WIN32)
|
||||
pthread_cond_t mCond;
|
||||
#else
|
||||
void* mState;
|
||||
#endif
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#if !defined(_WIN32)
|
||||
|
||||
inline Condition::Condition() {
|
||||
pthread_cond_init(&mCond, NULL);
|
||||
}
|
||||
inline Condition::Condition(int type) {
|
||||
if (type == SHARED) {
|
||||
pthread_condattr_t attr;
|
||||
pthread_condattr_init(&attr);
|
||||
pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
|
||||
pthread_cond_init(&mCond, &attr);
|
||||
pthread_condattr_destroy(&attr);
|
||||
} else {
|
||||
pthread_cond_init(&mCond, NULL);
|
||||
}
|
||||
}
|
||||
inline Condition::~Condition() {
|
||||
pthread_cond_destroy(&mCond);
|
||||
}
|
||||
inline status_t Condition::wait(Mutex& mutex) {
|
||||
return -pthread_cond_wait(&mCond, &mutex.mMutex);
|
||||
}
|
||||
inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) {
|
||||
#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
|
||||
struct timespec ts;
|
||||
ts.tv_sec = reltime/1000000000;
|
||||
ts.tv_nsec = reltime%1000000000;
|
||||
return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts);
|
||||
#else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
|
||||
struct timespec ts;
|
||||
#if defined(__linux__)
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
#else // __APPLE__
|
||||
// we don't support the clocks here.
|
||||
struct timeval t;
|
||||
gettimeofday(&t, NULL);
|
||||
ts.tv_sec = t.tv_sec;
|
||||
ts.tv_nsec= t.tv_usec*1000;
|
||||
#endif
|
||||
ts.tv_sec += reltime/1000000000;
|
||||
ts.tv_nsec+= reltime%1000000000;
|
||||
if (ts.tv_nsec >= 1000000000) {
|
||||
ts.tv_nsec -= 1000000000;
|
||||
ts.tv_sec += 1;
|
||||
}
|
||||
return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts);
|
||||
#endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
|
||||
}
|
||||
inline void Condition::signal() {
|
||||
/*
|
||||
* POSIX says pthread_cond_signal wakes up "one or more" waiting threads.
|
||||
* However bionic follows the glibc guarantee which wakes up "exactly one"
|
||||
* waiting thread.
|
||||
*
|
||||
* man 3 pthread_cond_signal
|
||||
* pthread_cond_signal restarts one of the threads that are waiting on
|
||||
* the condition variable cond. If no threads are waiting on cond,
|
||||
* nothing happens. If several threads are waiting on cond, exactly one
|
||||
* is restarted, but it is not specified which.
|
||||
*/
|
||||
pthread_cond_signal(&mCond);
|
||||
}
|
||||
inline void Condition::broadcast() {
|
||||
pthread_cond_broadcast(&mCond);
|
||||
}
|
||||
|
||||
#endif // !defined(_WIN32)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
}; // namespace android
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // _LIBS_UTILS_CONDITON_H
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_UTILS_DEBUG_H
|
||||
#define ANDROID_UTILS_DEBUG_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace android {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#ifdef __cplusplus
|
||||
template<bool> struct CompileTimeAssert;
|
||||
template<> struct CompileTimeAssert<true> {};
|
||||
#define COMPILE_TIME_ASSERT(_exp) \
|
||||
template class CompileTimeAssert< (_exp) >;
|
||||
#endif
|
||||
#define COMPILE_TIME_ASSERT_FUNCTION_SCOPE(_exp) \
|
||||
CompileTimeAssert<( _exp )>();
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#ifdef __cplusplus
|
||||
template<bool C, typename LSH, typename RHS> struct CompileTimeIfElse;
|
||||
template<typename LHS, typename RHS>
|
||||
struct CompileTimeIfElse<true, LHS, RHS> { typedef LHS TYPE; };
|
||||
template<typename LHS, typename RHS>
|
||||
struct CompileTimeIfElse<false, LHS, RHS> { typedef RHS TYPE; };
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
}; // namespace android
|
||||
|
||||
#endif // ANDROID_UTILS_DEBUG_H
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//
|
||||
// Android endian-ness defines.
|
||||
//
|
||||
#ifndef _LIBS_UTILS_ENDIAN_H
|
||||
#define _LIBS_UTILS_ENDIAN_H
|
||||
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
|
||||
#define __BIG_ENDIAN 0x1000
|
||||
#define __LITTLE_ENDIAN 0x0001
|
||||
#define __BYTE_ORDER __LITTLE_ENDIAN
|
||||
|
||||
#else
|
||||
|
||||
#include <endian.h>
|
||||
|
||||
#endif
|
||||
|
||||
#endif /*_LIBS_UTILS_ENDIAN_H*/
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_ERRORS_H
|
||||
#define ANDROID_ERRORS_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
// use this type to return error codes
|
||||
#ifdef HAVE_MS_C_RUNTIME
|
||||
typedef int status_t;
|
||||
#else
|
||||
typedef int32_t status_t;
|
||||
#endif
|
||||
|
||||
/* the MS C runtime lacks a few error codes */
|
||||
|
||||
/*
|
||||
* Error codes.
|
||||
* All error codes are negative values.
|
||||
*/
|
||||
|
||||
// Win32 #defines NO_ERROR as well. It has the same value, so there's no
|
||||
// real conflict, though it's a bit awkward.
|
||||
#ifdef _WIN32
|
||||
# undef NO_ERROR
|
||||
#endif
|
||||
|
||||
enum {
|
||||
OK = 0, // Everything's swell.
|
||||
NO_ERROR = 0, // No errors.
|
||||
|
||||
UNKNOWN_ERROR = (-2147483647-1), // INT32_MIN value
|
||||
|
||||
NO_MEMORY = -ENOMEM,
|
||||
INVALID_OPERATION = -ENOSYS,
|
||||
BAD_VALUE = -EINVAL,
|
||||
BAD_TYPE = (UNKNOWN_ERROR + 1),
|
||||
NAME_NOT_FOUND = -ENOENT,
|
||||
PERMISSION_DENIED = -EPERM,
|
||||
NO_INIT = -ENODEV,
|
||||
ALREADY_EXISTS = -EEXIST,
|
||||
DEAD_OBJECT = -EPIPE,
|
||||
FAILED_TRANSACTION = (UNKNOWN_ERROR + 2),
|
||||
JPARKS_BROKE_IT = -EPIPE,
|
||||
#if !defined(HAVE_MS_C_RUNTIME)
|
||||
BAD_INDEX = -EOVERFLOW,
|
||||
NOT_ENOUGH_DATA = -ENODATA,
|
||||
WOULD_BLOCK = -EWOULDBLOCK,
|
||||
TIMED_OUT = -ETIMEDOUT,
|
||||
UNKNOWN_TRANSACTION = -EBADMSG,
|
||||
#else
|
||||
BAD_INDEX = -E2BIG,
|
||||
NOT_ENOUGH_DATA = (UNKNOWN_ERROR + 3),
|
||||
WOULD_BLOCK = (UNKNOWN_ERROR + 4),
|
||||
TIMED_OUT = (UNKNOWN_ERROR + 5),
|
||||
UNKNOWN_TRANSACTION = (UNKNOWN_ERROR + 6),
|
||||
#endif
|
||||
FDS_NOT_ALLOWED = (UNKNOWN_ERROR + 7),
|
||||
};
|
||||
|
||||
// Restore define; enumeration is in "android" namespace, so the value defined
|
||||
// there won't work for Win32 code in a different namespace.
|
||||
#ifdef _WIN32
|
||||
# define NO_ERROR 0L
|
||||
#endif
|
||||
|
||||
}; // namespace android
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // ANDROID_ERRORS_H
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//
|
||||
// Encapsulate a shared file mapping.
|
||||
//
|
||||
#ifndef __LIBS_FILE_MAP_H
|
||||
#define __LIBS_FILE_MAP_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <utils/Compat.h>
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
// Ensure that we always pull in winsock2.h before windows.h
|
||||
#ifdef HAVE_WINSOCK
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace android {
|
||||
|
||||
/*
|
||||
* This represents a memory-mapped file. It might be the entire file or
|
||||
* only part of it. This requires a little bookkeeping because the mapping
|
||||
* needs to be aligned on page boundaries, and in some cases we'd like to
|
||||
* have multiple references to the mapped area without creating additional
|
||||
* maps.
|
||||
*
|
||||
* This always uses MAP_SHARED.
|
||||
*
|
||||
* TODO: we should be able to create a new FileMap that is a subset of
|
||||
* an existing FileMap and shares the underlying mapped pages. Requires
|
||||
* completing the refcounting stuff and possibly introducing the notion
|
||||
* of a FileMap hierarchy.
|
||||
*/
|
||||
class FileMap {
|
||||
public:
|
||||
FileMap(void);
|
||||
|
||||
/*
|
||||
* Create a new mapping on an open file.
|
||||
*
|
||||
* Closing the file descriptor does not unmap the pages, so we don't
|
||||
* claim ownership of the fd.
|
||||
*
|
||||
* Returns "false" on failure.
|
||||
*/
|
||||
bool create(const char* origFileName, int fd,
|
||||
off64_t offset, size_t length, bool readOnly);
|
||||
|
||||
~FileMap(void);
|
||||
|
||||
/*
|
||||
* Return the name of the file this map came from, if known.
|
||||
*/
|
||||
const char* getFileName(void) const { return mFileName; }
|
||||
|
||||
/*
|
||||
* Get a pointer to the piece of the file we requested.
|
||||
*/
|
||||
void* getDataPtr(void) const { return mDataPtr; }
|
||||
|
||||
/*
|
||||
* Get the length we requested.
|
||||
*/
|
||||
size_t getDataLength(void) const { return mDataLength; }
|
||||
|
||||
/*
|
||||
* Get the data offset used to create this map.
|
||||
*/
|
||||
off64_t getDataOffset(void) const { return mDataOffset; }
|
||||
|
||||
/*
|
||||
* This maps directly to madvise() values, but allows us to avoid
|
||||
* including <sys/mman.h> everywhere.
|
||||
*/
|
||||
enum MapAdvice {
|
||||
NORMAL, RANDOM, SEQUENTIAL, WILLNEED, DONTNEED
|
||||
};
|
||||
|
||||
/*
|
||||
* Apply an madvise() call to the entire file.
|
||||
*
|
||||
* Returns 0 on success, -1 on failure.
|
||||
*/
|
||||
int advise(MapAdvice advice);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
// these are not implemented
|
||||
FileMap(const FileMap& src);
|
||||
const FileMap& operator=(const FileMap& src);
|
||||
|
||||
char* mFileName; // original file name, if known
|
||||
void* mBasePtr; // base of mmap area; page aligned
|
||||
size_t mBaseLength; // length, measured from "mBasePtr"
|
||||
off64_t mDataOffset; // offset used when map was created
|
||||
void* mDataPtr; // start of requested data, offset from base
|
||||
size_t mDataLength; // length, measured from "mDataPtr"
|
||||
#if defined(__MINGW32__)
|
||||
HANDLE mFileHandle; // Win32 file handle
|
||||
HANDLE mFileMapping; // Win32 file mapping handle
|
||||
#endif
|
||||
|
||||
static long mPageSize;
|
||||
};
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#endif // __LIBS_FILE_MAP_H
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_UTILS_FLATTENABLE_H
|
||||
#define ANDROID_UTILS_FLATTENABLE_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/Debug.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
|
||||
class FlattenableUtils {
|
||||
public:
|
||||
template<int N>
|
||||
static size_t align(size_t size) {
|
||||
COMPILE_TIME_ASSERT_FUNCTION_SCOPE( !(N & (N-1)) );
|
||||
return (size + (N-1)) & ~(N-1);
|
||||
}
|
||||
|
||||
template<int N>
|
||||
static size_t align(void const*& buffer) {
|
||||
COMPILE_TIME_ASSERT_FUNCTION_SCOPE( !(N & (N-1)) );
|
||||
intptr_t b = intptr_t(buffer);
|
||||
buffer = (void*)((intptr_t(buffer) + (N-1)) & ~(N-1));
|
||||
return size_t(intptr_t(buffer) - b);
|
||||
}
|
||||
|
||||
template<int N>
|
||||
static size_t align(void*& buffer) {
|
||||
return align<N>( const_cast<void const*&>(buffer) );
|
||||
}
|
||||
|
||||
static void advance(void*& buffer, size_t& size, size_t offset) {
|
||||
buffer = reinterpret_cast<void*>( intptr_t(buffer) + offset );
|
||||
size -= offset;
|
||||
}
|
||||
|
||||
static void advance(void const*& buffer, size_t& size, size_t offset) {
|
||||
buffer = reinterpret_cast<void const*>( intptr_t(buffer) + offset );
|
||||
size -= offset;
|
||||
}
|
||||
|
||||
// write a POD structure
|
||||
template<typename T>
|
||||
static void write(void*& buffer, size_t& size, const T& value) {
|
||||
*static_cast<T*>(buffer) = value;
|
||||
advance(buffer, size, sizeof(T));
|
||||
}
|
||||
|
||||
// read a POD structure
|
||||
template<typename T>
|
||||
static void read(void const*& buffer, size_t& size, T& value) {
|
||||
value = *static_cast<T const*>(buffer);
|
||||
advance(buffer, size, sizeof(T));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* The Flattenable protocol allows an object to serialize itself out
|
||||
* to a byte-buffer and an array of file descriptors.
|
||||
* Flattenable objects must implement this protocol.
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
class Flattenable {
|
||||
public:
|
||||
// size in bytes of the flattened object
|
||||
inline size_t getFlattenedSize() const;
|
||||
|
||||
// number of file descriptors to flatten
|
||||
inline size_t getFdCount() const;
|
||||
|
||||
// flattens the object into buffer.
|
||||
// size should be at least of getFlattenedSize()
|
||||
// file descriptors are written in the fds[] array but ownership is
|
||||
// not transfered (ie: they must be dupped by the caller of
|
||||
// flatten() if needed).
|
||||
inline status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;
|
||||
|
||||
// unflattens the object from buffer.
|
||||
// size should be equal to the value of getFlattenedSize() when the
|
||||
// object was flattened.
|
||||
// unflattened file descriptors are found in the fds[] array and
|
||||
// don't need to be dupped(). ie: the caller of unflatten doesn't
|
||||
// keep ownership. If a fd is not retained by unflatten() it must be
|
||||
// explicitly closed.
|
||||
inline status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline size_t Flattenable<T>::getFlattenedSize() const {
|
||||
return static_cast<T const*>(this)->T::getFlattenedSize();
|
||||
}
|
||||
template<typename T>
|
||||
inline size_t Flattenable<T>::getFdCount() const {
|
||||
return static_cast<T const*>(this)->T::getFdCount();
|
||||
}
|
||||
template<typename T>
|
||||
inline status_t Flattenable<T>::flatten(
|
||||
void*& buffer, size_t& size, int*& fds, size_t& count) const {
|
||||
return static_cast<T const*>(this)->T::flatten(buffer, size, fds, count);
|
||||
}
|
||||
template<typename T>
|
||||
inline status_t Flattenable<T>::unflatten(
|
||||
void const*& buffer, size_t& size, int const*& fds, size_t& count) {
|
||||
return static_cast<T*>(this)->T::unflatten(buffer, size, fds, count);
|
||||
}
|
||||
|
||||
/*
|
||||
* LightFlattenable is a protocol allowing object to serialize themselves out
|
||||
* to a byte-buffer. Because it doesn't handle file-descriptors,
|
||||
* LightFlattenable is usually more size efficient than Flattenable.
|
||||
* LightFlattenable objects must implement this protocol.
|
||||
*/
|
||||
template <typename T>
|
||||
class LightFlattenable {
|
||||
public:
|
||||
// returns whether this object always flatten into the same size.
|
||||
// for efficiency, this should always be inline.
|
||||
inline bool isFixedSize() const;
|
||||
|
||||
// returns size in bytes of the flattened object. must be a constant.
|
||||
inline size_t getFlattenedSize() const;
|
||||
|
||||
// flattens the object into buffer.
|
||||
inline status_t flatten(void* buffer, size_t size) const;
|
||||
|
||||
// unflattens the object from buffer of given size.
|
||||
inline status_t unflatten(void const* buffer, size_t size);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline bool LightFlattenable<T>::isFixedSize() const {
|
||||
return static_cast<T const*>(this)->T::isFixedSize();
|
||||
}
|
||||
template <typename T>
|
||||
inline size_t LightFlattenable<T>::getFlattenedSize() const {
|
||||
return static_cast<T const*>(this)->T::getFlattenedSize();
|
||||
}
|
||||
template <typename T>
|
||||
inline status_t LightFlattenable<T>::flatten(void* buffer, size_t size) const {
|
||||
return static_cast<T const*>(this)->T::flatten(buffer, size);
|
||||
}
|
||||
template <typename T>
|
||||
inline status_t LightFlattenable<T>::unflatten(void const* buffer, size_t size) {
|
||||
return static_cast<T*>(this)->T::unflatten(buffer, size);
|
||||
}
|
||||
|
||||
/*
|
||||
* LightFlattenablePod is an implementation of the LightFlattenable protocol
|
||||
* for POD (plain-old-data) objects.
|
||||
* Simply derive from LightFlattenablePod<Foo> to make Foo flattenable; no
|
||||
* need to implement any methods; obviously Foo must be a POD structure.
|
||||
*/
|
||||
template <typename T>
|
||||
class LightFlattenablePod : public LightFlattenable<T> {
|
||||
public:
|
||||
inline bool isFixedSize() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline size_t getFlattenedSize() const {
|
||||
return sizeof(T);
|
||||
}
|
||||
inline status_t flatten(void* buffer, size_t size) const {
|
||||
if (size < sizeof(T)) return NO_MEMORY;
|
||||
*reinterpret_cast<T*>(buffer) = *static_cast<T const*>(this);
|
||||
return NO_ERROR;
|
||||
}
|
||||
inline status_t unflatten(void const* buffer, size_t) {
|
||||
*static_cast<T*>(this) = *reinterpret_cast<T const*>(buffer);
|
||||
return NO_ERROR;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}; // namespace android
|
||||
|
||||
|
||||
#endif /* ANDROID_UTILS_FLATTENABLE_H */
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_FUNCTOR_H
|
||||
#define ANDROID_FUNCTOR_H
|
||||
|
||||
#include <utils/Errors.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
class Functor {
|
||||
public:
|
||||
Functor() {}
|
||||
virtual ~Functor() {}
|
||||
virtual status_t operator ()(int /*what*/, void* /*data*/) { return NO_ERROR; }
|
||||
};
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#endif // ANDROID_FUNCTOR_H
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* Implementation of Jenkins one-at-a-time hash function. These choices are
|
||||
* optimized for code size and portability, rather than raw speed. But speed
|
||||
* should still be quite good.
|
||||
**/
|
||||
|
||||
#ifndef ANDROID_JENKINS_HASH_H
|
||||
#define ANDROID_JENKINS_HASH_H
|
||||
|
||||
#include <utils/TypeHelpers.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
/* The Jenkins hash of a sequence of 32 bit words A, B, C is:
|
||||
* Whiten(Mix(Mix(Mix(0, A), B), C)) */
|
||||
|
||||
inline uint32_t JenkinsHashMix(uint32_t hash, uint32_t data) {
|
||||
hash += data;
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
return hash;
|
||||
}
|
||||
|
||||
hash_t JenkinsHashWhiten(uint32_t hash);
|
||||
|
||||
/* Helpful utility functions for hashing data in 32 bit chunks */
|
||||
uint32_t JenkinsHashMixBytes(uint32_t hash, const uint8_t* bytes, size_t size);
|
||||
|
||||
uint32_t JenkinsHashMixShorts(uint32_t hash, const uint16_t* shorts, size_t size);
|
||||
|
||||
}
|
||||
|
||||
#endif // ANDROID_JENKINS_HASH_H
|
||||
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_KEYED_VECTOR_H
|
||||
#define ANDROID_KEYED_VECTOR_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include <utils/SortedVector.h>
|
||||
#include <utils/TypeHelpers.h>
|
||||
#include <utils/Errors.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
namespace android {
|
||||
|
||||
template <typename KEY, typename VALUE>
|
||||
class KeyedVector
|
||||
{
|
||||
public:
|
||||
typedef KEY key_type;
|
||||
typedef VALUE value_type;
|
||||
|
||||
inline KeyedVector();
|
||||
|
||||
/*
|
||||
* empty the vector
|
||||
*/
|
||||
|
||||
inline void clear() { mVector.clear(); }
|
||||
|
||||
/*!
|
||||
* vector stats
|
||||
*/
|
||||
|
||||
//! returns number of items in the vector
|
||||
inline size_t size() const { return mVector.size(); }
|
||||
//! returns whether or not the vector is empty
|
||||
inline bool isEmpty() const { return mVector.isEmpty(); }
|
||||
//! returns how many items can be stored without reallocating the backing store
|
||||
inline size_t capacity() const { return mVector.capacity(); }
|
||||
//! sets the capacity. capacity can never be reduced less than size()
|
||||
inline ssize_t setCapacity(size_t size) { return mVector.setCapacity(size); }
|
||||
|
||||
// returns true if the arguments is known to be identical to this vector
|
||||
inline bool isIdenticalTo(const KeyedVector& rhs) const;
|
||||
|
||||
/*!
|
||||
* accessors
|
||||
*/
|
||||
const VALUE& valueFor(const KEY& key) const;
|
||||
const VALUE& valueAt(size_t index) const;
|
||||
const KEY& keyAt(size_t index) const;
|
||||
ssize_t indexOfKey(const KEY& key) const;
|
||||
const VALUE& operator[] (size_t index) const;
|
||||
|
||||
/*!
|
||||
* modifying the array
|
||||
*/
|
||||
|
||||
VALUE& editValueFor(const KEY& key);
|
||||
VALUE& editValueAt(size_t index);
|
||||
|
||||
/*!
|
||||
* add/insert/replace items
|
||||
*/
|
||||
|
||||
ssize_t add(const KEY& key, const VALUE& item);
|
||||
ssize_t replaceValueFor(const KEY& key, const VALUE& item);
|
||||
ssize_t replaceValueAt(size_t index, const VALUE& item);
|
||||
|
||||
/*!
|
||||
* remove items
|
||||
*/
|
||||
|
||||
ssize_t removeItem(const KEY& key);
|
||||
ssize_t removeItemsAt(size_t index, size_t count = 1);
|
||||
|
||||
private:
|
||||
SortedVector< key_value_pair_t<KEY, VALUE> > mVector;
|
||||
};
|
||||
|
||||
// KeyedVector<KEY, VALUE> can be trivially moved using memcpy() because its
|
||||
// underlying SortedVector can be trivially moved.
|
||||
template<typename KEY, typename VALUE> struct trait_trivial_move<KeyedVector<KEY, VALUE> > {
|
||||
enum { value = trait_trivial_move<SortedVector< key_value_pair_t<KEY, VALUE> > >::value };
|
||||
};
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Variation of KeyedVector that holds a default value to return when
|
||||
* valueFor() is called with a key that doesn't exist.
|
||||
*/
|
||||
template <typename KEY, typename VALUE>
|
||||
class DefaultKeyedVector : public KeyedVector<KEY, VALUE>
|
||||
{
|
||||
public:
|
||||
inline DefaultKeyedVector(const VALUE& defValue = VALUE());
|
||||
const VALUE& valueFor(const KEY& key) const;
|
||||
|
||||
private:
|
||||
VALUE mDefault;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
template<typename KEY, typename VALUE> inline
|
||||
KeyedVector<KEY,VALUE>::KeyedVector()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename KEY, typename VALUE> inline
|
||||
bool KeyedVector<KEY,VALUE>::isIdenticalTo(const KeyedVector<KEY,VALUE>& rhs) const {
|
||||
return mVector.array() == rhs.mVector.array();
|
||||
}
|
||||
|
||||
template<typename KEY, typename VALUE> inline
|
||||
ssize_t KeyedVector<KEY,VALUE>::indexOfKey(const KEY& key) const {
|
||||
return mVector.indexOf( key_value_pair_t<KEY,VALUE>(key) );
|
||||
}
|
||||
|
||||
template<typename KEY, typename VALUE> inline
|
||||
const VALUE& KeyedVector<KEY,VALUE>::valueFor(const KEY& key) const {
|
||||
ssize_t i = this->indexOfKey(key);
|
||||
LOG_ALWAYS_FATAL_IF(i<0, "%s: key not found", __PRETTY_FUNCTION__);
|
||||
return mVector.itemAt(i).value;
|
||||
}
|
||||
|
||||
template<typename KEY, typename VALUE> inline
|
||||
const VALUE& KeyedVector<KEY,VALUE>::valueAt(size_t index) const {
|
||||
return mVector.itemAt(index).value;
|
||||
}
|
||||
|
||||
template<typename KEY, typename VALUE> inline
|
||||
const VALUE& KeyedVector<KEY,VALUE>::operator[] (size_t index) const {
|
||||
return valueAt(index);
|
||||
}
|
||||
|
||||
template<typename KEY, typename VALUE> inline
|
||||
const KEY& KeyedVector<KEY,VALUE>::keyAt(size_t index) const {
|
||||
return mVector.itemAt(index).key;
|
||||
}
|
||||
|
||||
template<typename KEY, typename VALUE> inline
|
||||
VALUE& KeyedVector<KEY,VALUE>::editValueFor(const KEY& key) {
|
||||
ssize_t i = this->indexOfKey(key);
|
||||
LOG_ALWAYS_FATAL_IF(i<0, "%s: key not found", __PRETTY_FUNCTION__);
|
||||
return mVector.editItemAt(i).value;
|
||||
}
|
||||
|
||||
template<typename KEY, typename VALUE> inline
|
||||
VALUE& KeyedVector<KEY,VALUE>::editValueAt(size_t index) {
|
||||
return mVector.editItemAt(index).value;
|
||||
}
|
||||
|
||||
template<typename KEY, typename VALUE> inline
|
||||
ssize_t KeyedVector<KEY,VALUE>::add(const KEY& key, const VALUE& value) {
|
||||
return mVector.add( key_value_pair_t<KEY,VALUE>(key, value) );
|
||||
}
|
||||
|
||||
template<typename KEY, typename VALUE> inline
|
||||
ssize_t KeyedVector<KEY,VALUE>::replaceValueFor(const KEY& key, const VALUE& value) {
|
||||
key_value_pair_t<KEY,VALUE> pair(key, value);
|
||||
mVector.remove(pair);
|
||||
return mVector.add(pair);
|
||||
}
|
||||
|
||||
template<typename KEY, typename VALUE> inline
|
||||
ssize_t KeyedVector<KEY,VALUE>::replaceValueAt(size_t index, const VALUE& item) {
|
||||
if (index<size()) {
|
||||
mVector.editItemAt(index).value = item;
|
||||
return index;
|
||||
}
|
||||
return BAD_INDEX;
|
||||
}
|
||||
|
||||
template<typename KEY, typename VALUE> inline
|
||||
ssize_t KeyedVector<KEY,VALUE>::removeItem(const KEY& key) {
|
||||
return mVector.remove(key_value_pair_t<KEY,VALUE>(key));
|
||||
}
|
||||
|
||||
template<typename KEY, typename VALUE> inline
|
||||
ssize_t KeyedVector<KEY, VALUE>::removeItemsAt(size_t index, size_t count) {
|
||||
return mVector.removeItemsAt(index, count);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
template<typename KEY, typename VALUE> inline
|
||||
DefaultKeyedVector<KEY,VALUE>::DefaultKeyedVector(const VALUE& defValue)
|
||||
: mDefault(defValue)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename KEY, typename VALUE> inline
|
||||
const VALUE& DefaultKeyedVector<KEY,VALUE>::valueFor(const KEY& key) const {
|
||||
ssize_t i = this->indexOfKey(key);
|
||||
return i >= 0 ? KeyedVector<KEY,VALUE>::valueAt(i) : mDefault;
|
||||
}
|
||||
|
||||
}; // namespace android
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // ANDROID_KEYED_VECTOR_H
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _LIBS_UTILS_LINEAR_TRANSFORM_H
|
||||
#define _LIBS_UTILS_LINEAR_TRANSFORM_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
// LinearTransform defines a structure which hold the definition of a
|
||||
// transformation from single dimensional coordinate system A into coordinate
|
||||
// system B (and back again). Values in A and in B are 64 bit, the linear
|
||||
// scale factor is expressed as a rational number using two 32 bit values.
|
||||
//
|
||||
// Specifically, let
|
||||
// f(a) = b
|
||||
// F(b) = f^-1(b) = a
|
||||
// then
|
||||
//
|
||||
// f(a) = (((a - a_zero) * a_to_b_numer) / a_to_b_denom) + b_zero;
|
||||
//
|
||||
// and
|
||||
//
|
||||
// F(b) = (((b - b_zero) * a_to_b_denom) / a_to_b_numer) + a_zero;
|
||||
//
|
||||
struct LinearTransform {
|
||||
int64_t a_zero;
|
||||
int64_t b_zero;
|
||||
int32_t a_to_b_numer;
|
||||
uint32_t a_to_b_denom;
|
||||
|
||||
// Transform from A->B
|
||||
// Returns true on success, or false in the case of a singularity or an
|
||||
// overflow.
|
||||
bool doForwardTransform(int64_t a_in, int64_t* b_out) const;
|
||||
|
||||
// Transform from B->A
|
||||
// Returns true on success, or false in the case of a singularity or an
|
||||
// overflow.
|
||||
bool doReverseTransform(int64_t b_in, int64_t* a_out) const;
|
||||
|
||||
// Helpers which will reduce the fraction N/D using Euclid's method.
|
||||
template <class T> static void reduce(T* N, T* D);
|
||||
static void reduce(int32_t* N, uint32_t* D);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // _LIBS_UTILS_LINEAR_TRANSFORM_H
|
||||
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//
|
||||
// Templated list class. Normally we'd use STL, but we don't have that.
|
||||
// This class mimics STL's interfaces.
|
||||
//
|
||||
// Objects are copied into the list with the '=' operator or with copy-
|
||||
// construction, so if the compiler's auto-generated versions won't work for
|
||||
// you, define your own.
|
||||
//
|
||||
// The only class you want to use from here is "List".
|
||||
//
|
||||
#ifndef _LIBS_UTILS_LIST_H
|
||||
#define _LIBS_UTILS_LIST_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
/*
|
||||
* Doubly-linked list. Instantiate with "List<MyClass> myList".
|
||||
*
|
||||
* Objects added to the list are copied using the assignment operator,
|
||||
* so this must be defined.
|
||||
*/
|
||||
template<typename T>
|
||||
class List
|
||||
{
|
||||
protected:
|
||||
/*
|
||||
* One element in the list.
|
||||
*/
|
||||
class _Node {
|
||||
public:
|
||||
explicit _Node(const T& val) : mVal(val) {}
|
||||
~_Node() {}
|
||||
inline T& getRef() { return mVal; }
|
||||
inline const T& getRef() const { return mVal; }
|
||||
inline _Node* getPrev() const { return mpPrev; }
|
||||
inline _Node* getNext() const { return mpNext; }
|
||||
inline void setVal(const T& val) { mVal = val; }
|
||||
inline void setPrev(_Node* ptr) { mpPrev = ptr; }
|
||||
inline void setNext(_Node* ptr) { mpNext = ptr; }
|
||||
private:
|
||||
friend class List;
|
||||
friend class _ListIterator;
|
||||
T mVal;
|
||||
_Node* mpPrev;
|
||||
_Node* mpNext;
|
||||
};
|
||||
|
||||
/*
|
||||
* Iterator for walking through the list.
|
||||
*/
|
||||
|
||||
template <typename TYPE>
|
||||
struct CONST_ITERATOR {
|
||||
typedef _Node const * NodePtr;
|
||||
typedef const TYPE Type;
|
||||
};
|
||||
|
||||
template <typename TYPE>
|
||||
struct NON_CONST_ITERATOR {
|
||||
typedef _Node* NodePtr;
|
||||
typedef TYPE Type;
|
||||
};
|
||||
|
||||
template<
|
||||
typename U,
|
||||
template <class> class Constness
|
||||
>
|
||||
class _ListIterator {
|
||||
typedef _ListIterator<U, Constness> _Iter;
|
||||
typedef typename Constness<U>::NodePtr _NodePtr;
|
||||
typedef typename Constness<U>::Type _Type;
|
||||
|
||||
explicit _ListIterator(_NodePtr ptr) : mpNode(ptr) {}
|
||||
|
||||
public:
|
||||
_ListIterator() {}
|
||||
_ListIterator(const _Iter& rhs) : mpNode(rhs.mpNode) {}
|
||||
~_ListIterator() {}
|
||||
|
||||
// this will handle conversions from iterator to const_iterator
|
||||
// (and also all convertible iterators)
|
||||
// Here, in this implementation, the iterators can be converted
|
||||
// if the nodes can be converted
|
||||
template<typename V> explicit
|
||||
_ListIterator(const V& rhs) : mpNode(rhs.mpNode) {}
|
||||
|
||||
|
||||
/*
|
||||
* Dereference operator. Used to get at the juicy insides.
|
||||
*/
|
||||
_Type& operator*() const { return mpNode->getRef(); }
|
||||
_Type* operator->() const { return &(mpNode->getRef()); }
|
||||
|
||||
/*
|
||||
* Iterator comparison.
|
||||
*/
|
||||
inline bool operator==(const _Iter& right) const {
|
||||
return mpNode == right.mpNode; }
|
||||
|
||||
inline bool operator!=(const _Iter& right) const {
|
||||
return mpNode != right.mpNode; }
|
||||
|
||||
/*
|
||||
* handle comparisons between iterator and const_iterator
|
||||
*/
|
||||
template<typename OTHER>
|
||||
inline bool operator==(const OTHER& right) const {
|
||||
return mpNode == right.mpNode; }
|
||||
|
||||
template<typename OTHER>
|
||||
inline bool operator!=(const OTHER& right) const {
|
||||
return mpNode != right.mpNode; }
|
||||
|
||||
/*
|
||||
* Incr/decr, used to move through the list.
|
||||
*/
|
||||
inline _Iter& operator++() { // pre-increment
|
||||
mpNode = mpNode->getNext();
|
||||
return *this;
|
||||
}
|
||||
const _Iter operator++(int) { // post-increment
|
||||
_Iter tmp(*this);
|
||||
mpNode = mpNode->getNext();
|
||||
return tmp;
|
||||
}
|
||||
inline _Iter& operator--() { // pre-increment
|
||||
mpNode = mpNode->getPrev();
|
||||
return *this;
|
||||
}
|
||||
const _Iter operator--(int) { // post-increment
|
||||
_Iter tmp(*this);
|
||||
mpNode = mpNode->getPrev();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline _NodePtr getNode() const { return mpNode; }
|
||||
|
||||
_NodePtr mpNode; /* should be private, but older gcc fails */
|
||||
private:
|
||||
friend class List;
|
||||
};
|
||||
|
||||
public:
|
||||
List() {
|
||||
prep();
|
||||
}
|
||||
List(const List<T>& src) { // copy-constructor
|
||||
prep();
|
||||
insert(begin(), src.begin(), src.end());
|
||||
}
|
||||
virtual ~List() {
|
||||
clear();
|
||||
delete[] (unsigned char*) mpMiddle;
|
||||
}
|
||||
|
||||
typedef _ListIterator<T, NON_CONST_ITERATOR> iterator;
|
||||
typedef _ListIterator<T, CONST_ITERATOR> const_iterator;
|
||||
|
||||
List<T>& operator=(const List<T>& right);
|
||||
|
||||
/* returns true if the list is empty */
|
||||
inline bool empty() const { return mpMiddle->getNext() == mpMiddle; }
|
||||
|
||||
/* return #of elements in list */
|
||||
size_t size() const {
|
||||
return size_t(distance(begin(), end()));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the first element or one past the last element. The
|
||||
* _Node* we're returning is converted to an "iterator" by a
|
||||
* constructor in _ListIterator.
|
||||
*/
|
||||
inline iterator begin() {
|
||||
return iterator(mpMiddle->getNext());
|
||||
}
|
||||
inline const_iterator begin() const {
|
||||
return const_iterator(const_cast<_Node const*>(mpMiddle->getNext()));
|
||||
}
|
||||
inline iterator end() {
|
||||
return iterator(mpMiddle);
|
||||
}
|
||||
inline const_iterator end() const {
|
||||
return const_iterator(const_cast<_Node const*>(mpMiddle));
|
||||
}
|
||||
|
||||
/* add the object to the head or tail of the list */
|
||||
void push_front(const T& val) { insert(begin(), val); }
|
||||
void push_back(const T& val) { insert(end(), val); }
|
||||
|
||||
/* insert before the current node; returns iterator at new node */
|
||||
iterator insert(iterator posn, const T& val)
|
||||
{
|
||||
_Node* newNode = new _Node(val); // alloc & copy-construct
|
||||
newNode->setNext(posn.getNode());
|
||||
newNode->setPrev(posn.getNode()->getPrev());
|
||||
posn.getNode()->getPrev()->setNext(newNode);
|
||||
posn.getNode()->setPrev(newNode);
|
||||
return iterator(newNode);
|
||||
}
|
||||
|
||||
/* insert a range of elements before the current node */
|
||||
void insert(iterator posn, const_iterator first, const_iterator last) {
|
||||
for ( ; first != last; ++first)
|
||||
insert(posn, *first);
|
||||
}
|
||||
|
||||
/* remove one entry; returns iterator at next node */
|
||||
iterator erase(iterator posn) {
|
||||
_Node* pNext = posn.getNode()->getNext();
|
||||
_Node* pPrev = posn.getNode()->getPrev();
|
||||
pPrev->setNext(pNext);
|
||||
pNext->setPrev(pPrev);
|
||||
delete posn.getNode();
|
||||
return iterator(pNext);
|
||||
}
|
||||
|
||||
/* remove a range of elements */
|
||||
iterator erase(iterator first, iterator last) {
|
||||
while (first != last)
|
||||
erase(first++); // don't erase than incr later!
|
||||
return iterator(last);
|
||||
}
|
||||
|
||||
/* remove all contents of the list */
|
||||
void clear() {
|
||||
_Node* pCurrent = mpMiddle->getNext();
|
||||
_Node* pNext;
|
||||
|
||||
while (pCurrent != mpMiddle) {
|
||||
pNext = pCurrent->getNext();
|
||||
delete pCurrent;
|
||||
pCurrent = pNext;
|
||||
}
|
||||
mpMiddle->setPrev(mpMiddle);
|
||||
mpMiddle->setNext(mpMiddle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Measure the distance between two iterators. On exist, "first"
|
||||
* will be equal to "last". The iterators must refer to the same
|
||||
* list.
|
||||
*
|
||||
* FIXME: This is actually a generic iterator function. It should be a
|
||||
* template function at the top-level with specializations for things like
|
||||
* vector<>, which can just do pointer math). Here we limit it to
|
||||
* _ListIterator of the same type but different constness.
|
||||
*/
|
||||
template<
|
||||
typename U,
|
||||
template <class> class CL,
|
||||
template <class> class CR
|
||||
>
|
||||
ptrdiff_t distance(
|
||||
_ListIterator<U, CL> first, _ListIterator<U, CR> last) const
|
||||
{
|
||||
ptrdiff_t count = 0;
|
||||
while (first != last) {
|
||||
++first;
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
private:
|
||||
/*
|
||||
* I want a _Node but don't need it to hold valid data. More
|
||||
* to the point, I don't want T's constructor to fire, since it
|
||||
* might have side-effects or require arguments. So, we do this
|
||||
* slightly uncouth storage alloc.
|
||||
*/
|
||||
void prep() {
|
||||
mpMiddle = (_Node*) new unsigned char[sizeof(_Node)];
|
||||
mpMiddle->setPrev(mpMiddle);
|
||||
mpMiddle->setNext(mpMiddle);
|
||||
}
|
||||
|
||||
/*
|
||||
* This node plays the role of "pointer to head" and "pointer to tail".
|
||||
* It sits in the middle of a circular list of nodes. The iterator
|
||||
* runs around the circle until it encounters this one.
|
||||
*/
|
||||
_Node* mpMiddle;
|
||||
};
|
||||
|
||||
/*
|
||||
* Assignment operator.
|
||||
*
|
||||
* The simplest way to do this would be to clear out the target list and
|
||||
* fill it with the source. However, we can speed things along by
|
||||
* re-using existing elements.
|
||||
*/
|
||||
template<class T>
|
||||
List<T>& List<T>::operator=(const List<T>& right)
|
||||
{
|
||||
if (this == &right)
|
||||
return *this; // self-assignment
|
||||
iterator firstDst = begin();
|
||||
iterator lastDst = end();
|
||||
const_iterator firstSrc = right.begin();
|
||||
const_iterator lastSrc = right.end();
|
||||
while (firstSrc != lastSrc && firstDst != lastDst)
|
||||
*firstDst++ = *firstSrc++;
|
||||
if (firstSrc == lastSrc) // ran out of elements in source?
|
||||
erase(firstDst, lastDst); // yes, erase any extras
|
||||
else
|
||||
insert(lastDst, firstSrc, lastSrc); // copy remaining over
|
||||
return *this;
|
||||
}
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#endif // _LIBS_UTILS_LIST_H
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//
|
||||
// C/C++ logging functions. See the logging documentation for API details.
|
||||
//
|
||||
// We'd like these to be available from C code (in case we import some from
|
||||
// somewhere), so this has a C interface.
|
||||
//
|
||||
// The output will be correct when the log file is shared between multiple
|
||||
// threads and/or multiple processes so long as the operating system
|
||||
// supports O_APPEND. These calls have mutex-protected data structures
|
||||
// and so are NOT reentrant. Do not use LOG in a signal handler.
|
||||
//
|
||||
#ifndef _LIBS_UTILS_LOG_H
|
||||
#define _LIBS_UTILS_LOG_H
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace android {
|
||||
|
||||
/*
|
||||
* A very simple utility that yells in the log when an operation takes too long.
|
||||
*/
|
||||
class LogIfSlow {
|
||||
public:
|
||||
LogIfSlow(const char* tag, android_LogPriority priority,
|
||||
int timeoutMillis, const char* message);
|
||||
~LogIfSlow();
|
||||
|
||||
private:
|
||||
const char* const mTag;
|
||||
const android_LogPriority mPriority;
|
||||
const int mTimeoutMillis;
|
||||
const char* const mMessage;
|
||||
const int64_t mStart;
|
||||
};
|
||||
|
||||
/*
|
||||
* Writes the specified debug log message if this block takes longer than the
|
||||
* specified number of milliseconds to run. Includes the time actually taken.
|
||||
*
|
||||
* {
|
||||
* ALOGD_IF_SLOW(50, "Excessive delay doing something.");
|
||||
* doSomething();
|
||||
* }
|
||||
*/
|
||||
#define ALOGD_IF_SLOW(timeoutMillis, message) \
|
||||
android::LogIfSlow _logIfSlow(LOG_TAG, ANDROID_LOG_DEBUG, timeoutMillis, message);
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // _LIBS_UTILS_LOG_H
|
||||
@@ -0,0 +1,487 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef UTILS_LOOPER_H
|
||||
#define UTILS_LOOPER_H
|
||||
|
||||
#include <utils/threads.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
#include <utils/Timers.h>
|
||||
|
||||
#include <sys/epoll.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
/*
|
||||
* NOTE: Since Looper is used to implement the NDK ALooper, the Looper
|
||||
* enums and the signature of Looper_callbackFunc need to align with
|
||||
* that implementation.
|
||||
*/
|
||||
|
||||
/**
|
||||
* For callback-based event loops, this is the prototype of the function
|
||||
* that is called when a file descriptor event occurs.
|
||||
* It is given the file descriptor it is associated with,
|
||||
* a bitmask of the poll events that were triggered (typically EVENT_INPUT),
|
||||
* and the data pointer that was originally supplied.
|
||||
*
|
||||
* Implementations should return 1 to continue receiving callbacks, or 0
|
||||
* to have this file descriptor and callback unregistered from the looper.
|
||||
*/
|
||||
typedef int (*Looper_callbackFunc)(int fd, int events, void* data);
|
||||
|
||||
/**
|
||||
* A message that can be posted to a Looper.
|
||||
*/
|
||||
struct Message {
|
||||
Message() : what(0) { }
|
||||
Message(int what) : what(what) { }
|
||||
|
||||
/* The message type. (interpretation is left up to the handler) */
|
||||
int what;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Interface for a Looper message handler.
|
||||
*
|
||||
* The Looper holds a strong reference to the message handler whenever it has
|
||||
* a message to deliver to it. Make sure to call Looper::removeMessages
|
||||
* to remove any pending messages destined for the handler so that the handler
|
||||
* can be destroyed.
|
||||
*/
|
||||
class MessageHandler : public virtual RefBase {
|
||||
protected:
|
||||
virtual ~MessageHandler() { }
|
||||
|
||||
public:
|
||||
/**
|
||||
* Handles a message.
|
||||
*/
|
||||
virtual void handleMessage(const Message& message) = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A simple proxy that holds a weak reference to a message handler.
|
||||
*/
|
||||
class WeakMessageHandler : public MessageHandler {
|
||||
protected:
|
||||
virtual ~WeakMessageHandler();
|
||||
|
||||
public:
|
||||
WeakMessageHandler(const wp<MessageHandler>& handler);
|
||||
virtual void handleMessage(const Message& message);
|
||||
|
||||
private:
|
||||
wp<MessageHandler> mHandler;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A looper callback.
|
||||
*/
|
||||
class LooperCallback : public virtual RefBase {
|
||||
protected:
|
||||
virtual ~LooperCallback() { }
|
||||
|
||||
public:
|
||||
/**
|
||||
* Handles a poll event for the given file descriptor.
|
||||
* It is given the file descriptor it is associated with,
|
||||
* a bitmask of the poll events that were triggered (typically EVENT_INPUT),
|
||||
* and the data pointer that was originally supplied.
|
||||
*
|
||||
* Implementations should return 1 to continue receiving callbacks, or 0
|
||||
* to have this file descriptor and callback unregistered from the looper.
|
||||
*/
|
||||
virtual int handleEvent(int fd, int events, void* data) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Wraps a Looper_callbackFunc function pointer.
|
||||
*/
|
||||
class SimpleLooperCallback : public LooperCallback {
|
||||
protected:
|
||||
virtual ~SimpleLooperCallback();
|
||||
|
||||
public:
|
||||
SimpleLooperCallback(Looper_callbackFunc callback);
|
||||
virtual int handleEvent(int fd, int events, void* data);
|
||||
|
||||
private:
|
||||
Looper_callbackFunc mCallback;
|
||||
};
|
||||
|
||||
/**
|
||||
* A polling loop that supports monitoring file descriptor events, optionally
|
||||
* using callbacks. The implementation uses epoll() internally.
|
||||
*
|
||||
* A looper can be associated with a thread although there is no requirement that it must be.
|
||||
*/
|
||||
class Looper : public RefBase {
|
||||
protected:
|
||||
virtual ~Looper();
|
||||
|
||||
public:
|
||||
enum {
|
||||
/**
|
||||
* Result from Looper_pollOnce() and Looper_pollAll():
|
||||
* The poll was awoken using wake() before the timeout expired
|
||||
* and no callbacks were executed and no other file descriptors were ready.
|
||||
*/
|
||||
POLL_WAKE = -1,
|
||||
|
||||
/**
|
||||
* Result from Looper_pollOnce() and Looper_pollAll():
|
||||
* One or more callbacks were executed.
|
||||
*/
|
||||
POLL_CALLBACK = -2,
|
||||
|
||||
/**
|
||||
* Result from Looper_pollOnce() and Looper_pollAll():
|
||||
* The timeout expired.
|
||||
*/
|
||||
POLL_TIMEOUT = -3,
|
||||
|
||||
/**
|
||||
* Result from Looper_pollOnce() and Looper_pollAll():
|
||||
* An error occurred.
|
||||
*/
|
||||
POLL_ERROR = -4,
|
||||
};
|
||||
|
||||
/**
|
||||
* Flags for file descriptor events that a looper can monitor.
|
||||
*
|
||||
* These flag bits can be combined to monitor multiple events at once.
|
||||
*/
|
||||
enum {
|
||||
/**
|
||||
* The file descriptor is available for read operations.
|
||||
*/
|
||||
EVENT_INPUT = 1 << 0,
|
||||
|
||||
/**
|
||||
* The file descriptor is available for write operations.
|
||||
*/
|
||||
EVENT_OUTPUT = 1 << 1,
|
||||
|
||||
/**
|
||||
* The file descriptor has encountered an error condition.
|
||||
*
|
||||
* The looper always sends notifications about errors; it is not necessary
|
||||
* to specify this event flag in the requested event set.
|
||||
*/
|
||||
EVENT_ERROR = 1 << 2,
|
||||
|
||||
/**
|
||||
* The file descriptor was hung up.
|
||||
* For example, indicates that the remote end of a pipe or socket was closed.
|
||||
*
|
||||
* The looper always sends notifications about hangups; it is not necessary
|
||||
* to specify this event flag in the requested event set.
|
||||
*/
|
||||
EVENT_HANGUP = 1 << 3,
|
||||
|
||||
/**
|
||||
* The file descriptor is invalid.
|
||||
* For example, the file descriptor was closed prematurely.
|
||||
*
|
||||
* The looper always sends notifications about invalid file descriptors; it is not necessary
|
||||
* to specify this event flag in the requested event set.
|
||||
*/
|
||||
EVENT_INVALID = 1 << 4,
|
||||
};
|
||||
|
||||
enum {
|
||||
/**
|
||||
* Option for Looper_prepare: this looper will accept calls to
|
||||
* Looper_addFd() that do not have a callback (that is provide NULL
|
||||
* for the callback). In this case the caller of Looper_pollOnce()
|
||||
* or Looper_pollAll() MUST check the return from these functions to
|
||||
* discover when data is available on such fds and process it.
|
||||
*/
|
||||
PREPARE_ALLOW_NON_CALLBACKS = 1<<0
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a looper.
|
||||
*
|
||||
* If allowNonCallbaks is true, the looper will allow file descriptors to be
|
||||
* registered without associated callbacks. This assumes that the caller of
|
||||
* pollOnce() is prepared to handle callback-less events itself.
|
||||
*/
|
||||
Looper(bool allowNonCallbacks);
|
||||
|
||||
/**
|
||||
* Returns whether this looper instance allows the registration of file descriptors
|
||||
* using identifiers instead of callbacks.
|
||||
*/
|
||||
bool getAllowNonCallbacks() const;
|
||||
|
||||
/**
|
||||
* Waits for events to be available, with optional timeout in milliseconds.
|
||||
* Invokes callbacks for all file descriptors on which an event occurred.
|
||||
*
|
||||
* If the timeout is zero, returns immediately without blocking.
|
||||
* If the timeout is negative, waits indefinitely until an event appears.
|
||||
*
|
||||
* Returns POLL_WAKE if the poll was awoken using wake() before
|
||||
* the timeout expired and no callbacks were invoked and no other file
|
||||
* descriptors were ready.
|
||||
*
|
||||
* Returns POLL_CALLBACK if one or more callbacks were invoked.
|
||||
*
|
||||
* Returns POLL_TIMEOUT if there was no data before the given
|
||||
* timeout expired.
|
||||
*
|
||||
* Returns POLL_ERROR if an error occurred.
|
||||
*
|
||||
* Returns a value >= 0 containing an identifier if its file descriptor has data
|
||||
* and it has no callback function (requiring the caller here to handle it).
|
||||
* In this (and only this) case outFd, outEvents and outData will contain the poll
|
||||
* events and data associated with the fd, otherwise they will be set to NULL.
|
||||
*
|
||||
* This method does not return until it has finished invoking the appropriate callbacks
|
||||
* for all file descriptors that were signalled.
|
||||
*/
|
||||
int pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);
|
||||
inline int pollOnce(int timeoutMillis) {
|
||||
return pollOnce(timeoutMillis, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like pollOnce(), but performs all pending callbacks until all
|
||||
* data has been consumed or a file descriptor is available with no callback.
|
||||
* This function will never return POLL_CALLBACK.
|
||||
*/
|
||||
int pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData);
|
||||
inline int pollAll(int timeoutMillis) {
|
||||
return pollAll(timeoutMillis, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wakes the poll asynchronously.
|
||||
*
|
||||
* This method can be called on any thread.
|
||||
* This method returns immediately.
|
||||
*/
|
||||
void wake();
|
||||
|
||||
/**
|
||||
* Adds a new file descriptor to be polled by the looper.
|
||||
* If the same file descriptor was previously added, it is replaced.
|
||||
*
|
||||
* "fd" is the file descriptor to be added.
|
||||
* "ident" is an identifier for this event, which is returned from pollOnce().
|
||||
* The identifier must be >= 0, or POLL_CALLBACK if providing a non-NULL callback.
|
||||
* "events" are the poll events to wake up on. Typically this is EVENT_INPUT.
|
||||
* "callback" is the function to call when there is an event on the file descriptor.
|
||||
* "data" is a private data pointer to supply to the callback.
|
||||
*
|
||||
* There are two main uses of this function:
|
||||
*
|
||||
* (1) If "callback" is non-NULL, then this function will be called when there is
|
||||
* data on the file descriptor. It should execute any events it has pending,
|
||||
* appropriately reading from the file descriptor. The 'ident' is ignored in this case.
|
||||
*
|
||||
* (2) If "callback" is NULL, the 'ident' will be returned by Looper_pollOnce
|
||||
* when its file descriptor has data available, requiring the caller to take
|
||||
* care of processing it.
|
||||
*
|
||||
* Returns 1 if the file descriptor was added, 0 if the arguments were invalid.
|
||||
*
|
||||
* This method can be called on any thread.
|
||||
* This method may block briefly if it needs to wake the poll.
|
||||
*
|
||||
* The callback may either be specified as a bare function pointer or as a smart
|
||||
* pointer callback object. The smart pointer should be preferred because it is
|
||||
* easier to avoid races when the callback is removed from a different thread.
|
||||
* See removeFd() for details.
|
||||
*/
|
||||
int addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data);
|
||||
int addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data);
|
||||
|
||||
/**
|
||||
* Removes a previously added file descriptor from the looper.
|
||||
*
|
||||
* When this method returns, it is safe to close the file descriptor since the looper
|
||||
* will no longer have a reference to it. However, it is possible for the callback to
|
||||
* already be running or for it to run one last time if the file descriptor was already
|
||||
* signalled. Calling code is responsible for ensuring that this case is safely handled.
|
||||
* For example, if the callback takes care of removing itself during its own execution either
|
||||
* by returning 0 or by calling this method, then it can be guaranteed to not be invoked
|
||||
* again at any later time unless registered anew.
|
||||
*
|
||||
* A simple way to avoid this problem is to use the version of addFd() that takes
|
||||
* a sp<LooperCallback> instead of a bare function pointer. The LooperCallback will
|
||||
* be released at the appropriate time by the Looper.
|
||||
*
|
||||
* Returns 1 if the file descriptor was removed, 0 if none was previously registered.
|
||||
*
|
||||
* This method can be called on any thread.
|
||||
* This method may block briefly if it needs to wake the poll.
|
||||
*/
|
||||
int removeFd(int fd);
|
||||
|
||||
/**
|
||||
* Enqueues a message to be processed by the specified handler.
|
||||
*
|
||||
* The handler must not be null.
|
||||
* This method can be called on any thread.
|
||||
*/
|
||||
void sendMessage(const sp<MessageHandler>& handler, const Message& message);
|
||||
|
||||
/**
|
||||
* Enqueues a message to be processed by the specified handler after all pending messages
|
||||
* after the specified delay.
|
||||
*
|
||||
* The time delay is specified in uptime nanoseconds.
|
||||
* The handler must not be null.
|
||||
* This method can be called on any thread.
|
||||
*/
|
||||
void sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler,
|
||||
const Message& message);
|
||||
|
||||
/**
|
||||
* Enqueues a message to be processed by the specified handler after all pending messages
|
||||
* at the specified time.
|
||||
*
|
||||
* The time is specified in uptime nanoseconds.
|
||||
* The handler must not be null.
|
||||
* This method can be called on any thread.
|
||||
*/
|
||||
void sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler,
|
||||
const Message& message);
|
||||
|
||||
/**
|
||||
* Removes all messages for the specified handler from the queue.
|
||||
*
|
||||
* The handler must not be null.
|
||||
* This method can be called on any thread.
|
||||
*/
|
||||
void removeMessages(const sp<MessageHandler>& handler);
|
||||
|
||||
/**
|
||||
* Removes all messages of a particular type for the specified handler from the queue.
|
||||
*
|
||||
* The handler must not be null.
|
||||
* This method can be called on any thread.
|
||||
*/
|
||||
void removeMessages(const sp<MessageHandler>& handler, int what);
|
||||
|
||||
/**
|
||||
* Returns whether this looper's thread is currently polling for more work to do.
|
||||
* This is a good signal that the loop is still alive rather than being stuck
|
||||
* handling a callback. Note that this method is intrinsically racy, since the
|
||||
* state of the loop can change before you get the result back.
|
||||
*/
|
||||
bool isPolling() const;
|
||||
|
||||
/**
|
||||
* Prepares a looper associated with the calling thread, and returns it.
|
||||
* If the thread already has a looper, it is returned. Otherwise, a new
|
||||
* one is created, associated with the thread, and returned.
|
||||
*
|
||||
* The opts may be PREPARE_ALLOW_NON_CALLBACKS or 0.
|
||||
*/
|
||||
static sp<Looper> prepare(int opts);
|
||||
|
||||
/**
|
||||
* Sets the given looper to be associated with the calling thread.
|
||||
* If another looper is already associated with the thread, it is replaced.
|
||||
*
|
||||
* If "looper" is NULL, removes the currently associated looper.
|
||||
*/
|
||||
static void setForThread(const sp<Looper>& looper);
|
||||
|
||||
/**
|
||||
* Returns the looper associated with the calling thread, or NULL if
|
||||
* there is not one.
|
||||
*/
|
||||
static sp<Looper> getForThread();
|
||||
|
||||
private:
|
||||
struct Request {
|
||||
int fd;
|
||||
int ident;
|
||||
int events;
|
||||
int seq;
|
||||
sp<LooperCallback> callback;
|
||||
void* data;
|
||||
|
||||
void initEventItem(struct epoll_event* eventItem) const;
|
||||
};
|
||||
|
||||
struct Response {
|
||||
int events;
|
||||
Request request;
|
||||
};
|
||||
|
||||
struct MessageEnvelope {
|
||||
MessageEnvelope() : uptime(0) { }
|
||||
|
||||
MessageEnvelope(nsecs_t uptime, const sp<MessageHandler> handler,
|
||||
const Message& message) : uptime(uptime), handler(handler), message(message) {
|
||||
}
|
||||
|
||||
nsecs_t uptime;
|
||||
sp<MessageHandler> handler;
|
||||
Message message;
|
||||
};
|
||||
|
||||
const bool mAllowNonCallbacks; // immutable
|
||||
|
||||
int mWakeEventFd; // immutable
|
||||
Mutex mLock;
|
||||
|
||||
Vector<MessageEnvelope> mMessageEnvelopes; // guarded by mLock
|
||||
bool mSendingMessage; // guarded by mLock
|
||||
|
||||
// Whether we are currently waiting for work. Not protected by a lock,
|
||||
// any use of it is racy anyway.
|
||||
volatile bool mPolling;
|
||||
|
||||
int mEpollFd; // guarded by mLock but only modified on the looper thread
|
||||
bool mEpollRebuildRequired; // guarded by mLock
|
||||
|
||||
// Locked list of file descriptor monitoring requests.
|
||||
KeyedVector<int, Request> mRequests; // guarded by mLock
|
||||
int mNextRequestSeq;
|
||||
|
||||
// This state is only used privately by pollOnce and does not require a lock since
|
||||
// it runs on a single thread.
|
||||
Vector<Response> mResponses;
|
||||
size_t mResponseIndex;
|
||||
nsecs_t mNextMessageUptime; // set to LLONG_MAX when none
|
||||
|
||||
int pollInner(int timeoutMillis);
|
||||
int removeFd(int fd, int seq);
|
||||
void awoken();
|
||||
void pushResponse(int events, const Request& request);
|
||||
void rebuildEpollLocked();
|
||||
void scheduleEpollRebuildLocked();
|
||||
|
||||
static void initTLSKey();
|
||||
static void threadDestructor(void *st);
|
||||
static void initEpollEvent(struct epoll_event* eventItem);
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // UTILS_LOOPER_H
|
||||
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_UTILS_LRU_CACHE_H
|
||||
#define ANDROID_UTILS_LRU_CACHE_H
|
||||
|
||||
#include <UniquePtr.h>
|
||||
#include <utils/BasicHashtable.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
/**
|
||||
* GenerationCache callback used when an item is removed
|
||||
*/
|
||||
template<typename EntryKey, typename EntryValue>
|
||||
class OnEntryRemoved {
|
||||
public:
|
||||
virtual ~OnEntryRemoved() { };
|
||||
virtual void operator()(EntryKey& key, EntryValue& value) = 0;
|
||||
}; // class OnEntryRemoved
|
||||
|
||||
template <typename TKey, typename TValue>
|
||||
class LruCache {
|
||||
public:
|
||||
explicit LruCache(uint32_t maxCapacity);
|
||||
|
||||
enum Capacity {
|
||||
kUnlimitedCapacity,
|
||||
};
|
||||
|
||||
void setOnEntryRemovedListener(OnEntryRemoved<TKey, TValue>* listener);
|
||||
size_t size() const;
|
||||
const TValue& get(const TKey& key);
|
||||
bool put(const TKey& key, const TValue& value);
|
||||
bool remove(const TKey& key);
|
||||
bool removeOldest();
|
||||
void clear();
|
||||
const TValue& peekOldestValue();
|
||||
|
||||
class Iterator {
|
||||
public:
|
||||
Iterator(const LruCache<TKey, TValue>& cache): mCache(cache), mIndex(-1) {
|
||||
}
|
||||
|
||||
bool next() {
|
||||
mIndex = mCache.mTable->next(mIndex);
|
||||
return (ssize_t)mIndex != -1;
|
||||
}
|
||||
|
||||
size_t index() const {
|
||||
return mIndex;
|
||||
}
|
||||
|
||||
const TValue& value() const {
|
||||
return mCache.mTable->entryAt(mIndex).value;
|
||||
}
|
||||
|
||||
const TKey& key() const {
|
||||
return mCache.mTable->entryAt(mIndex).key;
|
||||
}
|
||||
private:
|
||||
const LruCache<TKey, TValue>& mCache;
|
||||
size_t mIndex;
|
||||
};
|
||||
|
||||
private:
|
||||
LruCache(const LruCache& that); // disallow copy constructor
|
||||
|
||||
struct Entry {
|
||||
TKey key;
|
||||
TValue value;
|
||||
Entry* parent;
|
||||
Entry* child;
|
||||
|
||||
Entry(TKey key_, TValue value_) : key(key_), value(value_), parent(NULL), child(NULL) {
|
||||
}
|
||||
const TKey& getKey() const { return key; }
|
||||
};
|
||||
|
||||
void attachToCache(Entry& entry);
|
||||
void detachFromCache(Entry& entry);
|
||||
void rehash(size_t newCapacity);
|
||||
|
||||
UniquePtr<BasicHashtable<TKey, Entry> > mTable;
|
||||
OnEntryRemoved<TKey, TValue>* mListener;
|
||||
Entry* mOldest;
|
||||
Entry* mYoungest;
|
||||
uint32_t mMaxCapacity;
|
||||
TValue mNullValue;
|
||||
};
|
||||
|
||||
// Implementation is here, because it's fully templated
|
||||
template <typename TKey, typename TValue>
|
||||
LruCache<TKey, TValue>::LruCache(uint32_t maxCapacity)
|
||||
: mTable(new BasicHashtable<TKey, Entry>)
|
||||
, mListener(NULL)
|
||||
, mOldest(NULL)
|
||||
, mYoungest(NULL)
|
||||
, mMaxCapacity(maxCapacity)
|
||||
, mNullValue(NULL) {
|
||||
};
|
||||
|
||||
template<typename K, typename V>
|
||||
void LruCache<K, V>::setOnEntryRemovedListener(OnEntryRemoved<K, V>* listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
template <typename TKey, typename TValue>
|
||||
size_t LruCache<TKey, TValue>::size() const {
|
||||
return mTable->size();
|
||||
}
|
||||
|
||||
template <typename TKey, typename TValue>
|
||||
const TValue& LruCache<TKey, TValue>::get(const TKey& key) {
|
||||
hash_t hash = hash_type(key);
|
||||
ssize_t index = mTable->find(-1, hash, key);
|
||||
if (index == -1) {
|
||||
return mNullValue;
|
||||
}
|
||||
Entry& entry = mTable->editEntryAt(index);
|
||||
detachFromCache(entry);
|
||||
attachToCache(entry);
|
||||
return entry.value;
|
||||
}
|
||||
|
||||
template <typename TKey, typename TValue>
|
||||
bool LruCache<TKey, TValue>::put(const TKey& key, const TValue& value) {
|
||||
if (mMaxCapacity != kUnlimitedCapacity && size() >= mMaxCapacity) {
|
||||
removeOldest();
|
||||
}
|
||||
|
||||
hash_t hash = hash_type(key);
|
||||
ssize_t index = mTable->find(-1, hash, key);
|
||||
if (index >= 0) {
|
||||
return false;
|
||||
}
|
||||
if (!mTable->hasMoreRoom()) {
|
||||
rehash(mTable->capacity() * 2);
|
||||
}
|
||||
|
||||
// Would it be better to initialize a blank entry and assign key, value?
|
||||
Entry initEntry(key, value);
|
||||
index = mTable->add(hash, initEntry);
|
||||
Entry& entry = mTable->editEntryAt(index);
|
||||
attachToCache(entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TKey, typename TValue>
|
||||
bool LruCache<TKey, TValue>::remove(const TKey& key) {
|
||||
hash_t hash = hash_type(key);
|
||||
ssize_t index = mTable->find(-1, hash, key);
|
||||
if (index < 0) {
|
||||
return false;
|
||||
}
|
||||
Entry& entry = mTable->editEntryAt(index);
|
||||
if (mListener) {
|
||||
(*mListener)(entry.key, entry.value);
|
||||
}
|
||||
detachFromCache(entry);
|
||||
mTable->removeAt(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TKey, typename TValue>
|
||||
bool LruCache<TKey, TValue>::removeOldest() {
|
||||
if (mOldest != NULL) {
|
||||
return remove(mOldest->key);
|
||||
// TODO: should probably abort if false
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename TKey, typename TValue>
|
||||
const TValue& LruCache<TKey, TValue>::peekOldestValue() {
|
||||
if (mOldest) {
|
||||
return mOldest->value;
|
||||
}
|
||||
return mNullValue;
|
||||
}
|
||||
|
||||
template <typename TKey, typename TValue>
|
||||
void LruCache<TKey, TValue>::clear() {
|
||||
if (mListener) {
|
||||
for (Entry* p = mOldest; p != NULL; p = p->child) {
|
||||
(*mListener)(p->key, p->value);
|
||||
}
|
||||
}
|
||||
mYoungest = NULL;
|
||||
mOldest = NULL;
|
||||
mTable->clear();
|
||||
}
|
||||
|
||||
template <typename TKey, typename TValue>
|
||||
void LruCache<TKey, TValue>::attachToCache(Entry& entry) {
|
||||
if (mYoungest == NULL) {
|
||||
mYoungest = mOldest = &entry;
|
||||
} else {
|
||||
entry.parent = mYoungest;
|
||||
mYoungest->child = &entry;
|
||||
mYoungest = &entry;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TKey, typename TValue>
|
||||
void LruCache<TKey, TValue>::detachFromCache(Entry& entry) {
|
||||
if (entry.parent != NULL) {
|
||||
entry.parent->child = entry.child;
|
||||
} else {
|
||||
mOldest = entry.child;
|
||||
}
|
||||
if (entry.child != NULL) {
|
||||
entry.child->parent = entry.parent;
|
||||
} else {
|
||||
mYoungest = entry.parent;
|
||||
}
|
||||
|
||||
entry.parent = NULL;
|
||||
entry.child = NULL;
|
||||
}
|
||||
|
||||
template <typename TKey, typename TValue>
|
||||
void LruCache<TKey, TValue>::rehash(size_t newCapacity) {
|
||||
UniquePtr<BasicHashtable<TKey, Entry> > oldTable(mTable.release());
|
||||
Entry* oldest = mOldest;
|
||||
|
||||
mOldest = NULL;
|
||||
mYoungest = NULL;
|
||||
mTable.reset(new BasicHashtable<TKey, Entry>(newCapacity));
|
||||
for (Entry* p = oldest; p != NULL; p = p->child) {
|
||||
put(p->key, p->value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // ANDROID_UTILS_LRU_CACHE_H
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _LIBS_UTILS_MUTEX_H
|
||||
#define _LIBS_UTILS_MUTEX_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/Timers.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
namespace android {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class Condition;
|
||||
|
||||
/*
|
||||
* Simple mutex class. The implementation is system-dependent.
|
||||
*
|
||||
* The mutex must be unlocked by the thread that locked it. They are not
|
||||
* recursive, i.e. the same thread can't lock it multiple times.
|
||||
*/
|
||||
class Mutex {
|
||||
public:
|
||||
enum {
|
||||
PRIVATE = 0,
|
||||
SHARED = 1
|
||||
};
|
||||
|
||||
Mutex();
|
||||
Mutex(const char* name);
|
||||
Mutex(int type, const char* name = NULL);
|
||||
~Mutex();
|
||||
|
||||
// lock or unlock the mutex
|
||||
status_t lock();
|
||||
void unlock();
|
||||
|
||||
// lock if possible; returns 0 on success, error otherwise
|
||||
status_t tryLock();
|
||||
|
||||
#if HAVE_ANDROID_OS
|
||||
// lock the mutex, but don't wait longer than timeoutMilliseconds.
|
||||
// Returns 0 on success, TIMED_OUT for failure due to timeout expiration.
|
||||
//
|
||||
// OSX doesn't have pthread_mutex_timedlock() or equivalent. To keep
|
||||
// capabilities consistent across host OSes, this method is only available
|
||||
// when building Android binaries.
|
||||
status_t timedLock(nsecs_t timeoutMilliseconds);
|
||||
#endif
|
||||
|
||||
// Manages the mutex automatically. It'll be locked when Autolock is
|
||||
// constructed and released when Autolock goes out of scope.
|
||||
class Autolock {
|
||||
public:
|
||||
inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); }
|
||||
inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); }
|
||||
inline ~Autolock() { mLock.unlock(); }
|
||||
private:
|
||||
Mutex& mLock;
|
||||
};
|
||||
|
||||
private:
|
||||
friend class Condition;
|
||||
|
||||
// A mutex cannot be copied
|
||||
Mutex(const Mutex&);
|
||||
Mutex& operator = (const Mutex&);
|
||||
|
||||
#if !defined(_WIN32)
|
||||
pthread_mutex_t mMutex;
|
||||
#else
|
||||
void _init();
|
||||
void* mState;
|
||||
#endif
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#if !defined(_WIN32)
|
||||
|
||||
inline Mutex::Mutex() {
|
||||
pthread_mutex_init(&mMutex, NULL);
|
||||
}
|
||||
inline Mutex::Mutex(__attribute__((unused)) const char* name) {
|
||||
pthread_mutex_init(&mMutex, NULL);
|
||||
}
|
||||
inline Mutex::Mutex(int type, __attribute__((unused)) const char* name) {
|
||||
if (type == SHARED) {
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
|
||||
pthread_mutex_init(&mMutex, &attr);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
} else {
|
||||
pthread_mutex_init(&mMutex, NULL);
|
||||
}
|
||||
}
|
||||
inline Mutex::~Mutex() {
|
||||
pthread_mutex_destroy(&mMutex);
|
||||
}
|
||||
inline status_t Mutex::lock() {
|
||||
return -pthread_mutex_lock(&mMutex);
|
||||
}
|
||||
inline void Mutex::unlock() {
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
}
|
||||
inline status_t Mutex::tryLock() {
|
||||
return -pthread_mutex_trylock(&mMutex);
|
||||
}
|
||||
#if HAVE_ANDROID_OS
|
||||
inline status_t Mutex::timedLock(nsecs_t timeoutNs) {
|
||||
const struct timespec ts = {
|
||||
/* .tv_sec = */ static_cast<time_t>(timeoutNs / 1000000000),
|
||||
/* .tv_nsec = */ static_cast<long>(timeoutNs % 1000000000),
|
||||
};
|
||||
return -pthread_mutex_timedlock(&mMutex, &ts);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !defined(_WIN32)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Automatic mutex. Declare one of these at the top of a function.
|
||||
* When the function returns, it will go out of scope, and release the
|
||||
* mutex.
|
||||
*/
|
||||
|
||||
typedef Mutex::Autolock AutoMutex;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
}; // namespace android
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // _LIBS_UTILS_MUTEX_H
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_NATIVE_HANDLE_H
|
||||
#define ANDROID_NATIVE_HANDLE_H
|
||||
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/StrongPointer.h>
|
||||
|
||||
typedef struct native_handle native_handle_t;
|
||||
|
||||
namespace android {
|
||||
|
||||
class NativeHandle: public LightRefBase<NativeHandle> {
|
||||
public:
|
||||
// Create a refcounted wrapper around a native_handle_t, and declare
|
||||
// whether the wrapper owns the handle (so that it should clean up the
|
||||
// handle upon destruction) or not.
|
||||
// If handle is NULL, no NativeHandle will be created.
|
||||
static sp<NativeHandle> create(native_handle_t* handle, bool ownsHandle);
|
||||
|
||||
const native_handle_t* handle() const {
|
||||
return mHandle;
|
||||
}
|
||||
|
||||
private:
|
||||
// for access to the destructor
|
||||
friend class LightRefBase<NativeHandle>;
|
||||
|
||||
NativeHandle(native_handle_t* handle, bool ownsHandle);
|
||||
virtual ~NativeHandle();
|
||||
|
||||
native_handle_t* mHandle;
|
||||
bool mOwnsHandle;
|
||||
|
||||
// non-copyable
|
||||
NativeHandle(const NativeHandle&);
|
||||
NativeHandle& operator=(const NativeHandle&);
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_NATIVE_HANDLE_H
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_PRINTER_H
|
||||
#define ANDROID_PRINTER_H
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
// Interface for printing to an arbitrary data stream
|
||||
class Printer {
|
||||
public:
|
||||
// Print a new line specified by 'string'. \n is appended automatically.
|
||||
// -- Assumes that the string has no new line in it.
|
||||
virtual void printLine(const char* string = "") = 0;
|
||||
|
||||
// Print a new line specified by the format string. \n is appended automatically.
|
||||
// -- Assumes that the resulting string has no new line in it.
|
||||
virtual void printFormatLine(const char* format, ...) __attribute__((format (printf, 2, 3)));
|
||||
|
||||
protected:
|
||||
Printer();
|
||||
virtual ~Printer();
|
||||
}; // class Printer
|
||||
|
||||
// Print to logcat
|
||||
class LogPrinter : public Printer {
|
||||
public:
|
||||
// Create a printer using the specified logcat and log priority
|
||||
// - Unless ignoreBlankLines is false, print blank lines to logcat
|
||||
// (Note that the default ALOG behavior is to ignore blank lines)
|
||||
LogPrinter(const char* logtag,
|
||||
android_LogPriority priority = ANDROID_LOG_DEBUG,
|
||||
const char* prefix = 0,
|
||||
bool ignoreBlankLines = false);
|
||||
|
||||
// Print the specified line to logcat. No \n at the end is necessary.
|
||||
virtual void printLine(const char* string);
|
||||
|
||||
private:
|
||||
void printRaw(const char* string);
|
||||
|
||||
const char* mLogTag;
|
||||
android_LogPriority mPriority;
|
||||
const char* mPrefix;
|
||||
bool mIgnoreBlankLines;
|
||||
}; // class LogPrinter
|
||||
|
||||
// Print to a file descriptor
|
||||
class FdPrinter : public Printer {
|
||||
public:
|
||||
// Create a printer using the specified file descriptor.
|
||||
// - Each line will be prefixed with 'indent' number of blank spaces.
|
||||
// - In addition, each line will be prefixed with the 'prefix' string.
|
||||
FdPrinter(int fd, unsigned int indent = 0, const char* prefix = 0);
|
||||
|
||||
// Print the specified line to the file descriptor. \n is appended automatically.
|
||||
virtual void printLine(const char* string);
|
||||
|
||||
private:
|
||||
enum {
|
||||
MAX_FORMAT_STRING = 20,
|
||||
};
|
||||
|
||||
int mFd;
|
||||
unsigned int mIndent;
|
||||
const char* mPrefix;
|
||||
char mFormatString[MAX_FORMAT_STRING];
|
||||
}; // class FdPrinter
|
||||
|
||||
class String8;
|
||||
|
||||
// Print to a String8
|
||||
class String8Printer : public Printer {
|
||||
public:
|
||||
// Create a printer using the specified String8 as the target.
|
||||
// - In addition, each line will be prefixed with the 'prefix' string.
|
||||
// - target's memory lifetime must be a superset of this String8Printer.
|
||||
String8Printer(String8* target, const char* prefix = 0);
|
||||
|
||||
// Append the specified line to the String8. \n is appended automatically.
|
||||
virtual void printLine(const char* string);
|
||||
|
||||
private:
|
||||
String8* mTarget;
|
||||
const char* mPrefix;
|
||||
}; // class String8Printer
|
||||
|
||||
// Print to an existing Printer by adding a prefix to each line
|
||||
class PrefixPrinter : public Printer {
|
||||
public:
|
||||
// Create a printer using the specified printer as the target.
|
||||
PrefixPrinter(Printer& printer, const char* prefix);
|
||||
|
||||
// Print the line (prefixed with prefix) using the printer.
|
||||
virtual void printLine(const char* string);
|
||||
|
||||
private:
|
||||
Printer& mPrinter;
|
||||
const char* mPrefix;
|
||||
};
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#endif // ANDROID_PRINTER_H
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_PROCESS_CALLSTACK_H
|
||||
#define ANDROID_PROCESS_CALLSTACK_H
|
||||
|
||||
#include <utils/CallStack.h>
|
||||
#include <android/log.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
#include <utils/String8.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
class Printer;
|
||||
|
||||
// Collect/print the call stack (function, file, line) traces for all threads in a process.
|
||||
class ProcessCallStack {
|
||||
public:
|
||||
// Create an empty call stack. No-op.
|
||||
ProcessCallStack();
|
||||
// Copy the existing process callstack (no other side effects).
|
||||
ProcessCallStack(const ProcessCallStack& rhs);
|
||||
~ProcessCallStack();
|
||||
|
||||
// Immediately collect the stack traces for all threads.
|
||||
void update();
|
||||
|
||||
// Print all stack traces to the log using the supplied logtag.
|
||||
void log(const char* logtag, android_LogPriority priority = ANDROID_LOG_DEBUG,
|
||||
const char* prefix = 0) const;
|
||||
|
||||
// Dump all stack traces to the specified file descriptor.
|
||||
void dump(int fd, int indent = 0, const char* prefix = 0) const;
|
||||
|
||||
// Return a string (possibly very long) containing all the stack traces.
|
||||
String8 toString(const char* prefix = 0) const;
|
||||
|
||||
// Dump a serialized representation of all the stack traces to the specified printer.
|
||||
void print(Printer& printer) const;
|
||||
|
||||
// Get the number of threads whose stack traces were collected.
|
||||
size_t size() const;
|
||||
|
||||
private:
|
||||
void printInternal(Printer& printer, Printer& csPrinter) const;
|
||||
|
||||
// Reset the process's stack frames and metadata.
|
||||
void clear();
|
||||
|
||||
struct ThreadInfo {
|
||||
CallStack callStack;
|
||||
String8 threadName;
|
||||
};
|
||||
|
||||
// tid -> ThreadInfo
|
||||
KeyedVector<pid_t, ThreadInfo> mThreadMap;
|
||||
// Time that update() was last called
|
||||
struct tm mTimeUpdated;
|
||||
};
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#endif // ANDROID_PROCESS_CALLSTACK_H
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _UTILS_PROPERTY_MAP_H
|
||||
#define _UTILS_PROPERTY_MAP_H
|
||||
|
||||
#include <utils/KeyedVector.h>
|
||||
#include <utils/String8.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/Tokenizer.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
/*
|
||||
* Provides a mechanism for passing around string-based property key / value pairs
|
||||
* and loading them from property files.
|
||||
*
|
||||
* The property files have the following simple structure:
|
||||
*
|
||||
* # Comment
|
||||
* key = value
|
||||
*
|
||||
* Keys and values are any sequence of printable ASCII characters.
|
||||
* The '=' separates the key from the value.
|
||||
* The key and value may not contain whitespace.
|
||||
*
|
||||
* The '\' character is reserved for escape sequences and is not currently supported.
|
||||
* The '"" character is reserved for quoting and is not currently supported.
|
||||
* Files that contain the '\' or '"' character will fail to parse.
|
||||
*
|
||||
* The file must not contain duplicate keys.
|
||||
*
|
||||
* TODO Support escape sequences and quoted values when needed.
|
||||
*/
|
||||
class PropertyMap {
|
||||
public:
|
||||
/* Creates an empty property map. */
|
||||
PropertyMap();
|
||||
~PropertyMap();
|
||||
|
||||
/* Clears the property map. */
|
||||
void clear();
|
||||
|
||||
/* Adds a property.
|
||||
* Replaces the property with the same key if it is already present.
|
||||
*/
|
||||
void addProperty(const String8& key, const String8& value);
|
||||
|
||||
/* Returns true if the property map contains the specified key. */
|
||||
bool hasProperty(const String8& key) const;
|
||||
|
||||
/* Gets the value of a property and parses it.
|
||||
* Returns true and sets outValue if the key was found and its value was parsed successfully.
|
||||
* Otherwise returns false and does not modify outValue. (Also logs a warning.)
|
||||
*/
|
||||
bool tryGetProperty(const String8& key, String8& outValue) const;
|
||||
bool tryGetProperty(const String8& key, bool& outValue) const;
|
||||
bool tryGetProperty(const String8& key, int32_t& outValue) const;
|
||||
bool tryGetProperty(const String8& key, float& outValue) const;
|
||||
|
||||
/* Adds all values from the specified property map. */
|
||||
void addAll(const PropertyMap* map);
|
||||
|
||||
/* Gets the underlying property map. */
|
||||
inline const KeyedVector<String8, String8>& getProperties() const { return mProperties; }
|
||||
|
||||
/* Loads a property map from a file. */
|
||||
static status_t load(const String8& filename, PropertyMap** outMap);
|
||||
|
||||
private:
|
||||
class Parser {
|
||||
PropertyMap* mMap;
|
||||
Tokenizer* mTokenizer;
|
||||
|
||||
public:
|
||||
Parser(PropertyMap* map, Tokenizer* tokenizer);
|
||||
~Parser();
|
||||
status_t parse();
|
||||
|
||||
private:
|
||||
status_t parseType();
|
||||
status_t parseKey();
|
||||
status_t parseKeyProperty();
|
||||
status_t parseModifier(const String8& token, int32_t* outMetaState);
|
||||
status_t parseCharacterLiteral(char16_t* outCharacter);
|
||||
};
|
||||
|
||||
KeyedVector<String8, String8> mProperties;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // _UTILS_PROPERTY_MAP_H
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _LIBS_UTILS_RWLOCK_H
|
||||
#define _LIBS_UTILS_RWLOCK_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/ThreadDefs.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
namespace android {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#if !defined(_WIN32)
|
||||
|
||||
/*
|
||||
* Simple mutex class. The implementation is system-dependent.
|
||||
*
|
||||
* The mutex must be unlocked by the thread that locked it. They are not
|
||||
* recursive, i.e. the same thread can't lock it multiple times.
|
||||
*/
|
||||
class RWLock {
|
||||
public:
|
||||
enum {
|
||||
PRIVATE = 0,
|
||||
SHARED = 1
|
||||
};
|
||||
|
||||
RWLock();
|
||||
RWLock(const char* name);
|
||||
RWLock(int type, const char* name = NULL);
|
||||
~RWLock();
|
||||
|
||||
status_t readLock();
|
||||
status_t tryReadLock();
|
||||
status_t writeLock();
|
||||
status_t tryWriteLock();
|
||||
void unlock();
|
||||
|
||||
class AutoRLock {
|
||||
public:
|
||||
inline AutoRLock(RWLock& rwlock) : mLock(rwlock) { mLock.readLock(); }
|
||||
inline ~AutoRLock() { mLock.unlock(); }
|
||||
private:
|
||||
RWLock& mLock;
|
||||
};
|
||||
|
||||
class AutoWLock {
|
||||
public:
|
||||
inline AutoWLock(RWLock& rwlock) : mLock(rwlock) { mLock.writeLock(); }
|
||||
inline ~AutoWLock() { mLock.unlock(); }
|
||||
private:
|
||||
RWLock& mLock;
|
||||
};
|
||||
|
||||
private:
|
||||
// A RWLock cannot be copied
|
||||
RWLock(const RWLock&);
|
||||
RWLock& operator = (const RWLock&);
|
||||
|
||||
pthread_rwlock_t mRWLock;
|
||||
};
|
||||
|
||||
inline RWLock::RWLock() {
|
||||
pthread_rwlock_init(&mRWLock, NULL);
|
||||
}
|
||||
inline RWLock::RWLock(__attribute__((unused)) const char* name) {
|
||||
pthread_rwlock_init(&mRWLock, NULL);
|
||||
}
|
||||
inline RWLock::RWLock(int type, __attribute__((unused)) const char* name) {
|
||||
if (type == SHARED) {
|
||||
pthread_rwlockattr_t attr;
|
||||
pthread_rwlockattr_init(&attr);
|
||||
pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
|
||||
pthread_rwlock_init(&mRWLock, &attr);
|
||||
pthread_rwlockattr_destroy(&attr);
|
||||
} else {
|
||||
pthread_rwlock_init(&mRWLock, NULL);
|
||||
}
|
||||
}
|
||||
inline RWLock::~RWLock() {
|
||||
pthread_rwlock_destroy(&mRWLock);
|
||||
}
|
||||
inline status_t RWLock::readLock() {
|
||||
return -pthread_rwlock_rdlock(&mRWLock);
|
||||
}
|
||||
inline status_t RWLock::tryReadLock() {
|
||||
return -pthread_rwlock_tryrdlock(&mRWLock);
|
||||
}
|
||||
inline status_t RWLock::writeLock() {
|
||||
return -pthread_rwlock_wrlock(&mRWLock);
|
||||
}
|
||||
inline status_t RWLock::tryWriteLock() {
|
||||
return -pthread_rwlock_trywrlock(&mRWLock);
|
||||
}
|
||||
inline void RWLock::unlock() {
|
||||
pthread_rwlock_unlock(&mRWLock);
|
||||
}
|
||||
|
||||
#endif // !defined(_WIN32)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
}; // namespace android
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // _LIBS_UTILS_RWLOCK_H
|
||||
@@ -0,0 +1,555 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_REF_BASE_H
|
||||
#define ANDROID_REF_BASE_H
|
||||
|
||||
#include <cutils/atomic.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <utils/StrongPointer.h>
|
||||
#include <utils/TypeHelpers.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
namespace android {
|
||||
|
||||
class TextOutput;
|
||||
TextOutput& printWeakPointer(TextOutput& to, const void* val);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#define COMPARE_WEAK(_op_) \
|
||||
inline bool operator _op_ (const sp<T>& o) const { \
|
||||
return m_ptr _op_ o.m_ptr; \
|
||||
} \
|
||||
inline bool operator _op_ (const T* o) const { \
|
||||
return m_ptr _op_ o; \
|
||||
} \
|
||||
template<typename U> \
|
||||
inline bool operator _op_ (const sp<U>& o) const { \
|
||||
return m_ptr _op_ o.m_ptr; \
|
||||
} \
|
||||
template<typename U> \
|
||||
inline bool operator _op_ (const U* o) const { \
|
||||
return m_ptr _op_ o; \
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class ReferenceRenamer {
|
||||
protected:
|
||||
// destructor is purposedly not virtual so we avoid code overhead from
|
||||
// subclasses; we have to make it protected to guarantee that it
|
||||
// cannot be called from this base class (and to make strict compilers
|
||||
// happy).
|
||||
~ReferenceRenamer() { }
|
||||
public:
|
||||
virtual void operator()(size_t i) const = 0;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class RefBase
|
||||
{
|
||||
public:
|
||||
void incStrong(const void* id) const;
|
||||
void decStrong(const void* id) const;
|
||||
|
||||
void forceIncStrong(const void* id) const;
|
||||
|
||||
//! DEBUGGING ONLY: Get current strong ref count.
|
||||
int32_t getStrongCount() const;
|
||||
|
||||
class weakref_type
|
||||
{
|
||||
public:
|
||||
RefBase* refBase() const;
|
||||
|
||||
void incWeak(const void* id);
|
||||
void decWeak(const void* id);
|
||||
|
||||
// acquires a strong reference if there is already one.
|
||||
bool attemptIncStrong(const void* id);
|
||||
|
||||
// acquires a weak reference if there is already one.
|
||||
// This is not always safe. see ProcessState.cpp and BpBinder.cpp
|
||||
// for proper use.
|
||||
bool attemptIncWeak(const void* id);
|
||||
|
||||
//! DEBUGGING ONLY: Get current weak ref count.
|
||||
int32_t getWeakCount() const;
|
||||
|
||||
//! DEBUGGING ONLY: Print references held on object.
|
||||
void printRefs() const;
|
||||
|
||||
//! DEBUGGING ONLY: Enable tracking for this object.
|
||||
// enable -- enable/disable tracking
|
||||
// retain -- when tracking is enable, if true, then we save a stack trace
|
||||
// for each reference and dereference; when retain == false, we
|
||||
// match up references and dereferences and keep only the
|
||||
// outstanding ones.
|
||||
|
||||
void trackMe(bool enable, bool retain);
|
||||
};
|
||||
|
||||
weakref_type* createWeak(const void* id) const;
|
||||
|
||||
weakref_type* getWeakRefs() const;
|
||||
|
||||
//! DEBUGGING ONLY: Print references held on object.
|
||||
inline void printRefs() const { getWeakRefs()->printRefs(); }
|
||||
|
||||
//! DEBUGGING ONLY: Enable tracking of object.
|
||||
inline void trackMe(bool enable, bool retain)
|
||||
{
|
||||
getWeakRefs()->trackMe(enable, retain);
|
||||
}
|
||||
|
||||
typedef RefBase basetype;
|
||||
|
||||
protected:
|
||||
RefBase();
|
||||
virtual ~RefBase();
|
||||
|
||||
//! Flags for extendObjectLifetime()
|
||||
enum {
|
||||
OBJECT_LIFETIME_STRONG = 0x0000,
|
||||
OBJECT_LIFETIME_WEAK = 0x0001,
|
||||
OBJECT_LIFETIME_MASK = 0x0001
|
||||
};
|
||||
|
||||
void extendObjectLifetime(int32_t mode);
|
||||
|
||||
//! Flags for onIncStrongAttempted()
|
||||
enum {
|
||||
FIRST_INC_STRONG = 0x0001
|
||||
};
|
||||
|
||||
virtual void onFirstRef();
|
||||
virtual void onLastStrongRef(const void* id);
|
||||
virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
|
||||
virtual void onLastWeakRef(const void* id);
|
||||
|
||||
private:
|
||||
friend class weakref_type;
|
||||
class weakref_impl;
|
||||
|
||||
RefBase(const RefBase& o);
|
||||
RefBase& operator=(const RefBase& o);
|
||||
|
||||
private:
|
||||
friend class ReferenceMover;
|
||||
|
||||
static void renameRefs(size_t n, const ReferenceRenamer& renamer);
|
||||
|
||||
static void renameRefId(weakref_type* ref,
|
||||
const void* old_id, const void* new_id);
|
||||
|
||||
static void renameRefId(RefBase* ref,
|
||||
const void* old_id, const void* new_id);
|
||||
|
||||
weakref_impl* const mRefs;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
class LightRefBase
|
||||
{
|
||||
public:
|
||||
inline LightRefBase() : mCount(0) { }
|
||||
inline void incStrong(__attribute__((unused)) const void* id) const {
|
||||
android_atomic_inc(&mCount);
|
||||
}
|
||||
inline void decStrong(__attribute__((unused)) const void* id) const {
|
||||
if (android_atomic_dec(&mCount) == 1) {
|
||||
delete static_cast<const T*>(this);
|
||||
}
|
||||
}
|
||||
//! DEBUGGING ONLY: Get current strong ref count.
|
||||
inline int32_t getStrongCount() const {
|
||||
return mCount;
|
||||
}
|
||||
|
||||
typedef LightRefBase<T> basetype;
|
||||
|
||||
protected:
|
||||
inline ~LightRefBase() { }
|
||||
|
||||
private:
|
||||
friend class ReferenceMover;
|
||||
inline static void renameRefs(size_t n, const ReferenceRenamer& renamer) { }
|
||||
inline static void renameRefId(T* ref,
|
||||
const void* old_id, const void* new_id) { }
|
||||
|
||||
private:
|
||||
mutable volatile int32_t mCount;
|
||||
};
|
||||
|
||||
// This is a wrapper around LightRefBase that simply enforces a virtual
|
||||
// destructor to eliminate the template requirement of LightRefBase
|
||||
class VirtualLightRefBase : public LightRefBase<VirtualLightRefBase> {
|
||||
public:
|
||||
virtual ~VirtualLightRefBase() {}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
class wp
|
||||
{
|
||||
public:
|
||||
typedef typename RefBase::weakref_type weakref_type;
|
||||
|
||||
inline wp() : m_ptr(0) { }
|
||||
|
||||
wp(T* other);
|
||||
wp(const wp<T>& other);
|
||||
wp(const sp<T>& other);
|
||||
template<typename U> wp(U* other);
|
||||
template<typename U> wp(const sp<U>& other);
|
||||
template<typename U> wp(const wp<U>& other);
|
||||
|
||||
~wp();
|
||||
|
||||
// Assignment
|
||||
|
||||
wp& operator = (T* other);
|
||||
wp& operator = (const wp<T>& other);
|
||||
wp& operator = (const sp<T>& other);
|
||||
|
||||
template<typename U> wp& operator = (U* other);
|
||||
template<typename U> wp& operator = (const wp<U>& other);
|
||||
template<typename U> wp& operator = (const sp<U>& other);
|
||||
|
||||
void set_object_and_refs(T* other, weakref_type* refs);
|
||||
|
||||
// promotion to sp
|
||||
|
||||
sp<T> promote() const;
|
||||
|
||||
// Reset
|
||||
|
||||
void clear();
|
||||
|
||||
// Accessors
|
||||
|
||||
inline weakref_type* get_refs() const { return m_refs; }
|
||||
|
||||
inline T* unsafe_get() const { return m_ptr; }
|
||||
|
||||
// Operators
|
||||
|
||||
COMPARE_WEAK(==)
|
||||
COMPARE_WEAK(!=)
|
||||
COMPARE_WEAK(>)
|
||||
COMPARE_WEAK(<)
|
||||
COMPARE_WEAK(<=)
|
||||
COMPARE_WEAK(>=)
|
||||
|
||||
inline bool operator == (const wp<T>& o) const {
|
||||
return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);
|
||||
}
|
||||
template<typename U>
|
||||
inline bool operator == (const wp<U>& o) const {
|
||||
return m_ptr == o.m_ptr;
|
||||
}
|
||||
|
||||
inline bool operator > (const wp<T>& o) const {
|
||||
return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
|
||||
}
|
||||
template<typename U>
|
||||
inline bool operator > (const wp<U>& o) const {
|
||||
return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
|
||||
}
|
||||
|
||||
inline bool operator < (const wp<T>& o) const {
|
||||
return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
|
||||
}
|
||||
template<typename U>
|
||||
inline bool operator < (const wp<U>& o) const {
|
||||
return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
|
||||
}
|
||||
inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; }
|
||||
template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }
|
||||
inline bool operator <= (const wp<T>& o) const { return !operator > (o); }
|
||||
template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }
|
||||
inline bool operator >= (const wp<T>& o) const { return !operator < (o); }
|
||||
template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }
|
||||
|
||||
private:
|
||||
template<typename Y> friend class sp;
|
||||
template<typename Y> friend class wp;
|
||||
|
||||
T* m_ptr;
|
||||
weakref_type* m_refs;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
TextOutput& operator<<(TextOutput& to, const wp<T>& val);
|
||||
|
||||
#undef COMPARE_WEAK
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// No user serviceable parts below here.
|
||||
|
||||
template<typename T>
|
||||
wp<T>::wp(T* other)
|
||||
: m_ptr(other)
|
||||
{
|
||||
if (other) m_refs = other->createWeak(this);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
wp<T>::wp(const wp<T>& other)
|
||||
: m_ptr(other.m_ptr), m_refs(other.m_refs)
|
||||
{
|
||||
if (m_ptr) m_refs->incWeak(this);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
wp<T>::wp(const sp<T>& other)
|
||||
: m_ptr(other.m_ptr)
|
||||
{
|
||||
if (m_ptr) {
|
||||
m_refs = m_ptr->createWeak(this);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> template<typename U>
|
||||
wp<T>::wp(U* other)
|
||||
: m_ptr(other)
|
||||
{
|
||||
if (other) m_refs = other->createWeak(this);
|
||||
}
|
||||
|
||||
template<typename T> template<typename U>
|
||||
wp<T>::wp(const wp<U>& other)
|
||||
: m_ptr(other.m_ptr)
|
||||
{
|
||||
if (m_ptr) {
|
||||
m_refs = other.m_refs;
|
||||
m_refs->incWeak(this);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> template<typename U>
|
||||
wp<T>::wp(const sp<U>& other)
|
||||
: m_ptr(other.m_ptr)
|
||||
{
|
||||
if (m_ptr) {
|
||||
m_refs = m_ptr->createWeak(this);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
wp<T>::~wp()
|
||||
{
|
||||
if (m_ptr) m_refs->decWeak(this);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
wp<T>& wp<T>::operator = (T* other)
|
||||
{
|
||||
weakref_type* newRefs =
|
||||
other ? other->createWeak(this) : 0;
|
||||
if (m_ptr) m_refs->decWeak(this);
|
||||
m_ptr = other;
|
||||
m_refs = newRefs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
wp<T>& wp<T>::operator = (const wp<T>& other)
|
||||
{
|
||||
weakref_type* otherRefs(other.m_refs);
|
||||
T* otherPtr(other.m_ptr);
|
||||
if (otherPtr) otherRefs->incWeak(this);
|
||||
if (m_ptr) m_refs->decWeak(this);
|
||||
m_ptr = otherPtr;
|
||||
m_refs = otherRefs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
wp<T>& wp<T>::operator = (const sp<T>& other)
|
||||
{
|
||||
weakref_type* newRefs =
|
||||
other != NULL ? other->createWeak(this) : 0;
|
||||
T* otherPtr(other.m_ptr);
|
||||
if (m_ptr) m_refs->decWeak(this);
|
||||
m_ptr = otherPtr;
|
||||
m_refs = newRefs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T> template<typename U>
|
||||
wp<T>& wp<T>::operator = (U* other)
|
||||
{
|
||||
weakref_type* newRefs =
|
||||
other ? other->createWeak(this) : 0;
|
||||
if (m_ptr) m_refs->decWeak(this);
|
||||
m_ptr = other;
|
||||
m_refs = newRefs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T> template<typename U>
|
||||
wp<T>& wp<T>::operator = (const wp<U>& other)
|
||||
{
|
||||
weakref_type* otherRefs(other.m_refs);
|
||||
U* otherPtr(other.m_ptr);
|
||||
if (otherPtr) otherRefs->incWeak(this);
|
||||
if (m_ptr) m_refs->decWeak(this);
|
||||
m_ptr = otherPtr;
|
||||
m_refs = otherRefs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T> template<typename U>
|
||||
wp<T>& wp<T>::operator = (const sp<U>& other)
|
||||
{
|
||||
weakref_type* newRefs =
|
||||
other != NULL ? other->createWeak(this) : 0;
|
||||
U* otherPtr(other.m_ptr);
|
||||
if (m_ptr) m_refs->decWeak(this);
|
||||
m_ptr = otherPtr;
|
||||
m_refs = newRefs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void wp<T>::set_object_and_refs(T* other, weakref_type* refs)
|
||||
{
|
||||
if (other) refs->incWeak(this);
|
||||
if (m_ptr) m_refs->decWeak(this);
|
||||
m_ptr = other;
|
||||
m_refs = refs;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
sp<T> wp<T>::promote() const
|
||||
{
|
||||
sp<T> result;
|
||||
if (m_ptr && m_refs->attemptIncStrong(&result)) {
|
||||
result.set_pointer(m_ptr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void wp<T>::clear()
|
||||
{
|
||||
if (m_ptr) {
|
||||
m_refs->decWeak(this);
|
||||
m_ptr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline TextOutput& operator<<(TextOutput& to, const wp<T>& val)
|
||||
{
|
||||
return printWeakPointer(to, val.unsafe_get());
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// this class just serves as a namespace so TYPE::moveReferences can stay
|
||||
// private.
|
||||
class ReferenceMover {
|
||||
public:
|
||||
// it would be nice if we could make sure no extra code is generated
|
||||
// for sp<TYPE> or wp<TYPE> when TYPE is a descendant of RefBase:
|
||||
// Using a sp<RefBase> override doesn't work; it's a bit like we wanted
|
||||
// a template<typename TYPE inherits RefBase> template...
|
||||
|
||||
template<typename TYPE> static inline
|
||||
void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
|
||||
|
||||
class Renamer : public ReferenceRenamer {
|
||||
sp<TYPE>* d;
|
||||
sp<TYPE> const* s;
|
||||
virtual void operator()(size_t i) const {
|
||||
// The id are known to be the sp<>'s this pointer
|
||||
TYPE::renameRefId(d[i].get(), &s[i], &d[i]);
|
||||
}
|
||||
public:
|
||||
Renamer(sp<TYPE>* d, sp<TYPE> const* s) : d(d), s(s) { }
|
||||
virtual ~Renamer() { }
|
||||
};
|
||||
|
||||
memmove(d, s, n*sizeof(sp<TYPE>));
|
||||
TYPE::renameRefs(n, Renamer(d, s));
|
||||
}
|
||||
|
||||
|
||||
template<typename TYPE> static inline
|
||||
void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
|
||||
|
||||
class Renamer : public ReferenceRenamer {
|
||||
wp<TYPE>* d;
|
||||
wp<TYPE> const* s;
|
||||
virtual void operator()(size_t i) const {
|
||||
// The id are known to be the wp<>'s this pointer
|
||||
TYPE::renameRefId(d[i].get_refs(), &s[i], &d[i]);
|
||||
}
|
||||
public:
|
||||
Renamer(wp<TYPE>* d, wp<TYPE> const* s) : d(d), s(s) { }
|
||||
virtual ~Renamer() { }
|
||||
};
|
||||
|
||||
memmove(d, s, n*sizeof(wp<TYPE>));
|
||||
TYPE::renameRefs(n, Renamer(d, s));
|
||||
}
|
||||
};
|
||||
|
||||
// specialization for moving sp<> and wp<> types.
|
||||
// these are used by the [Sorted|Keyed]Vector<> implementations
|
||||
// sp<> and wp<> need to be handled specially, because they do not
|
||||
// have trivial copy operation in the general case (see RefBase.cpp
|
||||
// when DEBUG ops are enabled), but can be implemented very
|
||||
// efficiently in most cases.
|
||||
|
||||
template<typename TYPE> inline
|
||||
void move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
|
||||
ReferenceMover::move_references(d, s, n);
|
||||
}
|
||||
|
||||
template<typename TYPE> inline
|
||||
void move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
|
||||
ReferenceMover::move_references(d, s, n);
|
||||
}
|
||||
|
||||
template<typename TYPE> inline
|
||||
void move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
|
||||
ReferenceMover::move_references(d, s, n);
|
||||
}
|
||||
|
||||
template<typename TYPE> inline
|
||||
void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
|
||||
ReferenceMover::move_references(d, s, n);
|
||||
}
|
||||
|
||||
|
||||
}; // namespace android
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // ANDROID_REF_BASE_H
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_SHARED_BUFFER_H
|
||||
#define ANDROID_SHARED_BUFFER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
namespace android {
|
||||
|
||||
class SharedBuffer
|
||||
{
|
||||
public:
|
||||
|
||||
/* flags to use with release() */
|
||||
enum {
|
||||
eKeepStorage = 0x00000001
|
||||
};
|
||||
|
||||
/*! allocate a buffer of size 'size' and acquire() it.
|
||||
* call release() to free it.
|
||||
*/
|
||||
static SharedBuffer* alloc(size_t size);
|
||||
|
||||
/*! free the memory associated with the SharedBuffer.
|
||||
* Fails if there are any users associated with this SharedBuffer.
|
||||
* In other words, the buffer must have been release by all its
|
||||
* users.
|
||||
*/
|
||||
static ssize_t dealloc(const SharedBuffer* released);
|
||||
|
||||
//! access the data for read
|
||||
inline const void* data() const;
|
||||
|
||||
//! access the data for read/write
|
||||
inline void* data();
|
||||
|
||||
//! get size of the buffer
|
||||
inline size_t size() const;
|
||||
|
||||
//! get back a SharedBuffer object from its data
|
||||
static inline SharedBuffer* bufferFromData(void* data);
|
||||
|
||||
//! get back a SharedBuffer object from its data
|
||||
static inline const SharedBuffer* bufferFromData(const void* data);
|
||||
|
||||
//! get the size of a SharedBuffer object from its data
|
||||
static inline size_t sizeFromData(const void* data);
|
||||
|
||||
//! edit the buffer (get a writtable, or non-const, version of it)
|
||||
SharedBuffer* edit() const;
|
||||
|
||||
//! edit the buffer, resizing if needed
|
||||
SharedBuffer* editResize(size_t size) const;
|
||||
|
||||
//! like edit() but fails if a copy is required
|
||||
SharedBuffer* attemptEdit() const;
|
||||
|
||||
//! resize and edit the buffer, loose it's content.
|
||||
SharedBuffer* reset(size_t size) const;
|
||||
|
||||
//! acquire/release a reference on this buffer
|
||||
void acquire() const;
|
||||
|
||||
/*! release a reference on this buffer, with the option of not
|
||||
* freeing the memory associated with it if it was the last reference
|
||||
* returns the previous reference count
|
||||
*/
|
||||
int32_t release(uint32_t flags = 0) const;
|
||||
|
||||
//! returns wether or not we're the only owner
|
||||
inline bool onlyOwner() const;
|
||||
|
||||
|
||||
private:
|
||||
inline SharedBuffer() { }
|
||||
inline ~SharedBuffer() { }
|
||||
SharedBuffer(const SharedBuffer&);
|
||||
SharedBuffer& operator = (const SharedBuffer&);
|
||||
|
||||
// 16 bytes. must be sized to preserve correct alignment.
|
||||
mutable int32_t mRefs;
|
||||
size_t mSize;
|
||||
uint32_t mReserved[2];
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const void* SharedBuffer::data() const {
|
||||
return this + 1;
|
||||
}
|
||||
|
||||
void* SharedBuffer::data() {
|
||||
return this + 1;
|
||||
}
|
||||
|
||||
size_t SharedBuffer::size() const {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
SharedBuffer* SharedBuffer::bufferFromData(void* data) {
|
||||
return data ? static_cast<SharedBuffer *>(data)-1 : 0;
|
||||
}
|
||||
|
||||
const SharedBuffer* SharedBuffer::bufferFromData(const void* data) {
|
||||
return data ? static_cast<const SharedBuffer *>(data)-1 : 0;
|
||||
}
|
||||
|
||||
size_t SharedBuffer::sizeFromData(const void* data) {
|
||||
return data ? bufferFromData(data)->mSize : 0;
|
||||
}
|
||||
|
||||
bool SharedBuffer::onlyOwner() const {
|
||||
return (mRefs == 1);
|
||||
}
|
||||
|
||||
}; // namespace android
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // ANDROID_VECTOR_H
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_UTILS_SINGLETON_H
|
||||
#define ANDROID_UTILS_SINGLETON_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <utils/threads.h>
|
||||
#include <cutils/compiler.h>
|
||||
|
||||
namespace android {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
template <typename TYPE>
|
||||
class ANDROID_API Singleton
|
||||
{
|
||||
public:
|
||||
static TYPE& getInstance() {
|
||||
Mutex::Autolock _l(sLock);
|
||||
TYPE* instance = sInstance;
|
||||
if (instance == 0) {
|
||||
instance = new TYPE();
|
||||
sInstance = instance;
|
||||
}
|
||||
return *instance;
|
||||
}
|
||||
|
||||
static bool hasInstance() {
|
||||
Mutex::Autolock _l(sLock);
|
||||
return sInstance != 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
~Singleton() { };
|
||||
Singleton() { };
|
||||
|
||||
private:
|
||||
Singleton(const Singleton&);
|
||||
Singleton& operator = (const Singleton&);
|
||||
static Mutex sLock;
|
||||
static TYPE* sInstance;
|
||||
};
|
||||
|
||||
/*
|
||||
* use ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) in your implementation file
|
||||
* (eg: <TYPE>.cpp) to create the static instance of Singleton<>'s attributes,
|
||||
* and avoid to have a copy of them in each compilation units Singleton<TYPE>
|
||||
* is used.
|
||||
* NOTE: we use a version of Mutex ctor that takes a parameter, because
|
||||
* for some unknown reason using the default ctor doesn't emit the variable!
|
||||
*/
|
||||
|
||||
#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) \
|
||||
template<> ::android::Mutex \
|
||||
(::android::Singleton< TYPE >::sLock)(::android::Mutex::PRIVATE); \
|
||||
template<> TYPE* ::android::Singleton< TYPE >::sInstance(0); \
|
||||
template class ::android::Singleton< TYPE >;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
}; // namespace android
|
||||
|
||||
#endif // ANDROID_UTILS_SINGLETON_H
|
||||
|
||||
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_SORTED_VECTOR_H
|
||||
#define ANDROID_SORTED_VECTOR_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include <utils/Vector.h>
|
||||
#include <utils/VectorImpl.h>
|
||||
#include <utils/TypeHelpers.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
namespace android {
|
||||
|
||||
template <class TYPE>
|
||||
class SortedVector : private SortedVectorImpl
|
||||
{
|
||||
friend class Vector<TYPE>;
|
||||
|
||||
public:
|
||||
typedef TYPE value_type;
|
||||
|
||||
/*!
|
||||
* Constructors and destructors
|
||||
*/
|
||||
|
||||
SortedVector();
|
||||
SortedVector(const SortedVector<TYPE>& rhs);
|
||||
virtual ~SortedVector();
|
||||
|
||||
/*! copy operator */
|
||||
const SortedVector<TYPE>& operator = (const SortedVector<TYPE>& rhs) const;
|
||||
SortedVector<TYPE>& operator = (const SortedVector<TYPE>& rhs);
|
||||
|
||||
/*
|
||||
* empty the vector
|
||||
*/
|
||||
|
||||
inline void clear() { VectorImpl::clear(); }
|
||||
|
||||
/*!
|
||||
* vector stats
|
||||
*/
|
||||
|
||||
//! returns number of items in the vector
|
||||
inline size_t size() const { return VectorImpl::size(); }
|
||||
//! returns whether or not the vector is empty
|
||||
inline bool isEmpty() const { return VectorImpl::isEmpty(); }
|
||||
//! returns how many items can be stored without reallocating the backing store
|
||||
inline size_t capacity() const { return VectorImpl::capacity(); }
|
||||
//! sets the capacity. capacity can never be reduced less than size()
|
||||
inline ssize_t setCapacity(size_t size) { return VectorImpl::setCapacity(size); }
|
||||
|
||||
/*!
|
||||
* C-style array access
|
||||
*/
|
||||
|
||||
//! read-only C-style access
|
||||
inline const TYPE* array() const;
|
||||
|
||||
//! read-write C-style access. BE VERY CAREFUL when modifying the array
|
||||
//! you must keep it sorted! You usually don't use this function.
|
||||
TYPE* editArray();
|
||||
|
||||
//! finds the index of an item
|
||||
ssize_t indexOf(const TYPE& item) const;
|
||||
|
||||
//! finds where this item should be inserted
|
||||
size_t orderOf(const TYPE& item) const;
|
||||
|
||||
|
||||
/*!
|
||||
* accessors
|
||||
*/
|
||||
|
||||
//! read-only access to an item at a given index
|
||||
inline const TYPE& operator [] (size_t index) const;
|
||||
//! alternate name for operator []
|
||||
inline const TYPE& itemAt(size_t index) const;
|
||||
//! stack-usage of the vector. returns the top of the stack (last element)
|
||||
const TYPE& top() const;
|
||||
|
||||
/*!
|
||||
* modifying the array
|
||||
*/
|
||||
|
||||
//! add an item in the right place (and replace the one that is there)
|
||||
ssize_t add(const TYPE& item);
|
||||
|
||||
//! editItemAt() MUST NOT change the order of this item
|
||||
TYPE& editItemAt(size_t index) {
|
||||
return *( static_cast<TYPE *>(VectorImpl::editItemLocation(index)) );
|
||||
}
|
||||
|
||||
//! merges a vector into this one
|
||||
ssize_t merge(const Vector<TYPE>& vector);
|
||||
ssize_t merge(const SortedVector<TYPE>& vector);
|
||||
|
||||
//! removes an item
|
||||
ssize_t remove(const TYPE&);
|
||||
|
||||
//! remove several items
|
||||
inline ssize_t removeItemsAt(size_t index, size_t count = 1);
|
||||
//! remove one item
|
||||
inline ssize_t removeAt(size_t index) { return removeItemsAt(index); }
|
||||
|
||||
protected:
|
||||
virtual void do_construct(void* storage, size_t num) const;
|
||||
virtual void do_destroy(void* storage, size_t num) const;
|
||||
virtual void do_copy(void* dest, const void* from, size_t num) const;
|
||||
virtual void do_splat(void* dest, const void* item, size_t num) const;
|
||||
virtual void do_move_forward(void* dest, const void* from, size_t num) const;
|
||||
virtual void do_move_backward(void* dest, const void* from, size_t num) const;
|
||||
virtual int do_compare(const void* lhs, const void* rhs) const;
|
||||
};
|
||||
|
||||
// SortedVector<T> can be trivially moved using memcpy() because moving does not
|
||||
// require any change to the underlying SharedBuffer contents or reference count.
|
||||
template<typename T> struct trait_trivial_move<SortedVector<T> > { enum { value = true }; };
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// No user serviceable parts from here...
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
template<class TYPE> inline
|
||||
SortedVector<TYPE>::SortedVector()
|
||||
: SortedVectorImpl(sizeof(TYPE),
|
||||
((traits<TYPE>::has_trivial_ctor ? HAS_TRIVIAL_CTOR : 0)
|
||||
|(traits<TYPE>::has_trivial_dtor ? HAS_TRIVIAL_DTOR : 0)
|
||||
|(traits<TYPE>::has_trivial_copy ? HAS_TRIVIAL_COPY : 0))
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
SortedVector<TYPE>::SortedVector(const SortedVector<TYPE>& rhs)
|
||||
: SortedVectorImpl(rhs) {
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
SortedVector<TYPE>::~SortedVector() {
|
||||
finish_vector();
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) {
|
||||
SortedVectorImpl::operator = (rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
const SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const {
|
||||
SortedVectorImpl::operator = (rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
const TYPE* SortedVector<TYPE>::array() const {
|
||||
return static_cast<const TYPE *>(arrayImpl());
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
TYPE* SortedVector<TYPE>::editArray() {
|
||||
return static_cast<TYPE *>(editArrayImpl());
|
||||
}
|
||||
|
||||
|
||||
template<class TYPE> inline
|
||||
const TYPE& SortedVector<TYPE>::operator[](size_t index) const {
|
||||
LOG_FATAL_IF(index>=size(),
|
||||
"%s: index=%u out of range (%u)", __PRETTY_FUNCTION__,
|
||||
int(index), int(size()));
|
||||
return *(array() + index);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
const TYPE& SortedVector<TYPE>::itemAt(size_t index) const {
|
||||
return operator[](index);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
const TYPE& SortedVector<TYPE>::top() const {
|
||||
return *(array() + size() - 1);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
ssize_t SortedVector<TYPE>::add(const TYPE& item) {
|
||||
return SortedVectorImpl::add(&item);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
ssize_t SortedVector<TYPE>::indexOf(const TYPE& item) const {
|
||||
return SortedVectorImpl::indexOf(&item);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
size_t SortedVector<TYPE>::orderOf(const TYPE& item) const {
|
||||
return SortedVectorImpl::orderOf(&item);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
ssize_t SortedVector<TYPE>::merge(const Vector<TYPE>& vector) {
|
||||
return SortedVectorImpl::merge(reinterpret_cast<const VectorImpl&>(vector));
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
ssize_t SortedVector<TYPE>::merge(const SortedVector<TYPE>& vector) {
|
||||
return SortedVectorImpl::merge(reinterpret_cast<const SortedVectorImpl&>(vector));
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
ssize_t SortedVector<TYPE>::remove(const TYPE& item) {
|
||||
return SortedVectorImpl::remove(&item);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
ssize_t SortedVector<TYPE>::removeItemsAt(size_t index, size_t count) {
|
||||
return VectorImpl::removeItemsAt(index, count);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
template<class TYPE>
|
||||
void SortedVector<TYPE>::do_construct(void* storage, size_t num) const {
|
||||
construct_type( reinterpret_cast<TYPE*>(storage), num );
|
||||
}
|
||||
|
||||
template<class TYPE>
|
||||
void SortedVector<TYPE>::do_destroy(void* storage, size_t num) const {
|
||||
destroy_type( reinterpret_cast<TYPE*>(storage), num );
|
||||
}
|
||||
|
||||
template<class TYPE>
|
||||
void SortedVector<TYPE>::do_copy(void* dest, const void* from, size_t num) const {
|
||||
copy_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
|
||||
}
|
||||
|
||||
template<class TYPE>
|
||||
void SortedVector<TYPE>::do_splat(void* dest, const void* item, size_t num) const {
|
||||
splat_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(item), num );
|
||||
}
|
||||
|
||||
template<class TYPE>
|
||||
void SortedVector<TYPE>::do_move_forward(void* dest, const void* from, size_t num) const {
|
||||
move_forward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
|
||||
}
|
||||
|
||||
template<class TYPE>
|
||||
void SortedVector<TYPE>::do_move_backward(void* dest, const void* from, size_t num) const {
|
||||
move_backward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
|
||||
}
|
||||
|
||||
template<class TYPE>
|
||||
int SortedVector<TYPE>::do_compare(const void* lhs, const void* rhs) const {
|
||||
return compare_type( *reinterpret_cast<const TYPE*>(lhs), *reinterpret_cast<const TYPE*>(rhs) );
|
||||
}
|
||||
|
||||
}; // namespace android
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // ANDROID_SORTED_VECTOR_H
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_STOPWATCH_H
|
||||
#define ANDROID_STOPWATCH_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <utils/Timers.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
namespace android {
|
||||
|
||||
class StopWatch
|
||||
{
|
||||
public:
|
||||
StopWatch( const char *name,
|
||||
int clock = SYSTEM_TIME_MONOTONIC,
|
||||
uint32_t flags = 0);
|
||||
~StopWatch();
|
||||
|
||||
const char* name() const;
|
||||
nsecs_t lap();
|
||||
nsecs_t elapsedTime() const;
|
||||
|
||||
void reset();
|
||||
|
||||
private:
|
||||
const char* mName;
|
||||
int mClock;
|
||||
uint32_t mFlags;
|
||||
|
||||
struct lap_t {
|
||||
nsecs_t soFar;
|
||||
nsecs_t thisLap;
|
||||
};
|
||||
|
||||
nsecs_t mStartTime;
|
||||
lap_t mLaps[8];
|
||||
int mNumLaps;
|
||||
};
|
||||
|
||||
|
||||
}; // namespace android
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // ANDROID_STOPWATCH_H
|
||||
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_STRING16_H
|
||||
#define ANDROID_STRING16_H
|
||||
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/SharedBuffer.h>
|
||||
#include <utils/Unicode.h>
|
||||
#include <utils/TypeHelpers.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
extern "C" {
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
namespace android {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class String8;
|
||||
class TextOutput;
|
||||
|
||||
//! This is a string holding UTF-16 characters.
|
||||
class String16
|
||||
{
|
||||
public:
|
||||
/* use String16(StaticLinkage) if you're statically linking against
|
||||
* libutils and declaring an empty static String16, e.g.:
|
||||
*
|
||||
* static String16 sAStaticEmptyString(String16::kEmptyString);
|
||||
* static String16 sAnotherStaticEmptyString(sAStaticEmptyString);
|
||||
*/
|
||||
enum StaticLinkage { kEmptyString };
|
||||
|
||||
String16();
|
||||
explicit String16(StaticLinkage);
|
||||
String16(const String16& o);
|
||||
String16(const String16& o,
|
||||
size_t len,
|
||||
size_t begin=0);
|
||||
explicit String16(const char16_t* o);
|
||||
explicit String16(const char16_t* o, size_t len);
|
||||
explicit String16(const String8& o);
|
||||
explicit String16(const char* o);
|
||||
explicit String16(const char* o, size_t len);
|
||||
|
||||
~String16();
|
||||
|
||||
inline const char16_t* string() const;
|
||||
inline size_t size() const;
|
||||
|
||||
inline const SharedBuffer* sharedBuffer() const;
|
||||
|
||||
void setTo(const String16& other);
|
||||
status_t setTo(const char16_t* other);
|
||||
status_t setTo(const char16_t* other, size_t len);
|
||||
status_t setTo(const String16& other,
|
||||
size_t len,
|
||||
size_t begin=0);
|
||||
|
||||
status_t append(const String16& other);
|
||||
status_t append(const char16_t* other, size_t len);
|
||||
|
||||
inline String16& operator=(const String16& other);
|
||||
|
||||
inline String16& operator+=(const String16& other);
|
||||
inline String16 operator+(const String16& other) const;
|
||||
|
||||
status_t insert(size_t pos, const char16_t* chrs);
|
||||
status_t insert(size_t pos,
|
||||
const char16_t* chrs, size_t len);
|
||||
|
||||
ssize_t findFirst(char16_t c) const;
|
||||
ssize_t findLast(char16_t c) const;
|
||||
|
||||
bool startsWith(const String16& prefix) const;
|
||||
bool startsWith(const char16_t* prefix) const;
|
||||
|
||||
status_t makeLower();
|
||||
|
||||
status_t replaceAll(char16_t replaceThis,
|
||||
char16_t withThis);
|
||||
|
||||
status_t remove(size_t len, size_t begin=0);
|
||||
|
||||
inline int compare(const String16& other) const;
|
||||
|
||||
inline bool operator<(const String16& other) const;
|
||||
inline bool operator<=(const String16& other) const;
|
||||
inline bool operator==(const String16& other) const;
|
||||
inline bool operator!=(const String16& other) const;
|
||||
inline bool operator>=(const String16& other) const;
|
||||
inline bool operator>(const String16& other) const;
|
||||
|
||||
inline bool operator<(const char16_t* other) const;
|
||||
inline bool operator<=(const char16_t* other) const;
|
||||
inline bool operator==(const char16_t* other) const;
|
||||
inline bool operator!=(const char16_t* other) const;
|
||||
inline bool operator>=(const char16_t* other) const;
|
||||
inline bool operator>(const char16_t* other) const;
|
||||
|
||||
inline operator const char16_t*() const;
|
||||
|
||||
private:
|
||||
const char16_t* mString;
|
||||
};
|
||||
|
||||
// String16 can be trivially moved using memcpy() because moving does not
|
||||
// require any change to the underlying SharedBuffer contents or reference count.
|
||||
ANDROID_TRIVIAL_MOVE_TRAIT(String16)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// No user servicable parts below.
|
||||
|
||||
inline int compare_type(const String16& lhs, const String16& rhs)
|
||||
{
|
||||
return lhs.compare(rhs);
|
||||
}
|
||||
|
||||
inline int strictly_order_type(const String16& lhs, const String16& rhs)
|
||||
{
|
||||
return compare_type(lhs, rhs) < 0;
|
||||
}
|
||||
|
||||
inline const char16_t* String16::string() const
|
||||
{
|
||||
return mString;
|
||||
}
|
||||
|
||||
inline size_t String16::size() const
|
||||
{
|
||||
return SharedBuffer::sizeFromData(mString)/sizeof(char16_t)-1;
|
||||
}
|
||||
|
||||
inline const SharedBuffer* String16::sharedBuffer() const
|
||||
{
|
||||
return SharedBuffer::bufferFromData(mString);
|
||||
}
|
||||
|
||||
inline String16& String16::operator=(const String16& other)
|
||||
{
|
||||
setTo(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline String16& String16::operator+=(const String16& other)
|
||||
{
|
||||
append(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline String16 String16::operator+(const String16& other) const
|
||||
{
|
||||
String16 tmp(*this);
|
||||
tmp += other;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline int String16::compare(const String16& other) const
|
||||
{
|
||||
return strzcmp16(mString, size(), other.mString, other.size());
|
||||
}
|
||||
|
||||
inline bool String16::operator<(const String16& other) const
|
||||
{
|
||||
return strzcmp16(mString, size(), other.mString, other.size()) < 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator<=(const String16& other) const
|
||||
{
|
||||
return strzcmp16(mString, size(), other.mString, other.size()) <= 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator==(const String16& other) const
|
||||
{
|
||||
return strzcmp16(mString, size(), other.mString, other.size()) == 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator!=(const String16& other) const
|
||||
{
|
||||
return strzcmp16(mString, size(), other.mString, other.size()) != 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator>=(const String16& other) const
|
||||
{
|
||||
return strzcmp16(mString, size(), other.mString, other.size()) >= 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator>(const String16& other) const
|
||||
{
|
||||
return strzcmp16(mString, size(), other.mString, other.size()) > 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator<(const char16_t* other) const
|
||||
{
|
||||
return strcmp16(mString, other) < 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator<=(const char16_t* other) const
|
||||
{
|
||||
return strcmp16(mString, other) <= 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator==(const char16_t* other) const
|
||||
{
|
||||
return strcmp16(mString, other) == 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator!=(const char16_t* other) const
|
||||
{
|
||||
return strcmp16(mString, other) != 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator>=(const char16_t* other) const
|
||||
{
|
||||
return strcmp16(mString, other) >= 0;
|
||||
}
|
||||
|
||||
inline bool String16::operator>(const char16_t* other) const
|
||||
{
|
||||
return strcmp16(mString, other) > 0;
|
||||
}
|
||||
|
||||
inline String16::operator const char16_t*() const
|
||||
{
|
||||
return mString;
|
||||
}
|
||||
|
||||
}; // namespace android
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // ANDROID_STRING16_H
|
||||
@@ -0,0 +1,408 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_STRING8_H
|
||||
#define ANDROID_STRING8_H
|
||||
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/SharedBuffer.h>
|
||||
#include <utils/Unicode.h>
|
||||
#include <utils/TypeHelpers.h>
|
||||
|
||||
#include <string.h> // for strcmp
|
||||
#include <stdarg.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
namespace android {
|
||||
|
||||
class String16;
|
||||
class TextOutput;
|
||||
|
||||
//! This is a string holding UTF-8 characters. Does not allow the value more
|
||||
// than 0x10FFFF, which is not valid unicode codepoint.
|
||||
class String8
|
||||
{
|
||||
public:
|
||||
/* use String8(StaticLinkage) if you're statically linking against
|
||||
* libutils and declaring an empty static String8, e.g.:
|
||||
*
|
||||
* static String8 sAStaticEmptyString(String8::kEmptyString);
|
||||
* static String8 sAnotherStaticEmptyString(sAStaticEmptyString);
|
||||
*/
|
||||
enum StaticLinkage { kEmptyString };
|
||||
|
||||
String8();
|
||||
explicit String8(StaticLinkage);
|
||||
String8(const String8& o);
|
||||
explicit String8(const char* o);
|
||||
explicit String8(const char* o, size_t numChars);
|
||||
|
||||
explicit String8(const String16& o);
|
||||
explicit String8(const char16_t* o);
|
||||
explicit String8(const char16_t* o, size_t numChars);
|
||||
explicit String8(const char32_t* o);
|
||||
explicit String8(const char32_t* o, size_t numChars);
|
||||
~String8();
|
||||
|
||||
static inline const String8 empty();
|
||||
|
||||
static String8 format(const char* fmt, ...) __attribute__((format (printf, 1, 2)));
|
||||
static String8 formatV(const char* fmt, va_list args);
|
||||
|
||||
inline const char* string() const;
|
||||
inline size_t size() const;
|
||||
inline size_t length() const;
|
||||
inline size_t bytes() const;
|
||||
inline bool isEmpty() const;
|
||||
|
||||
inline const SharedBuffer* sharedBuffer() const;
|
||||
|
||||
void clear();
|
||||
|
||||
void setTo(const String8& other);
|
||||
status_t setTo(const char* other);
|
||||
status_t setTo(const char* other, size_t numChars);
|
||||
status_t setTo(const char16_t* other, size_t numChars);
|
||||
status_t setTo(const char32_t* other,
|
||||
size_t length);
|
||||
|
||||
status_t append(const String8& other);
|
||||
status_t append(const char* other);
|
||||
status_t append(const char* other, size_t numChars);
|
||||
|
||||
status_t appendFormat(const char* fmt, ...)
|
||||
__attribute__((format (printf, 2, 3)));
|
||||
status_t appendFormatV(const char* fmt, va_list args);
|
||||
|
||||
// Note that this function takes O(N) time to calculate the value.
|
||||
// No cache value is stored.
|
||||
size_t getUtf32Length() const;
|
||||
int32_t getUtf32At(size_t index,
|
||||
size_t *next_index) const;
|
||||
void getUtf32(char32_t* dst) const;
|
||||
|
||||
inline String8& operator=(const String8& other);
|
||||
inline String8& operator=(const char* other);
|
||||
|
||||
inline String8& operator+=(const String8& other);
|
||||
inline String8 operator+(const String8& other) const;
|
||||
|
||||
inline String8& operator+=(const char* other);
|
||||
inline String8 operator+(const char* other) const;
|
||||
|
||||
inline int compare(const String8& other) const;
|
||||
|
||||
inline bool operator<(const String8& other) const;
|
||||
inline bool operator<=(const String8& other) const;
|
||||
inline bool operator==(const String8& other) const;
|
||||
inline bool operator!=(const String8& other) const;
|
||||
inline bool operator>=(const String8& other) const;
|
||||
inline bool operator>(const String8& other) const;
|
||||
|
||||
inline bool operator<(const char* other) const;
|
||||
inline bool operator<=(const char* other) const;
|
||||
inline bool operator==(const char* other) const;
|
||||
inline bool operator!=(const char* other) const;
|
||||
inline bool operator>=(const char* other) const;
|
||||
inline bool operator>(const char* other) const;
|
||||
|
||||
inline operator const char*() const;
|
||||
|
||||
char* lockBuffer(size_t size);
|
||||
void unlockBuffer();
|
||||
status_t unlockBuffer(size_t size);
|
||||
|
||||
// return the index of the first byte of other in this at or after
|
||||
// start, or -1 if not found
|
||||
ssize_t find(const char* other, size_t start = 0) const;
|
||||
|
||||
// return true if this string contains the specified substring
|
||||
inline bool contains(const char* other) const;
|
||||
|
||||
// removes all occurrence of the specified substring
|
||||
// returns true if any were found and removed
|
||||
bool removeAll(const char* other);
|
||||
|
||||
void toLower();
|
||||
void toLower(size_t start, size_t numChars);
|
||||
void toUpper();
|
||||
void toUpper(size_t start, size_t numChars);
|
||||
|
||||
|
||||
/*
|
||||
* These methods operate on the string as if it were a path name.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Set the filename field to a specific value.
|
||||
*
|
||||
* Normalizes the filename, removing a trailing '/' if present.
|
||||
*/
|
||||
void setPathName(const char* name);
|
||||
void setPathName(const char* name, size_t numChars);
|
||||
|
||||
/*
|
||||
* Get just the filename component.
|
||||
*
|
||||
* "/tmp/foo/bar.c" --> "bar.c"
|
||||
*/
|
||||
String8 getPathLeaf(void) const;
|
||||
|
||||
/*
|
||||
* Remove the last (file name) component, leaving just the directory
|
||||
* name.
|
||||
*
|
||||
* "/tmp/foo/bar.c" --> "/tmp/foo"
|
||||
* "/tmp" --> "" // ????? shouldn't this be "/" ???? XXX
|
||||
* "bar.c" --> ""
|
||||
*/
|
||||
String8 getPathDir(void) const;
|
||||
|
||||
/*
|
||||
* Retrieve the front (root dir) component. Optionally also return the
|
||||
* remaining components.
|
||||
*
|
||||
* "/tmp/foo/bar.c" --> "tmp" (remain = "foo/bar.c")
|
||||
* "/tmp" --> "tmp" (remain = "")
|
||||
* "bar.c" --> "bar.c" (remain = "")
|
||||
*/
|
||||
String8 walkPath(String8* outRemains = NULL) const;
|
||||
|
||||
/*
|
||||
* Return the filename extension. This is the last '.' and any number
|
||||
* of characters that follow it. The '.' is included in case we
|
||||
* decide to expand our definition of what constitutes an extension.
|
||||
*
|
||||
* "/tmp/foo/bar.c" --> ".c"
|
||||
* "/tmp" --> ""
|
||||
* "/tmp/foo.bar/baz" --> ""
|
||||
* "foo.jpeg" --> ".jpeg"
|
||||
* "foo." --> ""
|
||||
*/
|
||||
String8 getPathExtension(void) const;
|
||||
|
||||
/*
|
||||
* Return the path without the extension. Rules for what constitutes
|
||||
* an extension are described in the comment for getPathExtension().
|
||||
*
|
||||
* "/tmp/foo/bar.c" --> "/tmp/foo/bar"
|
||||
*/
|
||||
String8 getBasePath(void) const;
|
||||
|
||||
/*
|
||||
* Add a component to the pathname. We guarantee that there is
|
||||
* exactly one path separator between the old path and the new.
|
||||
* If there is no existing name, we just copy the new name in.
|
||||
*
|
||||
* If leaf is a fully qualified path (i.e. starts with '/', it
|
||||
* replaces whatever was there before.
|
||||
*/
|
||||
String8& appendPath(const char* leaf);
|
||||
String8& appendPath(const String8& leaf) { return appendPath(leaf.string()); }
|
||||
|
||||
/*
|
||||
* Like appendPath(), but does not affect this string. Returns a new one instead.
|
||||
*/
|
||||
String8 appendPathCopy(const char* leaf) const
|
||||
{ String8 p(*this); p.appendPath(leaf); return p; }
|
||||
String8 appendPathCopy(const String8& leaf) const { return appendPathCopy(leaf.string()); }
|
||||
|
||||
/*
|
||||
* Converts all separators in this string to /, the default path separator.
|
||||
*
|
||||
* If the default OS separator is backslash, this converts all
|
||||
* backslashes to slashes, in-place. Otherwise it does nothing.
|
||||
* Returns self.
|
||||
*/
|
||||
String8& convertToResPath();
|
||||
|
||||
private:
|
||||
status_t real_append(const char* other, size_t numChars);
|
||||
char* find_extension(void) const;
|
||||
|
||||
const char* mString;
|
||||
};
|
||||
|
||||
// String8 can be trivially moved using memcpy() because moving does not
|
||||
// require any change to the underlying SharedBuffer contents or reference count.
|
||||
ANDROID_TRIVIAL_MOVE_TRAIT(String8)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// No user servicable parts below.
|
||||
|
||||
inline int compare_type(const String8& lhs, const String8& rhs)
|
||||
{
|
||||
return lhs.compare(rhs);
|
||||
}
|
||||
|
||||
inline int strictly_order_type(const String8& lhs, const String8& rhs)
|
||||
{
|
||||
return compare_type(lhs, rhs) < 0;
|
||||
}
|
||||
|
||||
inline const String8 String8::empty() {
|
||||
return String8();
|
||||
}
|
||||
|
||||
inline const char* String8::string() const
|
||||
{
|
||||
return mString;
|
||||
}
|
||||
|
||||
inline size_t String8::length() const
|
||||
{
|
||||
return SharedBuffer::sizeFromData(mString)-1;
|
||||
}
|
||||
|
||||
inline size_t String8::size() const
|
||||
{
|
||||
return length();
|
||||
}
|
||||
|
||||
inline bool String8::isEmpty() const
|
||||
{
|
||||
return length() == 0;
|
||||
}
|
||||
|
||||
inline size_t String8::bytes() const
|
||||
{
|
||||
return SharedBuffer::sizeFromData(mString)-1;
|
||||
}
|
||||
|
||||
inline const SharedBuffer* String8::sharedBuffer() const
|
||||
{
|
||||
return SharedBuffer::bufferFromData(mString);
|
||||
}
|
||||
|
||||
inline bool String8::contains(const char* other) const
|
||||
{
|
||||
return find(other) >= 0;
|
||||
}
|
||||
|
||||
inline String8& String8::operator=(const String8& other)
|
||||
{
|
||||
setTo(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline String8& String8::operator=(const char* other)
|
||||
{
|
||||
setTo(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline String8& String8::operator+=(const String8& other)
|
||||
{
|
||||
append(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline String8 String8::operator+(const String8& other) const
|
||||
{
|
||||
String8 tmp(*this);
|
||||
tmp += other;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline String8& String8::operator+=(const char* other)
|
||||
{
|
||||
append(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline String8 String8::operator+(const char* other) const
|
||||
{
|
||||
String8 tmp(*this);
|
||||
tmp += other;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline int String8::compare(const String8& other) const
|
||||
{
|
||||
return strcmp(mString, other.mString);
|
||||
}
|
||||
|
||||
inline bool String8::operator<(const String8& other) const
|
||||
{
|
||||
return strcmp(mString, other.mString) < 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator<=(const String8& other) const
|
||||
{
|
||||
return strcmp(mString, other.mString) <= 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator==(const String8& other) const
|
||||
{
|
||||
return strcmp(mString, other.mString) == 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator!=(const String8& other) const
|
||||
{
|
||||
return strcmp(mString, other.mString) != 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator>=(const String8& other) const
|
||||
{
|
||||
return strcmp(mString, other.mString) >= 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator>(const String8& other) const
|
||||
{
|
||||
return strcmp(mString, other.mString) > 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator<(const char* other) const
|
||||
{
|
||||
return strcmp(mString, other) < 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator<=(const char* other) const
|
||||
{
|
||||
return strcmp(mString, other) <= 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator==(const char* other) const
|
||||
{
|
||||
return strcmp(mString, other) == 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator!=(const char* other) const
|
||||
{
|
||||
return strcmp(mString, other) != 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator>=(const char* other) const
|
||||
{
|
||||
return strcmp(mString, other) >= 0;
|
||||
}
|
||||
|
||||
inline bool String8::operator>(const char* other) const
|
||||
{
|
||||
return strcmp(mString, other) > 0;
|
||||
}
|
||||
|
||||
inline String8::operator const char*() const
|
||||
{
|
||||
return mString;
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // ANDROID_STRING8_H
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_STRONG_POINTER_H
|
||||
#define ANDROID_STRONG_POINTER_H
|
||||
|
||||
#include <cutils/atomic.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
namespace android {
|
||||
|
||||
template<typename T> class wp;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#define COMPARE(_op_) \
|
||||
inline bool operator _op_ (const sp<T>& o) const { \
|
||||
return m_ptr _op_ o.m_ptr; \
|
||||
} \
|
||||
inline bool operator _op_ (const T* o) const { \
|
||||
return m_ptr _op_ o; \
|
||||
} \
|
||||
template<typename U> \
|
||||
inline bool operator _op_ (const sp<U>& o) const { \
|
||||
return m_ptr _op_ o.m_ptr; \
|
||||
} \
|
||||
template<typename U> \
|
||||
inline bool operator _op_ (const U* o) const { \
|
||||
return m_ptr _op_ o; \
|
||||
} \
|
||||
inline bool operator _op_ (const wp<T>& o) const { \
|
||||
return m_ptr _op_ o.m_ptr; \
|
||||
} \
|
||||
template<typename U> \
|
||||
inline bool operator _op_ (const wp<U>& o) const { \
|
||||
return m_ptr _op_ o.m_ptr; \
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
template<typename T>
|
||||
class sp {
|
||||
public:
|
||||
inline sp() : m_ptr(0) { }
|
||||
|
||||
sp(T* other);
|
||||
sp(const sp<T>& other);
|
||||
template<typename U> sp(U* other);
|
||||
template<typename U> sp(const sp<U>& other);
|
||||
|
||||
~sp();
|
||||
|
||||
// Assignment
|
||||
|
||||
sp& operator = (T* other);
|
||||
sp& operator = (const sp<T>& other);
|
||||
|
||||
template<typename U> sp& operator = (const sp<U>& other);
|
||||
template<typename U> sp& operator = (U* other);
|
||||
|
||||
//! Special optimization for use by ProcessState (and nobody else).
|
||||
void force_set(T* other);
|
||||
|
||||
// Reset
|
||||
|
||||
void clear();
|
||||
|
||||
// Accessors
|
||||
|
||||
inline T& operator* () const { return *m_ptr; }
|
||||
inline T* operator-> () const { return m_ptr; }
|
||||
inline T* get() const { return m_ptr; }
|
||||
|
||||
// Operators
|
||||
|
||||
COMPARE(==)
|
||||
COMPARE(!=)
|
||||
COMPARE(>)
|
||||
COMPARE(<)
|
||||
COMPARE(<=)
|
||||
COMPARE(>=)
|
||||
|
||||
private:
|
||||
template<typename Y> friend class sp;
|
||||
template<typename Y> friend class wp;
|
||||
void set_pointer(T* ptr);
|
||||
T* m_ptr;
|
||||
};
|
||||
|
||||
#undef COMPARE
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// No user serviceable parts below here.
|
||||
|
||||
template<typename T>
|
||||
sp<T>::sp(T* other)
|
||||
: m_ptr(other) {
|
||||
if (other)
|
||||
other->incStrong(this);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
sp<T>::sp(const sp<T>& other)
|
||||
: m_ptr(other.m_ptr) {
|
||||
if (m_ptr)
|
||||
m_ptr->incStrong(this);
|
||||
}
|
||||
|
||||
template<typename T> template<typename U>
|
||||
sp<T>::sp(U* other)
|
||||
: m_ptr(other) {
|
||||
if (other)
|
||||
((T*) other)->incStrong(this);
|
||||
}
|
||||
|
||||
template<typename T> template<typename U>
|
||||
sp<T>::sp(const sp<U>& other)
|
||||
: m_ptr(other.m_ptr) {
|
||||
if (m_ptr)
|
||||
m_ptr->incStrong(this);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
sp<T>::~sp() {
|
||||
if (m_ptr)
|
||||
m_ptr->decStrong(this);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
sp<T>& sp<T>::operator =(const sp<T>& other) {
|
||||
T* otherPtr(other.m_ptr);
|
||||
if (otherPtr)
|
||||
otherPtr->incStrong(this);
|
||||
if (m_ptr)
|
||||
m_ptr->decStrong(this);
|
||||
m_ptr = otherPtr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
sp<T>& sp<T>::operator =(T* other) {
|
||||
if (other)
|
||||
other->incStrong(this);
|
||||
if (m_ptr)
|
||||
m_ptr->decStrong(this);
|
||||
m_ptr = other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T> template<typename U>
|
||||
sp<T>& sp<T>::operator =(const sp<U>& other) {
|
||||
T* otherPtr(other.m_ptr);
|
||||
if (otherPtr)
|
||||
otherPtr->incStrong(this);
|
||||
if (m_ptr)
|
||||
m_ptr->decStrong(this);
|
||||
m_ptr = otherPtr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T> template<typename U>
|
||||
sp<T>& sp<T>::operator =(U* other) {
|
||||
if (other)
|
||||
((T*) other)->incStrong(this);
|
||||
if (m_ptr)
|
||||
m_ptr->decStrong(this);
|
||||
m_ptr = other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void sp<T>::force_set(T* other) {
|
||||
other->forceIncStrong(this);
|
||||
m_ptr = other;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void sp<T>::clear() {
|
||||
if (m_ptr) {
|
||||
m_ptr->decStrong(this);
|
||||
m_ptr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void sp<T>::set_pointer(T* ptr) {
|
||||
m_ptr = ptr;
|
||||
}
|
||||
|
||||
}; // namespace android
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // ANDROID_STRONG_POINTER_H
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_UTILS_SYSTEMCLOCK_H
|
||||
#define ANDROID_UTILS_SYSTEMCLOCK_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
int64_t uptimeMillis();
|
||||
int64_t elapsedRealtime();
|
||||
int64_t elapsedRealtimeNano();
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#endif // ANDROID_UTILS_SYSTEMCLOCK_H
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _LIBS_UTILS_THREAD_H
|
||||
#define _LIBS_UTILS_THREAD_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include <utils/Condition.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/Mutex.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/Timers.h>
|
||||
#include <utils/ThreadDefs.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
namespace android {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class Thread : virtual public RefBase
|
||||
{
|
||||
public:
|
||||
// Create a Thread object, but doesn't create or start the associated
|
||||
// thread. See the run() method.
|
||||
Thread(bool canCallJava = true);
|
||||
virtual ~Thread();
|
||||
|
||||
// Start the thread in threadLoop() which needs to be implemented.
|
||||
virtual status_t run( const char* name = 0,
|
||||
int32_t priority = PRIORITY_DEFAULT,
|
||||
size_t stack = 0);
|
||||
|
||||
// Ask this object's thread to exit. This function is asynchronous, when the
|
||||
// function returns the thread might still be running. Of course, this
|
||||
// function can be called from a different thread.
|
||||
virtual void requestExit();
|
||||
|
||||
// Good place to do one-time initializations
|
||||
virtual status_t readyToRun();
|
||||
|
||||
// Call requestExit() and wait until this object's thread exits.
|
||||
// BE VERY CAREFUL of deadlocks. In particular, it would be silly to call
|
||||
// this function from this object's thread. Will return WOULD_BLOCK in
|
||||
// that case.
|
||||
status_t requestExitAndWait();
|
||||
|
||||
// Wait until this object's thread exits. Returns immediately if not yet running.
|
||||
// Do not call from this object's thread; will return WOULD_BLOCK in that case.
|
||||
status_t join();
|
||||
|
||||
// Indicates whether this thread is running or not.
|
||||
bool isRunning() const;
|
||||
|
||||
#ifdef HAVE_ANDROID_OS
|
||||
// Return the thread's kernel ID, same as the thread itself calling gettid(),
|
||||
// or -1 if the thread is not running.
|
||||
pid_t getTid() const;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// exitPending() returns true if requestExit() has been called.
|
||||
bool exitPending() const;
|
||||
|
||||
private:
|
||||
// Derived class must implement threadLoop(). The thread starts its life
|
||||
// here. There are two ways of using the Thread object:
|
||||
// 1) loop: if threadLoop() returns true, it will be called again if
|
||||
// requestExit() wasn't called.
|
||||
// 2) once: if threadLoop() returns false, the thread will exit upon return.
|
||||
virtual bool threadLoop() = 0;
|
||||
|
||||
private:
|
||||
Thread& operator=(const Thread&);
|
||||
static int _threadLoop(void* user);
|
||||
const bool mCanCallJava;
|
||||
// always hold mLock when reading or writing
|
||||
thread_id_t mThread;
|
||||
mutable Mutex mLock;
|
||||
Condition mThreadExitedCondition;
|
||||
status_t mStatus;
|
||||
// note that all accesses of mExitPending and mRunning need to hold mLock
|
||||
volatile bool mExitPending;
|
||||
volatile bool mRunning;
|
||||
sp<Thread> mHoldSelf;
|
||||
#ifdef HAVE_ANDROID_OS
|
||||
// legacy for debugging, not used by getTid() as it is set by the child thread
|
||||
// and so is not initialized until the child reaches that point
|
||||
pid_t mTid;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
}; // namespace android
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
#endif // _LIBS_UTILS_THREAD_H
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _LIBS_UTILS_THREAD_DEFS_H
|
||||
#define _LIBS_UTILS_THREAD_DEFS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <system/graphics.h>
|
||||
#include <system/thread_defs.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// C API
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void* android_thread_id_t;
|
||||
|
||||
typedef int (*android_thread_func_t)(void*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// C++ API
|
||||
#ifdef __cplusplus
|
||||
namespace android {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
typedef android_thread_id_t thread_id_t;
|
||||
typedef android_thread_func_t thread_func_t;
|
||||
|
||||
enum {
|
||||
PRIORITY_LOWEST = ANDROID_PRIORITY_LOWEST,
|
||||
PRIORITY_BACKGROUND = ANDROID_PRIORITY_BACKGROUND,
|
||||
PRIORITY_NORMAL = ANDROID_PRIORITY_NORMAL,
|
||||
PRIORITY_FOREGROUND = ANDROID_PRIORITY_FOREGROUND,
|
||||
PRIORITY_DISPLAY = ANDROID_PRIORITY_DISPLAY,
|
||||
PRIORITY_URGENT_DISPLAY = ANDROID_PRIORITY_URGENT_DISPLAY,
|
||||
PRIORITY_AUDIO = ANDROID_PRIORITY_AUDIO,
|
||||
PRIORITY_URGENT_AUDIO = ANDROID_PRIORITY_URGENT_AUDIO,
|
||||
PRIORITY_HIGHEST = ANDROID_PRIORITY_HIGHEST,
|
||||
PRIORITY_DEFAULT = ANDROID_PRIORITY_DEFAULT,
|
||||
PRIORITY_MORE_FAVORABLE = ANDROID_PRIORITY_MORE_FAVORABLE,
|
||||
PRIORITY_LESS_FAVORABLE = ANDROID_PRIORITY_LESS_FAVORABLE,
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
}; // namespace android
|
||||
#endif // __cplusplus
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
#endif // _LIBS_UTILS_THREAD_DEFS_H
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//
|
||||
// Timer functions.
|
||||
//
|
||||
#ifndef _LIBS_UTILS_TIMERS_H
|
||||
#define _LIBS_UTILS_TIMERS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <utils/Compat.h>
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// C API
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int64_t nsecs_t; // nano-seconds
|
||||
|
||||
static CONSTEXPR inline nsecs_t seconds_to_nanoseconds(nsecs_t secs)
|
||||
{
|
||||
return secs*1000000000;
|
||||
}
|
||||
|
||||
static CONSTEXPR inline nsecs_t milliseconds_to_nanoseconds(nsecs_t secs)
|
||||
{
|
||||
return secs*1000000;
|
||||
}
|
||||
|
||||
static CONSTEXPR inline nsecs_t microseconds_to_nanoseconds(nsecs_t secs)
|
||||
{
|
||||
return secs*1000;
|
||||
}
|
||||
|
||||
static CONSTEXPR inline nsecs_t nanoseconds_to_seconds(nsecs_t secs)
|
||||
{
|
||||
return secs/1000000000;
|
||||
}
|
||||
|
||||
static CONSTEXPR inline nsecs_t nanoseconds_to_milliseconds(nsecs_t secs)
|
||||
{
|
||||
return secs/1000000;
|
||||
}
|
||||
|
||||
static CONSTEXPR inline nsecs_t nanoseconds_to_microseconds(nsecs_t secs)
|
||||
{
|
||||
return secs/1000;
|
||||
}
|
||||
|
||||
static CONSTEXPR inline nsecs_t s2ns(nsecs_t v) {return seconds_to_nanoseconds(v);}
|
||||
static CONSTEXPR inline nsecs_t ms2ns(nsecs_t v) {return milliseconds_to_nanoseconds(v);}
|
||||
static CONSTEXPR inline nsecs_t us2ns(nsecs_t v) {return microseconds_to_nanoseconds(v);}
|
||||
static CONSTEXPR inline nsecs_t ns2s(nsecs_t v) {return nanoseconds_to_seconds(v);}
|
||||
static CONSTEXPR inline nsecs_t ns2ms(nsecs_t v) {return nanoseconds_to_milliseconds(v);}
|
||||
static CONSTEXPR inline nsecs_t ns2us(nsecs_t v) {return nanoseconds_to_microseconds(v);}
|
||||
|
||||
static CONSTEXPR inline nsecs_t seconds(nsecs_t v) { return s2ns(v); }
|
||||
static CONSTEXPR inline nsecs_t milliseconds(nsecs_t v) { return ms2ns(v); }
|
||||
static CONSTEXPR inline nsecs_t microseconds(nsecs_t v) { return us2ns(v); }
|
||||
|
||||
enum {
|
||||
SYSTEM_TIME_REALTIME = 0, // system-wide realtime clock
|
||||
SYSTEM_TIME_MONOTONIC = 1, // monotonic time since unspecified starting point
|
||||
SYSTEM_TIME_PROCESS = 2, // high-resolution per-process clock
|
||||
SYSTEM_TIME_THREAD = 3, // high-resolution per-thread clock
|
||||
SYSTEM_TIME_BOOTTIME = 4 // same as SYSTEM_TIME_MONOTONIC, but including CPU suspend time
|
||||
};
|
||||
|
||||
// return the system-time according to the specified clock
|
||||
#ifdef __cplusplus
|
||||
nsecs_t systemTime(int clock = SYSTEM_TIME_MONOTONIC);
|
||||
#else
|
||||
nsecs_t systemTime(int clock);
|
||||
#endif // def __cplusplus
|
||||
|
||||
/**
|
||||
* Returns the number of milliseconds to wait between the reference time and the timeout time.
|
||||
* If the timeout is in the past relative to the reference time, returns 0.
|
||||
* If the timeout is more than INT_MAX milliseconds in the future relative to the reference time,
|
||||
* such as when timeoutTime == LLONG_MAX, returns -1 to indicate an infinite timeout delay.
|
||||
* Otherwise, returns the difference between the reference time and timeout time
|
||||
* rounded up to the next millisecond.
|
||||
*/
|
||||
int toMillisecondTimeoutDelay(nsecs_t referenceTime, nsecs_t timeoutTime);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // _LIBS_UTILS_TIMERS_H
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _UTILS_TOKENIZER_H
|
||||
#define _UTILS_TOKENIZER_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/FileMap.h>
|
||||
#include <utils/String8.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
/**
|
||||
* A simple tokenizer for loading and parsing ASCII text files line by line.
|
||||
*/
|
||||
class Tokenizer {
|
||||
Tokenizer(const String8& filename, FileMap* fileMap, char* buffer,
|
||||
bool ownBuffer, size_t length);
|
||||
|
||||
public:
|
||||
~Tokenizer();
|
||||
|
||||
/**
|
||||
* Opens a file and maps it into memory.
|
||||
*
|
||||
* Returns NO_ERROR and a tokenizer for the file, if successful.
|
||||
* Otherwise returns an error and sets outTokenizer to NULL.
|
||||
*/
|
||||
static status_t open(const String8& filename, Tokenizer** outTokenizer);
|
||||
|
||||
/**
|
||||
* Prepares to tokenize the contents of a string.
|
||||
*
|
||||
* Returns NO_ERROR and a tokenizer for the string, if successful.
|
||||
* Otherwise returns an error and sets outTokenizer to NULL.
|
||||
*/
|
||||
static status_t fromContents(const String8& filename,
|
||||
const char* contents, Tokenizer** outTokenizer);
|
||||
|
||||
/**
|
||||
* Returns true if at the end of the file.
|
||||
*/
|
||||
inline bool isEof() const { return mCurrent == getEnd(); }
|
||||
|
||||
/**
|
||||
* Returns true if at the end of the line or end of the file.
|
||||
*/
|
||||
inline bool isEol() const { return isEof() || *mCurrent == '\n'; }
|
||||
|
||||
/**
|
||||
* Gets the name of the file.
|
||||
*/
|
||||
inline String8 getFilename() const { return mFilename; }
|
||||
|
||||
/**
|
||||
* Gets a 1-based line number index for the current position.
|
||||
*/
|
||||
inline int32_t getLineNumber() const { return mLineNumber; }
|
||||
|
||||
/**
|
||||
* Formats a location string consisting of the filename and current line number.
|
||||
* Returns a string like "MyFile.txt:33".
|
||||
*/
|
||||
String8 getLocation() const;
|
||||
|
||||
/**
|
||||
* Gets the character at the current position.
|
||||
* Returns null at end of file.
|
||||
*/
|
||||
inline char peekChar() const { return isEof() ? '\0' : *mCurrent; }
|
||||
|
||||
/**
|
||||
* Gets the remainder of the current line as a string, excluding the newline character.
|
||||
*/
|
||||
String8 peekRemainderOfLine() const;
|
||||
|
||||
/**
|
||||
* Gets the character at the current position and advances past it.
|
||||
* Returns null at end of file.
|
||||
*/
|
||||
inline char nextChar() { return isEof() ? '\0' : *(mCurrent++); }
|
||||
|
||||
/**
|
||||
* Gets the next token on this line stopping at the specified delimiters
|
||||
* or the end of the line whichever comes first and advances past it.
|
||||
* Also stops at embedded nulls.
|
||||
* Returns the token or an empty string if the current character is a delimiter
|
||||
* or is at the end of the line.
|
||||
*/
|
||||
String8 nextToken(const char* delimiters);
|
||||
|
||||
/**
|
||||
* Advances to the next line.
|
||||
* Does nothing if already at the end of the file.
|
||||
*/
|
||||
void nextLine();
|
||||
|
||||
/**
|
||||
* Skips over the specified delimiters in the line.
|
||||
* Also skips embedded nulls.
|
||||
*/
|
||||
void skipDelimiters(const char* delimiters);
|
||||
|
||||
private:
|
||||
Tokenizer(const Tokenizer& other); // not copyable
|
||||
|
||||
String8 mFilename;
|
||||
FileMap* mFileMap;
|
||||
char* mBuffer;
|
||||
bool mOwnBuffer;
|
||||
size_t mLength;
|
||||
|
||||
const char* mCurrent;
|
||||
int32_t mLineNumber;
|
||||
|
||||
inline const char* getEnd() const { return mBuffer + mLength; }
|
||||
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // _UTILS_TOKENIZER_H
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_TRACE_H
|
||||
#define ANDROID_TRACE_H
|
||||
|
||||
#ifdef HAVE_ANDROID_OS
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cutils/compiler.h>
|
||||
#include <utils/threads.h>
|
||||
#include <cutils/trace.h>
|
||||
|
||||
// See <cutils/trace.h> for more ATRACE_* macros.
|
||||
|
||||
// ATRACE_NAME traces the beginning and end of the current scope. To trace
|
||||
// the correct start and end times this macro should be declared first in the
|
||||
// scope body.
|
||||
#define ATRACE_NAME(name) android::ScopedTrace ___tracer(ATRACE_TAG, name)
|
||||
// ATRACE_CALL is an ATRACE_NAME that uses the current function name.
|
||||
#define ATRACE_CALL() ATRACE_NAME(__FUNCTION__)
|
||||
|
||||
namespace android {
|
||||
|
||||
class ScopedTrace {
|
||||
public:
|
||||
inline ScopedTrace(uint64_t tag, const char* name)
|
||||
: mTag(tag) {
|
||||
atrace_begin(mTag,name);
|
||||
}
|
||||
|
||||
inline ~ScopedTrace() {
|
||||
atrace_end(mTag);
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t mTag;
|
||||
};
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#else // HAVE_ANDROID_OS
|
||||
|
||||
#define ATRACE_NAME(...)
|
||||
#define ATRACE_CALL()
|
||||
|
||||
#endif // HAVE_ANDROID_OS
|
||||
|
||||
#endif // ANDROID_TRACE_H
|
||||
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_TYPE_HELPERS_H
|
||||
#define ANDROID_TYPE_HELPERS_H
|
||||
|
||||
#include <new>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
namespace android {
|
||||
|
||||
/*
|
||||
* Types traits
|
||||
*/
|
||||
|
||||
template <typename T> struct trait_trivial_ctor { enum { value = false }; };
|
||||
template <typename T> struct trait_trivial_dtor { enum { value = false }; };
|
||||
template <typename T> struct trait_trivial_copy { enum { value = false }; };
|
||||
template <typename T> struct trait_trivial_move { enum { value = false }; };
|
||||
template <typename T> struct trait_pointer { enum { value = false }; };
|
||||
template <typename T> struct trait_pointer<T*> { enum { value = true }; };
|
||||
|
||||
template <typename TYPE>
|
||||
struct traits {
|
||||
enum {
|
||||
// whether this type is a pointer
|
||||
is_pointer = trait_pointer<TYPE>::value,
|
||||
// whether this type's constructor is a no-op
|
||||
has_trivial_ctor = is_pointer || trait_trivial_ctor<TYPE>::value,
|
||||
// whether this type's destructor is a no-op
|
||||
has_trivial_dtor = is_pointer || trait_trivial_dtor<TYPE>::value,
|
||||
// whether this type type can be copy-constructed with memcpy
|
||||
has_trivial_copy = is_pointer || trait_trivial_copy<TYPE>::value,
|
||||
// whether this type can be moved with memmove
|
||||
has_trivial_move = is_pointer || trait_trivial_move<TYPE>::value
|
||||
};
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
struct aggregate_traits {
|
||||
enum {
|
||||
is_pointer = false,
|
||||
has_trivial_ctor =
|
||||
traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor,
|
||||
has_trivial_dtor =
|
||||
traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor,
|
||||
has_trivial_copy =
|
||||
traits<T>::has_trivial_copy && traits<U>::has_trivial_copy,
|
||||
has_trivial_move =
|
||||
traits<T>::has_trivial_move && traits<U>::has_trivial_move
|
||||
};
|
||||
};
|
||||
|
||||
#define ANDROID_TRIVIAL_CTOR_TRAIT( T ) \
|
||||
template<> struct trait_trivial_ctor< T > { enum { value = true }; };
|
||||
|
||||
#define ANDROID_TRIVIAL_DTOR_TRAIT( T ) \
|
||||
template<> struct trait_trivial_dtor< T > { enum { value = true }; };
|
||||
|
||||
#define ANDROID_TRIVIAL_COPY_TRAIT( T ) \
|
||||
template<> struct trait_trivial_copy< T > { enum { value = true }; };
|
||||
|
||||
#define ANDROID_TRIVIAL_MOVE_TRAIT( T ) \
|
||||
template<> struct trait_trivial_move< T > { enum { value = true }; };
|
||||
|
||||
#define ANDROID_BASIC_TYPES_TRAITS( T ) \
|
||||
ANDROID_TRIVIAL_CTOR_TRAIT( T ) \
|
||||
ANDROID_TRIVIAL_DTOR_TRAIT( T ) \
|
||||
ANDROID_TRIVIAL_COPY_TRAIT( T ) \
|
||||
ANDROID_TRIVIAL_MOVE_TRAIT( T )
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* basic types traits
|
||||
*/
|
||||
|
||||
ANDROID_BASIC_TYPES_TRAITS( void )
|
||||
ANDROID_BASIC_TYPES_TRAITS( bool )
|
||||
ANDROID_BASIC_TYPES_TRAITS( char )
|
||||
ANDROID_BASIC_TYPES_TRAITS( unsigned char )
|
||||
ANDROID_BASIC_TYPES_TRAITS( short )
|
||||
ANDROID_BASIC_TYPES_TRAITS( unsigned short )
|
||||
ANDROID_BASIC_TYPES_TRAITS( int )
|
||||
ANDROID_BASIC_TYPES_TRAITS( unsigned int )
|
||||
ANDROID_BASIC_TYPES_TRAITS( long )
|
||||
ANDROID_BASIC_TYPES_TRAITS( unsigned long )
|
||||
ANDROID_BASIC_TYPES_TRAITS( long long )
|
||||
ANDROID_BASIC_TYPES_TRAITS( unsigned long long )
|
||||
ANDROID_BASIC_TYPES_TRAITS( float )
|
||||
ANDROID_BASIC_TYPES_TRAITS( double )
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*
|
||||
* compare and order types
|
||||
*/
|
||||
|
||||
template<typename TYPE> inline
|
||||
int strictly_order_type(const TYPE& lhs, const TYPE& rhs) {
|
||||
return (lhs < rhs) ? 1 : 0;
|
||||
}
|
||||
|
||||
template<typename TYPE> inline
|
||||
int compare_type(const TYPE& lhs, const TYPE& rhs) {
|
||||
return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs);
|
||||
}
|
||||
|
||||
/*
|
||||
* create, destroy, copy and move types...
|
||||
*/
|
||||
|
||||
template<typename TYPE> inline
|
||||
void construct_type(TYPE* p, size_t n) {
|
||||
if (!traits<TYPE>::has_trivial_ctor) {
|
||||
while (n--) {
|
||||
new(p++) TYPE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TYPE> inline
|
||||
void destroy_type(TYPE* p, size_t n) {
|
||||
if (!traits<TYPE>::has_trivial_dtor) {
|
||||
while (n--) {
|
||||
p->~TYPE();
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TYPE> inline
|
||||
void copy_type(TYPE* d, const TYPE* s, size_t n) {
|
||||
if (!traits<TYPE>::has_trivial_copy) {
|
||||
while (n--) {
|
||||
new(d) TYPE(*s);
|
||||
d++, s++;
|
||||
}
|
||||
} else {
|
||||
memcpy(d,s,n*sizeof(TYPE));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TYPE> inline
|
||||
void splat_type(TYPE* where, const TYPE* what, size_t n) {
|
||||
if (!traits<TYPE>::has_trivial_copy) {
|
||||
while (n--) {
|
||||
new(where) TYPE(*what);
|
||||
where++;
|
||||
}
|
||||
} else {
|
||||
while (n--) {
|
||||
*where++ = *what;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TYPE> inline
|
||||
void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
|
||||
if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy)
|
||||
|| traits<TYPE>::has_trivial_move)
|
||||
{
|
||||
memmove(d,s,n*sizeof(TYPE));
|
||||
} else {
|
||||
d += n;
|
||||
s += n;
|
||||
while (n--) {
|
||||
--d, --s;
|
||||
if (!traits<TYPE>::has_trivial_copy) {
|
||||
new(d) TYPE(*s);
|
||||
} else {
|
||||
*d = *s;
|
||||
}
|
||||
if (!traits<TYPE>::has_trivial_dtor) {
|
||||
s->~TYPE();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TYPE> inline
|
||||
void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
|
||||
if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy)
|
||||
|| traits<TYPE>::has_trivial_move)
|
||||
{
|
||||
memmove(d,s,n*sizeof(TYPE));
|
||||
} else {
|
||||
while (n--) {
|
||||
if (!traits<TYPE>::has_trivial_copy) {
|
||||
new(d) TYPE(*s);
|
||||
} else {
|
||||
*d = *s;
|
||||
}
|
||||
if (!traits<TYPE>::has_trivial_dtor) {
|
||||
s->~TYPE();
|
||||
}
|
||||
d++, s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* a key/value pair
|
||||
*/
|
||||
|
||||
template <typename KEY, typename VALUE>
|
||||
struct key_value_pair_t {
|
||||
typedef KEY key_t;
|
||||
typedef VALUE value_t;
|
||||
|
||||
KEY key;
|
||||
VALUE value;
|
||||
key_value_pair_t() { }
|
||||
key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { }
|
||||
key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v) { }
|
||||
key_value_pair_t(const KEY& k) : key(k) { }
|
||||
inline bool operator < (const key_value_pair_t& o) const {
|
||||
return strictly_order_type(key, o.key);
|
||||
}
|
||||
inline const KEY& getKey() const {
|
||||
return key;
|
||||
}
|
||||
inline const VALUE& getValue() const {
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
struct trait_trivial_ctor< key_value_pair_t<K, V> >
|
||||
{ enum { value = aggregate_traits<K,V>::has_trivial_ctor }; };
|
||||
template <typename K, typename V>
|
||||
struct trait_trivial_dtor< key_value_pair_t<K, V> >
|
||||
{ enum { value = aggregate_traits<K,V>::has_trivial_dtor }; };
|
||||
template <typename K, typename V>
|
||||
struct trait_trivial_copy< key_value_pair_t<K, V> >
|
||||
{ enum { value = aggregate_traits<K,V>::has_trivial_copy }; };
|
||||
template <typename K, typename V>
|
||||
struct trait_trivial_move< key_value_pair_t<K, V> >
|
||||
{ enum { value = aggregate_traits<K,V>::has_trivial_move }; };
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Hash codes.
|
||||
*/
|
||||
typedef uint32_t hash_t;
|
||||
|
||||
template <typename TKey>
|
||||
hash_t hash_type(const TKey& key);
|
||||
|
||||
/* Built-in hash code specializations.
|
||||
* Assumes pointers are 32bit. */
|
||||
#define ANDROID_INT32_HASH(T) \
|
||||
template <> inline hash_t hash_type(const T& value) { return hash_t(value); }
|
||||
#define ANDROID_INT64_HASH(T) \
|
||||
template <> inline hash_t hash_type(const T& value) { \
|
||||
return hash_t((value >> 32) ^ value); }
|
||||
#define ANDROID_REINTERPRET_HASH(T, R) \
|
||||
template <> inline hash_t hash_type(const T& value) { \
|
||||
return hash_type(*reinterpret_cast<const R*>(&value)); }
|
||||
|
||||
ANDROID_INT32_HASH(bool)
|
||||
ANDROID_INT32_HASH(int8_t)
|
||||
ANDROID_INT32_HASH(uint8_t)
|
||||
ANDROID_INT32_HASH(int16_t)
|
||||
ANDROID_INT32_HASH(uint16_t)
|
||||
ANDROID_INT32_HASH(int32_t)
|
||||
ANDROID_INT32_HASH(uint32_t)
|
||||
ANDROID_INT64_HASH(int64_t)
|
||||
ANDROID_INT64_HASH(uint64_t)
|
||||
ANDROID_REINTERPRET_HASH(float, uint32_t)
|
||||
ANDROID_REINTERPRET_HASH(double, uint64_t)
|
||||
|
||||
template <typename T> inline hash_t hash_type(T* const & value) {
|
||||
return hash_type(uintptr_t(value));
|
||||
}
|
||||
|
||||
}; // namespace android
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // ANDROID_TYPE_HELPERS_H
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_UNICODE_H
|
||||
#define ANDROID_UNICODE_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
// Standard string functions on char16_t strings.
|
||||
int strcmp16(const char16_t *, const char16_t *);
|
||||
int strncmp16(const char16_t *s1, const char16_t *s2, size_t n);
|
||||
size_t strlen16(const char16_t *);
|
||||
size_t strnlen16(const char16_t *, size_t);
|
||||
char16_t *strcpy16(char16_t *, const char16_t *);
|
||||
char16_t *strncpy16(char16_t *, const char16_t *, size_t);
|
||||
|
||||
// Version of comparison that supports embedded nulls.
|
||||
// This is different than strncmp() because we don't stop
|
||||
// at a nul character and consider the strings to be different
|
||||
// if the lengths are different (thus we need to supply the
|
||||
// lengths of both strings). This can also be used when
|
||||
// your string is not nul-terminated as it will have the
|
||||
// equivalent result as strcmp16 (unlike strncmp16).
|
||||
int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2);
|
||||
|
||||
// Version of strzcmp16 for comparing strings in different endianness.
|
||||
int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2);
|
||||
|
||||
// Standard string functions on char32_t strings.
|
||||
size_t strlen32(const char32_t *);
|
||||
size_t strnlen32(const char32_t *, size_t);
|
||||
|
||||
/**
|
||||
* Measure the length of a UTF-32 string in UTF-8. If the string is invalid
|
||||
* such as containing a surrogate character, -1 will be returned.
|
||||
*/
|
||||
ssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len);
|
||||
|
||||
/**
|
||||
* Stores a UTF-8 string converted from "src" in "dst", if "dst_length" is not
|
||||
* large enough to store the string, the part of the "src" string is stored
|
||||
* into "dst" as much as possible. See the examples for more detail.
|
||||
* Returns the size actually used for storing the string.
|
||||
* dst" is not null-terminated when dst_len is fully used (like strncpy).
|
||||
*
|
||||
* Example 1
|
||||
* "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84)
|
||||
* "src_len" == 2
|
||||
* "dst_len" >= 7
|
||||
* ->
|
||||
* Returned value == 6
|
||||
* "dst" becomes \xE3\x81\x82\xE3\x81\x84\0
|
||||
* (note that "dst" is null-terminated)
|
||||
*
|
||||
* Example 2
|
||||
* "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84)
|
||||
* "src_len" == 2
|
||||
* "dst_len" == 5
|
||||
* ->
|
||||
* Returned value == 3
|
||||
* "dst" becomes \xE3\x81\x82\0
|
||||
* (note that "dst" is null-terminated, but \u3044 is not stored in "dst"
|
||||
* since "dst" does not have enough size to store the character)
|
||||
*
|
||||
* Example 3
|
||||
* "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84)
|
||||
* "src_len" == 2
|
||||
* "dst_len" == 6
|
||||
* ->
|
||||
* Returned value == 6
|
||||
* "dst" becomes \xE3\x81\x82\xE3\x81\x84
|
||||
* (note that "dst" is NOT null-terminated, like strncpy)
|
||||
*/
|
||||
void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst, size_t dst_len);
|
||||
|
||||
/**
|
||||
* Returns the unicode value at "index".
|
||||
* Returns -1 when the index is invalid (equals to or more than "src_len").
|
||||
* If returned value is positive, it is able to be converted to char32_t, which
|
||||
* is unsigned. Then, if "next_index" is not NULL, the next index to be used is
|
||||
* stored in "next_index". "next_index" can be NULL.
|
||||
*/
|
||||
int32_t utf32_from_utf8_at(const char *src, size_t src_len, size_t index, size_t *next_index);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the UTF-8 length of UTF-16 string "src".
|
||||
*/
|
||||
ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len);
|
||||
|
||||
/**
|
||||
* Converts a UTF-16 string to UTF-8. The destination buffer must be large
|
||||
* enough to fit the UTF-16 as measured by utf16_to_utf8_length with an added
|
||||
* NULL terminator.
|
||||
*/
|
||||
void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst, size_t dst_len);
|
||||
|
||||
/**
|
||||
* Returns the length of "src" when "src" is valid UTF-8 string.
|
||||
* Returns 0 if src is NULL or 0-length string. Returns -1 when the source
|
||||
* is an invalid string.
|
||||
*
|
||||
* This function should be used to determine whether "src" is valid UTF-8
|
||||
* characters with valid unicode codepoints. "src" must be null-terminated.
|
||||
*
|
||||
* If you are going to use other utf8_to_... functions defined in this header
|
||||
* with string which may not be valid UTF-8 with valid codepoint (form 0 to
|
||||
* 0x10FFFF), you should use this function before calling others, since the
|
||||
* other functions do not check whether the string is valid UTF-8 or not.
|
||||
*
|
||||
* If you do not care whether "src" is valid UTF-8 or not, you should use
|
||||
* strlen() as usual, which should be much faster.
|
||||
*/
|
||||
ssize_t utf8_length(const char *src);
|
||||
|
||||
/**
|
||||
* Measure the length of a UTF-32 string.
|
||||
*/
|
||||
size_t utf8_to_utf32_length(const char *src, size_t src_len);
|
||||
|
||||
/**
|
||||
* Stores a UTF-32 string converted from "src" in "dst". "dst" must be large
|
||||
* enough to store the entire converted string as measured by
|
||||
* utf8_to_utf32_length plus space for a NULL terminator.
|
||||
*/
|
||||
void utf8_to_utf32(const char* src, size_t src_len, char32_t* dst);
|
||||
|
||||
/**
|
||||
* Returns the UTF-16 length of UTF-8 string "src".
|
||||
*/
|
||||
ssize_t utf8_to_utf16_length(const uint8_t* src, size_t srcLen);
|
||||
|
||||
/**
|
||||
* Convert UTF-8 to UTF-16 including surrogate pairs.
|
||||
* Returns a pointer to the end of the string (where a null terminator might go
|
||||
* if you wanted to add one).
|
||||
*/
|
||||
char16_t* utf8_to_utf16_no_null_terminator(const uint8_t* src, size_t srcLen, char16_t* dst);
|
||||
|
||||
/**
|
||||
* Convert UTF-8 to UTF-16 including surrogate pairs. The destination buffer
|
||||
* must be large enough to hold the result as measured by utf8_to_utf16_length
|
||||
* plus an added NULL terminator.
|
||||
*/
|
||||
void utf8_to_utf16(const uint8_t* src, size_t srcLen, char16_t* dst);
|
||||
|
||||
/**
|
||||
* Like utf8_to_utf16_no_null_terminator, but you can supply a maximum length of the
|
||||
* decoded string. The decoded string will fill up to that length; if it is longer
|
||||
* the returned pointer will be to the character after dstLen.
|
||||
*/
|
||||
char16_t* utf8_to_utf16_n(const uint8_t* src, size_t srcLen, char16_t* dst, size_t dstLen);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,423 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_VECTOR_H
|
||||
#define ANDROID_VECTOR_H
|
||||
|
||||
#include <new>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include <utils/VectorImpl.h>
|
||||
#include <utils/TypeHelpers.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
namespace android {
|
||||
|
||||
template <typename TYPE>
|
||||
class SortedVector;
|
||||
|
||||
/*!
|
||||
* The main templated vector class ensuring type safety
|
||||
* while making use of VectorImpl.
|
||||
* This is the class users want to use.
|
||||
*/
|
||||
|
||||
template <class TYPE>
|
||||
class Vector : private VectorImpl
|
||||
{
|
||||
public:
|
||||
typedef TYPE value_type;
|
||||
|
||||
/*!
|
||||
* Constructors and destructors
|
||||
*/
|
||||
|
||||
Vector();
|
||||
Vector(const Vector<TYPE>& rhs);
|
||||
explicit Vector(const SortedVector<TYPE>& rhs);
|
||||
virtual ~Vector();
|
||||
|
||||
/*! copy operator */
|
||||
const Vector<TYPE>& operator = (const Vector<TYPE>& rhs) const;
|
||||
Vector<TYPE>& operator = (const Vector<TYPE>& rhs);
|
||||
|
||||
const Vector<TYPE>& operator = (const SortedVector<TYPE>& rhs) const;
|
||||
Vector<TYPE>& operator = (const SortedVector<TYPE>& rhs);
|
||||
|
||||
/*
|
||||
* empty the vector
|
||||
*/
|
||||
|
||||
inline void clear() { VectorImpl::clear(); }
|
||||
|
||||
/*!
|
||||
* vector stats
|
||||
*/
|
||||
|
||||
//! returns number of items in the vector
|
||||
inline size_t size() const { return VectorImpl::size(); }
|
||||
//! returns whether or not the vector is empty
|
||||
inline bool isEmpty() const { return VectorImpl::isEmpty(); }
|
||||
//! returns how many items can be stored without reallocating the backing store
|
||||
inline size_t capacity() const { return VectorImpl::capacity(); }
|
||||
//! sets the capacity. capacity can never be reduced less than size()
|
||||
inline ssize_t setCapacity(size_t size) { return VectorImpl::setCapacity(size); }
|
||||
|
||||
/*!
|
||||
* set the size of the vector. items are appended with the default
|
||||
* constructor, or removed from the end as needed.
|
||||
*/
|
||||
inline ssize_t resize(size_t size) { return VectorImpl::resize(size); }
|
||||
|
||||
/*!
|
||||
* C-style array access
|
||||
*/
|
||||
|
||||
//! read-only C-style access
|
||||
inline const TYPE* array() const;
|
||||
//! read-write C-style access
|
||||
TYPE* editArray();
|
||||
|
||||
/*!
|
||||
* accessors
|
||||
*/
|
||||
|
||||
//! read-only access to an item at a given index
|
||||
inline const TYPE& operator [] (size_t index) const;
|
||||
//! alternate name for operator []
|
||||
inline const TYPE& itemAt(size_t index) const;
|
||||
//! stack-usage of the vector. returns the top of the stack (last element)
|
||||
const TYPE& top() const;
|
||||
|
||||
/*!
|
||||
* modifying the array
|
||||
*/
|
||||
|
||||
//! copy-on write support, grants write access to an item
|
||||
TYPE& editItemAt(size_t index);
|
||||
//! grants right access to the top of the stack (last element)
|
||||
TYPE& editTop();
|
||||
|
||||
/*!
|
||||
* append/insert another vector
|
||||
*/
|
||||
|
||||
//! insert another vector at a given index
|
||||
ssize_t insertVectorAt(const Vector<TYPE>& vector, size_t index);
|
||||
|
||||
//! append another vector at the end of this one
|
||||
ssize_t appendVector(const Vector<TYPE>& vector);
|
||||
|
||||
|
||||
//! insert an array at a given index
|
||||
ssize_t insertArrayAt(const TYPE* array, size_t index, size_t length);
|
||||
|
||||
//! append an array at the end of this vector
|
||||
ssize_t appendArray(const TYPE* array, size_t length);
|
||||
|
||||
/*!
|
||||
* add/insert/replace items
|
||||
*/
|
||||
|
||||
//! insert one or several items initialized with their default constructor
|
||||
inline ssize_t insertAt(size_t index, size_t numItems = 1);
|
||||
//! insert one or several items initialized from a prototype item
|
||||
ssize_t insertAt(const TYPE& prototype_item, size_t index, size_t numItems = 1);
|
||||
//! pop the top of the stack (removes the last element). No-op if the stack's empty
|
||||
inline void pop();
|
||||
//! pushes an item initialized with its default constructor
|
||||
inline void push();
|
||||
//! pushes an item on the top of the stack
|
||||
void push(const TYPE& item);
|
||||
//! same as push() but returns the index the item was added at (or an error)
|
||||
inline ssize_t add();
|
||||
//! same as push() but returns the index the item was added at (or an error)
|
||||
ssize_t add(const TYPE& item);
|
||||
//! replace an item with a new one initialized with its default constructor
|
||||
inline ssize_t replaceAt(size_t index);
|
||||
//! replace an item with a new one
|
||||
ssize_t replaceAt(const TYPE& item, size_t index);
|
||||
|
||||
/*!
|
||||
* remove items
|
||||
*/
|
||||
|
||||
//! remove several items
|
||||
inline ssize_t removeItemsAt(size_t index, size_t count = 1);
|
||||
//! remove one item
|
||||
inline ssize_t removeAt(size_t index) { return removeItemsAt(index); }
|
||||
|
||||
/*!
|
||||
* sort (stable) the array
|
||||
*/
|
||||
|
||||
typedef int (*compar_t)(const TYPE* lhs, const TYPE* rhs);
|
||||
typedef int (*compar_r_t)(const TYPE* lhs, const TYPE* rhs, void* state);
|
||||
|
||||
inline status_t sort(compar_t cmp);
|
||||
inline status_t sort(compar_r_t cmp, void* state);
|
||||
|
||||
// for debugging only
|
||||
inline size_t getItemSize() const { return itemSize(); }
|
||||
|
||||
|
||||
/*
|
||||
* these inlines add some level of compatibility with STL. eventually
|
||||
* we should probably turn things around.
|
||||
*/
|
||||
typedef TYPE* iterator;
|
||||
typedef TYPE const* const_iterator;
|
||||
|
||||
inline iterator begin() { return editArray(); }
|
||||
inline iterator end() { return editArray() + size(); }
|
||||
inline const_iterator begin() const { return array(); }
|
||||
inline const_iterator end() const { return array() + size(); }
|
||||
inline void reserve(size_t n) { setCapacity(n); }
|
||||
inline bool empty() const{ return isEmpty(); }
|
||||
inline void push_back(const TYPE& item) { insertAt(item, size(), 1); }
|
||||
inline void push_front(const TYPE& item) { insertAt(item, 0, 1); }
|
||||
inline iterator erase(iterator pos) {
|
||||
ssize_t index = removeItemsAt(pos-array());
|
||||
return begin() + index;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void do_construct(void* storage, size_t num) const;
|
||||
virtual void do_destroy(void* storage, size_t num) const;
|
||||
virtual void do_copy(void* dest, const void* from, size_t num) const;
|
||||
virtual void do_splat(void* dest, const void* item, size_t num) const;
|
||||
virtual void do_move_forward(void* dest, const void* from, size_t num) const;
|
||||
virtual void do_move_backward(void* dest, const void* from, size_t num) const;
|
||||
};
|
||||
|
||||
// Vector<T> can be trivially moved using memcpy() because moving does not
|
||||
// require any change to the underlying SharedBuffer contents or reference count.
|
||||
template<typename T> struct trait_trivial_move<Vector<T> > { enum { value = true }; };
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// No user serviceable parts from here...
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
template<class TYPE> inline
|
||||
Vector<TYPE>::Vector()
|
||||
: VectorImpl(sizeof(TYPE),
|
||||
((traits<TYPE>::has_trivial_ctor ? HAS_TRIVIAL_CTOR : 0)
|
||||
|(traits<TYPE>::has_trivial_dtor ? HAS_TRIVIAL_DTOR : 0)
|
||||
|(traits<TYPE>::has_trivial_copy ? HAS_TRIVIAL_COPY : 0))
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
Vector<TYPE>::Vector(const Vector<TYPE>& rhs)
|
||||
: VectorImpl(rhs) {
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
Vector<TYPE>::Vector(const SortedVector<TYPE>& rhs)
|
||||
: VectorImpl(static_cast<const VectorImpl&>(rhs)) {
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
Vector<TYPE>::~Vector() {
|
||||
finish_vector();
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) {
|
||||
VectorImpl::operator = (rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
const Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) const {
|
||||
VectorImpl::operator = (static_cast<const VectorImpl&>(rhs));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) {
|
||||
VectorImpl::operator = (static_cast<const VectorImpl&>(rhs));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
const Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const {
|
||||
VectorImpl::operator = (rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
const TYPE* Vector<TYPE>::array() const {
|
||||
return static_cast<const TYPE *>(arrayImpl());
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
TYPE* Vector<TYPE>::editArray() {
|
||||
return static_cast<TYPE *>(editArrayImpl());
|
||||
}
|
||||
|
||||
|
||||
template<class TYPE> inline
|
||||
const TYPE& Vector<TYPE>::operator[](size_t index) const {
|
||||
LOG_FATAL_IF(index>=size(),
|
||||
"%s: index=%u out of range (%u)", __PRETTY_FUNCTION__,
|
||||
int(index), int(size()));
|
||||
return *(array() + index);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
const TYPE& Vector<TYPE>::itemAt(size_t index) const {
|
||||
return operator[](index);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
const TYPE& Vector<TYPE>::top() const {
|
||||
return *(array() + size() - 1);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
TYPE& Vector<TYPE>::editItemAt(size_t index) {
|
||||
return *( static_cast<TYPE *>(editItemLocation(index)) );
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
TYPE& Vector<TYPE>::editTop() {
|
||||
return *( static_cast<TYPE *>(editItemLocation(size()-1)) );
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
ssize_t Vector<TYPE>::insertVectorAt(const Vector<TYPE>& vector, size_t index) {
|
||||
return VectorImpl::insertVectorAt(reinterpret_cast<const VectorImpl&>(vector), index);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
ssize_t Vector<TYPE>::appendVector(const Vector<TYPE>& vector) {
|
||||
return VectorImpl::appendVector(reinterpret_cast<const VectorImpl&>(vector));
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
ssize_t Vector<TYPE>::insertArrayAt(const TYPE* array, size_t index, size_t length) {
|
||||
return VectorImpl::insertArrayAt(array, index, length);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
ssize_t Vector<TYPE>::appendArray(const TYPE* array, size_t length) {
|
||||
return VectorImpl::appendArray(array, length);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
ssize_t Vector<TYPE>::insertAt(const TYPE& item, size_t index, size_t numItems) {
|
||||
return VectorImpl::insertAt(&item, index, numItems);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
void Vector<TYPE>::push(const TYPE& item) {
|
||||
return VectorImpl::push(&item);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
ssize_t Vector<TYPE>::add(const TYPE& item) {
|
||||
return VectorImpl::add(&item);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
ssize_t Vector<TYPE>::replaceAt(const TYPE& item, size_t index) {
|
||||
return VectorImpl::replaceAt(&item, index);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
ssize_t Vector<TYPE>::insertAt(size_t index, size_t numItems) {
|
||||
return VectorImpl::insertAt(index, numItems);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
void Vector<TYPE>::pop() {
|
||||
VectorImpl::pop();
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
void Vector<TYPE>::push() {
|
||||
VectorImpl::push();
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
ssize_t Vector<TYPE>::add() {
|
||||
return VectorImpl::add();
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
ssize_t Vector<TYPE>::replaceAt(size_t index) {
|
||||
return VectorImpl::replaceAt(index);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
ssize_t Vector<TYPE>::removeItemsAt(size_t index, size_t count) {
|
||||
return VectorImpl::removeItemsAt(index, count);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
status_t Vector<TYPE>::sort(Vector<TYPE>::compar_t cmp) {
|
||||
return VectorImpl::sort((VectorImpl::compar_t)cmp);
|
||||
}
|
||||
|
||||
template<class TYPE> inline
|
||||
status_t Vector<TYPE>::sort(Vector<TYPE>::compar_r_t cmp, void* state) {
|
||||
return VectorImpl::sort((VectorImpl::compar_r_t)cmp, state);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
template<class TYPE>
|
||||
void Vector<TYPE>::do_construct(void* storage, size_t num) const {
|
||||
construct_type( reinterpret_cast<TYPE*>(storage), num );
|
||||
}
|
||||
|
||||
template<class TYPE>
|
||||
void Vector<TYPE>::do_destroy(void* storage, size_t num) const {
|
||||
destroy_type( reinterpret_cast<TYPE*>(storage), num );
|
||||
}
|
||||
|
||||
template<class TYPE>
|
||||
void Vector<TYPE>::do_copy(void* dest, const void* from, size_t num) const {
|
||||
copy_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
|
||||
}
|
||||
|
||||
template<class TYPE>
|
||||
void Vector<TYPE>::do_splat(void* dest, const void* item, size_t num) const {
|
||||
splat_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(item), num );
|
||||
}
|
||||
|
||||
template<class TYPE>
|
||||
void Vector<TYPE>::do_move_forward(void* dest, const void* from, size_t num) const {
|
||||
move_forward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
|
||||
}
|
||||
|
||||
template<class TYPE>
|
||||
void Vector<TYPE>::do_move_backward(void* dest, const void* from, size_t num) const {
|
||||
move_backward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
|
||||
}
|
||||
|
||||
}; // namespace android
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // ANDROID_VECTOR_H
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_VECTOR_IMPL_H
|
||||
#define ANDROID_VECTOR_IMPL_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <utils/Errors.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// No user serviceable parts in here...
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
namespace android {
|
||||
|
||||
/*!
|
||||
* Implementation of the guts of the vector<> class
|
||||
* this ensures backward binary compatibility and
|
||||
* reduces code size.
|
||||
* For performance reasons, we expose mStorage and mCount
|
||||
* so these fields are set in stone.
|
||||
*
|
||||
*/
|
||||
|
||||
class VectorImpl
|
||||
{
|
||||
public:
|
||||
enum { // flags passed to the ctor
|
||||
HAS_TRIVIAL_CTOR = 0x00000001,
|
||||
HAS_TRIVIAL_DTOR = 0x00000002,
|
||||
HAS_TRIVIAL_COPY = 0x00000004,
|
||||
};
|
||||
|
||||
VectorImpl(size_t itemSize, uint32_t flags);
|
||||
VectorImpl(const VectorImpl& rhs);
|
||||
virtual ~VectorImpl();
|
||||
|
||||
/*! must be called from subclasses destructor */
|
||||
void finish_vector();
|
||||
|
||||
VectorImpl& operator = (const VectorImpl& rhs);
|
||||
|
||||
/*! C-style array access */
|
||||
inline const void* arrayImpl() const { return mStorage; }
|
||||
void* editArrayImpl();
|
||||
|
||||
/*! vector stats */
|
||||
inline size_t size() const { return mCount; }
|
||||
inline bool isEmpty() const { return mCount == 0; }
|
||||
size_t capacity() const;
|
||||
ssize_t setCapacity(size_t size);
|
||||
ssize_t resize(size_t size);
|
||||
|
||||
/*! append/insert another vector or array */
|
||||
ssize_t insertVectorAt(const VectorImpl& vector, size_t index);
|
||||
ssize_t appendVector(const VectorImpl& vector);
|
||||
ssize_t insertArrayAt(const void* array, size_t index, size_t length);
|
||||
ssize_t appendArray(const void* array, size_t length);
|
||||
|
||||
/*! add/insert/replace items */
|
||||
ssize_t insertAt(size_t where, size_t numItems = 1);
|
||||
ssize_t insertAt(const void* item, size_t where, size_t numItems = 1);
|
||||
void pop();
|
||||
void push();
|
||||
void push(const void* item);
|
||||
ssize_t add();
|
||||
ssize_t add(const void* item);
|
||||
ssize_t replaceAt(size_t index);
|
||||
ssize_t replaceAt(const void* item, size_t index);
|
||||
|
||||
/*! remove items */
|
||||
ssize_t removeItemsAt(size_t index, size_t count = 1);
|
||||
void clear();
|
||||
|
||||
const void* itemLocation(size_t index) const;
|
||||
void* editItemLocation(size_t index);
|
||||
|
||||
typedef int (*compar_t)(const void* lhs, const void* rhs);
|
||||
typedef int (*compar_r_t)(const void* lhs, const void* rhs, void* state);
|
||||
status_t sort(compar_t cmp);
|
||||
status_t sort(compar_r_t cmp, void* state);
|
||||
|
||||
protected:
|
||||
size_t itemSize() const;
|
||||
void release_storage();
|
||||
|
||||
virtual void do_construct(void* storage, size_t num) const = 0;
|
||||
virtual void do_destroy(void* storage, size_t num) const = 0;
|
||||
virtual void do_copy(void* dest, const void* from, size_t num) const = 0;
|
||||
virtual void do_splat(void* dest, const void* item, size_t num) const = 0;
|
||||
virtual void do_move_forward(void* dest, const void* from, size_t num) const = 0;
|
||||
virtual void do_move_backward(void* dest, const void* from, size_t num) const = 0;
|
||||
|
||||
private:
|
||||
void* _grow(size_t where, size_t amount);
|
||||
void _shrink(size_t where, size_t amount);
|
||||
|
||||
inline void _do_construct(void* storage, size_t num) const;
|
||||
inline void _do_destroy(void* storage, size_t num) const;
|
||||
inline void _do_copy(void* dest, const void* from, size_t num) const;
|
||||
inline void _do_splat(void* dest, const void* item, size_t num) const;
|
||||
inline void _do_move_forward(void* dest, const void* from, size_t num) const;
|
||||
inline void _do_move_backward(void* dest, const void* from, size_t num) const;
|
||||
|
||||
// These 2 fields are exposed in the inlines below,
|
||||
// so they're set in stone.
|
||||
void * mStorage; // base address of the vector
|
||||
size_t mCount; // number of items
|
||||
|
||||
const uint32_t mFlags;
|
||||
const size_t mItemSize;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class SortedVectorImpl : public VectorImpl
|
||||
{
|
||||
public:
|
||||
SortedVectorImpl(size_t itemSize, uint32_t flags);
|
||||
SortedVectorImpl(const VectorImpl& rhs);
|
||||
virtual ~SortedVectorImpl();
|
||||
|
||||
SortedVectorImpl& operator = (const SortedVectorImpl& rhs);
|
||||
|
||||
//! finds the index of an item
|
||||
ssize_t indexOf(const void* item) const;
|
||||
|
||||
//! finds where this item should be inserted
|
||||
size_t orderOf(const void* item) const;
|
||||
|
||||
//! add an item in the right place (or replaces it if there is one)
|
||||
ssize_t add(const void* item);
|
||||
|
||||
//! merges a vector into this one
|
||||
ssize_t merge(const VectorImpl& vector);
|
||||
ssize_t merge(const SortedVectorImpl& vector);
|
||||
|
||||
//! removes an item
|
||||
ssize_t remove(const void* item);
|
||||
|
||||
protected:
|
||||
virtual int do_compare(const void* lhs, const void* rhs) const = 0;
|
||||
|
||||
private:
|
||||
ssize_t _indexOrderOf(const void* item, size_t* order = 0) const;
|
||||
|
||||
// these are made private, because they can't be used on a SortedVector
|
||||
// (they don't have an implementation either)
|
||||
ssize_t add();
|
||||
void pop();
|
||||
void push();
|
||||
void push(const void* item);
|
||||
ssize_t insertVectorAt(const VectorImpl& vector, size_t index);
|
||||
ssize_t appendVector(const VectorImpl& vector);
|
||||
ssize_t insertArrayAt(const void* array, size_t index, size_t length);
|
||||
ssize_t appendArray(const void* array, size_t length);
|
||||
ssize_t insertAt(size_t where, size_t numItems = 1);
|
||||
ssize_t insertAt(const void* item, size_t where, size_t numItems = 1);
|
||||
ssize_t replaceAt(size_t index);
|
||||
ssize_t replaceAt(const void* item, size_t index);
|
||||
};
|
||||
|
||||
}; // namespace android
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // ANDROID_VECTOR_IMPL_H
|
||||
@@ -0,0 +1,41 @@
|
||||
/* utils/ashmem.h
|
||||
**
|
||||
** Copyright 2008 The Android Open Source Project
|
||||
**
|
||||
** This file is dual licensed. It may be redistributed and/or modified
|
||||
** under the terms of the Apache 2.0 License OR version 2 of the GNU
|
||||
** General Public License.
|
||||
*/
|
||||
|
||||
#ifndef _UTILS_ASHMEM_H
|
||||
#define _UTILS_ASHMEM_H
|
||||
|
||||
#include <linux/limits.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
#define ASHMEM_NAME_LEN 256
|
||||
|
||||
#define ASHMEM_NAME_DEF "dev/ashmem"
|
||||
|
||||
/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */
|
||||
#define ASHMEM_NOT_REAPED 0
|
||||
#define ASHMEM_WAS_REAPED 1
|
||||
|
||||
/* Return values from ASHMEM_UNPIN: Is the mapping now pinned or unpinned? */
|
||||
#define ASHMEM_NOW_UNPINNED 0
|
||||
#define ASHMEM_NOW_PINNED 1
|
||||
|
||||
#define __ASHMEMIOC 0x77
|
||||
|
||||
#define ASHMEM_SET_NAME _IOW(__ASHMEMIOC, 1, char[ASHMEM_NAME_LEN])
|
||||
#define ASHMEM_GET_NAME _IOR(__ASHMEMIOC, 2, char[ASHMEM_NAME_LEN])
|
||||
#define ASHMEM_SET_SIZE _IOW(__ASHMEMIOC, 3, size_t)
|
||||
#define ASHMEM_GET_SIZE _IO(__ASHMEMIOC, 4)
|
||||
#define ASHMEM_SET_PROT_MASK _IOW(__ASHMEMIOC, 5, unsigned long)
|
||||
#define ASHMEM_GET_PROT_MASK _IO(__ASHMEMIOC, 6)
|
||||
#define ASHMEM_PIN _IO(__ASHMEMIOC, 7)
|
||||
#define ASHMEM_UNPIN _IO(__ASHMEMIOC, 8)
|
||||
#define ASHMEM_ISPINNED _IO(__ASHMEMIOC, 9)
|
||||
#define ASHMEM_PURGE_ALL_CACHES _IO(__ASHMEMIOC, 10)
|
||||
|
||||
#endif /* _UTILS_ASHMEM_H */
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//
|
||||
// Handy utility functions and portability code.
|
||||
//
|
||||
#ifndef _LIBS_UTILS_MISC_H
|
||||
#define _LIBS_UTILS_MISC_H
|
||||
|
||||
#include <utils/Endian.h>
|
||||
|
||||
/* get #of elements in a static array */
|
||||
#ifndef NELEM
|
||||
# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
|
||||
#endif
|
||||
|
||||
namespace android {
|
||||
|
||||
typedef void (*sysprop_change_callback)(void);
|
||||
void add_sysprop_change_callback(sysprop_change_callback cb, int priority);
|
||||
void report_sysprop_change();
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#endif // _LIBS_UTILS_MISC_H
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _LIBS_UTILS_THREADS_H
|
||||
#define _LIBS_UTILS_THREADS_H
|
||||
|
||||
/*
|
||||
* Please, DO NOT USE!
|
||||
*
|
||||
* This file is here only for legacy reasons. Instead, include directly
|
||||
* the headers you need below.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <utils/AndroidThreads.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <utils/Condition.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/Mutex.h>
|
||||
#include <utils/RWLock.h>
|
||||
#include <utils/Thread.h>
|
||||
#endif
|
||||
|
||||
#endif // _LIBS_UTILS_THREADS_H
|
||||
Reference in New Issue
Block a user