summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:45 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:45 -0800
commitd83a98f4ce9cfa908f5c54bbd70f03eec07e7553 (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /libs
parent076357b8567458d4b6dfdcf839ef751634cd2bfb (diff)
downloadframeworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.zip
frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.tar.gz
frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'libs')
-rw-r--r--libs/audioflinger/A2dpAudioInterface.cpp243
-rw-r--r--libs/audioflinger/A2dpAudioInterface.h110
-rw-r--r--libs/audioflinger/Android.mk56
-rw-r--r--libs/audioflinger/AudioBufferProvider.h47
-rw-r--r--libs/audioflinger/AudioDumpInterface.cpp117
-rw-r--r--libs/audioflinger/AudioDumpInterface.h97
-rw-r--r--libs/audioflinger/AudioFlinger.cpp2471
-rw-r--r--libs/audioflinger/AudioFlinger.h640
-rw-r--r--libs/audioflinger/AudioHardwareGeneric.cpp313
-rw-r--r--libs/audioflinger/AudioHardwareGeneric.h141
-rw-r--r--libs/audioflinger/AudioHardwareInterface.cpp247
-rw-r--r--libs/audioflinger/AudioHardwareStub.cpp185
-rw-r--r--libs/audioflinger/AudioHardwareStub.h100
-rw-r--r--libs/audioflinger/AudioMixer.cpp913
-rw-r--r--libs/audioflinger/AudioMixer.h192
-rw-r--r--libs/audioflinger/AudioResampler.cpp595
-rw-r--r--libs/audioflinger/AudioResampler.h93
-rw-r--r--libs/audioflinger/AudioResamplerCubic.cpp184
-rw-r--r--libs/audioflinger/AudioResamplerCubic.h68
-rw-r--r--libs/audioflinger/AudioResamplerSinc.cpp358
-rw-r--r--libs/audioflinger/AudioResamplerSinc.h88
-rw-r--r--libs/surfaceflinger/Android.mk49
-rw-r--r--libs/surfaceflinger/Barrier.h59
-rw-r--r--libs/surfaceflinger/BlurFilter.cpp326
-rw-r--r--libs/surfaceflinger/BlurFilter.h35
-rw-r--r--libs/surfaceflinger/BootAnimation.cpp403
-rw-r--r--libs/surfaceflinger/BootAnimation.h87
-rw-r--r--libs/surfaceflinger/CPUGauge.cpp171
-rw-r--r--libs/surfaceflinger/CPUGauge.h74
-rw-r--r--libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp353
-rw-r--r--libs/surfaceflinger/DisplayHardware/DisplayHardware.h113
-rw-r--r--libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp403
-rw-r--r--libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h96
-rw-r--r--libs/surfaceflinger/GPUHardware/GPUHardware.cpp581
-rw-r--r--libs/surfaceflinger/GPUHardware/GPUHardware.h63
-rw-r--r--libs/surfaceflinger/Layer.cpp568
-rw-r--r--libs/surfaceflinger/Layer.h120
-rw-r--r--libs/surfaceflinger/LayerBase.cpp740
-rw-r--r--libs/surfaceflinger/LayerBase.h356
-rw-r--r--libs/surfaceflinger/LayerBitmap.cpp185
-rw-r--r--libs/surfaceflinger/LayerBitmap.h84
-rw-r--r--libs/surfaceflinger/LayerBlur.cpp234
-rw-r--r--libs/surfaceflinger/LayerBlur.h65
-rw-r--r--libs/surfaceflinger/LayerBuffer.cpp655
-rw-r--r--libs/surfaceflinger/LayerBuffer.h216
-rw-r--r--libs/surfaceflinger/LayerDim.cpp113
-rw-r--r--libs/surfaceflinger/LayerDim.h57
-rw-r--r--libs/surfaceflinger/LayerOrientationAnim.cpp287
-rw-r--r--libs/surfaceflinger/LayerOrientationAnim.h75
-rw-r--r--libs/surfaceflinger/MODULE_LICENSE_APACHE20
-rw-r--r--libs/surfaceflinger/OrientationAnimation.cpp155
-rw-r--r--libs/surfaceflinger/OrientationAnimation.h73
-rw-r--r--libs/surfaceflinger/SurfaceFlinger.cpp1840
-rw-r--r--libs/surfaceflinger/SurfaceFlinger.h435
-rw-r--r--libs/surfaceflinger/Tokenizer.cpp172
-rw-r--r--libs/surfaceflinger/Tokenizer.h57
-rw-r--r--libs/surfaceflinger/Transform.cpp204
-rw-r--r--libs/surfaceflinger/Transform.h87
-rw-r--r--libs/surfaceflinger/VRamHeap.cpp176
-rw-r--r--libs/surfaceflinger/VRamHeap.h78
-rw-r--r--libs/surfaceflinger/clz.cpp37
-rw-r--r--libs/surfaceflinger/clz.h37
-rw-r--r--libs/surfaceflinger/tests/Android.mk1
-rw-r--r--libs/surfaceflinger/tests/overlays/Android.mk16
-rw-r--r--libs/surfaceflinger/tests/overlays/overlays.cpp58
-rw-r--r--libs/ui/Android.mk41
-rw-r--r--libs/ui/Camera.cpp406
-rw-r--r--libs/ui/CameraParameters.cpp273
-rw-r--r--libs/ui/EGLDisplaySurface.cpp519
-rw-r--r--libs/ui/EGLNativeWindowSurface.cpp161
-rw-r--r--libs/ui/EventHub.cpp793
-rw-r--r--libs/ui/EventRecurrence.cpp484
-rw-r--r--libs/ui/ICamera.cpp346
-rw-r--r--libs/ui/ICameraClient.cpp185
-rw-r--r--libs/ui/ICameraService.cpp77
-rw-r--r--libs/ui/IOverlay.cpp72
-rw-r--r--libs/ui/ISurface.cpp164
-rw-r--r--libs/ui/ISurfaceComposer.cpp277
-rw-r--r--libs/ui/ISurfaceFlingerClient.cpp208
-rw-r--r--libs/ui/KeyCharacterMap.cpp263
-rw-r--r--libs/ui/KeyLayoutMap.cpp235
-rw-r--r--libs/ui/KeyLayoutMap.h31
-rw-r--r--libs/ui/LayerState.cpp53
-rw-r--r--libs/ui/MODULE_LICENSE_APACHE20
-rw-r--r--libs/ui/NOTICE190
-rw-r--r--libs/ui/Overlay.cpp181
-rw-r--r--libs/ui/PixelFormat.cpp97
-rw-r--r--libs/ui/Point.cpp11
-rw-r--r--libs/ui/Rect.cpp86
-rw-r--r--libs/ui/Region.cpp313
-rw-r--r--libs/ui/Surface.cpp256
-rw-r--r--libs/ui/SurfaceComposerClient.cpp1026
-rw-r--r--libs/ui/SurfaceFlingerSynchro.cpp123
-rw-r--r--libs/ui/Time.cpp199
-rw-r--r--libs/utils/Android.mk156
-rw-r--r--libs/utils/Asset.cpp813
-rw-r--r--libs/utils/AssetDir.cpp66
-rw-r--r--libs/utils/AssetManager.cpp1637
-rw-r--r--libs/utils/Binder.cpp242
-rw-r--r--libs/utils/BpBinder.cpp348
-rw-r--r--libs/utils/BufferedTextOutput.cpp279
-rw-r--r--libs/utils/CallStack.cpp335
-rw-r--r--libs/utils/Debug.cpp318
-rw-r--r--libs/utils/FileMap.cpp222
-rw-r--r--libs/utils/IDataConnection.cpp89
-rw-r--r--libs/utils/IInterface.cpp35
-rw-r--r--libs/utils/IMemory.cpp486
-rw-r--r--libs/utils/IPCThreadState.cpp1030
-rw-r--r--libs/utils/IPermissionController.cpp86
-rw-r--r--libs/utils/IServiceManager.cpp230
-rw-r--r--libs/utils/InetAddress.cpp236
-rw-r--r--libs/utils/LogSocket.cpp129
-rw-r--r--libs/utils/MODULE_LICENSE_APACHE20
-rw-r--r--libs/utils/MemoryBase.cpp46
-rw-r--r--libs/utils/MemoryDealer.cpp409
-rw-r--r--libs/utils/MemoryHeapBase.cpp183
-rw-r--r--libs/utils/MemoryHeapPmem.cpp248
-rw-r--r--libs/utils/NOTICE190
-rw-r--r--libs/utils/Parcel.cpp1377
-rw-r--r--libs/utils/Pipe.cpp465
-rw-r--r--libs/utils/ProcessState.cpp398
-rw-r--r--libs/utils/README14
-rw-r--r--libs/utils/RefBase.cpp534
-rw-r--r--libs/utils/ResourceTypes.cpp3983
-rw-r--r--libs/utils/SharedBuffer.cpp113
-rw-r--r--libs/utils/Socket.cpp388
-rw-r--r--libs/utils/Static.cpp120
-rw-r--r--libs/utils/StopWatch.cpp79
-rw-r--r--libs/utils/String16.cpp609
-rw-r--r--libs/utils/String8.cpp604
-rw-r--r--libs/utils/SystemClock.cpp139
-rw-r--r--libs/utils/TextOutput.cpp146
-rw-r--r--libs/utils/Threads.cpp1126
-rw-r--r--libs/utils/TimerProbe.cpp131
-rw-r--r--libs/utils/Timers.cpp240
-rw-r--r--libs/utils/Unicode.cpp193
-rw-r--r--libs/utils/VectorImpl.cpp611
-rw-r--r--libs/utils/ZipEntry.cpp696
-rw-r--r--libs/utils/ZipFile.cpp1296
-rw-r--r--libs/utils/ZipFileCRO.cpp54
-rw-r--r--libs/utils/ZipFileRO.cpp724
-rw-r--r--libs/utils/ZipUtils.cpp344
-rw-r--r--libs/utils/characterData.h730
-rw-r--r--libs/utils/executablepath_darwin.cpp31
-rw-r--r--libs/utils/executablepath_linux.cpp30
-rw-r--r--libs/utils/futex_synchro.c175
-rw-r--r--libs/utils/misc.cpp185
-rw-r--r--libs/utils/ported.cpp106
148 files changed, 0 insertions, 47776 deletions
diff --git a/libs/audioflinger/A2dpAudioInterface.cpp b/libs/audioflinger/A2dpAudioInterface.cpp
deleted file mode 100644
index d1b7af3..0000000
--- a/libs/audioflinger/A2dpAudioInterface.cpp
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * 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.
- */
-
-#include <math.h>
-
-#define LOG_NDEBUG 0
-#define LOG_TAG "A2dpAudioInterface"
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include "A2dpAudioInterface.h"
-#include "audio/liba2dp.h"
-
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-A2dpAudioInterface::A2dpAudioInterface() :
- mOutput(0)
-{
-}
-
-A2dpAudioInterface::~A2dpAudioInterface()
-{
- delete mOutput;
-}
-
-status_t A2dpAudioInterface::initCheck()
-{
- return 0;
-}
-
-AudioStreamOut* A2dpAudioInterface::openOutputStream(
- int format, int channelCount, uint32_t sampleRate, status_t *status)
-{
- LOGD("A2dpAudioInterface::openOutputStream %d, %d, %d\n", format, channelCount, sampleRate);
- Mutex::Autolock lock(mLock);
- status_t err = 0;
-
- // only one output stream allowed
- if (mOutput) {
- if (status)
- *status = -1;
- return NULL;
- }
-
- // create new output stream
- A2dpAudioStreamOut* out = new A2dpAudioStreamOut();
- if ((err = out->set(format, channelCount, sampleRate)) == NO_ERROR) {
- mOutput = out;
- } else {
- delete out;
- }
-
- if (status)
- *status = err;
- return mOutput;
-}
-
-AudioStreamIn* A2dpAudioInterface::openInputStream(
- int format, int channelCount, uint32_t sampleRate, status_t *status,
- AudioSystem::audio_in_acoustics acoustics)
-{
- if (status)
- *status = -1;
- return NULL;
-}
-
-status_t A2dpAudioInterface::setMicMute(bool state)
-{
- return 0;
-}
-
-status_t A2dpAudioInterface::getMicMute(bool* state)
-{
- return 0;
-}
-
-status_t A2dpAudioInterface::setParameter(const char *key, const char *value)
-{
- LOGD("setParameter %s,%s\n", key, value);
-
- if (!key || !value)
- return -EINVAL;
-
- if (strcmp(key, "a2dp_sink_address") == 0) {
- return mOutput->setAddress(value);
- }
- if (strcmp(key, "bluetooth_enabled") == 0 &&
- strcmp(value, "false") == 0) {
- return mOutput->close();
- }
-
- return 0;
-}
-
-status_t A2dpAudioInterface::setVoiceVolume(float v)
-{
- return 0;
-}
-
-status_t A2dpAudioInterface::setMasterVolume(float v)
-{
- return 0;
-}
-
-status_t A2dpAudioInterface::doRouting()
-{
- return 0;
-}
-
-status_t A2dpAudioInterface::dump(int fd, const Vector<String16>& args)
-{
- return 0;
-}
-
-// ----------------------------------------------------------------------------
-
-A2dpAudioInterface::A2dpAudioStreamOut::A2dpAudioStreamOut() :
- mFd(-1), mStandby(true), mStartCount(0), mRetryCount(0), mData(NULL),
- mInitialized(false)
-{
- // use any address by default
- strncpy(mA2dpAddress, "00:00:00:00:00:00", sizeof(mA2dpAddress));
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::set(
- int format, int channels, uint32_t rate)
-{
- LOGD("A2dpAudioStreamOut::set %d, %d, %d\n", format, channels, rate);
-
- // fix up defaults
- if (format == 0) format = AudioSystem::PCM_16_BIT;
- if (channels == 0) channels = channelCount();
- if (rate == 0) rate = sampleRate();
-
- // check values
- if ((format != AudioSystem::PCM_16_BIT) ||
- (channels != channelCount()) ||
- (rate != sampleRate()))
- return BAD_VALUE;
-
- return NO_ERROR;
-}
-
-A2dpAudioInterface::A2dpAudioStreamOut::~A2dpAudioStreamOut()
-{
- close();
-}
-
-ssize_t A2dpAudioInterface::A2dpAudioStreamOut::write(const void* buffer, size_t bytes)
-{
- status_t status = NO_INIT;
- size_t remaining = bytes;
-
- if (!mInitialized) {
- status = a2dp_init(mA2dpAddress, 44100, 2, &mData);
- if (status < 0) {
- LOGE("a2dp_init failed err: %d\n", status);
- goto Error;
- }
- mInitialized = true;
- }
-
- while (remaining > 0) {
- status = a2dp_write(mData, buffer, remaining);
- if (status <= 0) {
- LOGE("a2dp_write failed err: %d\n", status);
- goto Error;
- }
- remaining -= status;
- buffer = ((char *)buffer) + status;
- }
-
- mStandby = false;
-
- return bytes;
-
-Error:
- close();
- // Simulate audio output timing in case of error
- usleep(bytes * 1000000 / frameSize() / sampleRate());
-
- return status;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::standby()
-{
- int result = 0;
-
- if (!mStandby) {
- result = a2dp_stop(mData);
- if (result == 0)
- mStandby = true;
- }
-
- return result;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::setAddress(const char* address)
-{
- if (strlen(address) < sizeof(mA2dpAddress))
- return -EINVAL;
-
- if (strcmp(address, mA2dpAddress)) {
- strcpy(mA2dpAddress, address);
- close();
- }
-
- return NO_ERROR;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::close()
-{
- if (mData) {
- a2dp_cleanup(mData);
- mData = NULL;
- mInitialized = false;
- }
- return NO_ERROR;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::dump(int fd, const Vector<String16>& args)
-{
- return NO_ERROR;
-}
-
-
-}; // namespace android
diff --git a/libs/audioflinger/A2dpAudioInterface.h b/libs/audioflinger/A2dpAudioInterface.h
deleted file mode 100644
index 5bef5da..0000000
--- a/libs/audioflinger/A2dpAudioInterface.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 A2DP_AUDIO_HARDWARE_H
-#define A2DP_AUDIO_HARDWARE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/threads.h>
-
-#include <hardware_legacy/AudioHardwareBase.h>
-
-
-namespace android {
-
-class A2dpAudioInterface : public AudioHardwareBase
-{
- class A2dpAudioStreamOut;
-
-public:
- A2dpAudioInterface();
- virtual ~A2dpAudioInterface();
- virtual status_t initCheck();
-
- virtual status_t setVoiceVolume(float volume);
- virtual status_t setMasterVolume(float volume);
-
- // mic mute
- virtual status_t setMicMute(bool state);
- virtual status_t getMicMute(bool* state);
-
- // Temporary interface, do not use
- // TODO: Replace with a more generic key:value get/set mechanism
- virtual status_t setParameter(const char *key, const char *value);
-
- // create I/O streams
- virtual AudioStreamOut* openOutputStream(
- int format=0,
- int channelCount=0,
- uint32_t sampleRate=0,
- status_t *status=0);
-
- virtual AudioStreamIn* openInputStream(
- int format,
- int channelCount,
- uint32_t sampleRate,
- status_t *status,
- AudioSystem::audio_in_acoustics acoustics);
-
-protected:
- virtual status_t doRouting();
- virtual status_t dump(int fd, const Vector<String16>& args);
-
-private:
- class A2dpAudioStreamOut : public AudioStreamOut {
- public:
- A2dpAudioStreamOut();
- virtual ~A2dpAudioStreamOut();
- status_t set(int format,
- int channelCount,
- uint32_t sampleRate);
- virtual uint32_t sampleRate() const { return 44100; }
- // SBC codec wants a multiple of 512
- virtual size_t bufferSize() const { return 512 * 20; }
- virtual int channelCount() const { return 2; }
- virtual int format() const { return AudioSystem::PCM_16_BIT; }
- virtual uint32_t latency() const { return ((1000*bufferSize())/frameSize())/sampleRate() + 200; }
- virtual status_t setVolume(float volume) { return INVALID_OPERATION; }
- virtual ssize_t write(const void* buffer, size_t bytes);
- status_t standby();
- status_t close();
- virtual status_t dump(int fd, const Vector<String16>& args);
-
- private:
- friend class A2dpAudioInterface;
- status_t setAddress(const char* address);
-
- private:
- int mFd;
- bool mStandby;
- int mStartCount;
- int mRetryCount;
- char mA2dpAddress[20];
- void* mData;
- bool mInitialized;
- };
-
- Mutex mLock;
- A2dpAudioStreamOut* mOutput;
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // A2DP_AUDIO_HARDWARE_H
diff --git a/libs/audioflinger/Android.mk b/libs/audioflinger/Android.mk
deleted file mode 100644
index 50d516b..0000000
--- a/libs/audioflinger/Android.mk
+++ /dev/null
@@ -1,56 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- AudioHardwareGeneric.cpp \
- AudioHardwareStub.cpp \
- AudioDumpInterface.cpp \
- AudioHardwareInterface.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libutils \
- libmedia \
- libhardware_legacy
-
-ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
- LOCAL_CFLAGS += -DGENERIC_AUDIO
-endif
-
-LOCAL_MODULE:= libaudiointerface
-
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- AudioFlinger.cpp \
- AudioMixer.cpp.arm \
- AudioResampler.cpp.arm \
- AudioResamplerSinc.cpp.arm \
- AudioResamplerCubic.cpp.arm
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libutils \
- libmedia \
- libhardware_legacy
-
-ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
- LOCAL_STATIC_LIBRARIES += libaudiointerface
-else
- LOCAL_SHARED_LIBRARIES += libaudio
-endif
-
-LOCAL_MODULE:= libaudioflinger
-
-ifeq ($(BOARD_HAVE_BLUETOOTH),true)
- LOCAL_SRC_FILES += A2dpAudioInterface.cpp
- LOCAL_SHARED_LIBRARIES += liba2dp
- LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
- LOCAL_C_INCLUDES += $(call include-path-for, bluez-libs)
- LOCAL_C_INCLUDES += $(call include-path-for, bluez-utils)
-endif
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/audioflinger/AudioBufferProvider.h b/libs/audioflinger/AudioBufferProvider.h
deleted file mode 100644
index 1a467c7..0000000
--- a/libs/audioflinger/AudioBufferProvider.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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_AUDIO_BUFFER_PROVIDER_H
-#define ANDROID_AUDIO_BUFFER_PROVIDER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/Errors.h>
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-class AudioBufferProvider
-{
-public:
-
- struct Buffer {
- union {
- void* raw;
- short* i16;
- int8_t* i8;
- };
- size_t frameCount;
- };
-
- virtual status_t getNextBuffer(Buffer* buffer) = 0;
- virtual void releaseBuffer(Buffer* buffer) = 0;
-};
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-
-#endif // ANDROID_AUDIO_BUFFER_PROVIDER_H
diff --git a/libs/audioflinger/AudioDumpInterface.cpp b/libs/audioflinger/AudioDumpInterface.cpp
deleted file mode 100644
index b4940cb..0000000
--- a/libs/audioflinger/AudioDumpInterface.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/* //device/servers/AudioFlinger/AudioDumpInterface.cpp
-**
-** Copyright 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.
-*/
-
-#define LOG_TAG "AudioFlingerDump"
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/Log.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "AudioDumpInterface.h"
-
-namespace android {
-
-bool gFirst = true; // true if first write after a standby
-
-// ----------------------------------------------------------------------------
-
-AudioDumpInterface::AudioDumpInterface(AudioHardwareInterface* hw)
-{
- if(hw == 0) {
- LOGE("Dump construct hw = 0");
- }
- mFinalInterface = hw;
- mStreamOut = 0;
-}
-
-
-AudioDumpInterface::~AudioDumpInterface()
-{
- if(mFinalInterface) delete mFinalInterface;
- if(mStreamOut) delete mStreamOut;
-}
-
-
-AudioStreamOut* AudioDumpInterface::openOutputStream(
- int format, int channelCount, uint32_t sampleRate, status_t *status)
-{
- AudioStreamOut* outFinal = mFinalInterface->openOutputStream(format, channelCount, sampleRate, status);
-
- if(outFinal) {
- mStreamOut = new AudioStreamOutDump(outFinal);
- return mStreamOut;
- } else {
- LOGE("Dump outFinal=0");
- return 0;
- }
-}
-
-// ----------------------------------------------------------------------------
-
-AudioStreamOutDump::AudioStreamOutDump( AudioStreamOut* finalStream)
-{
- mFinalStream = finalStream;
- mOutFile = 0;
-}
-
-
-AudioStreamOutDump::~AudioStreamOutDump()
-{
- Close();
- delete mFinalStream;
-}
-
-ssize_t AudioStreamOutDump::write(const void* buffer, size_t bytes)
-{
- ssize_t ret;
-
- ret = mFinalStream->write(buffer, bytes);
- if(!mOutFile && gFirst) {
- gFirst = false;
- // check if dump file exist
- mOutFile = fopen(FLINGER_DUMP_NAME, "r");
- if(mOutFile) {
- fclose(mOutFile);
- mOutFile = fopen(FLINGER_DUMP_NAME, "ab");
- }
- }
- if (mOutFile) {
- fwrite(buffer, bytes, 1, mOutFile);
- }
- return ret;
-}
-
-status_t AudioStreamOutDump::standby()
-{
- Close();
- gFirst = true;
- return mFinalStream->standby();
-}
-
-
-void AudioStreamOutDump::Close(void)
-{
- if(mOutFile) {
- fclose(mOutFile);
- mOutFile = 0;
- }
-}
-
-}; // namespace android
diff --git a/libs/audioflinger/AudioDumpInterface.h b/libs/audioflinger/AudioDumpInterface.h
deleted file mode 100644
index 9a94102..0000000
--- a/libs/audioflinger/AudioDumpInterface.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* //device/servers/AudioFlinger/AudioDumpInterface.h
-**
-** Copyright 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_AUDIO_DUMP_INTERFACE_H
-#define ANDROID_AUDIO_DUMP_INTERFACE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <hardware_legacy/AudioHardwareBase.h>
-
-namespace android {
-
-#define FLINGER_DUMP_NAME "/data/FlingerOut.pcm" // name of file used for dump
-
-class AudioStreamOutDump : public AudioStreamOut {
-public:
- AudioStreamOutDump( AudioStreamOut* FinalStream);
- ~AudioStreamOutDump();
- virtual ssize_t write(const void* buffer, size_t bytes);
-
- virtual uint32_t sampleRate() const { return mFinalStream->sampleRate(); }
- virtual size_t bufferSize() const { return mFinalStream->bufferSize(); }
- virtual int channelCount() const { return mFinalStream->channelCount(); }
- virtual int format() const { return mFinalStream->format(); }
- virtual uint32_t latency() const { return mFinalStream->latency(); }
- virtual status_t setVolume(float volume)
- { return mFinalStream->setVolume(volume); }
- virtual status_t standby();
- virtual status_t dump(int fd, const Vector<String16>& args) { return mFinalStream->dump(fd, args); }
- void Close(void);
-
-private:
- AudioStreamOut *mFinalStream;
- FILE *mOutFile; // output file
-};
-
-
-class AudioDumpInterface : public AudioHardwareBase
-{
-
-public:
- AudioDumpInterface(AudioHardwareInterface* hw);
- virtual AudioStreamOut* openOutputStream(
- int format=0,
- int channelCount=0,
- uint32_t sampleRate=0,
- status_t *status=0);
- virtual ~AudioDumpInterface();
-
- virtual status_t initCheck()
- {return mFinalInterface->initCheck();}
- virtual status_t setVoiceVolume(float volume)
- {return mFinalInterface->setVoiceVolume(volume);}
- virtual status_t setMasterVolume(float volume)
- {return mFinalInterface->setMasterVolume(volume);}
-
- // mic mute
- virtual status_t setMicMute(bool state)
- {return mFinalInterface->setMicMute(state);}
- virtual status_t getMicMute(bool* state)
- {return mFinalInterface->getMicMute(state);}
-
- virtual status_t setParameter(const char* key, const char* value)
- {return mFinalInterface->setParameter(key, value);}
-
- virtual AudioStreamIn* openInputStream( int format, int channelCount, uint32_t sampleRate, status_t *status,
- AudioSystem::audio_in_acoustics acoustics)
- {return mFinalInterface->openInputStream( format, channelCount, sampleRate, status, acoustics);}
-
- virtual status_t dump(int fd, const Vector<String16>& args) { return mFinalInterface->dumpState(fd, args); }
-
-protected:
- virtual status_t doRouting() {return mFinalInterface->setRouting(mMode, mRoutes[mMode]);}
-
- AudioHardwareInterface *mFinalInterface;
- AudioStreamOutDump *mStreamOut;
-
-};
-
-}; // namespace android
-
-#endif // ANDROID_AUDIO_DUMP_INTERFACE_H
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
deleted file mode 100644
index 557d93b..0000000
--- a/libs/audioflinger/AudioFlinger.cpp
+++ /dev/null
@@ -1,2471 +0,0 @@
-/* //device/include/server/AudioFlinger/AudioFlinger.cpp
-**
-** Copyright 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.
-*/
-
-
-#define LOG_TAG "AudioFlinger"
-//#define LOG_NDEBUG 0
-
-#include <math.h>
-#include <signal.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-
-#include <utils/IServiceManager.h>
-#include <utils/Log.h>
-#include <utils/Parcel.h>
-#include <utils/IPCThreadState.h>
-#include <utils/String16.h>
-#include <utils/threads.h>
-
-#include <cutils/properties.h>
-
-#include <media/AudioTrack.h>
-#include <media/AudioRecord.h>
-
-#include <private/media/AudioTrackShared.h>
-
-#include <hardware_legacy/AudioHardwareInterface.h>
-
-#include "AudioMixer.h"
-#include "AudioFlinger.h"
-
-#ifdef WITH_A2DP
-#include "A2dpAudioInterface.h"
-#endif
-
-// ----------------------------------------------------------------------------
-// the sim build doesn't have gettid
-
-#ifndef HAVE_GETTID
-# define gettid getpid
-#endif
-
-// ----------------------------------------------------------------------------
-
-namespace android {
-
-//static const nsecs_t kStandbyTimeInNsecs = seconds(3);
-static const unsigned long kBufferRecoveryInUsecs = 2000;
-static const unsigned long kMaxBufferRecoveryInUsecs = 20000;
-static const float MAX_GAIN = 4096.0f;
-
-// retry counts for buffer fill timeout
-// 50 * ~20msecs = 1 second
-static const int8_t kMaxTrackRetries = 50;
-static const int8_t kMaxTrackStartupRetries = 50;
-
-static const int kStartSleepTime = 30000;
-static const int kStopSleepTime = 30000;
-
-// Maximum number of pending buffers allocated by OutputTrack::write()
-static const uint8_t kMaxOutputTrackBuffers = 5;
-
-
-#define AUDIOFLINGER_SECURITY_ENABLED 1
-
-// ----------------------------------------------------------------------------
-
-static bool recordingAllowed() {
-#ifndef HAVE_ANDROID_OS
- return true;
-#endif
-#if AUDIOFLINGER_SECURITY_ENABLED
- if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
- bool ok = checkCallingPermission(String16("android.permission.RECORD_AUDIO"));
- if (!ok) LOGE("Request requires android.permission.RECORD_AUDIO");
- return ok;
-#else
- if (!checkCallingPermission(String16("android.permission.RECORD_AUDIO")))
- LOGW("WARNING: Need to add android.permission.RECORD_AUDIO to manifest");
- return true;
-#endif
-}
-
-static bool settingsAllowed() {
-#ifndef HAVE_ANDROID_OS
- return true;
-#endif
-#if AUDIOFLINGER_SECURITY_ENABLED
- if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
- bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
- if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
- return ok;
-#else
- if (!checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS")))
- LOGW("WARNING: Need to add android.permission.MODIFY_AUDIO_SETTINGS to manifest");
- return true;
-#endif
-}
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::AudioFlinger()
- : BnAudioFlinger(),
- mAudioHardware(0), mA2dpAudioInterface(0),
- mA2dpEnabled(false), mA2dpEnabledReq(false),
- mForcedSpeakerCount(0), mForcedRoute(0), mRouteRestoreTime(0), mMusicMuteSaved(false)
-{
- mHardwareStatus = AUDIO_HW_IDLE;
- mAudioHardware = AudioHardwareInterface::create();
- mHardwareStatus = AUDIO_HW_INIT;
- if (mAudioHardware->initCheck() == NO_ERROR) {
- // open 16-bit output stream for s/w mixer
- mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
- status_t status;
- AudioStreamOut *hwOutput = mAudioHardware->openOutputStream(AudioSystem::PCM_16_BIT, 0, 0, &status);
- mHardwareStatus = AUDIO_HW_IDLE;
- if (hwOutput) {
- mHardwareMixerThread = new MixerThread(this, hwOutput, AudioSystem::AUDIO_OUTPUT_HARDWARE);
- } else {
- LOGE("Failed to initialize hardware output stream, status: %d", status);
- }
-
-#ifdef WITH_A2DP
- // Create A2DP interface
- mA2dpAudioInterface = new A2dpAudioInterface();
- AudioStreamOut *a2dpOutput = mA2dpAudioInterface->openOutputStream(AudioSystem::PCM_16_BIT, 0, 0, &status);
- if (a2dpOutput) {
- mA2dpMixerThread = new MixerThread(this, a2dpOutput, AudioSystem::AUDIO_OUTPUT_A2DP);
- if (hwOutput) {
- uint32_t frameCount = ((a2dpOutput->bufferSize()/a2dpOutput->frameSize()) * hwOutput->sampleRate()) / a2dpOutput->sampleRate();
- MixerThread::OutputTrack *a2dpOutTrack = new MixerThread::OutputTrack(mA2dpMixerThread,
- hwOutput->sampleRate(),
- AudioSystem::PCM_16_BIT,
- hwOutput->channelCount(),
- frameCount);
- mHardwareMixerThread->setOuputTrack(a2dpOutTrack);
- }
- } else {
- LOGE("Failed to initialize A2DP output stream, status: %d", status);
- }
-#endif
-
- // FIXME - this should come from settings
- setRouting(AudioSystem::MODE_NORMAL, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
- setRouting(AudioSystem::MODE_RINGTONE, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
- setRouting(AudioSystem::MODE_IN_CALL, AudioSystem::ROUTE_EARPIECE, AudioSystem::ROUTE_ALL);
- setMode(AudioSystem::MODE_NORMAL);
-
- setMasterVolume(1.0f);
- setMasterMute(false);
-
- // Start record thread
- mAudioRecordThread = new AudioRecordThread(mAudioHardware);
- if (mAudioRecordThread != 0) {
- mAudioRecordThread->run("AudioRecordThread", PRIORITY_URGENT_AUDIO);
- }
- } else {
- LOGE("Couldn't even initialize the stubbed audio hardware!");
- }
-
- char value[PROPERTY_VALUE_MAX];
- property_get("ro.audio.silent", value, "0");
- if (atoi(value)) {
- LOGD("Silence is golden");
- setMasterMute(true);
- }
-}
-
-AudioFlinger::~AudioFlinger()
-{
- if (mAudioRecordThread != 0) {
- mAudioRecordThread->exit();
- mAudioRecordThread.clear();
- }
- mHardwareMixerThread.clear();
- delete mAudioHardware;
- // deleting mA2dpAudioInterface also deletes mA2dpOutput;
-#ifdef WITH_A2DP
- mA2dpMixerThread.clear();
- delete mA2dpAudioInterface;
-#endif
-}
-
-
-#ifdef WITH_A2DP
-void AudioFlinger::setA2dpEnabled(bool enable)
-{
- LOGV_IF(enable, "set output to A2DP\n");
- LOGV_IF(!enable, "set output to hardware audio\n");
-
- mA2dpEnabledReq = enable;
- mA2dpMixerThread->wakeUp();
-}
-#endif // WITH_A2DP
-
-bool AudioFlinger::streamForcedToSpeaker(int streamType)
-{
- // NOTE that streams listed here must not be routed to A2DP by default:
- // AudioSystem::routedToA2dpOutput(streamType) == false
- return (streamType == AudioSystem::RING ||
- streamType == AudioSystem::ALARM ||
- streamType == AudioSystem::NOTIFICATION);
-}
-
-status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
-
- result.append("Clients:\n");
- for (size_t i = 0; i < mClients.size(); ++i) {
- wp<Client> wClient = mClients.valueAt(i);
- if (wClient != 0) {
- sp<Client> client = wClient.promote();
- if (client != 0) {
- snprintf(buffer, SIZE, " pid: %d\n", client->pid());
- result.append(buffer);
- }
- }
- }
- write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-
-status_t AudioFlinger::dumpInternals(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
-
- snprintf(buffer, SIZE, "Hardware status: %d\n", mHardwareStatus);
- result.append(buffer);
- write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-status_t AudioFlinger::dumpPermissionDenial(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
- snprintf(buffer, SIZE, "Permission Denial: "
- "can't dump AudioFlinger from pid=%d, uid=%d\n",
- IPCThreadState::self()->getCallingPid(),
- IPCThreadState::self()->getCallingUid());
- result.append(buffer);
- write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
-{
- if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
- dumpPermissionDenial(fd, args);
- } else {
- AutoMutex lock(&mLock);
-
- dumpClients(fd, args);
- dumpInternals(fd, args);
- mHardwareMixerThread->dump(fd, args);
-#ifdef WITH_A2DP
- mA2dpMixerThread->dump(fd, args);
-#endif
-
- // dump record client
- if (mAudioRecordThread != 0) mAudioRecordThread->dump(fd, args);
-
- if (mAudioHardware) {
- mAudioHardware->dumpState(fd, args);
- }
- }
- return NO_ERROR;
-}
-
-// IAudioFlinger interface
-
-
-sp<IAudioTrack> AudioFlinger::createTrack(
- pid_t pid,
- int streamType,
- uint32_t sampleRate,
- int format,
- int channelCount,
- int frameCount,
- uint32_t flags,
- const sp<IMemory>& sharedBuffer,
- status_t *status)
-{
- sp<MixerThread::Track> track;
- sp<TrackHandle> trackHandle;
- sp<Client> client;
- wp<Client> wclient;
- status_t lStatus;
-
- if (streamType >= AudioSystem::NUM_STREAM_TYPES) {
- LOGE("invalid stream type");
- lStatus = BAD_VALUE;
- goto Exit;
- }
-
- {
- Mutex::Autolock _l(mLock);
-
- wclient = mClients.valueFor(pid);
-
- if (wclient != NULL) {
- client = wclient.promote();
- } else {
- client = new Client(this, pid);
- mClients.add(pid, client);
- }
-#ifdef WITH_A2DP
- if (isA2dpEnabled() && AudioSystem::routedToA2dpOutput(streamType)) {
- track = mA2dpMixerThread->createTrack(client, streamType, sampleRate, format,
- channelCount, frameCount, sharedBuffer, &lStatus);
- } else
-#endif
- {
- track = mHardwareMixerThread->createTrack(client, streamType, sampleRate, format,
- channelCount, frameCount, sharedBuffer, &lStatus);
- }
- if (track != NULL) {
- trackHandle = new TrackHandle(track);
- lStatus = NO_ERROR;
- }
- }
-
-Exit:
- if(status) {
- *status = lStatus;
- }
- return trackHandle;
-}
-
-uint32_t AudioFlinger::sampleRate(int output) const
-{
-#ifdef WITH_A2DP
- if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
- return mA2dpMixerThread->sampleRate();
- }
-#endif
- return mHardwareMixerThread->sampleRate();
-}
-
-int AudioFlinger::channelCount(int output) const
-{
-#ifdef WITH_A2DP
- if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
- return mA2dpMixerThread->channelCount();
- }
-#endif
- return mHardwareMixerThread->channelCount();
-}
-
-int AudioFlinger::format(int output) const
-{
-#ifdef WITH_A2DP
- if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
- return mA2dpMixerThread->format();
- }
-#endif
- return mHardwareMixerThread->format();
-}
-
-size_t AudioFlinger::frameCount(int output) const
-{
-#ifdef WITH_A2DP
- if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
- return mA2dpMixerThread->frameCount();
- }
-#endif
- return mHardwareMixerThread->frameCount();
-}
-
-uint32_t AudioFlinger::latency(int output) const
-{
-#ifdef WITH_A2DP
- if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
- return mA2dpMixerThread->latency();
- }
-#endif
- return mHardwareMixerThread->latency();
-}
-
-status_t AudioFlinger::setMasterVolume(float value)
-{
- // check calling permissions
- if (!settingsAllowed()) {
- return PERMISSION_DENIED;
- }
-
- // when hw supports master volume, don't scale in sw mixer
- AutoMutex lock(mHardwareLock);
- mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
- if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
- value = 1.0f;
- }
- mHardwareStatus = AUDIO_HW_IDLE;
- mHardwareMixerThread->setMasterVolume(value);
-#ifdef WITH_A2DP
- mA2dpMixerThread->setMasterVolume(value);
-#endif
-
- return NO_ERROR;
-}
-
-status_t AudioFlinger::setRouting(int mode, uint32_t routes, uint32_t mask)
-{
- status_t err = NO_ERROR;
-
- // check calling permissions
- if (!settingsAllowed()) {
- return PERMISSION_DENIED;
- }
- if ((mode < AudioSystem::MODE_CURRENT) || (mode >= AudioSystem::NUM_MODES)) {
- LOGW("Illegal value: setRouting(%d, %u, %u)", mode, routes, mask);
- return BAD_VALUE;
- }
-
-#ifdef WITH_A2DP
- LOGD("setRouting %d %d %d, tid %d, calling tid %d\n", mode, routes, mask, gettid(), IPCThreadState::self()->getCallingPid());
- if (mode == AudioSystem::MODE_NORMAL &&
- (mask & AudioSystem::ROUTE_BLUETOOTH_A2DP)) {
- AutoMutex lock(&mLock);
-
- bool enableA2dp = false;
- if (routes & AudioSystem::ROUTE_BLUETOOTH_A2DP) {
- enableA2dp = true;
- }
- setA2dpEnabled(enableA2dp);
- LOGV("setOutput done\n");
- }
-#endif
-
- // do nothing if only A2DP routing is affected
- mask &= ~AudioSystem::ROUTE_BLUETOOTH_A2DP;
- if (mask) {
- AutoMutex lock(mHardwareLock);
- mHardwareStatus = AUDIO_HW_GET_ROUTING;
- uint32_t r;
- err = mAudioHardware->getRouting(mode, &r);
- if (err == NO_ERROR) {
- r = (r & ~mask) | (routes & mask);
- if (mode == AudioSystem::MODE_NORMAL ||
- (mode == AudioSystem::MODE_CURRENT && getMode() == AudioSystem::MODE_NORMAL)) {
- mSavedRoute = r;
- r |= mForcedRoute;
- LOGV("setRouting mSavedRoute %08x mForcedRoute %08x\n", mSavedRoute, mForcedRoute);
- }
- mHardwareStatus = AUDIO_HW_SET_ROUTING;
- err = mAudioHardware->setRouting(mode, r);
- }
- mHardwareStatus = AUDIO_HW_IDLE;
- }
- return err;
-}
-
-uint32_t AudioFlinger::getRouting(int mode) const
-{
- uint32_t routes = 0;
- if ((mode >= AudioSystem::MODE_CURRENT) && (mode < AudioSystem::NUM_MODES)) {
- if (mode == AudioSystem::MODE_NORMAL ||
- (mode == AudioSystem::MODE_CURRENT && getMode() == AudioSystem::MODE_NORMAL)) {
- routes = mSavedRoute;
- } else {
- mHardwareStatus = AUDIO_HW_GET_ROUTING;
- mAudioHardware->getRouting(mode, &routes);
- mHardwareStatus = AUDIO_HW_IDLE;
- }
- } else {
- LOGW("Illegal value: getRouting(%d)", mode);
- }
- return routes;
-}
-
-status_t AudioFlinger::setMode(int mode)
-{
- // check calling permissions
- if (!settingsAllowed()) {
- return PERMISSION_DENIED;
- }
- if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) {
- LOGW("Illegal value: setMode(%d)", mode);
- return BAD_VALUE;
- }
-
- AutoMutex lock(mHardwareLock);
- mHardwareStatus = AUDIO_HW_SET_MODE;
- status_t ret = mAudioHardware->setMode(mode);
- mHardwareStatus = AUDIO_HW_IDLE;
- return ret;
-}
-
-int AudioFlinger::getMode() const
-{
- int mode = AudioSystem::MODE_INVALID;
- mHardwareStatus = AUDIO_HW_SET_MODE;
- mAudioHardware->getMode(&mode);
- mHardwareStatus = AUDIO_HW_IDLE;
- return mode;
-}
-
-status_t AudioFlinger::setMicMute(bool state)
-{
- // check calling permissions
- if (!settingsAllowed()) {
- return PERMISSION_DENIED;
- }
-
- AutoMutex lock(mHardwareLock);
- mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
- status_t ret = mAudioHardware->setMicMute(state);
- mHardwareStatus = AUDIO_HW_IDLE;
- return ret;
-}
-
-bool AudioFlinger::getMicMute() const
-{
- bool state = AudioSystem::MODE_INVALID;
- mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
- mAudioHardware->getMicMute(&state);
- mHardwareStatus = AUDIO_HW_IDLE;
- return state;
-}
-
-status_t AudioFlinger::setMasterMute(bool muted)
-{
- // check calling permissions
- if (!settingsAllowed()) {
- return PERMISSION_DENIED;
- }
- mHardwareMixerThread->setMasterMute(muted);
-#ifdef WITH_A2DP
- mA2dpMixerThread->setMasterMute(muted);
-#endif
- return NO_ERROR;
-}
-
-float AudioFlinger::masterVolume() const
-{
- return mHardwareMixerThread->masterVolume();
-}
-
-bool AudioFlinger::masterMute() const
-{
- return mHardwareMixerThread->masterMute();
-}
-
-status_t AudioFlinger::setStreamVolume(int stream, float value)
-{
- // check calling permissions
- if (!settingsAllowed()) {
- return PERMISSION_DENIED;
- }
-
- if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
- return BAD_VALUE;
- }
-
- mHardwareMixerThread->setStreamVolume(stream, value);
-#ifdef WITH_A2DP
- mA2dpMixerThread->setStreamVolume(stream, value);
-#endif
-
- status_t ret = NO_ERROR;
- if (stream == AudioSystem::VOICE_CALL ||
- stream == AudioSystem::BLUETOOTH_SCO) {
-
- if (stream == AudioSystem::VOICE_CALL) {
- value = (float)AudioSystem::logToLinear(value)/100.0f;
- } else { // (type == AudioSystem::BLUETOOTH_SCO)
- value = 1.0f;
- }
-
- AutoMutex lock(mHardwareLock);
- mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
- ret = mAudioHardware->setVoiceVolume(value);
- mHardwareStatus = AUDIO_HW_IDLE;
- }
-
- return ret;
-}
-
-status_t AudioFlinger::setStreamMute(int stream, bool muted)
-{
- // check calling permissions
- if (!settingsAllowed()) {
- return PERMISSION_DENIED;
- }
-
- if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
- return BAD_VALUE;
- }
-
-#ifdef WITH_A2DP
- mA2dpMixerThread->setStreamMute(stream, muted);
-#endif
- if (stream == AudioSystem::MUSIC)
- {
- AutoMutex lock(&mHardwareLock);
- if (mForcedRoute != 0)
- mMusicMuteSaved = muted;
- else
- mHardwareMixerThread->setStreamMute(stream, muted);
- } else {
- mHardwareMixerThread->setStreamMute(stream, muted);
- }
-
-
-
- return NO_ERROR;
-}
-
-float AudioFlinger::streamVolume(int stream) const
-{
- if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
- return 0.0f;
- }
- return mHardwareMixerThread->streamVolume(stream);
-}
-
-bool AudioFlinger::streamMute(int stream) const
-{
- if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
- return true;
- }
-
- if (stream == AudioSystem::MUSIC && mForcedRoute != 0)
- {
- return mMusicMuteSaved;
- }
- return mHardwareMixerThread->streamMute(stream);
-}
-
-bool AudioFlinger::isMusicActive() const
-{
- #ifdef WITH_A2DP
- if (isA2dpEnabled()) {
- return mA2dpMixerThread->isMusicActive();
- }
- #endif
- return mHardwareMixerThread->isMusicActive();
-}
-
-status_t AudioFlinger::setParameter(const char* key, const char* value)
-{
- status_t result, result2;
- AutoMutex lock(mHardwareLock);
- mHardwareStatus = AUDIO_SET_PARAMETER;
-
- LOGV("setParameter() key %s, value %s, tid %d, calling tid %d", key, value, gettid(), IPCThreadState::self()->getCallingPid());
- result = mAudioHardware->setParameter(key, value);
- if (mA2dpAudioInterface) {
- result2 = mA2dpAudioInterface->setParameter(key, value);
- if (result2)
- result = result2;
- }
- mHardwareStatus = AUDIO_HW_IDLE;
- return result;
-}
-
-size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
-{
- return mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
-}
-
-void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
-{
-
- LOGV("registerClient() %p, tid %d, calling tid %d", client.get(), gettid(), IPCThreadState::self()->getCallingPid());
- Mutex::Autolock _l(mLock);
-
- sp<IBinder> binder = client->asBinder();
- if (mNotificationClients.indexOf(binder) < 0) {
- LOGV("Adding notification client %p", binder.get());
- binder->linkToDeath(this);
- mNotificationClients.add(binder);
- client->a2dpEnabledChanged(isA2dpEnabled());
- }
-}
-
-void AudioFlinger::binderDied(const wp<IBinder>& who) {
-
- LOGV("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
- Mutex::Autolock _l(mLock);
-
- IBinder *binder = who.unsafe_get();
-
- if (binder != NULL) {
- int index = mNotificationClients.indexOf(binder);
- if (index >= 0) {
- LOGV("Removing notification client %p", binder);
- mNotificationClients.removeAt(index);
- }
- }
-}
-
-void AudioFlinger::handleOutputSwitch()
-{
- if (mA2dpEnabled != mA2dpEnabledReq)
- {
- Mutex::Autolock _l(mLock);
-
- if (mA2dpEnabled != mA2dpEnabledReq)
- {
- mA2dpEnabled = mA2dpEnabledReq;
- SortedVector < sp<MixerThread::Track> > tracks;
- SortedVector < wp<MixerThread::Track> > activeTracks;
-
- // We hold mA2dpMixerThread mLock already
- Mutex::Autolock _l(mHardwareMixerThread->mLock);
-
- // Transfer tracks playing on MUSIC stream from one mixer to the other
- if (mA2dpEnabled) {
- mHardwareMixerThread->getTracks(tracks, activeTracks);
- mA2dpMixerThread->putTracks(tracks, activeTracks);
- } else {
- mA2dpMixerThread->getTracks(tracks, activeTracks);
- mHardwareMixerThread->putTracks(tracks, activeTracks);
- }
-
- // Notify AudioSystem of the A2DP activation/deactivation
- size_t size = mNotificationClients.size();
- for (size_t i = 0; i < size; i++) {
- sp<IBinder> binder = mNotificationClients.itemAt(i).promote();
- if (binder != NULL) {
- LOGV("Notifying output change to client %p", binder.get());
- sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient> (binder);
- client->a2dpEnabledChanged(mA2dpEnabled);
- }
- }
-
- mHardwareMixerThread->wakeUp();
- }
- }
-}
-
-void AudioFlinger::removeClient(pid_t pid)
-{
- LOGV("removeClient() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid());
- Mutex::Autolock _l(mLock);
- mClients.removeItem(pid);
-}
-
-void AudioFlinger::wakeUp()
-{
- mHardwareMixerThread->wakeUp();
-#ifdef WITH_A2DP
- mA2dpMixerThread->wakeUp();
-#endif // WITH_A2DP
-}
-
-bool AudioFlinger::isA2dpEnabled() const
-{
- return mA2dpEnabledReq;
-}
-
-void AudioFlinger::handleForcedSpeakerRoute(int command)
-{
- switch(command) {
- case ACTIVE_TRACK_ADDED:
- {
- AutoMutex lock(mHardwareLock);
- if (mForcedSpeakerCount++ == 0) {
- mRouteRestoreTime = 0;
- mMusicMuteSaved = mHardwareMixerThread->streamMute(AudioSystem::MUSIC);
- if (mForcedRoute == 0 && !(mSavedRoute & AudioSystem::ROUTE_SPEAKER)) {
- LOGV("Route forced to Speaker ON %08x", mSavedRoute | AudioSystem::ROUTE_SPEAKER);
- mHardwareMixerThread->setStreamMute(AudioSystem::MUSIC, true);
- mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
- mAudioHardware->setMasterVolume(0);
- usleep(mHardwareMixerThread->latency()*1000);
- mHardwareStatus = AUDIO_HW_SET_ROUTING;
- mAudioHardware->setRouting(AudioSystem::MODE_NORMAL, mSavedRoute | AudioSystem::ROUTE_SPEAKER);
- mHardwareStatus = AUDIO_HW_IDLE;
- // delay track start so that audio hardware has time to siwtch routes
- usleep(kStartSleepTime);
- mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
- mAudioHardware->setMasterVolume(mHardwareMixerThread->masterVolume());
- mHardwareStatus = AUDIO_HW_IDLE;
- }
- mForcedRoute = AudioSystem::ROUTE_SPEAKER;
- }
- LOGV("mForcedSpeakerCount incremented to %d", mForcedSpeakerCount);
- }
- break;
- case ACTIVE_TRACK_REMOVED:
- {
- AutoMutex lock(mHardwareLock);
- if (mForcedSpeakerCount > 0){
- if (--mForcedSpeakerCount == 0) {
- mRouteRestoreTime = systemTime() + milliseconds(kStopSleepTime/1000);
- }
- LOGV("mForcedSpeakerCount decremented to %d", mForcedSpeakerCount);
- } else {
- LOGE("mForcedSpeakerCount is already zero");
- }
- }
- break;
- case CHECK_ROUTE_RESTORE_TIME:
- case FORCE_ROUTE_RESTORE:
- if (mRouteRestoreTime) {
- AutoMutex lock(mHardwareLock);
- if (mRouteRestoreTime &&
- (systemTime() > mRouteRestoreTime || command == FORCE_ROUTE_RESTORE)) {
- mHardwareMixerThread->setStreamMute(AudioSystem::MUSIC, mMusicMuteSaved);
- mForcedRoute = 0;
- if (!(mSavedRoute & AudioSystem::ROUTE_SPEAKER)) {
- mHardwareStatus = AUDIO_HW_SET_ROUTING;
- mAudioHardware->setRouting(AudioSystem::MODE_NORMAL, mSavedRoute);
- mHardwareStatus = AUDIO_HW_IDLE;
- LOGV("Route forced to Speaker OFF %08x", mSavedRoute);
- }
- mRouteRestoreTime = 0;
- }
- }
- break;
- }
-}
-
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int outputType)
- : Thread(false),
- mAudioFlinger(audioFlinger), mAudioMixer(0), mOutput(output), mOutputType(outputType),
- mSampleRate(0), mFrameCount(0), mChannelCount(0), mFormat(0), mMixBuffer(0),
- mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mStandby(false),
- mInWrite(false)
-{
- mSampleRate = output->sampleRate();
- mChannelCount = output->channelCount();
-
- // FIXME - Current mixer implementation only supports stereo output
- if (mChannelCount == 1) {
- LOGE("Invalid audio hardware channel count");
- }
-
- mFormat = output->format();
- mFrameCount = output->bufferSize() / output->channelCount() / sizeof(int16_t);
- mAudioMixer = new AudioMixer(mFrameCount, output->sampleRate());
-
- // FIXME - Current mixer implementation only supports stereo output: Always
- // Allocate a stereo buffer even if HW output is mono.
- mMixBuffer = new int16_t[mFrameCount * 2];
- memset(mMixBuffer, 0, mFrameCount * 2 * sizeof(int16_t));
-}
-
-AudioFlinger::MixerThread::~MixerThread()
-{
- delete [] mMixBuffer;
- delete mAudioMixer;
-}
-
-status_t AudioFlinger::MixerThread::dump(int fd, const Vector<String16>& args)
-{
- dumpInternals(fd, args);
- dumpTracks(fd, args);
- return NO_ERROR;
-}
-
-status_t AudioFlinger::MixerThread::dumpTracks(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
-
- snprintf(buffer, SIZE, "Output %d mixer thread tracks\n", mOutputType);
- result.append(buffer);
- result.append(" Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
- for (size_t i = 0; i < mTracks.size(); ++i) {
- wp<Track> wTrack = mTracks[i];
- if (wTrack != 0) {
- sp<Track> track = wTrack.promote();
- if (track != 0) {
- track->dump(buffer, SIZE);
- result.append(buffer);
- }
- }
- }
-
- snprintf(buffer, SIZE, "Output %d mixer thread active tracks\n", mOutputType);
- result.append(buffer);
- result.append(" Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
- for (size_t i = 0; i < mActiveTracks.size(); ++i) {
- wp<Track> wTrack = mTracks[i];
- if (wTrack != 0) {
- sp<Track> track = wTrack.promote();
- if (track != 0) {
- track->dump(buffer, SIZE);
- result.append(buffer);
- }
- }
- }
- write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-status_t AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
-
- snprintf(buffer, SIZE, "Output %d mixer thread internals\n", mOutputType);
- result.append(buffer);
- snprintf(buffer, SIZE, "AudioMixer tracks: %08x\n", mAudioMixer->trackNames());
- result.append(buffer);
- snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
- result.append(buffer);
- snprintf(buffer, SIZE, "total writes: %d\n", mNumWrites);
- result.append(buffer);
- snprintf(buffer, SIZE, "delayed writes: %d\n", mNumDelayedWrites);
- result.append(buffer);
- snprintf(buffer, SIZE, "blocked in write: %d\n", mInWrite);
- result.append(buffer);
- snprintf(buffer, SIZE, "standby: %d\n", mStandby);
- result.append(buffer);
- write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-// Thread virtuals
-bool AudioFlinger::MixerThread::threadLoop()
-{
- unsigned long sleepTime = kBufferRecoveryInUsecs;
- int16_t* curBuf = mMixBuffer;
- Vector< sp<Track> > tracksToRemove;
- size_t enabledTracks = 0;
- nsecs_t standbyTime = systemTime();
- size_t mixBufferSize = mFrameCount*mChannelCount*sizeof(int16_t);
- nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 2;
-
-#ifdef WITH_A2DP
- bool outputTrackActive = false;
-#endif
-
- do {
- enabledTracks = 0;
- { // scope for the mLock
-
- Mutex::Autolock _l(mLock);
-
-#ifdef WITH_A2DP
- if (mOutputType == AudioSystem::AUDIO_OUTPUT_A2DP) {
- mAudioFlinger->handleOutputSwitch();
- }
- if (mOutputTrack != NULL && !mAudioFlinger->isA2dpEnabled()) {
- if (outputTrackActive) {
- mOutputTrack->stop();
- outputTrackActive = false;
- }
- }
-#endif
-
- const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
-
- // put audio hardware into standby after short delay
- if UNLIKELY(!activeTracks.size() && systemTime() > standbyTime) {
- // wait until we have something to do...
- LOGV("Audio hardware entering standby, output %d\n", mOutputType);
-// mAudioFlinger->mHardwareStatus = AUDIO_HW_STANDBY;
- if (!mStandby) {
- mOutput->standby();
- mStandby = true;
- }
-
-#ifdef WITH_A2DP
- if (outputTrackActive) {
- mOutputTrack->stop();
- outputTrackActive = false;
- }
-#endif
- if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
- mAudioFlinger->handleForcedSpeakerRoute(FORCE_ROUTE_RESTORE);
- }
-// mHardwareStatus = AUDIO_HW_IDLE;
- // we're about to wait, flush the binder command buffer
- IPCThreadState::self()->flushCommands();
- mWaitWorkCV.wait(mLock);
- LOGV("Audio hardware exiting standby, output %d\n", mOutputType);
- standbyTime = systemTime() + kStandbyTimeInNsecs;
- continue;
- }
-
- // Forced route to speaker is handled by hardware mixer thread
- if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
- mAudioFlinger->handleForcedSpeakerRoute(CHECK_ROUTE_RESTORE_TIME);
- }
-
- // find out which tracks need to be processed
- size_t count = activeTracks.size();
- for (size_t i=0 ; i<count ; i++) {
- sp<Track> t = activeTracks[i].promote();
- if (t == 0) continue;
-
- Track* const track = t.get();
- audio_track_cblk_t* cblk = track->cblk();
-
- // The first time a track is added we wait
- // for all its buffers to be filled before processing it
- mAudioMixer->setActiveTrack(track->name());
- if (cblk->framesReady() && (track->isReady() || track->isStopped()) &&
- !track->isPaused())
- {
- //LOGV("track %d u=%08x, s=%08x [OK]", track->name(), cblk->user, cblk->server);
-
- // compute volume for this track
- int16_t left, right;
- if (track->isMuted() || mMasterMute || track->isPausing()) {
- left = right = 0;
- if (track->isPausing()) {
- LOGV("paused(%d)", track->name());
- track->setPaused();
- }
- } else {
- float typeVolume = mStreamTypes[track->type()].volume;
- float v = mMasterVolume * typeVolume;
- float v_clamped = v * cblk->volume[0];
- if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
- left = int16_t(v_clamped);
- v_clamped = v * cblk->volume[1];
- if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
- right = int16_t(v_clamped);
- }
-
- // XXX: these things DON'T need to be done each time
- mAudioMixer->setBufferProvider(track);
- mAudioMixer->enable(AudioMixer::MIXING);
-
- int param;
- if ( track->mFillingUpStatus == Track::FS_FILLED) {
- // no ramp for the first volume setting
- track->mFillingUpStatus = Track::FS_ACTIVE;
- if (track->mState == TrackBase::RESUMING) {
- track->mState = TrackBase::ACTIVE;
- param = AudioMixer::RAMP_VOLUME;
- } else {
- param = AudioMixer::VOLUME;
- }
- } else {
- param = AudioMixer::RAMP_VOLUME;
- }
- mAudioMixer->setParameter(param, AudioMixer::VOLUME0, left);
- mAudioMixer->setParameter(param, AudioMixer::VOLUME1, right);
- mAudioMixer->setParameter(
- AudioMixer::TRACK,
- AudioMixer::FORMAT, track->format());
- mAudioMixer->setParameter(
- AudioMixer::TRACK,
- AudioMixer::CHANNEL_COUNT, track->channelCount());
- mAudioMixer->setParameter(
- AudioMixer::RESAMPLE,
- AudioMixer::SAMPLE_RATE,
- int(cblk->sampleRate));
-
- // reset retry count
- track->mRetryCount = kMaxTrackRetries;
- enabledTracks++;
- } else {
- //LOGV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server);
- if (track->isStopped()) {
- track->reset();
- }
- if (track->isTerminated() || track->isStopped() || track->isPaused()) {
- // We have consumed all the buffers of this track.
- // Remove it from the list of active tracks.
- LOGV("remove(%d) from active list", track->name());
- tracksToRemove.add(track);
- } else {
- // No buffers for this track. Give it a few chances to
- // fill a buffer, then remove it from active list.
- if (--(track->mRetryCount) <= 0) {
- LOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
- tracksToRemove.add(track);
- }
- }
- // LOGV("disable(%d)", track->name());
- mAudioMixer->disable(AudioMixer::MIXING);
- }
- }
-
- // remove all the tracks that need to be...
- count = tracksToRemove.size();
- if (UNLIKELY(count)) {
- for (size_t i=0 ; i<count ; i++) {
- const sp<Track>& track = tracksToRemove[i];
- removeActiveTrack(track);
- if (track->isTerminated()) {
- mTracks.remove(track);
- deleteTrackName(track->mName);
- }
- }
- }
- }
-
- if (LIKELY(enabledTracks)) {
- // mix buffers...
- mAudioMixer->process(curBuf);
-
-#ifdef WITH_A2DP
- if (mOutputTrack != NULL && mAudioFlinger->isA2dpEnabled()) {
- if (!outputTrackActive) {
- LOGV("starting output track in mixer for output %d", mOutputType);
- mOutputTrack->start();
- outputTrackActive = true;
- }
- mOutputTrack->write(curBuf, mFrameCount);
- }
-#endif
-
- // output audio to hardware
- mLastWriteTime = systemTime();
- mInWrite = true;
- mOutput->write(curBuf, mixBufferSize);
- mNumWrites++;
- mInWrite = false;
- mStandby = false;
- nsecs_t temp = systemTime();
- standbyTime = temp + kStandbyTimeInNsecs;
- nsecs_t delta = temp - mLastWriteTime;
- if (delta > maxPeriod) {
- LOGW("write blocked for %llu msecs", ns2ms(delta));
- mNumDelayedWrites++;
- }
- sleepTime = kBufferRecoveryInUsecs;
- } else {
-#ifdef WITH_A2DP
- if (mOutputTrack != NULL && mAudioFlinger->isA2dpEnabled()) {
- if (outputTrackActive) {
- mOutputTrack->write(curBuf, 0);
- if (mOutputTrack->bufferQueueEmpty()) {
- mOutputTrack->stop();
- outputTrackActive = false;
- } else {
- standbyTime = systemTime() + kStandbyTimeInNsecs;
- }
- }
- }
-#endif
- // There was nothing to mix this round, which means all
- // active tracks were late. Sleep a little bit to give
- // them another chance. If we're too late, the audio
- // hardware will zero-fill for us.
- //LOGV("no buffers - usleep(%lu)", sleepTime);
- usleep(sleepTime);
- if (sleepTime < kMaxBufferRecoveryInUsecs) {
- sleepTime += kBufferRecoveryInUsecs;
- }
- }
-
- // finally let go of all our tracks, without the lock held
- // since we can't guarantee the destructors won't acquire that
- // same lock.
- tracksToRemove.clear();
- } while (true);
-
- return false;
-}
-
-status_t AudioFlinger::MixerThread::readyToRun()
-{
- if (mSampleRate == 0) {
- LOGE("No working audio driver found.");
- return NO_INIT;
- }
- LOGI("AudioFlinger's thread ready to run for output %d", mOutputType);
- return NO_ERROR;
-}
-
-void AudioFlinger::MixerThread::onFirstRef()
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
-
- snprintf(buffer, SIZE, "Mixer Thread for output %d", mOutputType);
-
- run(buffer, ANDROID_PRIORITY_URGENT_AUDIO);
-}
-
-
-sp<AudioFlinger::MixerThread::Track> AudioFlinger::MixerThread::createTrack(
- const sp<AudioFlinger::Client>& client,
- int streamType,
- uint32_t sampleRate,
- int format,
- int channelCount,
- int frameCount,
- const sp<IMemory>& sharedBuffer,
- status_t *status)
-{
- sp<Track> track;
- status_t lStatus;
-
- // Resampler implementation limits input sampling rate to 2 x output sampling rate.
- if (sampleRate > MAX_SAMPLE_RATE || sampleRate > mSampleRate*2) {
- LOGE("Sample rate out of range: %d mSampleRate %d", sampleRate, mSampleRate);
- lStatus = BAD_VALUE;
- goto Exit;
- }
-
- {
- Mutex::Autolock _l(mLock);
-
- if (mSampleRate == 0) {
- LOGE("Audio driver not initialized.");
- lStatus = NO_INIT;
- goto Exit;
- }
-
- track = new Track(this, client, streamType, sampleRate, format,
- channelCount, frameCount, sharedBuffer);
- if (track->getCblk() == NULL) {
- track.clear();
- lStatus = NO_MEMORY;
- goto Exit;
- }
- mTracks.add(track);
- lStatus = NO_ERROR;
- }
-
-Exit:
- if(status) {
- *status = lStatus;
- }
- return track;
-}
-
-void AudioFlinger::MixerThread::getTracks(
- SortedVector < sp<Track> >& tracks,
- SortedVector < wp<Track> >& activeTracks)
-{
- size_t size = mTracks.size();
- LOGV ("MixerThread::getTracks() for output %d, mTracks.size %d, mActiveTracks.size %d", mOutputType, mTracks.size(), mActiveTracks.size());
- for (size_t i = 0; i < size; i++) {
- sp<Track> t = mTracks[i];
- if (AudioSystem::routedToA2dpOutput(t->mStreamType)) {
- tracks.add(t);
- int j = mActiveTracks.indexOf(t);
- if (j >= 0) {
- t = mActiveTracks[j].promote();
- if (t != NULL) {
- activeTracks.add(t);
- }
- }
- }
- }
-
- size = activeTracks.size();
- for (size_t i = 0; i < size; i++) {
- removeActiveTrack(activeTracks[i]);
- }
-
- size = tracks.size();
- for (size_t i = 0; i < size; i++) {
- sp<Track> t = tracks[i];
- mTracks.remove(t);
- deleteTrackName(t->name());
- }
-}
-
-void AudioFlinger::MixerThread::putTracks(
- SortedVector < sp<Track> >& tracks,
- SortedVector < wp<Track> >& activeTracks)
-{
-
- LOGV ("MixerThread::putTracks() for output %d, tracks.size %d, activeTracks.size %d", mOutputType, tracks.size(), activeTracks.size());
-
- size_t size = tracks.size();
- for (size_t i = 0; i < size ; i++) {
- sp<Track> t = tracks[i];
- int name = getTrackName();
-
- if (name < 0) return;
-
- t->mName = name;
- t->mMixerThread = this;
- mTracks.add(t);
-
- int j = activeTracks.indexOf(t);
- if (j >= 0) {
- addActiveTrack(t);
- }
- }
-}
-
-uint32_t AudioFlinger::MixerThread::sampleRate() const
-{
- return mSampleRate;
-}
-
-int AudioFlinger::MixerThread::channelCount() const
-{
- return mChannelCount;
-}
-
-int AudioFlinger::MixerThread::format() const
-{
- return mFormat;
-}
-
-size_t AudioFlinger::MixerThread::frameCount() const
-{
- return mFrameCount;
-}
-
-uint32_t AudioFlinger::MixerThread::latency() const
-{
- if (mOutput) {
- return mOutput->latency();
- }
- else {
- return 0;
- }
-}
-
-status_t AudioFlinger::MixerThread::setMasterVolume(float value)
-{
- mMasterVolume = value;
- return NO_ERROR;
-}
-
-status_t AudioFlinger::MixerThread::setMasterMute(bool muted)
-{
- mMasterMute = muted;
- return NO_ERROR;
-}
-
-float AudioFlinger::MixerThread::masterVolume() const
-{
- return mMasterVolume;
-}
-
-bool AudioFlinger::MixerThread::masterMute() const
-{
- return mMasterMute;
-}
-
-status_t AudioFlinger::MixerThread::setStreamVolume(int stream, float value)
-{
- mStreamTypes[stream].volume = value;
- return NO_ERROR;
-}
-
-status_t AudioFlinger::MixerThread::setStreamMute(int stream, bool muted)
-{
- mStreamTypes[stream].mute = muted;
- return NO_ERROR;
-}
-
-float AudioFlinger::MixerThread::streamVolume(int stream) const
-{
- return mStreamTypes[stream].volume;
-}
-
-bool AudioFlinger::MixerThread::streamMute(int stream) const
-{
- return mStreamTypes[stream].mute;
-}
-
-bool AudioFlinger::MixerThread::isMusicActive() const
-{
- size_t count = mActiveTracks.size();
- for (size_t i = 0 ; i < count ; ++i) {
- sp<Track> t = mActiveTracks[i].promote();
- if (t == 0) continue;
- Track* const track = t.get();
- if (t->mStreamType == AudioSystem::MUSIC)
- return true;
- }
- return false;
-}
-
-status_t AudioFlinger::MixerThread::addTrack(const sp<Track>& track)
-{
- status_t status = ALREADY_EXISTS;
- Mutex::Autolock _l(mLock);
-
- // here the track could be either new, or restarted
- // in both cases "unstop" the track
- if (track->isPaused()) {
- track->mState = TrackBase::RESUMING;
- LOGV("PAUSED => RESUMING (%d)", track->name());
- } else {
- track->mState = TrackBase::ACTIVE;
- LOGV("? => ACTIVE (%d)", track->name());
- }
- // set retry count for buffer fill
- track->mRetryCount = kMaxTrackStartupRetries;
- if (mActiveTracks.indexOf(track) < 0) {
- // the track is newly added, make sure it fills up all its
- // buffers before playing. This is to ensure the client will
- // effectively get the latency it requested.
- track->mFillingUpStatus = Track::FS_FILLING;
- track->mResetDone = false;
- addActiveTrack(track);
- status = NO_ERROR;
- }
-
- LOGV("mWaitWorkCV.broadcast");
- mWaitWorkCV.broadcast();
-
- return status;
-}
-
-void AudioFlinger::MixerThread::removeTrack(wp<Track> track, int name)
-{
- Mutex::Autolock _l(mLock);
- sp<Track> t = track.promote();
- if (t!=NULL && (t->mState <= TrackBase::STOPPED)) {
- remove_track_l(track, name);
- }
-}
-
-void AudioFlinger::MixerThread::remove_track_l(wp<Track> track, int name)
-{
- sp<Track> t = track.promote();
- if (t!=NULL) {
- t->reset();
- }
- deleteTrackName(name);
- removeActiveTrack(track);
- mWaitWorkCV.broadcast();
-}
-
-void AudioFlinger::MixerThread::destroyTrack(const sp<Track>& track)
-{
- // NOTE: We're acquiring a strong reference on the track before
- // acquiring the lock, this is to make sure removing it from
- // mTracks won't cause the destructor to be called while the lock is
- // held (note that technically, 'track' could be a reference to an item
- // in mTracks, which is why we need to do this).
- sp<Track> keep(track);
- Mutex::Autolock _l(mLock);
- track->mState = TrackBase::TERMINATED;
- if (mActiveTracks.indexOf(track) < 0) {
- LOGV("remove track (%d) and delete from mixer", track->name());
- mTracks.remove(track);
- deleteTrackName(keep->name());
- }
-}
-
-
-void AudioFlinger::MixerThread::addActiveTrack(const wp<Track>& t)
-{
- mActiveTracks.add(t);
-
- // Force routing to speaker for certain stream types
- // The forced routing to speaker is managed by hardware mixer
- if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
- sp<Track> track = t.promote();
- if (track == NULL) return;
-
- if (streamForcedToSpeaker(track->type())) {
- mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_ADDED);
- }
- }
-}
-
-void AudioFlinger::MixerThread::removeActiveTrack(const wp<Track>& t)
-{
- mActiveTracks.remove(t);
-
- // Force routing to speaker for certain stream types
- // The forced routing to speaker is managed by hardware mixer
- if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
- sp<Track> track = t.promote();
- if (track == NULL) return;
-
- if (streamForcedToSpeaker(track->type())) {
- mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_REMOVED);
- }
- }
-}
-
-int AudioFlinger::MixerThread::getTrackName()
-{
- return mAudioMixer->getTrackName();
-}
-
-void AudioFlinger::MixerThread::deleteTrackName(int name)
-{
- mAudioMixer->deleteTrackName(name);
-}
-
-size_t AudioFlinger::MixerThread::getOutputFrameCount()
-{
- return mOutput->bufferSize() / mOutput->channelCount() / sizeof(int16_t);
-}
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::MixerThread::TrackBase::TrackBase(
- const sp<MixerThread>& mixerThread,
- const sp<Client>& client,
- int streamType,
- uint32_t sampleRate,
- int format,
- int channelCount,
- int frameCount,
- uint32_t flags,
- const sp<IMemory>& sharedBuffer)
- : RefBase(),
- mMixerThread(mixerThread),
- mClient(client),
- mStreamType(streamType),
- mFrameCount(0),
- mState(IDLE),
- mClientTid(-1),
- mFormat(format),
- mFlags(flags & ~SYSTEM_FLAGS_MASK)
-{
- mName = mixerThread->getTrackName();
- LOGV("TrackBase contructor name %d, calling thread %d", mName, IPCThreadState::self()->getCallingPid());
- if (mName < 0) {
- LOGE("no more track names availlable");
- return;
- }
-
- LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
-
- // LOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
- size_t size = sizeof(audio_track_cblk_t);
- size_t bufferSize = frameCount*channelCount*sizeof(int16_t);
- if (sharedBuffer == 0) {
- size += bufferSize;
- }
-
- if (client != NULL) {
- mCblkMemory = client->heap()->allocate(size);
- if (mCblkMemory != 0) {
- mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer());
- if (mCblk) { // construct the shared structure in-place.
- new(mCblk) audio_track_cblk_t();
- // clear all buffers
- mCblk->frameCount = frameCount;
- mCblk->sampleRate = sampleRate;
- mCblk->channels = channelCount;
- if (sharedBuffer == 0) {
- mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
- memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
- // Force underrun condition to avoid false underrun callback until first data is
- // written to buffer
- mCblk->flowControlFlag = 1;
- } else {
- mBuffer = sharedBuffer->pointer();
- }
- mBufferEnd = (uint8_t *)mBuffer + bufferSize;
- }
- } else {
- LOGE("not enough memory for AudioTrack size=%u", size);
- client->heap()->dump("AudioTrack");
- return;
- }
- } else {
- mCblk = (audio_track_cblk_t *)(new uint8_t[size]);
- if (mCblk) { // construct the shared structure in-place.
- new(mCblk) audio_track_cblk_t();
- // clear all buffers
- mCblk->frameCount = frameCount;
- mCblk->sampleRate = sampleRate;
- mCblk->channels = channelCount;
- mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
- memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
- // Force underrun condition to avoid false underrun callback until first data is
- // written to buffer
- mCblk->flowControlFlag = 1;
- mBufferEnd = (uint8_t *)mBuffer + bufferSize;
- }
- }
-}
-
-AudioFlinger::MixerThread::TrackBase::~TrackBase()
-{
- if (mCblk) {
- mCblk->~audio_track_cblk_t(); // destroy our shared-structure.
- }
- mCblkMemory.clear(); // and free the shared memory
- mClient.clear();
-}
-
-void AudioFlinger::MixerThread::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
-{
- buffer->raw = 0;
- mFrameCount = buffer->frameCount;
- step();
- buffer->frameCount = 0;
-}
-
-bool AudioFlinger::MixerThread::TrackBase::step() {
- bool result;
- audio_track_cblk_t* cblk = this->cblk();
-
- result = cblk->stepServer(mFrameCount);
- if (!result) {
- LOGV("stepServer failed acquiring cblk mutex");
- mFlags |= STEPSERVER_FAILED;
- }
- return result;
-}
-
-void AudioFlinger::MixerThread::TrackBase::reset() {
- audio_track_cblk_t* cblk = this->cblk();
-
- cblk->user = 0;
- cblk->server = 0;
- cblk->userBase = 0;
- cblk->serverBase = 0;
- mFlags &= (uint32_t)(~SYSTEM_FLAGS_MASK);
- LOGV("TrackBase::reset");
-}
-
-sp<IMemory> AudioFlinger::MixerThread::TrackBase::getCblk() const
-{
- return mCblkMemory;
-}
-
-int AudioFlinger::MixerThread::TrackBase::sampleRate() const {
- return mCblk->sampleRate;
-}
-
-int AudioFlinger::MixerThread::TrackBase::channelCount() const {
- return mCblk->channels;
-}
-
-void* AudioFlinger::MixerThread::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const {
- audio_track_cblk_t* cblk = this->cblk();
- int16_t *bufferStart = (int16_t *)mBuffer + (offset-cblk->serverBase)*cblk->channels;
- int16_t *bufferEnd = bufferStart + frames * cblk->channels;
-
- // Check validity of returned pointer in case the track control block would have been corrupted.
- if (bufferStart < mBuffer || bufferStart > bufferEnd || bufferEnd > mBufferEnd) {
- LOGW("TrackBase::getBuffer buffer out of range:\n start: %p, end %p , mBuffer %p mBufferEnd %p\n \
- server %d, serverBase %d, user %d, userBase %d",
- bufferStart, bufferEnd, mBuffer, mBufferEnd,
- cblk->server, cblk->serverBase, cblk->user, cblk->userBase);
- return 0;
- }
-
- return bufferStart;
-}
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::MixerThread::Track::Track(
- const sp<MixerThread>& mixerThread,
- const sp<Client>& client,
- int streamType,
- uint32_t sampleRate,
- int format,
- int channelCount,
- int frameCount,
- const sp<IMemory>& sharedBuffer)
- : TrackBase(mixerThread, client, streamType, sampleRate, format, channelCount, frameCount, 0, sharedBuffer)
-{
- mVolume[0] = 1.0f;
- mVolume[1] = 1.0f;
- mMute = false;
- mSharedBuffer = sharedBuffer;
-}
-
-AudioFlinger::MixerThread::Track::~Track()
-{
- wp<Track> weak(this); // never create a strong ref from the dtor
- mState = TERMINATED;
- mMixerThread->removeTrack(weak, mName);
-}
-
-void AudioFlinger::MixerThread::Track::destroy()
-{
- mMixerThread->destroyTrack(this);
-}
-
-void AudioFlinger::MixerThread::Track::dump(char* buffer, size_t size)
-{
- snprintf(buffer, size, " %5d %5d %3u %3u %3u %3u %1d %1d %1d %5u %5u %5u %04x %04x\n",
- mName - AudioMixer::TRACK0,
- (mClient == NULL) ? getpid() : mClient->pid(),
- mStreamType,
- mFormat,
- mCblk->channels,
- mFrameCount,
- mState,
- mMute,
- mFillingUpStatus,
- mCblk->sampleRate,
- mCblk->volume[0],
- mCblk->volume[1],
- mCblk->server,
- mCblk->user);
-}
-
-status_t AudioFlinger::MixerThread::Track::getNextBuffer(AudioBufferProvider::Buffer* buffer)
-{
- audio_track_cblk_t* cblk = this->cblk();
- uint32_t framesReady;
- uint32_t framesReq = buffer->frameCount;
-
- // Check if last stepServer failed, try to step now
- if (mFlags & TrackBase::STEPSERVER_FAILED) {
- if (!step()) goto getNextBuffer_exit;
- LOGV("stepServer recovered");
- mFlags &= ~TrackBase::STEPSERVER_FAILED;
- }
-
- framesReady = cblk->framesReady();
-
- if (LIKELY(framesReady)) {
- uint32_t s = cblk->server;
- uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
-
- bufferEnd = (cblk->loopEnd < bufferEnd) ? cblk->loopEnd : bufferEnd;
- if (framesReq > framesReady) {
- framesReq = framesReady;
- }
- if (s + framesReq > bufferEnd) {
- framesReq = bufferEnd - s;
- }
-
- buffer->raw = getBuffer(s, framesReq);
- if (buffer->raw == 0) goto getNextBuffer_exit;
-
- buffer->frameCount = framesReq;
- return NO_ERROR;
- }
-
-getNextBuffer_exit:
- buffer->raw = 0;
- buffer->frameCount = 0;
- return NOT_ENOUGH_DATA;
-}
-
-bool AudioFlinger::MixerThread::Track::isReady() const {
- if (mFillingUpStatus != FS_FILLING) return true;
-
- if (mCblk->framesReady() >= mCblk->frameCount ||
- mCblk->forceReady) {
- mFillingUpStatus = FS_FILLED;
- mCblk->forceReady = 0;
- LOGV("Track::isReady() track %d for output %d", mName, mMixerThread->mOutputType);
- return true;
- }
- return false;
-}
-
-status_t AudioFlinger::MixerThread::Track::start()
-{
- LOGV("start(%d), calling thread %d for output %d", mName, IPCThreadState::self()->getCallingPid(), mMixerThread->mOutputType);
- mMixerThread->addTrack(this);
- return NO_ERROR;
-}
-
-void AudioFlinger::MixerThread::Track::stop()
-{
- LOGV("stop(%d), calling thread %d for output %d", mName, IPCThreadState::self()->getCallingPid(), mMixerThread->mOutputType);
- Mutex::Autolock _l(mMixerThread->mLock);
- if (mState > STOPPED) {
- mState = STOPPED;
- // If the track is not active (PAUSED and buffers full), flush buffers
- if (mMixerThread->mActiveTracks.indexOf(this) < 0) {
- reset();
- }
- LOGV("(> STOPPED) => STOPPED (%d)", mName);
- }
-}
-
-void AudioFlinger::MixerThread::Track::pause()
-{
- LOGV("pause(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid());
- Mutex::Autolock _l(mMixerThread->mLock);
- if (mState == ACTIVE || mState == RESUMING) {
- mState = PAUSING;
- LOGV("ACTIVE/RESUMING => PAUSING (%d)", mName);
- }
-}
-
-void AudioFlinger::MixerThread::Track::flush()
-{
- LOGV("flush(%d)", mName);
- Mutex::Autolock _l(mMixerThread->mLock);
- if (mState != STOPPED && mState != PAUSED && mState != PAUSING) {
- return;
- }
- // No point remaining in PAUSED state after a flush => go to
- // STOPPED state
- mState = STOPPED;
-
- // NOTE: reset() will reset cblk->user and cblk->server with
- // the risk that at the same time, the AudioMixer is trying to read
- // data. In this case, getNextBuffer() would return a NULL pointer
- // as audio buffer => the AudioMixer code MUST always test that pointer
- // returned by getNextBuffer() is not NULL!
- reset();
-}
-
-void AudioFlinger::MixerThread::Track::reset()
-{
- // Do not reset twice to avoid discarding data written just after a flush and before
- // the audioflinger thread detects the track is stopped.
- if (!mResetDone) {
- TrackBase::reset();
- // Force underrun condition to avoid false underrun callback until first data is
- // written to buffer
- mCblk->flowControlFlag = 1;
- mCblk->forceReady = 0;
- mFillingUpStatus = FS_FILLING;
- mResetDone = true;
- }
-}
-
-void AudioFlinger::MixerThread::Track::mute(bool muted)
-{
- mMute = muted;
-}
-
-void AudioFlinger::MixerThread::Track::setVolume(float left, float right)
-{
- mVolume[0] = left;
- mVolume[1] = right;
-}
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::MixerThread::RecordTrack::RecordTrack(
- const sp<MixerThread>& mixerThread,
- const sp<Client>& client,
- int streamType,
- uint32_t sampleRate,
- int format,
- int channelCount,
- int frameCount,
- uint32_t flags)
- : TrackBase(mixerThread, client, streamType, sampleRate, format,
- channelCount, frameCount, flags, 0),
- mOverflow(false)
-{
-}
-
-AudioFlinger::MixerThread::RecordTrack::~RecordTrack()
-{
- mMixerThread->deleteTrackName(mName);
-}
-
-status_t AudioFlinger::MixerThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
-{
- audio_track_cblk_t* cblk = this->cblk();
- uint32_t framesAvail;
- uint32_t framesReq = buffer->frameCount;
-
- // Check if last stepServer failed, try to step now
- if (mFlags & TrackBase::STEPSERVER_FAILED) {
- if (!step()) goto getNextBuffer_exit;
- LOGV("stepServer recovered");
- mFlags &= ~TrackBase::STEPSERVER_FAILED;
- }
-
- framesAvail = cblk->framesAvailable_l();
-
- if (LIKELY(framesAvail)) {
- uint32_t s = cblk->server;
- uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
-
- if (framesReq > framesAvail) {
- framesReq = framesAvail;
- }
- if (s + framesReq > bufferEnd) {
- framesReq = bufferEnd - s;
- }
-
- buffer->raw = getBuffer(s, framesReq);
- if (buffer->raw == 0) goto getNextBuffer_exit;
-
- buffer->frameCount = framesReq;
- return NO_ERROR;
- }
-
-getNextBuffer_exit:
- buffer->raw = 0;
- buffer->frameCount = 0;
- return NOT_ENOUGH_DATA;
-}
-
-status_t AudioFlinger::MixerThread::RecordTrack::start()
-{
- return mMixerThread->mAudioFlinger->startRecord(this);
-}
-
-void AudioFlinger::MixerThread::RecordTrack::stop()
-{
- mMixerThread->mAudioFlinger->stopRecord(this);
- TrackBase::reset();
- // Force overerrun condition to avoid false overrun callback until first data is
- // read from buffer
- mCblk->flowControlFlag = 1;
-}
-
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::MixerThread::OutputTrack::OutputTrack(
- const sp<MixerThread>& mixerThread,
- uint32_t sampleRate,
- int format,
- int channelCount,
- int frameCount)
- : Track(mixerThread, NULL, AudioSystem::SYSTEM, sampleRate, format, channelCount, frameCount, NULL),
- mOutputMixerThread(mixerThread)
-{
-
- mCblk->out = 1;
- mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
- mCblk->volume[0] = mCblk->volume[1] = 0x1000;
- mOutBuffer.frameCount = 0;
- mCblk->bufferTimeoutMs = 10;
-
- LOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, mCblk->frameCount %d, mCblk->sampleRate %d, mCblk->channels %d mBufferEnd %p",
- mCblk, mBuffer, mCblk->buffers, mCblk->frameCount, mCblk->sampleRate, mCblk->channels, mBufferEnd);
-
-}
-
-AudioFlinger::MixerThread::OutputTrack::~OutputTrack()
-{
- stop();
-}
-
-status_t AudioFlinger::MixerThread::OutputTrack::start()
-{
- status_t status = Track::start();
-
- mRetryCount = 127;
- return status;
-}
-
-void AudioFlinger::MixerThread::OutputTrack::stop()
-{
- Track::stop();
- clearBufferQueue();
- mOutBuffer.frameCount = 0;
-}
-
-void AudioFlinger::MixerThread::OutputTrack::write(int16_t* data, uint32_t frames)
-{
- Buffer *pInBuffer;
- Buffer inBuffer;
- uint32_t channels = mCblk->channels;
-
- inBuffer.frameCount = frames;
- inBuffer.i16 = data;
-
- if (mCblk->user == 0) {
- if (mOutputMixerThread->isMusicActive()) {
- mCblk->forceReady = 1;
- LOGV("OutputTrack::start() force ready");
- } else if (mCblk->frameCount > frames){
- if (mBufferQueue.size() < kMaxOutputTrackBuffers) {
- uint32_t startFrames = (mCblk->frameCount - frames);
- LOGV("OutputTrack::start() write %d frames", startFrames);
- pInBuffer = new Buffer;
- pInBuffer->mBuffer = new int16_t[startFrames * channels];
- pInBuffer->frameCount = startFrames;
- pInBuffer->i16 = pInBuffer->mBuffer;
- memset(pInBuffer->raw, 0, startFrames * channels * sizeof(int16_t));
- mBufferQueue.add(pInBuffer);
- } else {
- LOGW ("OutputTrack::write() no more buffers");
- }
- }
- }
-
- while (1) {
- // First write pending buffers, then new data
- if (mBufferQueue.size()) {
- pInBuffer = mBufferQueue.itemAt(0);
- } else {
- pInBuffer = &inBuffer;
- }
-
- if (pInBuffer->frameCount == 0) {
- break;
- }
-
- if (mOutBuffer.frameCount == 0) {
- mOutBuffer.frameCount = pInBuffer->frameCount;
- if (obtainBuffer(&mOutBuffer) == (status_t)AudioTrack::NO_MORE_BUFFERS) {
- break;
- }
- }
-
- uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount : pInBuffer->frameCount;
- memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * channels * sizeof(int16_t));
- mCblk->stepUser(outFrames);
- pInBuffer->frameCount -= outFrames;
- pInBuffer->i16 += outFrames * channels;
- mOutBuffer.frameCount -= outFrames;
- mOutBuffer.i16 += outFrames * channels;
-
- if (pInBuffer->frameCount == 0) {
- if (mBufferQueue.size()) {
- mBufferQueue.removeAt(0);
- delete [] pInBuffer->mBuffer;
- delete pInBuffer;
- } else {
- break;
- }
- }
- }
-
- // If we could not write all frames, allocate a buffer and queue it for next time.
- if (inBuffer.frameCount) {
- if (mBufferQueue.size() < kMaxOutputTrackBuffers) {
- pInBuffer = new Buffer;
- pInBuffer->mBuffer = new int16_t[inBuffer.frameCount * channels];
- pInBuffer->frameCount = inBuffer.frameCount;
- pInBuffer->i16 = pInBuffer->mBuffer;
- memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * channels * sizeof(int16_t));
- mBufferQueue.add(pInBuffer);
- } else {
- LOGW("OutputTrack::write() no more buffers");
- }
- }
-
- // Calling write() with a 0 length buffer, means that no more data will be written:
- // If no more buffers are pending, fill output track buffer to make sure it is started
- // by output mixer.
- if (frames == 0 && mBufferQueue.size() == 0 && mCblk->user < mCblk->frameCount) {
- frames = mCblk->frameCount - mCblk->user;
- pInBuffer = new Buffer;
- pInBuffer->mBuffer = new int16_t[frames * channels];
- pInBuffer->frameCount = frames;
- pInBuffer->i16 = pInBuffer->mBuffer;
- memset(pInBuffer->raw, 0, frames * channels * sizeof(int16_t));
- mBufferQueue.add(pInBuffer);
- }
-
-}
-
-status_t AudioFlinger::MixerThread::OutputTrack::obtainBuffer(AudioBufferProvider::Buffer* buffer)
-{
- int active;
- int timeout = 0;
- status_t result;
- audio_track_cblk_t* cblk = mCblk;
- uint32_t framesReq = buffer->frameCount;
-
- LOGV("OutputTrack::obtainBuffer user %d, server %d", cblk->user, cblk->server);
- buffer->frameCount = 0;
-
- uint32_t framesAvail = cblk->framesAvailable();
-
- if (framesAvail == 0) {
- return AudioTrack::NO_MORE_BUFFERS;
- }
-
- if (framesReq > framesAvail) {
- framesReq = framesAvail;
- }
-
- uint32_t u = cblk->user;
- uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
-
- if (u + framesReq > bufferEnd) {
- framesReq = bufferEnd - u;
- }
-
- buffer->frameCount = framesReq;
- buffer->raw = (void *)cblk->buffer(u);
- return NO_ERROR;
-}
-
-
-void AudioFlinger::MixerThread::OutputTrack::clearBufferQueue()
-{
- size_t size = mBufferQueue.size();
- Buffer *pBuffer;
-
- for (size_t i = 0; i < size; i++) {
- pBuffer = mBufferQueue.itemAt(i);
- delete [] pBuffer->mBuffer;
- delete pBuffer;
- }
- mBufferQueue.clear();
-}
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
- : RefBase(),
- mAudioFlinger(audioFlinger),
- mMemoryDealer(new MemoryDealer(1024*1024)),
- mPid(pid)
-{
- // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
-}
-
-AudioFlinger::Client::~Client()
-{
- mAudioFlinger->removeClient(mPid);
-}
-
-const sp<MemoryDealer>& AudioFlinger::Client::heap() const
-{
- return mMemoryDealer;
-}
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::MixerThread::Track>& track)
- : BnAudioTrack(),
- mTrack(track)
-{
-}
-
-AudioFlinger::TrackHandle::~TrackHandle() {
- // just stop the track on deletion, associated resources
- // will be freed from the main thread once all pending buffers have
- // been played. Unless it's not in the active track list, in which
- // case we free everything now...
- mTrack->destroy();
-}
-
-status_t AudioFlinger::TrackHandle::start() {
- return mTrack->start();
-}
-
-void AudioFlinger::TrackHandle::stop() {
- mTrack->stop();
-}
-
-void AudioFlinger::TrackHandle::flush() {
- mTrack->flush();
-}
-
-void AudioFlinger::TrackHandle::mute(bool e) {
- mTrack->mute(e);
-}
-
-void AudioFlinger::TrackHandle::pause() {
- mTrack->pause();
-}
-
-void AudioFlinger::TrackHandle::setVolume(float left, float right) {
- mTrack->setVolume(left, right);
-}
-
-sp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
- return mTrack->getCblk();
-}
-
-status_t AudioFlinger::TrackHandle::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- return BnAudioTrack::onTransact(code, data, reply, flags);
-}
-
-// ----------------------------------------------------------------------------
-
-sp<IAudioRecord> AudioFlinger::openRecord(
- pid_t pid,
- int streamType,
- uint32_t sampleRate,
- int format,
- int channelCount,
- int frameCount,
- uint32_t flags,
- status_t *status)
-{
- sp<AudioRecordThread> thread;
- sp<MixerThread::RecordTrack> recordTrack;
- sp<RecordHandle> recordHandle;
- sp<Client> client;
- wp<Client> wclient;
- AudioStreamIn* input = 0;
- int inFrameCount;
- size_t inputBufferSize;
- status_t lStatus;
-
- // check calling permissions
- if (!recordingAllowed()) {
- lStatus = PERMISSION_DENIED;
- goto Exit;
- }
-
- if (uint32_t(streamType) >= AudioRecord::NUM_STREAM_TYPES) {
- LOGE("invalid stream type");
- lStatus = BAD_VALUE;
- goto Exit;
- }
-
- if (sampleRate > MAX_SAMPLE_RATE) {
- LOGE("Sample rate out of range");
- lStatus = BAD_VALUE;
- goto Exit;
- }
-
- if (mAudioRecordThread == 0) {
- LOGE("Audio record thread not started");
- lStatus = NO_INIT;
- goto Exit;
- }
-
-
- // Check that audio input stream accepts requested audio parameters
- inputBufferSize = mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
- if (inputBufferSize == 0) {
- lStatus = BAD_VALUE;
- LOGE("Bad audio input parameters: sampling rate %u, format %d, channels %d", sampleRate, format, channelCount);
- goto Exit;
- }
-
- // add client to list
- {
- Mutex::Autolock _l(mLock);
- wclient = mClients.valueFor(pid);
- if (wclient != NULL) {
- client = wclient.promote();
- } else {
- client = new Client(this, pid);
- mClients.add(pid, client);
- }
- }
-
- // frameCount must be a multiple of input buffer size
- inFrameCount = inputBufferSize/channelCount/sizeof(short);
- frameCount = ((frameCount - 1)/inFrameCount + 1) * inFrameCount;
-
- // create new record track and pass to record thread
- recordTrack = new MixerThread::RecordTrack(mHardwareMixerThread, client, streamType, sampleRate,
- format, channelCount, frameCount, flags);
- if (recordTrack->getCblk() == NULL) {
- recordTrack.clear();
- lStatus = NO_MEMORY;
- goto Exit;
- }
-
- // return to handle to client
- recordHandle = new RecordHandle(recordTrack);
- lStatus = NO_ERROR;
-
-Exit:
- if (status) {
- *status = lStatus;
- }
- return recordHandle;
-}
-
-status_t AudioFlinger::startRecord(MixerThread::RecordTrack* recordTrack) {
- if (mAudioRecordThread != 0) {
- return mAudioRecordThread->start(recordTrack);
- }
- return NO_INIT;
-}
-
-void AudioFlinger::stopRecord(MixerThread::RecordTrack* recordTrack) {
- if (mAudioRecordThread != 0) {
- mAudioRecordThread->stop(recordTrack);
- }
-}
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::RecordHandle::RecordHandle(const sp<AudioFlinger::MixerThread::RecordTrack>& recordTrack)
- : BnAudioRecord(),
- mRecordTrack(recordTrack)
-{
-}
-
-AudioFlinger::RecordHandle::~RecordHandle() {
- stop();
-}
-
-status_t AudioFlinger::RecordHandle::start() {
- LOGV("RecordHandle::start()");
- return mRecordTrack->start();
-}
-
-void AudioFlinger::RecordHandle::stop() {
- LOGV("RecordHandle::stop()");
- mRecordTrack->stop();
-}
-
-sp<IMemory> AudioFlinger::RecordHandle::getCblk() const {
- return mRecordTrack->getCblk();
-}
-
-status_t AudioFlinger::RecordHandle::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- return BnAudioRecord::onTransact(code, data, reply, flags);
-}
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::AudioRecordThread::AudioRecordThread(AudioHardwareInterface* audioHardware) :
- mAudioHardware(audioHardware),
- mActive(false)
-{
-}
-
-AudioFlinger::AudioRecordThread::~AudioRecordThread()
-{
-}
-
-bool AudioFlinger::AudioRecordThread::threadLoop()
-{
- LOGV("AudioRecordThread: start record loop");
- AudioBufferProvider::Buffer buffer;
- int inBufferSize = 0;
- int inFrameCount = 0;
- AudioStreamIn* input = 0;
-
- mActive = 0;
-
- // start recording
- while (!exitPending()) {
- if (!mActive) {
- mLock.lock();
- if (!mActive && !exitPending()) {
- LOGV("AudioRecordThread: loop stopping");
- if (input) {
- delete input;
- input = 0;
- }
- mRecordTrack.clear();
- mStopped.signal();
-
- mWaitWorkCV.wait(mLock);
-
- LOGV("AudioRecordThread: loop starting");
- if (mRecordTrack != 0) {
- input = mAudioHardware->openInputStream(mRecordTrack->format(),
- mRecordTrack->channelCount(),
- mRecordTrack->sampleRate(),
- &mStartStatus,
- (AudioSystem::audio_in_acoustics)(mRecordTrack->mFlags >> 16));
- if (input != 0) {
- inBufferSize = input->bufferSize();
- inFrameCount = inBufferSize/input->frameSize();
- }
- } else {
- mStartStatus = NO_INIT;
- }
- if (mStartStatus !=NO_ERROR) {
- LOGW("record start failed, status %d", mStartStatus);
- mActive = false;
- mRecordTrack.clear();
- }
- mWaitWorkCV.signal();
- }
- mLock.unlock();
- } else if (mRecordTrack != 0) {
-
- buffer.frameCount = inFrameCount;
- if (LIKELY(mRecordTrack->getNextBuffer(&buffer) == NO_ERROR)) {
- LOGV("AudioRecordThread read: %d frames", buffer.frameCount);
- ssize_t bytesRead = input->read(buffer.raw, inBufferSize);
- if (bytesRead < 0) {
- LOGE("Error reading audio input");
- sleep(1);
- }
- mRecordTrack->releaseBuffer(&buffer);
- mRecordTrack->overflow();
- }
-
- // client isn't retrieving buffers fast enough
- else {
- if (!mRecordTrack->setOverflow())
- LOGW("AudioRecordThread: buffer overflow");
- // Release the processor for a while before asking for a new buffer.
- // This will give the application more chance to read from the buffer and
- // clear the overflow.
- usleep(5000);
- }
- }
- }
-
-
- if (input) {
- delete input;
- }
- mRecordTrack.clear();
-
- return false;
-}
-
-status_t AudioFlinger::AudioRecordThread::start(MixerThread::RecordTrack* recordTrack)
-{
- LOGV("AudioRecordThread::start");
- AutoMutex lock(&mLock);
- mActive = true;
- // If starting the active track, just reset mActive in case a stop
- // was pending and exit
- if (recordTrack == mRecordTrack.get()) return NO_ERROR;
-
- if (mRecordTrack != 0) return -EBUSY;
-
- mRecordTrack = recordTrack;
-
- // signal thread to start
- LOGV("Signal record thread");
- mWaitWorkCV.signal();
- mWaitWorkCV.wait(mLock);
- LOGV("Record started, status %d", mStartStatus);
- return mStartStatus;
-}
-
-void AudioFlinger::AudioRecordThread::stop(MixerThread::RecordTrack* recordTrack) {
- LOGV("AudioRecordThread::stop");
- AutoMutex lock(&mLock);
- if (mActive && (recordTrack == mRecordTrack.get())) {
- mActive = false;
- mStopped.wait(mLock);
- }
-}
-
-void AudioFlinger::AudioRecordThread::exit()
-{
- LOGV("AudioRecordThread::exit");
- {
- AutoMutex lock(&mLock);
- requestExit();
- mWaitWorkCV.signal();
- }
- requestExitAndWait();
-}
-
-status_t AudioFlinger::AudioRecordThread::dump(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
- pid_t pid = 0;
-
- if (mRecordTrack != 0 && mRecordTrack->mClient != 0) {
- snprintf(buffer, SIZE, "Record client pid: %d\n", mRecordTrack->mClient->pid());
- result.append(buffer);
- } else {
- result.append("No record client\n");
- }
- write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-status_t AudioFlinger::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- return BnAudioFlinger::onTransact(code, data, reply, flags);
-}
-
-// ----------------------------------------------------------------------------
-void AudioFlinger::instantiate() {
- defaultServiceManager()->addService(
- String16("media.audio_flinger"), new AudioFlinger());
-}
-
-}; // namespace android
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
deleted file mode 100644
index dfbb1e9..0000000
--- a/libs/audioflinger/AudioFlinger.h
+++ /dev/null
@@ -1,640 +0,0 @@
-/* //device/include/server/AudioFlinger/AudioFlinger.h
-**
-** Copyright 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_AUDIO_FLINGER_H
-#define ANDROID_AUDIO_FLINGER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <media/IAudioFlinger.h>
-#include <media/IAudioFlingerClient.h>
-#include <media/IAudioTrack.h>
-#include <media/IAudioRecord.h>
-#include <media/AudioTrack.h>
-
-#include <utils/Atomic.h>
-#include <utils/Errors.h>
-#include <utils/threads.h>
-#include <utils/MemoryDealer.h>
-#include <utils/KeyedVector.h>
-#include <utils/SortedVector.h>
-#include <utils/Vector.h>
-
-#include <hardware_legacy/AudioHardwareInterface.h>
-
-#include "AudioBufferProvider.h"
-
-namespace android {
-
-class audio_track_cblk_t;
-class AudioMixer;
-class AudioBuffer;
-
-
-// ----------------------------------------------------------------------------
-
-#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
-#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
-
-
-// ----------------------------------------------------------------------------
-
-static const nsecs_t kStandbyTimeInNsecs = seconds(3);
-
-class AudioFlinger : public BnAudioFlinger, public IBinder::DeathRecipient
-{
-public:
- static void instantiate();
-
- virtual status_t dump(int fd, const Vector<String16>& args);
-
- // IAudioFlinger interface
- virtual sp<IAudioTrack> createTrack(
- pid_t pid,
- int streamType,
- uint32_t sampleRate,
- int format,
- int channelCount,
- int frameCount,
- uint32_t flags,
- const sp<IMemory>& sharedBuffer,
- status_t *status);
-
- virtual uint32_t sampleRate(int output) const;
- virtual int channelCount(int output) const;
- virtual int format(int output) const;
- virtual size_t frameCount(int output) const;
- virtual uint32_t latency(int output) const;
-
- virtual status_t setMasterVolume(float value);
- virtual status_t setMasterMute(bool muted);
-
- virtual float masterVolume() const;
- virtual bool masterMute() const;
-
- virtual status_t setStreamVolume(int stream, float value);
- virtual status_t setStreamMute(int stream, bool muted);
-
- virtual float streamVolume(int stream) const;
- virtual bool streamMute(int stream) const;
-
- virtual status_t setRouting(int mode, uint32_t routes, uint32_t mask);
- virtual uint32_t getRouting(int mode) const;
-
- virtual status_t setMode(int mode);
- virtual int getMode() const;
-
- virtual status_t setMicMute(bool state);
- virtual bool getMicMute() const;
-
- virtual bool isMusicActive() const;
-
- virtual bool isA2dpEnabled() const;
-
- virtual status_t setParameter(const char* key, const char* value);
-
- virtual void registerClient(const sp<IAudioFlingerClient>& client);
-
- virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount);
-
- virtual void wakeUp();
-
- // IBinder::DeathRecipient
- virtual void binderDied(const wp<IBinder>& who);
-
- enum hardware_call_state {
- AUDIO_HW_IDLE = 0,
- AUDIO_HW_INIT,
- AUDIO_HW_OUTPUT_OPEN,
- AUDIO_HW_OUTPUT_CLOSE,
- AUDIO_HW_INPUT_OPEN,
- AUDIO_HW_INPUT_CLOSE,
- AUDIO_HW_STANDBY,
- AUDIO_HW_SET_MASTER_VOLUME,
- AUDIO_HW_GET_ROUTING,
- AUDIO_HW_SET_ROUTING,
- AUDIO_HW_GET_MODE,
- AUDIO_HW_SET_MODE,
- AUDIO_HW_GET_MIC_MUTE,
- AUDIO_HW_SET_MIC_MUTE,
- AUDIO_SET_VOICE_VOLUME,
- AUDIO_SET_PARAMETER,
- };
-
- // record interface
- virtual sp<IAudioRecord> openRecord(
- pid_t pid,
- int streamType,
- uint32_t sampleRate,
- int format,
- int channelCount,
- int frameCount,
- uint32_t flags,
- status_t *status);
-
- virtual status_t onTransact(
- uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags);
-
-private:
- AudioFlinger();
- virtual ~AudioFlinger();
-
- void setOutput(int outputType);
- void doSetOutput(int outputType);
-
-#ifdef WITH_A2DP
- void setA2dpEnabled(bool enable);
-#endif
- static bool streamForcedToSpeaker(int streamType);
-
- // Management of forced route to speaker for certain track types.
- enum force_speaker_command {
- ACTIVE_TRACK_ADDED = 0,
- ACTIVE_TRACK_REMOVED,
- CHECK_ROUTE_RESTORE_TIME,
- FORCE_ROUTE_RESTORE
- };
- void handleForcedSpeakerRoute(int command);
-
- // Internal dump utilites.
- status_t dumpPermissionDenial(int fd, const Vector<String16>& args);
- status_t dumpClients(int fd, const Vector<String16>& args);
- status_t dumpInternals(int fd, const Vector<String16>& args);
-
- // --- Client ---
- class Client : public RefBase {
- public:
- Client(const sp<AudioFlinger>& audioFlinger, pid_t pid);
- virtual ~Client();
- const sp<MemoryDealer>& heap() const;
- pid_t pid() const { return mPid; }
- private:
- Client(const Client&);
- Client& operator = (const Client&);
- sp<AudioFlinger> mAudioFlinger;
- sp<MemoryDealer> mMemoryDealer;
- pid_t mPid;
- };
-
-
- class TrackHandle;
- class RecordHandle;
- class AudioRecordThread;
-
-
- // --- MixerThread ---
- class MixerThread : public Thread {
- public:
-
- // --- Track ---
-
- // base for record and playback
- class TrackBase : public AudioBufferProvider, public RefBase {
-
- public:
- enum track_state {
- IDLE,
- TERMINATED,
- STOPPED,
- RESUMING,
- ACTIVE,
- PAUSING,
- PAUSED
- };
-
- enum track_flags {
- STEPSERVER_FAILED = 0x01, // StepServer could not acquire cblk->lock mutex
- SYSTEM_FLAGS_MASK = 0x0000ffffUL,
-
- AUDIO_IN_AGC_ENABLE = AudioSystem::AGC_ENABLE << 16,
- AUDIO_IN_NS_ENABLE = AudioSystem::NS_ENABLE << 16,
- AUDIO_IN_IIR_ENABLE = AudioSystem::TX_IIR_ENABLE << 16
- };
-
- TrackBase(const sp<MixerThread>& mixerThread,
- const sp<Client>& client,
- int streamType,
- uint32_t sampleRate,
- int format,
- int channelCount,
- int frameCount,
- uint32_t flags,
- const sp<IMemory>& sharedBuffer);
- ~TrackBase();
-
- virtual status_t start() = 0;
- virtual void stop() = 0;
- sp<IMemory> getCblk() const;
-
- protected:
- friend class MixerThread;
- friend class RecordHandle;
- friend class AudioRecordThread;
-
- TrackBase(const TrackBase&);
- TrackBase& operator = (const TrackBase&);
-
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
- virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
-
- audio_track_cblk_t* cblk() const {
- return mCblk;
- }
-
- int type() const {
- return mStreamType;
- }
-
- int format() const {
- return mFormat;
- }
-
- int channelCount() const ;
-
- int sampleRate() const;
-
- void* getBuffer(uint32_t offset, uint32_t frames) const;
-
- int name() const {
- return mName;
- }
-
- bool isStopped() const {
- return mState == STOPPED;
- }
-
- bool isTerminated() const {
- return mState == TERMINATED;
- }
-
- bool step();
- void reset();
-
- sp<MixerThread> mMixerThread;
- sp<Client> mClient;
- sp<IMemory> mCblkMemory;
- audio_track_cblk_t* mCblk;
- int mStreamType;
- void* mBuffer;
- void* mBufferEnd;
- uint32_t mFrameCount;
- int mName;
- // we don't really need a lock for these
- int mState;
- int mClientTid;
- uint8_t mFormat;
- uint32_t mFlags;
- };
-
- // playback track
- class Track : public TrackBase {
- public:
- Track( const sp<MixerThread>& mixerThread,
- const sp<Client>& client,
- int streamType,
- uint32_t sampleRate,
- int format,
- int channelCount,
- int frameCount,
- const sp<IMemory>& sharedBuffer);
- ~Track();
-
- void dump(char* buffer, size_t size);
- virtual status_t start();
- virtual void stop();
- void pause();
-
- void flush();
- void destroy();
- void mute(bool);
- void setVolume(float left, float right);
-
- protected:
- friend class MixerThread;
- friend class AudioFlinger;
- friend class AudioFlinger::TrackHandle;
-
- Track(const Track&);
- Track& operator = (const Track&);
-
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
-
- bool isMuted() const {
- return (mMute || mMixerThread->mStreamTypes[mStreamType].mute);
- }
-
- bool isPausing() const {
- return mState == PAUSING;
- }
-
- bool isPaused() const {
- return mState == PAUSED;
- }
-
- bool isReady() const;
-
- void setPaused() { mState = PAUSED; }
- void reset();
-
- // we don't really need a lock for these
- float mVolume[2];
- volatile bool mMute;
- // FILLED state is used for suppressing volume ramp at begin of playing
- enum {FS_FILLING, FS_FILLED, FS_ACTIVE};
- mutable uint8_t mFillingUpStatus;
- int8_t mRetryCount;
- sp<IMemory> mSharedBuffer;
- bool mResetDone;
- }; // end of Track
-
- // record track
- class RecordTrack : public TrackBase {
- public:
- RecordTrack(const sp<MixerThread>& mixerThread,
- const sp<Client>& client,
- int streamType,
- uint32_t sampleRate,
- int format,
- int channelCount,
- int frameCount,
- uint32_t flags);
- ~RecordTrack();
-
- virtual status_t start();
- virtual void stop();
-
- bool overflow() { bool tmp = mOverflow; mOverflow = false; return tmp; }
- bool setOverflow() { bool tmp = mOverflow; mOverflow = true; return tmp; }
-
- private:
- friend class AudioFlinger;
- friend class AudioFlinger::RecordHandle;
- friend class AudioFlinger::AudioRecordThread;
- friend class MixerThread;
-
- RecordTrack(const Track&);
- RecordTrack& operator = (const Track&);
-
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
-
- bool mOverflow;
- };
-
- // playback track
- class OutputTrack : public Track {
- public:
-
- class Buffer: public AudioBufferProvider::Buffer {
- public:
- int16_t *mBuffer;
- };
-
- OutputTrack( const sp<MixerThread>& mixerThread,
- uint32_t sampleRate,
- int format,
- int channelCount,
- int frameCount);
- ~OutputTrack();
-
- virtual status_t start();
- virtual void stop();
- void write(int16_t* data, uint32_t frames);
- bool bufferQueueEmpty() { return (mBufferQueue.size() == 0) ? true : false; }
-
- private:
-
- status_t obtainBuffer(AudioBufferProvider::Buffer* buffer);
- void clearBufferQueue();
-
- sp<MixerThread> mOutputMixerThread;
- Vector < Buffer* > mBufferQueue;
- AudioBufferProvider::Buffer mOutBuffer;
- uint32_t mFramesWritten;
-
- }; // end of OutputTrack
-
- MixerThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int outputType);
- virtual ~MixerThread();
-
- virtual status_t dump(int fd, const Vector<String16>& args);
-
- // Thread virtuals
- virtual bool threadLoop();
- virtual status_t readyToRun();
- virtual void onFirstRef();
-
- virtual uint32_t sampleRate() const;
- virtual int channelCount() const;
- virtual int format() const;
- virtual size_t frameCount() const;
- virtual uint32_t latency() const;
-
- virtual status_t setMasterVolume(float value);
- virtual status_t setMasterMute(bool muted);
-
- virtual float masterVolume() const;
- virtual bool masterMute() const;
-
- virtual status_t setStreamVolume(int stream, float value);
- virtual status_t setStreamMute(int stream, bool muted);
-
- virtual float streamVolume(int stream) const;
- virtual bool streamMute(int stream) const;
-
- bool isMusicActive() const;
-
-
- sp<Track> createTrack(
- const sp<AudioFlinger::Client>& client,
- int streamType,
- uint32_t sampleRate,
- int format,
- int channelCount,
- int frameCount,
- const sp<IMemory>& sharedBuffer,
- status_t *status);
-
- void wakeUp() { mWaitWorkCV.broadcast(); }
-
- void getTracks(SortedVector < sp<Track> >& tracks,
- SortedVector < wp<Track> >& activeTracks);
- void putTracks(SortedVector < sp<Track> >& tracks,
- SortedVector < wp<Track> >& activeTracks);
- void setOuputTrack(OutputTrack *track) { mOutputTrack = track; }
-
- struct stream_type_t {
- stream_type_t()
- : volume(1.0f),
- mute(false)
- {
- }
- float volume;
- bool mute;
- };
-
- private:
-
-
- friend class AudioFlinger;
- friend class Track;
- friend class TrackBase;
- friend class RecordTrack;
-
- MixerThread(const Client&);
- MixerThread& operator = (const MixerThread&);
-
- status_t addTrack(const sp<Track>& track);
- void removeTrack(wp<Track> track, int name);
- void remove_track_l(wp<Track> track, int name);
- void destroyTrack(const sp<Track>& track);
- int getTrackName();
- void deleteTrackName(int name);
- void addActiveTrack(const wp<Track>& t);
- void removeActiveTrack(const wp<Track>& t);
- size_t getOutputFrameCount();
-
- status_t dumpInternals(int fd, const Vector<String16>& args);
- status_t dumpTracks(int fd, const Vector<String16>& args);
-
- sp<AudioFlinger> mAudioFlinger;
- mutable Mutex mLock;
- mutable Condition mWaitWorkCV;
- SortedVector< wp<Track> > mActiveTracks;
- SortedVector< sp<Track> > mTracks;
- stream_type_t mStreamTypes[AudioSystem::NUM_STREAM_TYPES];
- AudioMixer* mAudioMixer;
- AudioStreamOut* mOutput;
- int mOutputType;
- uint32_t mSampleRate;
- size_t mFrameCount;
- int mChannelCount;
- int mFormat;
- int16_t* mMixBuffer;
- float mMasterVolume;
- bool mMasterMute;
- nsecs_t mLastWriteTime;
- int mNumWrites;
- int mNumDelayedWrites;
- bool mStandby;
- bool mInWrite;
- sp <OutputTrack> mOutputTrack;
- };
-
-
- friend class AudioBuffer;
-
- class TrackHandle : public android::BnAudioTrack {
- public:
- TrackHandle(const sp<MixerThread::Track>& track);
- virtual ~TrackHandle();
- virtual status_t start();
- virtual void stop();
- virtual void flush();
- virtual void mute(bool);
- virtual void pause();
- virtual void setVolume(float left, float right);
- virtual sp<IMemory> getCblk() const;
- virtual status_t onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
- private:
- sp<MixerThread::Track> mTrack;
- };
-
- friend class Client;
- friend class MixerThread::Track;
-
-
- void removeClient(pid_t pid);
-
-
-
- class RecordHandle : public android::BnAudioRecord {
- public:
- RecordHandle(const sp<MixerThread::RecordTrack>& recordTrack);
- virtual ~RecordHandle();
- virtual status_t start();
- virtual void stop();
- virtual sp<IMemory> getCblk() const;
- virtual status_t onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
- private:
- sp<MixerThread::RecordTrack> mRecordTrack;
- };
-
- // record thread
- class AudioRecordThread : public Thread
- {
- public:
- AudioRecordThread(AudioHardwareInterface* audioHardware);
- virtual ~AudioRecordThread();
- virtual bool threadLoop();
- virtual status_t readyToRun() { return NO_ERROR; }
- virtual void onFirstRef() {}
-
- status_t start(MixerThread::RecordTrack* recordTrack);
- void stop(MixerThread::RecordTrack* recordTrack);
- void exit();
- status_t dump(int fd, const Vector<String16>& args);
-
- private:
- AudioRecordThread();
- AudioHardwareInterface *mAudioHardware;
- sp<MixerThread::RecordTrack> mRecordTrack;
- Mutex mLock;
- Condition mWaitWorkCV;
- Condition mStopped;
- volatile bool mActive;
- status_t mStartStatus;
- };
-
- friend class AudioRecordThread;
- friend class MixerThread;
-
- status_t startRecord(MixerThread::RecordTrack* recordTrack);
- void stopRecord(MixerThread::RecordTrack* recordTrack);
-
- void handleOutputSwitch();
-
- mutable Mutex mHardwareLock;
- mutable Mutex mLock;
- DefaultKeyedVector< pid_t, wp<Client> > mClients;
-
- sp<MixerThread> mA2dpMixerThread;
- sp<MixerThread> mHardwareMixerThread;
- AudioHardwareInterface* mAudioHardware;
- AudioHardwareInterface* mA2dpAudioInterface;
- sp<AudioRecordThread> mAudioRecordThread;
- bool mA2dpEnabled;
- bool mA2dpEnabledReq;
- mutable int mHardwareStatus;
- SortedVector< wp<IBinder> > mNotificationClients;
- int mForcedSpeakerCount;
- uint32_t mSavedRoute;
- uint32_t mForcedRoute;
- nsecs_t mRouteRestoreTime;
- bool mMusicMuteSaved;
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_AUDIO_FLINGER_H
diff --git a/libs/audioflinger/AudioHardwareGeneric.cpp b/libs/audioflinger/AudioHardwareGeneric.cpp
deleted file mode 100644
index 62beada..0000000
--- a/libs/audioflinger/AudioHardwareGeneric.cpp
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
-**
-** Copyright 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.
-*/
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sched.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-
-#define LOG_TAG "AudioHardware"
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include "AudioHardwareGeneric.h"
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-static char const * const kAudioDeviceName = "/dev/eac";
-
-// ----------------------------------------------------------------------------
-
-AudioHardwareGeneric::AudioHardwareGeneric()
- : mOutput(0), mInput(0), mFd(-1), mMicMute(false)
-{
- mFd = ::open(kAudioDeviceName, O_RDWR);
-}
-
-AudioHardwareGeneric::~AudioHardwareGeneric()
-{
- if (mFd >= 0) ::close(mFd);
- delete mOutput;
- delete mInput;
-}
-
-status_t AudioHardwareGeneric::initCheck()
-{
- if (mFd >= 0) {
- if (::access(kAudioDeviceName, O_RDWR) == NO_ERROR)
- return NO_ERROR;
- }
- return NO_INIT;
-}
-
-AudioStreamOut* AudioHardwareGeneric::openOutputStream(
- int format, int channelCount, uint32_t sampleRate, status_t *status)
-{
- AutoMutex lock(mLock);
-
- // only one output stream allowed
- if (mOutput) {
- if (status) {
- *status = INVALID_OPERATION;
- }
- return 0;
- }
-
- // create new output stream
- AudioStreamOutGeneric* out = new AudioStreamOutGeneric();
- status_t lStatus = out->set(this, mFd, format, channelCount, sampleRate);
- if (status) {
- *status = lStatus;
- }
- if (lStatus == NO_ERROR) {
- mOutput = out;
- } else {
- delete out;
- }
- return mOutput;
-}
-
-void AudioHardwareGeneric::closeOutputStream(AudioStreamOutGeneric* out) {
- if (out == mOutput) mOutput = 0;
-}
-
-AudioStreamIn* AudioHardwareGeneric::openInputStream(
- int format, int channelCount, uint32_t sampleRate, status_t *status,
- AudioSystem::audio_in_acoustics acoustics)
-{
- AutoMutex lock(mLock);
-
- // only one input stream allowed
- if (mInput) {
- if (status) {
- *status = INVALID_OPERATION;
- }
- return 0;
- }
-
- // create new output stream
- AudioStreamInGeneric* in = new AudioStreamInGeneric();
- status_t lStatus = in->set(this, mFd, format, channelCount, sampleRate, acoustics);
- if (status) {
- *status = lStatus;
- }
- if (lStatus == NO_ERROR) {
- mInput = in;
- } else {
- delete in;
- }
- return mInput;
-}
-
-void AudioHardwareGeneric::closeInputStream(AudioStreamInGeneric* in) {
- if (in == mInput) mInput = 0;
-}
-
-status_t AudioHardwareGeneric::setVoiceVolume(float v)
-{
- // Implement: set voice volume
- return NO_ERROR;
-}
-
-status_t AudioHardwareGeneric::setMasterVolume(float v)
-{
- // Implement: set master volume
- // return error - software mixer will handle it
- return INVALID_OPERATION;
-}
-
-status_t AudioHardwareGeneric::setMicMute(bool state)
-{
- mMicMute = state;
- return NO_ERROR;
-}
-
-status_t AudioHardwareGeneric::getMicMute(bool* state)
-{
- *state = mMicMute;
- return NO_ERROR;
-}
-
-status_t AudioHardwareGeneric::dumpInternals(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
- result.append("AudioHardwareGeneric::dumpInternals\n");
- snprintf(buffer, SIZE, "\tmFd: %d mMicMute: %s\n", mFd, mMicMute? "true": "false");
- result.append(buffer);
- ::write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-status_t AudioHardwareGeneric::dump(int fd, const Vector<String16>& args)
-{
- dumpInternals(fd, args);
- if (mInput) {
- mInput->dump(fd, args);
- }
- if (mOutput) {
- mOutput->dump(fd, args);
- }
- return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-status_t AudioStreamOutGeneric::set(
- AudioHardwareGeneric *hw,
- int fd,
- int format,
- int channels,
- uint32_t rate)
-{
- // fix up defaults
- if (format == 0) format = AudioSystem::PCM_16_BIT;
- if (channels == 0) channels = channelCount();
- if (rate == 0) rate = sampleRate();
-
- // check values
- if ((format != AudioSystem::PCM_16_BIT) ||
- (channels != channelCount()) ||
- (rate != sampleRate()))
- return BAD_VALUE;
-
- mAudioHardware = hw;
- mFd = fd;
- return NO_ERROR;
-}
-
-AudioStreamOutGeneric::~AudioStreamOutGeneric()
-{
- if (mAudioHardware)
- mAudioHardware->closeOutputStream(this);
-}
-
-ssize_t AudioStreamOutGeneric::write(const void* buffer, size_t bytes)
-{
- Mutex::Autolock _l(mLock);
- return ssize_t(::write(mFd, buffer, bytes));
-}
-
-status_t AudioStreamOutGeneric::standby()
-{
- // Implement: audio hardware to standby mode
- return NO_ERROR;
-}
-
-status_t AudioStreamOutGeneric::dump(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
- snprintf(buffer, SIZE, "AudioStreamOutGeneric::dump\n");
- result.append(buffer);
- snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tformat: %d\n", format());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
- result.append(buffer);
- snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
- result.append(buffer);
- ::write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-// record functions
-status_t AudioStreamInGeneric::set(
- AudioHardwareGeneric *hw,
- int fd,
- int format,
- int channels,
- uint32_t rate,
- AudioSystem::audio_in_acoustics acoustics)
-{
- // FIXME: remove logging
- LOGD("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, format, channels, rate);
- // check values
- if ((format != AudioSystem::PCM_16_BIT) ||
- (channels != channelCount()) ||
- (rate != sampleRate())) {
- LOGE("Error opening input channel");
- return BAD_VALUE;
- }
-
- mAudioHardware = hw;
- mFd = fd;
- return NO_ERROR;
-}
-
-AudioStreamInGeneric::~AudioStreamInGeneric()
-{
- // FIXME: remove logging
- LOGD("AudioStreamInGeneric destructor");
- if (mAudioHardware)
- mAudioHardware->closeInputStream(this);
-}
-
-ssize_t AudioStreamInGeneric::read(void* buffer, ssize_t bytes)
-{
- // FIXME: remove logging
- LOGD("AudioStreamInGeneric::read(%p, %d) from fd %d", buffer, bytes, mFd);
- AutoMutex lock(mLock);
- if (mFd < 0) {
- LOGE("Attempt to read from unopened device");
- return NO_INIT;
- }
- return ::read(mFd, buffer, bytes);
-}
-
-status_t AudioStreamInGeneric::dump(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
- snprintf(buffer, SIZE, "AudioStreamInGeneric::dump\n");
- result.append(buffer);
- snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tformat: %d\n", format());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
- result.append(buffer);
- snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
- result.append(buffer);
- ::write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/audioflinger/AudioHardwareGeneric.h b/libs/audioflinger/AudioHardwareGeneric.h
deleted file mode 100644
index 1d58389..0000000
--- a/libs/audioflinger/AudioHardwareGeneric.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
-**
-** Copyright 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_AUDIO_HARDWARE_GENERIC_H
-#define ANDROID_AUDIO_HARDWARE_GENERIC_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/threads.h>
-
-#include <hardware_legacy/AudioHardwareBase.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class AudioHardwareGeneric;
-
-class AudioStreamOutGeneric : public AudioStreamOut {
-public:
- AudioStreamOutGeneric() : mAudioHardware(0), mFd(-1) {}
- virtual ~AudioStreamOutGeneric();
-
- virtual status_t set(
- AudioHardwareGeneric *hw,
- int mFd,
- int format,
- int channelCount,
- uint32_t sampleRate);
-
- virtual uint32_t sampleRate() const { return 44100; }
- virtual size_t bufferSize() const { return 4096; }
- virtual int channelCount() const { return 2; }
- virtual int format() const { return AudioSystem::PCM_16_BIT; }
- virtual uint32_t latency() const { return 0; }
- virtual status_t setVolume(float volume) { return INVALID_OPERATION; }
- virtual ssize_t write(const void* buffer, size_t bytes);
- virtual status_t standby();
- virtual status_t dump(int fd, const Vector<String16>& args);
-
-private:
- AudioHardwareGeneric *mAudioHardware;
- Mutex mLock;
- int mFd;
-};
-
-class AudioStreamInGeneric : public AudioStreamIn {
-public:
- AudioStreamInGeneric() : mAudioHardware(0), mFd(-1) {}
- virtual ~AudioStreamInGeneric();
-
- virtual status_t set(
- AudioHardwareGeneric *hw,
- int mFd,
- int format,
- int channelCount,
- uint32_t sampleRate,
- AudioSystem::audio_in_acoustics acoustics);
-
- uint32_t sampleRate() const { return 8000; }
- virtual size_t bufferSize() const { return 320; }
- virtual int channelCount() const { return 1; }
- virtual int format() const { return AudioSystem::PCM_16_BIT; }
- virtual status_t setGain(float gain) { return INVALID_OPERATION; }
- virtual ssize_t read(void* buffer, ssize_t bytes);
- virtual status_t dump(int fd, const Vector<String16>& args);
- virtual status_t standby() { return NO_ERROR; }
-
-private:
- AudioHardwareGeneric *mAudioHardware;
- Mutex mLock;
- int mFd;
-};
-
-
-class AudioHardwareGeneric : public AudioHardwareBase
-{
-public:
- AudioHardwareGeneric();
- virtual ~AudioHardwareGeneric();
- virtual status_t initCheck();
- virtual status_t setVoiceVolume(float volume);
- virtual status_t setMasterVolume(float volume);
-
- // mic mute
- virtual status_t setMicMute(bool state);
- virtual status_t getMicMute(bool* state);
-
- virtual status_t setParameter(const char* key, const char* value)
- { return NO_ERROR; }
-
- // create I/O streams
- virtual AudioStreamOut* openOutputStream(
- int format=0,
- int channelCount=0,
- uint32_t sampleRate=0,
- status_t *status=0);
-
- virtual AudioStreamIn* openInputStream(
- int format,
- int channelCount,
- uint32_t sampleRate,
- status_t *status,
- AudioSystem::audio_in_acoustics acoustics);
-
- void closeOutputStream(AudioStreamOutGeneric* out);
- void closeInputStream(AudioStreamInGeneric* in);
-protected:
- virtual status_t doRouting() { return NO_ERROR; }
- virtual status_t dump(int fd, const Vector<String16>& args);
-
-private:
- status_t dumpInternals(int fd, const Vector<String16>& args);
-
- Mutex mLock;
- AudioStreamOutGeneric *mOutput;
- AudioStreamInGeneric *mInput;
- int mFd;
- bool mMicMute;
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_AUDIO_HARDWARE_GENERIC_H
diff --git a/libs/audioflinger/AudioHardwareInterface.cpp b/libs/audioflinger/AudioHardwareInterface.cpp
deleted file mode 100644
index ac76a19..0000000
--- a/libs/audioflinger/AudioHardwareInterface.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
-**
-** Copyright 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.
-*/
-
-#include <cutils/properties.h>
-#include <string.h>
-#include <unistd.h>
-
-#define LOG_TAG "AudioHardwareInterface"
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include "AudioHardwareStub.h"
-#include "AudioHardwareGeneric.h"
-
-//#define DUMP_FLINGER_OUT // if defined allows recording samples in a file
-#ifdef DUMP_FLINGER_OUT
-#include "AudioDumpInterface.h"
-#endif
-
-
-// change to 1 to log routing calls
-#define LOG_ROUTING_CALLS 0
-
-namespace android {
-
-#if LOG_ROUTING_CALLS
-static const char* routingModeStrings[] =
-{
- "OUT OF RANGE",
- "INVALID",
- "CURRENT",
- "NORMAL",
- "RINGTONE",
- "IN_CALL"
-};
-
-static const char* routeStrings[] =
-{
- "EARPIECE ",
- "SPEAKER ",
- "BLUETOOTH ",
- "HEADSET "
- "BLUETOOTH_A2DP "
-};
-static const char* routeNone = "NONE";
-
-static const char* displayMode(int mode)
-{
- if ((mode < -2) || (mode > 2))
- return routingModeStrings[0];
- return routingModeStrings[mode+3];
-}
-
-static const char* displayRoutes(uint32_t routes)
-{
- static char routeStr[80];
- if (routes == 0)
- return routeNone;
- routeStr[0] = 0;
- int bitMask = 1;
- for (int i = 0; i < 4; ++i, bitMask <<= 1) {
- if (routes & bitMask) {
- strcat(routeStr, routeStrings[i]);
- }
- }
- routeStr[strlen(routeStr)-1] = 0;
- return routeStr;
-}
-#endif
-
-// ----------------------------------------------------------------------------
-
-AudioHardwareInterface* AudioHardwareInterface::create()
-{
- /*
- * FIXME: This code needs to instantiate the correct audio device
- * interface. For now - we use compile-time switches.
- */
- AudioHardwareInterface* hw = 0;
- char value[PROPERTY_VALUE_MAX];
-
-#ifdef GENERIC_AUDIO
- hw = new AudioHardwareGeneric();
-#else
- // if running in emulation - use the emulator driver
- if (property_get("ro.kernel.qemu", value, 0)) {
- LOGD("Running in emulation - using generic audio driver");
- hw = new AudioHardwareGeneric();
- }
- else {
- LOGV("Creating Vendor Specific AudioHardware");
- hw = createAudioHardware();
- }
-#endif
- if (hw->initCheck() != NO_ERROR) {
- LOGW("Using stubbed audio hardware. No sound will be produced.");
- delete hw;
- hw = new AudioHardwareStub();
- }
-
-#ifdef DUMP_FLINGER_OUT
- // This code adds a record of buffers in a file to write calls made by AudioFlinger.
- // It replaces the current AudioHardwareInterface object by an intermediate one which
- // will record buffers in a file (after sending them to hardware) for testing purpose.
- // This feature is enabled by defining symbol DUMP_FLINGER_OUT.
- // The output file is FLINGER_DUMP_NAME. Pause are not recorded in the file.
-
- hw = new AudioDumpInterface(hw); // replace interface
-#endif
- return hw;
-}
-
-AudioStreamOut::~AudioStreamOut()
-{
-}
-
-AudioStreamIn::~AudioStreamIn() {}
-
-AudioHardwareBase::AudioHardwareBase()
-{
- // force a routing update on initialization
- memset(&mRoutes, 0, sizeof(mRoutes));
- mMode = 0;
-}
-
-// generics for audio routing - the real work is done in doRouting
-status_t AudioHardwareBase::setRouting(int mode, uint32_t routes)
-{
-#if LOG_ROUTING_CALLS
- LOGD("setRouting: mode=%s, routes=[%s]", displayMode(mode), displayRoutes(routes));
-#endif
- if (mode == AudioSystem::MODE_CURRENT)
- mode = mMode;
- if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
- return BAD_VALUE;
- uint32_t old = mRoutes[mode];
- mRoutes[mode] = routes;
- if ((mode != mMode) || (old == routes))
- return NO_ERROR;
-#if LOG_ROUTING_CALLS
- const char* oldRouteStr = strdup(displayRoutes(old));
- LOGD("doRouting: mode=%s, old route=[%s], new route=[%s]",
- displayMode(mode), oldRouteStr, displayRoutes(routes));
- delete oldRouteStr;
-#endif
- return doRouting();
-}
-
-status_t AudioHardwareBase::getRouting(int mode, uint32_t* routes)
-{
- if (mode == AudioSystem::MODE_CURRENT)
- mode = mMode;
- if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
- return BAD_VALUE;
- *routes = mRoutes[mode];
-#if LOG_ROUTING_CALLS
- LOGD("getRouting: mode=%s, routes=[%s]",
- displayMode(mode), displayRoutes(*routes));
-#endif
- return NO_ERROR;
-}
-
-status_t AudioHardwareBase::setMode(int mode)
-{
-#if LOG_ROUTING_CALLS
- LOGD("setMode(%s)", displayMode(mode));
-#endif
- if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
- return BAD_VALUE;
- if (mMode == mode)
- return NO_ERROR;
-#if LOG_ROUTING_CALLS
- LOGD("doRouting: old mode=%s, new mode=%s route=[%s]",
- displayMode(mMode), displayMode(mode), displayRoutes(mRoutes[mode]));
-#endif
- mMode = mode;
- return doRouting();
-}
-
-status_t AudioHardwareBase::getMode(int* mode)
-{
- // Implement: set audio routing
- *mode = mMode;
- return NO_ERROR;
-}
-
-status_t AudioHardwareBase::setParameter(const char* key, const char* value)
-{
- // default implementation is to ignore
- return NO_ERROR;
-}
-
-
-// default implementation
-size_t AudioHardwareBase::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
-{
- if (sampleRate != 8000) {
- LOGW("getInputBufferSize bad sampling rate: %d", sampleRate);
- return 0;
- }
- if (format != AudioSystem::PCM_16_BIT) {
- LOGW("getInputBufferSize bad format: %d", format);
- return 0;
- }
- if (channelCount != 1) {
- LOGW("getInputBufferSize bad channel count: %d", channelCount);
- return 0;
- }
-
- return 320;
-}
-
-status_t AudioHardwareBase::dumpState(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
- snprintf(buffer, SIZE, "AudioHardwareBase::dumpState\n");
- result.append(buffer);
- snprintf(buffer, SIZE, "\tmMode: %d\n", mMode);
- result.append(buffer);
- for (int i = 0, n = AudioSystem::NUM_MODES; i < n; ++i) {
- snprintf(buffer, SIZE, "\tmRoutes[%d]: %d\n", i, mRoutes[i]);
- result.append(buffer);
- }
- ::write(fd, result.string(), result.size());
- dump(fd, args); // Dump the state of the concrete child.
- return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/audioflinger/AudioHardwareStub.cpp b/libs/audioflinger/AudioHardwareStub.cpp
deleted file mode 100644
index b13cb1c..0000000
--- a/libs/audioflinger/AudioHardwareStub.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/* //device/servers/AudioFlinger/AudioHardwareStub.cpp
-**
-** Copyright 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.
-*/
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <utils/String8.h>
-
-#include "AudioHardwareStub.h"
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-AudioHardwareStub::AudioHardwareStub() : mMicMute(false)
-{
-}
-
-AudioHardwareStub::~AudioHardwareStub()
-{
-}
-
-status_t AudioHardwareStub::initCheck()
-{
- return NO_ERROR;
-}
-
-AudioStreamOut* AudioHardwareStub::openOutputStream(
- int format, int channelCount, uint32_t sampleRate, status_t *status)
-{
- AudioStreamOutStub* out = new AudioStreamOutStub();
- status_t lStatus = out->set(format, channelCount, sampleRate);
- if (status) {
- *status = lStatus;
- }
- if (lStatus == NO_ERROR)
- return out;
- delete out;
- return 0;
-}
-
-AudioStreamIn* AudioHardwareStub::openInputStream(
- int format, int channelCount, uint32_t sampleRate,
- status_t *status, AudioSystem::audio_in_acoustics acoustics)
-{
- AudioStreamInStub* in = new AudioStreamInStub();
- status_t lStatus = in->set(format, channelCount, sampleRate, acoustics);
- if (status) {
- *status = lStatus;
- }
- if (lStatus == NO_ERROR)
- return in;
- delete in;
- return 0;
-}
-
-status_t AudioHardwareStub::setVoiceVolume(float volume)
-{
- return NO_ERROR;
-}
-
-status_t AudioHardwareStub::setMasterVolume(float volume)
-{
- return NO_ERROR;
-}
-
-status_t AudioHardwareStub::dumpInternals(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
- result.append("AudioHardwareStub::dumpInternals\n");
- snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false");
- result.append(buffer);
- ::write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-status_t AudioHardwareStub::dump(int fd, const Vector<String16>& args)
-{
- dumpInternals(fd, args);
- return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-status_t AudioStreamOutStub::set(int format, int channels, uint32_t rate)
-{
- // fix up defaults
- if (format == 0) format = AudioSystem::PCM_16_BIT;
- if (channels == 0) channels = channelCount();
- if (rate == 0) rate = sampleRate();
-
- if ((format == AudioSystem::PCM_16_BIT) &&
- (channels == channelCount()) &&
- (rate == sampleRate()))
- return NO_ERROR;
- return BAD_VALUE;
-}
-
-ssize_t AudioStreamOutStub::write(const void* buffer, size_t bytes)
-{
- // fake timing for audio output
- usleep(bytes * 1000000 / sizeof(int16_t) / channelCount() / sampleRate());
- return bytes;
-}
-
-status_t AudioStreamOutStub::standby()
-{
- return NO_ERROR;
-}
-
-status_t AudioStreamOutStub::dump(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
- snprintf(buffer, SIZE, "AudioStreamOutStub::dump\n");
- snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
- snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
- snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount());
- snprintf(buffer, SIZE, "\tformat: %d\n", format());
- result.append(buffer);
- ::write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-status_t AudioStreamInStub::set(int format, int channels, uint32_t rate,
- AudioSystem::audio_in_acoustics acoustics)
-{
- if ((format == AudioSystem::PCM_16_BIT) &&
- (channels == channelCount()) &&
- (rate == sampleRate()))
- return NO_ERROR;
- return BAD_VALUE;
-}
-
-ssize_t AudioStreamInStub::read(void* buffer, ssize_t bytes)
-{
- // fake timing for audio input
- usleep(bytes * 1000000 / sizeof(int16_t) / channelCount() / sampleRate());
- memset(buffer, 0, bytes);
- return bytes;
-}
-
-status_t AudioStreamInStub::dump(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
- snprintf(buffer, SIZE, "AudioStreamInStub::dump\n");
- result.append(buffer);
- snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount());
- result.append(buffer);
- snprintf(buffer, SIZE, "\tformat: %d\n", format());
- result.append(buffer);
- ::write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/audioflinger/AudioHardwareStub.h b/libs/audioflinger/AudioHardwareStub.h
deleted file mode 100644
index d406424..0000000
--- a/libs/audioflinger/AudioHardwareStub.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* //device/servers/AudioFlinger/AudioHardwareStub.h
-**
-** Copyright 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_AUDIO_HARDWARE_STUB_H
-#define ANDROID_AUDIO_HARDWARE_STUB_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <hardware_legacy/AudioHardwareBase.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class AudioStreamOutStub : public AudioStreamOut {
-public:
- virtual status_t set(int format, int channelCount, uint32_t sampleRate);
- virtual uint32_t sampleRate() const { return 44100; }
- virtual size_t bufferSize() const { return 4096; }
- virtual int channelCount() const { return 2; }
- virtual int format() const { return AudioSystem::PCM_16_BIT; }
- virtual uint32_t latency() const { return 0; }
- virtual status_t setVolume(float volume) { return NO_ERROR; }
- virtual ssize_t write(const void* buffer, size_t bytes);
- virtual status_t standby();
- virtual status_t dump(int fd, const Vector<String16>& args);
-};
-
-class AudioStreamInStub : public AudioStreamIn {
-public:
- virtual status_t set(int format, int channelCount, uint32_t sampleRate, AudioSystem::audio_in_acoustics acoustics);
- virtual uint32_t sampleRate() const { return 8000; }
- virtual size_t bufferSize() const { return 320; }
- virtual int channelCount() const { return 1; }
- virtual int format() const { return AudioSystem::PCM_16_BIT; }
- virtual status_t setGain(float gain) { return NO_ERROR; }
- virtual ssize_t read(void* buffer, ssize_t bytes);
- virtual status_t dump(int fd, const Vector<String16>& args);
- virtual status_t standby() { return NO_ERROR; }
-};
-
-class AudioHardwareStub : public AudioHardwareBase
-{
-public:
- AudioHardwareStub();
- virtual ~AudioHardwareStub();
- virtual status_t initCheck();
- virtual status_t setVoiceVolume(float volume);
- virtual status_t setMasterVolume(float volume);
-
- // mic mute
- virtual status_t setMicMute(bool state) { mMicMute = state; return NO_ERROR; }
- virtual status_t getMicMute(bool* state) { *state = mMicMute ; return NO_ERROR; }
-
- virtual status_t setParameter(const char* key, const char* value)
- { return NO_ERROR; }
-
- // create I/O streams
- virtual AudioStreamOut* openOutputStream(
- int format=0,
- int channelCount=0,
- uint32_t sampleRate=0,
- status_t *status=0);
-
- virtual AudioStreamIn* openInputStream(
- int format,
- int channelCount,
- uint32_t sampleRate,
- status_t *status,
- AudioSystem::audio_in_acoustics acoustics);
-
-protected:
- virtual status_t doRouting() { return NO_ERROR; }
- virtual status_t dump(int fd, const Vector<String16>& args);
-
- bool mMicMute;
-private:
- status_t dumpInternals(int fd, const Vector<String16>& args);
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_AUDIO_HARDWARE_STUB_H
diff --git a/libs/audioflinger/AudioMixer.cpp b/libs/audioflinger/AudioMixer.cpp
deleted file mode 100644
index b03467f..0000000
--- a/libs/audioflinger/AudioMixer.cpp
+++ /dev/null
@@ -1,913 +0,0 @@
-/* //device/include/server/AudioFlinger/AudioMixer.cpp
-**
-** Copyright 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.
-*/
-
-#define LOG_TAG "AudioMixer"
-
-#include <stdint.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-#include "AudioMixer.h"
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-static inline int16_t clamp16(int32_t sample)
-{
- if ((sample>>15) ^ (sample>>31))
- sample = 0x7FFF ^ (sample>>31);
- return sample;
-}
-
-// ----------------------------------------------------------------------------
-
-AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate)
- : mActiveTrack(0), mTrackNames(0), mSampleRate(sampleRate)
-{
- mState.enabledTracks= 0;
- mState.needsChanged = 0;
- mState.frameCount = frameCount;
- mState.outputTemp = 0;
- mState.resampleTemp = 0;
- mState.hook = process__nop;
- track_t* t = mState.tracks;
- for (int i=0 ; i<32 ; i++) {
- t->needs = 0;
- t->volume[0] = UNITY_GAIN;
- t->volume[1] = UNITY_GAIN;
- t->volumeInc[0] = 0;
- t->volumeInc[1] = 0;
- t->channelCount = 2;
- t->enabled = 0;
- t->format = 16;
- t->buffer.raw = 0;
- t->bufferProvider = 0;
- t->hook = 0;
- t->resampler = 0;
- t->sampleRate = mSampleRate;
- t->in = 0;
- t++;
- }
-}
-
- AudioMixer::~AudioMixer()
- {
- track_t* t = mState.tracks;
- for (int i=0 ; i<32 ; i++) {
- delete t->resampler;
- t++;
- }
- delete [] mState.outputTemp;
- delete [] mState.resampleTemp;
- }
-
- int AudioMixer::getTrackName()
- {
- uint32_t names = mTrackNames;
- uint32_t mask = 1;
- int n = 0;
- while (names & mask) {
- mask <<= 1;
- n++;
- }
- if (mask) {
- LOGV("add track (%d)", n);
- mTrackNames |= mask;
- return TRACK0 + n;
- }
- return -1;
- }
-
- void AudioMixer::invalidateState(uint32_t mask)
- {
- if (mask) {
- mState.needsChanged |= mask;
- mState.hook = process__validate;
- }
- }
-
- void AudioMixer::deleteTrackName(int name)
- {
- name -= TRACK0;
- if (uint32_t(name) < MAX_NUM_TRACKS) {
- LOGV("deleteTrackName(%d)", name);
- track_t& track(mState.tracks[ name ]);
- if (track.enabled != 0) {
- track.enabled = 0;
- invalidateState(1<<name);
- }
- if (track.resampler) {
- // delete the resampler
- delete track.resampler;
- track.resampler = 0;
- track.sampleRate = mSampleRate;
- invalidateState(1<<name);
- }
- track.volumeInc[0] = 0;
- track.volumeInc[1] = 0;
- mTrackNames &= ~(1<<name);
- }
- }
-
-status_t AudioMixer::enable(int name)
-{
- switch (name) {
- case MIXING: {
- if (mState.tracks[ mActiveTrack ].enabled != 1) {
- mState.tracks[ mActiveTrack ].enabled = 1;
- LOGV("enable(%d)", mActiveTrack);
- invalidateState(1<<mActiveTrack);
- }
- } break;
- default:
- return NAME_NOT_FOUND;
- }
- return NO_ERROR;
-}
-
-status_t AudioMixer::disable(int name)
-{
- switch (name) {
- case MIXING: {
- if (mState.tracks[ mActiveTrack ].enabled != 0) {
- mState.tracks[ mActiveTrack ].enabled = 0;
- LOGV("disable(%d)", mActiveTrack);
- invalidateState(1<<mActiveTrack);
- }
- } break;
- default:
- return NAME_NOT_FOUND;
- }
- return NO_ERROR;
-}
-
-status_t AudioMixer::setActiveTrack(int track)
-{
- if (uint32_t(track-TRACK0) >= MAX_NUM_TRACKS) {
- return BAD_VALUE;
- }
- mActiveTrack = track - TRACK0;
- return NO_ERROR;
-}
-
-status_t AudioMixer::setParameter(int target, int name, int value)
-{
- switch (target) {
- case TRACK:
- if (name == CHANNEL_COUNT) {
- if ((uint32_t(value) <= MAX_NUM_CHANNELS) && (value)) {
- if (mState.tracks[ mActiveTrack ].channelCount != value) {
- mState.tracks[ mActiveTrack ].channelCount = value;
- LOGV("setParameter(TRACK, CHANNEL_COUNT, %d)", value);
- invalidateState(1<<mActiveTrack);
- }
- return NO_ERROR;
- }
- }
- break;
- case RESAMPLE:
- if (name == SAMPLE_RATE) {
- if (value > 0) {
- track_t& track = mState.tracks[ mActiveTrack ];
- if (track.setResampler(uint32_t(value), mSampleRate)) {
- LOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
- uint32_t(value));
- invalidateState(1<<mActiveTrack);
- }
- return NO_ERROR;
- }
- }
- break;
- case RAMP_VOLUME:
- case VOLUME:
- if ((uint32_t(name-VOLUME0) < MAX_NUM_CHANNELS)) {
- track_t& track = mState.tracks[ mActiveTrack ];
- if (track.volume[name-VOLUME0] != value) {
- track.prevVolume[name-VOLUME0] = track.volume[name-VOLUME0] << 16;
- track.volume[name-VOLUME0] = value;
- if (target == VOLUME) {
- track.prevVolume[name-VOLUME0] = value << 16;
- track.volumeInc[name-VOLUME0] = 0;
- } else {
- int32_t d = (value<<16) - track.prevVolume[name-VOLUME0];
- int32_t volInc = d / int32_t(mState.frameCount);
- track.volumeInc[name-VOLUME0] = volInc;
- if (volInc == 0) {
- track.prevVolume[name-VOLUME0] = value << 16;
- }
- }
- invalidateState(1<<mActiveTrack);
- }
- return NO_ERROR;
- }
- break;
- }
- return BAD_VALUE;
-}
-
-bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
-{
- if (value!=devSampleRate || resampler) {
- if (sampleRate != value) {
- sampleRate = value;
- if (resampler == 0) {
- resampler = AudioResampler::create(
- format, channelCount, devSampleRate);
- }
- return true;
- }
- }
- return false;
-}
-
-bool AudioMixer::track_t::doesResample() const
-{
- return resampler != 0;
-}
-
-inline
-void AudioMixer::track_t::adjustVolumeRamp()
-{
- for (int i=0 ; i<2 ; i++) {
- if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
- ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
- volumeInc[i] = 0;
- prevVolume[i] = volume[i]<<16;
- }
- }
-}
-
-
-status_t AudioMixer::setBufferProvider(AudioBufferProvider* buffer)
-{
- mState.tracks[ mActiveTrack ].bufferProvider = buffer;
- return NO_ERROR;
-}
-
-
-
-void AudioMixer::process(void* output)
-{
- mState.hook(&mState, output);
-}
-
-
-void AudioMixer::process__validate(state_t* state, void* output)
-{
- LOGW_IF(!state->needsChanged,
- "in process__validate() but nothing's invalid");
-
- uint32_t changed = state->needsChanged;
- state->needsChanged = 0; // clear the validation flag
-
- // recompute which tracks are enabled / disabled
- uint32_t enabled = 0;
- uint32_t disabled = 0;
- while (changed) {
- const int i = 31 - __builtin_clz(changed);
- const uint32_t mask = 1<<i;
- changed &= ~mask;
- track_t& t = state->tracks[i];
- (t.enabled ? enabled : disabled) |= mask;
- }
- state->enabledTracks &= ~disabled;
- state->enabledTracks |= enabled;
-
- // compute everything we need...
- int countActiveTracks = 0;
- int all16BitsStereoNoResample = 1;
- int resampling = 0;
- int volumeRamp = 0;
- uint32_t en = state->enabledTracks;
- while (en) {
- const int i = 31 - __builtin_clz(en);
- en &= ~(1<<i);
-
- countActiveTracks++;
- track_t& t = state->tracks[i];
- uint32_t n = 0;
- n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
- n |= NEEDS_FORMAT_16;
- n |= t.doesResample() ? NEEDS_RESAMPLE_ENABLED : NEEDS_RESAMPLE_DISABLED;
-
- if (t.volumeInc[0]|t.volumeInc[1]) {
- volumeRamp = 1;
- } else if (!t.doesResample() && t.volumeRL == 0) {
- n |= NEEDS_MUTE_ENABLED;
- }
- t.needs = n;
-
- if ((n & NEEDS_MUTE__MASK) == NEEDS_MUTE_ENABLED) {
- t.hook = track__nop;
- } else {
- if ((n & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
- all16BitsStereoNoResample = 0;
- resampling = 1;
- t.hook = track__genericResample;
- } else {
- if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
- t.hook = track__16BitsMono;
- all16BitsStereoNoResample = 0;
- }
- if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_2){
- t.hook = track__16BitsStereo;
- }
- }
- }
- }
-
- // select the processing hooks
- state->hook = process__nop;
- if (countActiveTracks) {
- if (resampling) {
- if (!state->outputTemp) {
- state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
- }
- if (!state->resampleTemp) {
- state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
- }
- state->hook = process__genericResampling;
- } else {
- if (state->outputTemp) {
- delete [] state->outputTemp;
- state->outputTemp = 0;
- }
- if (state->resampleTemp) {
- delete [] state->resampleTemp;
- state->resampleTemp = 0;
- }
- state->hook = process__genericNoResampling;
- if (all16BitsStereoNoResample && !volumeRamp) {
- if (countActiveTracks == 1) {
- state->hook = process__OneTrack16BitsStereoNoResampling;
- }
- }
- }
- }
-
- LOGV("mixer configuration change: %d activeTracks (%08x) "
- "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
- countActiveTracks, state->enabledTracks,
- all16BitsStereoNoResample, resampling, volumeRamp);
-
- state->hook(state, output);
-
- // Now that the volume ramp has been done, set optimal state and
- // track hooks for subsequent mixer process
- if (countActiveTracks) {
- int allMuted = 1;
- uint32_t en = state->enabledTracks;
- while (en) {
- const int i = 31 - __builtin_clz(en);
- en &= ~(1<<i);
- track_t& t = state->tracks[i];
- if (!t.doesResample() && t.volumeRL == 0)
- {
- t.needs |= NEEDS_MUTE_ENABLED;
- t.hook = track__nop;
- } else {
- allMuted = 0;
- }
- }
- if (allMuted) {
- state->hook = process__nop;
- } else if (!resampling && all16BitsStereoNoResample) {
- if (countActiveTracks == 1) {
- state->hook = process__OneTrack16BitsStereoNoResampling;
- }
- }
- }
-}
-
-static inline
-int32_t mulAdd(int16_t in, int16_t v, int32_t a)
-{
-#if defined(__arm__) && !defined(__thumb__)
- int32_t out;
- asm( "smlabb %[out], %[in], %[v], %[a] \n"
- : [out]"=r"(out)
- : [in]"%r"(in), [v]"r"(v), [a]"r"(a)
- : );
- return out;
-#else
- return a + in * int32_t(v);
-#endif
-}
-
-static inline
-int32_t mul(int16_t in, int16_t v)
-{
-#if defined(__arm__) && !defined(__thumb__)
- int32_t out;
- asm( "smulbb %[out], %[in], %[v] \n"
- : [out]"=r"(out)
- : [in]"%r"(in), [v]"r"(v)
- : );
- return out;
-#else
- return in * int32_t(v);
-#endif
-}
-
-static inline
-int32_t mulAddRL(int left, uint32_t inRL, uint32_t vRL, int32_t a)
-{
-#if defined(__arm__) && !defined(__thumb__)
- int32_t out;
- if (left) {
- asm( "smlabb %[out], %[inRL], %[vRL], %[a] \n"
- : [out]"=r"(out)
- : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a)
- : );
- } else {
- asm( "smlatt %[out], %[inRL], %[vRL], %[a] \n"
- : [out]"=r"(out)
- : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a)
- : );
- }
- return out;
-#else
- if (left) {
- return a + int16_t(inRL&0xFFFF) * int16_t(vRL&0xFFFF);
- } else {
- return a + int16_t(inRL>>16) * int16_t(vRL>>16);
- }
-#endif
-}
-
-static inline
-int32_t mulRL(int left, uint32_t inRL, uint32_t vRL)
-{
-#if defined(__arm__) && !defined(__thumb__)
- int32_t out;
- if (left) {
- asm( "smulbb %[out], %[inRL], %[vRL] \n"
- : [out]"=r"(out)
- : [inRL]"%r"(inRL), [vRL]"r"(vRL)
- : );
- } else {
- asm( "smultt %[out], %[inRL], %[vRL] \n"
- : [out]"=r"(out)
- : [inRL]"%r"(inRL), [vRL]"r"(vRL)
- : );
- }
- return out;
-#else
- if (left) {
- return int16_t(inRL&0xFFFF) * int16_t(vRL&0xFFFF);
- } else {
- return int16_t(inRL>>16) * int16_t(vRL>>16);
- }
-#endif
-}
-
-
-void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp)
-{
- t->resampler->setSampleRate(t->sampleRate);
-
- // ramp gain - resample to temp buffer and scale/mix in 2nd step
- if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
- t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
- memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
- t->resampler->resample(temp, outFrameCount, t->bufferProvider);
- volumeRampStereo(t, out, outFrameCount, temp);
- }
-
- // constant gain
- else {
- t->resampler->setVolume(t->volume[0], t->volume[1]);
- t->resampler->resample(out, outFrameCount, t->bufferProvider);
- }
-}
-
-void AudioMixer::track__nop(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp)
-{
-}
-
-void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp)
-{
- int32_t vl = t->prevVolume[0];
- int32_t vr = t->prevVolume[1];
- const int32_t vlInc = t->volumeInc[0];
- const int32_t vrInc = t->volumeInc[1];
-
- //LOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
- // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
- // (vl + vlInc*frameCount)/65536.0f, frameCount);
-
- // ramp volume
- do {
- *out++ += (vl >> 16) * (*temp++ >> 12);
- *out++ += (vr >> 16) * (*temp++ >> 12);
- vl += vlInc;
- vr += vrInc;
- } while (--frameCount);
-
- t->prevVolume[0] = vl;
- t->prevVolume[1] = vr;
- t->adjustVolumeRamp();
-}
-
-void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp)
-{
- int16_t const *in = static_cast<int16_t const *>(t->in);
-
- // ramp gain
- if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
- int32_t vl = t->prevVolume[0];
- int32_t vr = t->prevVolume[1];
- const int32_t vlInc = t->volumeInc[0];
- const int32_t vrInc = t->volumeInc[1];
-
- // LOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
- // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
- // (vl + vlInc*frameCount)/65536.0f, frameCount);
-
- do {
- *out++ += (vl >> 16) * (int32_t) *in++;
- *out++ += (vr >> 16) * (int32_t) *in++;
- vl += vlInc;
- vr += vrInc;
- } while (--frameCount);
-
- t->prevVolume[0] = vl;
- t->prevVolume[1] = vr;
- t->adjustVolumeRamp();
- }
-
- // constant gain
- else {
- const uint32_t vrl = t->volumeRL;
- do {
- uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
- in += 2;
- out[0] = mulAddRL(1, rl, vrl, out[0]);
- out[1] = mulAddRL(0, rl, vrl, out[1]);
- out += 2;
- } while (--frameCount);
- }
- t->in = in;
-}
-
-void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount, int32_t* temp)
-{
- int16_t const *in = static_cast<int16_t const *>(t->in);
-
- // ramp gain
- if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
- int32_t vl = t->prevVolume[0];
- int32_t vr = t->prevVolume[1];
- const int32_t vlInc = t->volumeInc[0];
- const int32_t vrInc = t->volumeInc[1];
-
- // LOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
- // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
- // (vl + vlInc*frameCount)/65536.0f, frameCount);
-
- do {
- int32_t l = *in++;
- *out++ += (vl >> 16) * l;
- *out++ += (vr >> 16) * l;
- vl += vlInc;
- vr += vrInc;
- } while (--frameCount);
-
- t->prevVolume[0] = vl;
- t->prevVolume[1] = vr;
- t->adjustVolumeRamp();
- }
- // constant gain
- else {
- const int16_t vl = t->volume[0];
- const int16_t vr = t->volume[1];
- do {
- int16_t l = *in++;
- out[0] = mulAdd(l, vl, out[0]);
- out[1] = mulAdd(l, vr, out[1]);
- out += 2;
- } while (--frameCount);
- }
- t->in = in;
-}
-
-inline
-void AudioMixer::ditherAndClamp(int32_t* out, int32_t const *sums, size_t c)
-{
- for (size_t i=0 ; i<c ; i++) {
- int32_t l = *sums++;
- int32_t r = *sums++;
- int32_t nl = l >> 12;
- int32_t nr = r >> 12;
- l = clamp16(nl);
- r = clamp16(nr);
- *out++ = (r<<16) | (l & 0xFFFF);
- }
-}
-
-// no-op case
-void AudioMixer::process__nop(state_t* state, void* output)
-{
- // this assumes output 16 bits stereo, no resampling
- memset(output, 0, state->frameCount*4);
- uint32_t en = state->enabledTracks;
- while (en) {
- const int i = 31 - __builtin_clz(en);
- en &= ~(1<<i);
- track_t& t = state->tracks[i];
- size_t outFrames = state->frameCount;
- while (outFrames) {
- t.buffer.frameCount = outFrames;
- t.bufferProvider->getNextBuffer(&t.buffer);
- if (!t.buffer.raw) break;
- outFrames -= t.buffer.frameCount;
- t.bufferProvider->releaseBuffer(&t.buffer);
- }
- }
-}
-
-// generic code without resampling
-void AudioMixer::process__genericNoResampling(state_t* state, void* output)
-{
- int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
-
- // acquire each track's buffer
- uint32_t enabledTracks = state->enabledTracks;
- uint32_t en = enabledTracks;
- while (en) {
- const int i = 31 - __builtin_clz(en);
- en &= ~(1<<i);
- track_t& t = state->tracks[i];
- t.buffer.frameCount = state->frameCount;
- t.bufferProvider->getNextBuffer(&t.buffer);
- t.frameCount = t.buffer.frameCount;
- t.in = t.buffer.raw;
- // t.in == NULL can happen if the track was flushed just after having
- // been enabled for mixing.
- if (t.in == NULL)
- enabledTracks &= ~(1<<i);
- }
-
- // this assumes output 16 bits stereo, no resampling
- int32_t* out = static_cast<int32_t*>(output);
- size_t numFrames = state->frameCount;
- do {
- memset(outTemp, 0, sizeof(outTemp));
-
- en = enabledTracks;
- while (en) {
- const int i = 31 - __builtin_clz(en);
- en &= ~(1<<i);
- track_t& t = state->tracks[i];
- size_t outFrames = BLOCKSIZE;
-
- while (outFrames) {
- size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
- if (inFrames) {
- (t.hook)(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, state->resampleTemp);
- t.frameCount -= inFrames;
- outFrames -= inFrames;
- }
- if (t.frameCount == 0 && outFrames) {
- t.bufferProvider->releaseBuffer(&t.buffer);
- t.buffer.frameCount = numFrames - (BLOCKSIZE - outFrames);
- t.bufferProvider->getNextBuffer(&t.buffer);
- t.in = t.buffer.raw;
- if (t.in == NULL) {
- enabledTracks &= ~(1<<i);
- break;
- }
- t.frameCount = t.buffer.frameCount;
- }
- }
- }
-
- ditherAndClamp(out, outTemp, BLOCKSIZE);
- out += BLOCKSIZE;
- numFrames -= BLOCKSIZE;
- } while (numFrames);
-
-
- // release each track's buffer
- en = enabledTracks;
- while (en) {
- const int i = 31 - __builtin_clz(en);
- en &= ~(1<<i);
- track_t& t = state->tracks[i];
- t.bufferProvider->releaseBuffer(&t.buffer);
- }
-}
-
-// generic code with resampling
-void AudioMixer::process__genericResampling(state_t* state, void* output)
-{
- int32_t* const outTemp = state->outputTemp;
- const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
- memset(outTemp, 0, size);
-
- int32_t* out = static_cast<int32_t*>(output);
- size_t numFrames = state->frameCount;
-
- uint32_t en = state->enabledTracks;
- while (en) {
- const int i = 31 - __builtin_clz(en);
- en &= ~(1<<i);
- track_t& t = state->tracks[i];
-
- // this is a little goofy, on the resampling case we don't
- // acquire/release the buffers because it's done by
- // the resampler.
- if ((t.needs & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
- (t.hook)(&t, outTemp, numFrames, state->resampleTemp);
- } else {
-
- size_t outFrames = numFrames;
-
- while (outFrames) {
- t.buffer.frameCount = outFrames;
- t.bufferProvider->getNextBuffer(&t.buffer);
- t.in = t.buffer.raw;
- // t.in == NULL can happen if the track was flushed just after having
- // been enabled for mixing.
- if (t.in == NULL) break;
-
- (t.hook)(&t, outTemp + (numFrames-outFrames)*MAX_NUM_CHANNELS, t.buffer.frameCount, state->resampleTemp);
- outFrames -= t.buffer.frameCount;
- t.bufferProvider->releaseBuffer(&t.buffer);
- }
- }
- }
-
- ditherAndClamp(out, outTemp, numFrames);
-}
-
-// one track, 16 bits stereo without resampling is the most common case
-void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state, void* output)
-{
- const int i = 31 - __builtin_clz(state->enabledTracks);
- const track_t& t = state->tracks[i];
-
- AudioBufferProvider::Buffer& b(t.buffer);
-
- int32_t* out = static_cast<int32_t*>(output);
- size_t numFrames = state->frameCount;
-
- const int16_t vl = t.volume[0];
- const int16_t vr = t.volume[1];
- const uint32_t vrl = t.volumeRL;
- while (numFrames) {
- b.frameCount = numFrames;
- t.bufferProvider->getNextBuffer(&b);
- int16_t const *in = b.i16;
-
- // in == NULL can happen if the track was flushed just after having
- // been enabled for mixing.
- if (in == NULL) {
- memset(out, 0, numFrames*MAX_NUM_CHANNELS*sizeof(int16_t));
- return;
- }
- size_t outFrames = b.frameCount;
-
- if (UNLIKELY(uint32_t(vl) > UNITY_GAIN || uint32_t(vr) > UNITY_GAIN)) {
- // volume is boosted, so we might need to clamp even though
- // we process only one track.
- do {
- uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
- in += 2;
- int32_t l = mulRL(1, rl, vrl) >> 12;
- int32_t r = mulRL(0, rl, vrl) >> 12;
- // clamping...
- l = clamp16(l);
- r = clamp16(r);
- *out++ = (r<<16) | (l & 0xFFFF);
- } while (--outFrames);
- } else {
- do {
- uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
- in += 2;
- int32_t l = mulRL(1, rl, vrl) >> 12;
- int32_t r = mulRL(0, rl, vrl) >> 12;
- *out++ = (r<<16) | (l & 0xFFFF);
- } while (--outFrames);
- }
- numFrames -= b.frameCount;
- t.bufferProvider->releaseBuffer(&b);
- }
-}
-
-// 2 tracks is also a common case
-void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state, void* output)
-{
- int i;
- uint32_t en = state->enabledTracks;
-
- i = 31 - __builtin_clz(en);
- const track_t& t0 = state->tracks[i];
- AudioBufferProvider::Buffer& b0(t0.buffer);
-
- en &= ~(1<<i);
- i = 31 - __builtin_clz(en);
- const track_t& t1 = state->tracks[i];
- AudioBufferProvider::Buffer& b1(t1.buffer);
-
- int16_t const *in0;
- const int16_t vl0 = t0.volume[0];
- const int16_t vr0 = t0.volume[1];
- size_t frameCount0 = 0;
-
- int16_t const *in1;
- const int16_t vl1 = t1.volume[0];
- const int16_t vr1 = t1.volume[1];
- size_t frameCount1 = 0;
-
- int32_t* out = static_cast<int32_t*>(output);
- size_t numFrames = state->frameCount;
- int16_t const *buff = NULL;
-
-
- while (numFrames) {
-
- if (frameCount0 == 0) {
- b0.frameCount = numFrames;
- t0.bufferProvider->getNextBuffer(&b0);
- if (b0.i16 == NULL) {
- if (buff == NULL) {
- buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
- }
- in0 = buff;
- b0.frameCount = numFrames;
- } else {
- in0 = b0.i16;
- }
- frameCount0 = b0.frameCount;
- }
- if (frameCount1 == 0) {
- b1.frameCount = numFrames;
- t1.bufferProvider->getNextBuffer(&b1);
- if (b1.i16 == NULL) {
- if (buff == NULL) {
- buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
- }
- in1 = buff;
- b1.frameCount = numFrames;
- } else {
- in1 = b1.i16;
- }
- frameCount1 = b1.frameCount;
- }
-
- size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
-
- numFrames -= outFrames;
- frameCount0 -= outFrames;
- frameCount1 -= outFrames;
-
- do {
- int32_t l0 = *in0++;
- int32_t r0 = *in0++;
- l0 = mul(l0, vl0);
- r0 = mul(r0, vr0);
- int32_t l = *in1++;
- int32_t r = *in1++;
- l = mulAdd(l, vl1, l0) >> 12;
- r = mulAdd(r, vr1, r0) >> 12;
- // clamping...
- l = clamp16(l);
- r = clamp16(r);
- *out++ = (r<<16) | (l & 0xFFFF);
- } while (--outFrames);
-
- if (frameCount0 == 0) {
- t0.bufferProvider->releaseBuffer(&b0);
- }
- if (frameCount1 == 0) {
- t1.bufferProvider->releaseBuffer(&b1);
- }
- }
-
- if (buff != NULL) {
- delete [] buff;
- }
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-
diff --git a/libs/audioflinger/AudioMixer.h b/libs/audioflinger/AudioMixer.h
deleted file mode 100644
index 72ca28a..0000000
--- a/libs/audioflinger/AudioMixer.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/* //device/include/server/AudioFlinger/AudioMixer.h
-**
-** Copyright 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_AUDIO_MIXER_H
-#define ANDROID_AUDIO_MIXER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "AudioBufferProvider.h"
-#include "AudioResampler.h"
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
-#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
-
-// ----------------------------------------------------------------------------
-
-class AudioMixer
-{
-public:
- AudioMixer(size_t frameCount, uint32_t sampleRate);
-
- ~AudioMixer();
-
- static const uint32_t MAX_NUM_TRACKS = 32;
- static const uint32_t MAX_NUM_CHANNELS = 2;
-
- static const uint16_t UNITY_GAIN = 0x1000;
-
- enum { // names
-
- // track units (32 units)
- TRACK0 = 0x1000,
-
- // enable/disable
- MIXING = 0x2000,
-
- // setParameter targets
- TRACK = 0x3000,
- RESAMPLE = 0x3001,
- RAMP_VOLUME = 0x3002, // ramp to new volume
- VOLUME = 0x3003, // don't ramp
-
- // set Parameter names
- // for target TRACK
- CHANNEL_COUNT = 0x4000,
- FORMAT = 0x4001,
- // for TARGET RESAMPLE
- SAMPLE_RATE = 0x4100,
- // for TARGET VOLUME (8 channels max)
- VOLUME0 = 0x4200,
- VOLUME1 = 0x4201,
- };
-
-
- int getTrackName();
- void deleteTrackName(int name);
-
- status_t enable(int name);
- status_t disable(int name);
-
- status_t setActiveTrack(int track);
- status_t setParameter(int target, int name, int value);
-
- status_t setBufferProvider(AudioBufferProvider* bufferProvider);
- void process(void* output);
-
- uint32_t trackNames() const { return mTrackNames; }
-
-private:
-
- enum {
- NEEDS_CHANNEL_COUNT__MASK = 0x00000003,
- NEEDS_FORMAT__MASK = 0x000000F0,
- NEEDS_MUTE__MASK = 0x00000100,
- NEEDS_RESAMPLE__MASK = 0x00001000,
- };
-
- enum {
- NEEDS_CHANNEL_1 = 0x00000000,
- NEEDS_CHANNEL_2 = 0x00000001,
-
- NEEDS_FORMAT_16 = 0x00000010,
-
- NEEDS_MUTE_DISABLED = 0x00000000,
- NEEDS_MUTE_ENABLED = 0x00000100,
-
- NEEDS_RESAMPLE_DISABLED = 0x00000000,
- NEEDS_RESAMPLE_ENABLED = 0x00001000,
- };
-
- static inline int32_t applyVolume(int32_t in, int32_t v) {
- return in * v;
- }
-
-
- struct state_t;
-
- typedef void (*mix_t)(state_t* state, void* output);
-
- static const int BLOCKSIZE = 16; // 4 cache lines
-
- struct track_t {
- uint32_t needs;
-
- union {
- int16_t volume[2]; // [0]3.12 fixed point
- int32_t volumeRL;
- };
-
- int32_t prevVolume[2];
-
- int32_t volumeInc[2];
-
- uint16_t frameCount;
-
- uint8_t channelCount : 4;
- uint8_t enabled : 1;
- uint8_t reserved0 : 3;
- uint8_t format;
-
- AudioBufferProvider* bufferProvider;
- mutable AudioBufferProvider::Buffer buffer;
-
- void (*hook)(track_t* t, int32_t* output, size_t numOutFrames, int32_t* temp);
- void const* in; // current location in buffer
-
- AudioResampler* resampler;
- uint32_t sampleRate;
-
- bool setResampler(uint32_t sampleRate, uint32_t devSampleRate);
- bool doesResample() const;
- void adjustVolumeRamp();
- };
-
- // pad to 32-bytes to fill cache line
- struct state_t {
- uint32_t enabledTracks;
- uint32_t needsChanged;
- size_t frameCount;
- mix_t hook;
- int32_t *outputTemp;
- int32_t *resampleTemp;
- int32_t reserved[2];
- track_t tracks[32]; __attribute__((aligned(32)));
- };
-
- int mActiveTrack;
- uint32_t mTrackNames;
- const uint32_t mSampleRate;
-
- state_t mState __attribute__((aligned(32)));
-
- void invalidateState(uint32_t mask);
-
- static void track__genericResample(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
- static void track__nop(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
- static void volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp);
- static void track__16BitsStereo(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
- static void track__16BitsMono(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
- static void ditherAndClamp(int32_t* out, int32_t const *sums, size_t c);
-
- static void process__validate(state_t* state, void* output);
- static void process__nop(state_t* state, void* output);
- static void process__genericNoResampling(state_t* state, void* output);
- static void process__genericResampling(state_t* state, void* output);
- static void process__OneTrack16BitsStereoNoResampling(state_t* state, void* output);
- static void process__TwoTracks16BitsStereoNoResampling(state_t* state, void* output);
-};
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-
-#endif // ANDROID_AUDIO_MIXER_H
diff --git a/libs/audioflinger/AudioResampler.cpp b/libs/audioflinger/AudioResampler.cpp
deleted file mode 100644
index 5dabacb..0000000
--- a/libs/audioflinger/AudioResampler.cpp
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "AudioResampler"
-//#define LOG_NDEBUG 0
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <cutils/log.h>
-#include <cutils/properties.h>
-#include "AudioResampler.h"
-#include "AudioResamplerSinc.h"
-#include "AudioResamplerCubic.h"
-
-namespace android {
-
-#ifdef __ARM_ARCH_5E__ // optimized asm option
- #define ASM_ARM_RESAMP1 // enable asm optimisation for ResamplerOrder1
-#endif // __ARM_ARCH_5E__
-// ----------------------------------------------------------------------------
-
-class AudioResamplerOrder1 : public AudioResampler {
-public:
- AudioResamplerOrder1(int bitDepth, int inChannelCount, int32_t sampleRate) :
- AudioResampler(bitDepth, inChannelCount, sampleRate), mX0L(0), mX0R(0) {
- }
- virtual void resample(int32_t* out, size_t outFrameCount,
- AudioBufferProvider* provider);
-private:
- // number of bits used in interpolation multiply - 15 bits avoids overflow
- static const int kNumInterpBits = 15;
-
- // bits to shift the phase fraction down to avoid overflow
- static const int kPreInterpShift = kNumPhaseBits - kNumInterpBits;
-
- void init() {}
- void resampleMono16(int32_t* out, size_t outFrameCount,
- AudioBufferProvider* provider);
- void resampleStereo16(int32_t* out, size_t outFrameCount,
- AudioBufferProvider* provider);
-#ifdef ASM_ARM_RESAMP1 // asm optimisation for ResamplerOrder1
- void AsmMono16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
- size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
- uint32_t &phaseFraction, uint32_t phaseIncrement);
- void AsmStereo16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
- size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
- uint32_t &phaseFraction, uint32_t phaseIncrement);
-#endif // ASM_ARM_RESAMP1
-
- static inline int32_t Interp(int32_t x0, int32_t x1, uint32_t f) {
- return x0 + (((x1 - x0) * (int32_t)(f >> kPreInterpShift)) >> kNumInterpBits);
- }
- static inline void Advance(size_t* index, uint32_t* frac, uint32_t inc) {
- *frac += inc;
- *index += (size_t)(*frac >> kNumPhaseBits);
- *frac &= kPhaseMask;
- }
- int mX0L;
- int mX0R;
-};
-
-// ----------------------------------------------------------------------------
-AudioResampler* AudioResampler::create(int bitDepth, int inChannelCount,
- int32_t sampleRate, int quality) {
-
- // can only create low quality resample now
- AudioResampler* resampler;
-
- char value[PROPERTY_VALUE_MAX];
- if (property_get("af.resampler.quality", value, 0)) {
- quality = atoi(value);
- LOGD("forcing AudioResampler quality to %d", quality);
- }
-
- if (quality == DEFAULT)
- quality = LOW_QUALITY;
-
- switch (quality) {
- default:
- case LOW_QUALITY:
- LOGV("Create linear Resampler");
- resampler = new AudioResamplerOrder1(bitDepth, inChannelCount, sampleRate);
- break;
- case MED_QUALITY:
- LOGV("Create cubic Resampler");
- resampler = new AudioResamplerCubic(bitDepth, inChannelCount, sampleRate);
- break;
- case HIGH_QUALITY:
- LOGV("Create sinc Resampler");
- resampler = new AudioResamplerSinc(bitDepth, inChannelCount, sampleRate);
- break;
- }
-
- // initialize resampler
- resampler->init();
- return resampler;
-}
-
-AudioResampler::AudioResampler(int bitDepth, int inChannelCount,
- int32_t sampleRate) :
- mBitDepth(bitDepth), mChannelCount(inChannelCount),
- mSampleRate(sampleRate), mInSampleRate(sampleRate), mInputIndex(0),
- mPhaseFraction(0) {
- // sanity check on format
- if ((bitDepth != 16) ||(inChannelCount < 1) || (inChannelCount > 2)) {
- LOGE("Unsupported sample format, %d bits, %d channels", bitDepth,
- inChannelCount);
- // LOG_ASSERT(0);
- }
-
- // initialize common members
- mVolume[0] = mVolume[1] = 0;
- mBuffer.frameCount = 0;
-
- // save format for quick lookup
- if (inChannelCount == 1) {
- mFormat = MONO_16_BIT;
- } else {
- mFormat = STEREO_16_BIT;
- }
-}
-
-AudioResampler::~AudioResampler() {
-}
-
-void AudioResampler::setSampleRate(int32_t inSampleRate) {
- mInSampleRate = inSampleRate;
- mPhaseIncrement = (uint32_t)((kPhaseMultiplier * inSampleRate) / mSampleRate);
-}
-
-void AudioResampler::setVolume(int16_t left, int16_t right) {
- // TODO: Implement anti-zipper filter
- mVolume[0] = left;
- mVolume[1] = right;
-}
-
-// ----------------------------------------------------------------------------
-
-void AudioResamplerOrder1::resample(int32_t* out, size_t outFrameCount,
- AudioBufferProvider* provider) {
-
- // should never happen, but we overflow if it does
- // LOG_ASSERT(outFrameCount < 32767);
-
- // select the appropriate resampler
- switch (mChannelCount) {
- case 1:
- resampleMono16(out, outFrameCount, provider);
- break;
- case 2:
- resampleStereo16(out, outFrameCount, provider);
- break;
- }
-}
-
-void AudioResamplerOrder1::resampleStereo16(int32_t* out, size_t outFrameCount,
- AudioBufferProvider* provider) {
-
- int32_t vl = mVolume[0];
- int32_t vr = mVolume[1];
-
- size_t inputIndex = mInputIndex;
- uint32_t phaseFraction = mPhaseFraction;
- uint32_t phaseIncrement = mPhaseIncrement;
- size_t outputIndex = 0;
- size_t outputSampleCount = outFrameCount * 2;
- size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
-
- // LOGE("starting resample %d frames, inputIndex=%d, phaseFraction=%d, phaseIncrement=%d\n",
- // outFrameCount, inputIndex, phaseFraction, phaseIncrement);
-
- while (outputIndex < outputSampleCount) {
-
- // buffer is empty, fetch a new one
- while (mBuffer.frameCount == 0) {
- mBuffer.frameCount = inFrameCount;
- provider->getNextBuffer(&mBuffer);
- if (mBuffer.raw == NULL) {
- goto resampleStereo16_exit;
- }
-
- // LOGE("New buffer fetched: %d frames\n", mBuffer.frameCount);
- if (mBuffer.frameCount > inputIndex) break;
-
- inputIndex -= mBuffer.frameCount;
- mX0L = mBuffer.i16[mBuffer.frameCount*2-2];
- mX0R = mBuffer.i16[mBuffer.frameCount*2-1];
- provider->releaseBuffer(&mBuffer);
- // mBuffer.frameCount == 0 now so we reload a new buffer
- }
-
- int16_t *in = mBuffer.i16;
-
- // handle boundary case
- while (inputIndex == 0) {
- // LOGE("boundary case\n");
- out[outputIndex++] += vl * Interp(mX0L, in[0], phaseFraction);
- out[outputIndex++] += vr * Interp(mX0R, in[1], phaseFraction);
- Advance(&inputIndex, &phaseFraction, phaseIncrement);
- if (outputIndex == outputSampleCount)
- break;
- }
-
- // process input samples
- // LOGE("general case\n");
-
-#ifdef ASM_ARM_RESAMP1 // asm optimisation for ResamplerOrder1
- if (inputIndex + 2 < mBuffer.frameCount) {
- int32_t* maxOutPt;
- int32_t maxInIdx;
-
- maxOutPt = out + (outputSampleCount - 2); // 2 because 2 frames per loop
- maxInIdx = mBuffer.frameCount - 2;
- AsmStereo16Loop(in, maxOutPt, maxInIdx, outputIndex, out, inputIndex, vl, vr,
- phaseFraction, phaseIncrement);
- }
-#endif // ASM_ARM_RESAMP1
-
- while (outputIndex < outputSampleCount && inputIndex < mBuffer.frameCount) {
- out[outputIndex++] += vl * Interp(in[inputIndex*2-2],
- in[inputIndex*2], phaseFraction);
- out[outputIndex++] += vr * Interp(in[inputIndex*2-1],
- in[inputIndex*2+1], phaseFraction);
- Advance(&inputIndex, &phaseFraction, phaseIncrement);
- }
-
- // LOGE("loop done - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
-
- // if done with buffer, save samples
- if (inputIndex >= mBuffer.frameCount) {
- inputIndex -= mBuffer.frameCount;
-
- // LOGE("buffer done, new input index %d", inputIndex);
-
- mX0L = mBuffer.i16[mBuffer.frameCount*2-2];
- mX0R = mBuffer.i16[mBuffer.frameCount*2-1];
- provider->releaseBuffer(&mBuffer);
-
- // verify that the releaseBuffer resets the buffer frameCount
- // LOG_ASSERT(mBuffer.frameCount == 0);
- }
- }
-
- // LOGE("output buffer full - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
-
-resampleStereo16_exit:
- // save state
- mInputIndex = inputIndex;
- mPhaseFraction = phaseFraction;
-}
-
-void AudioResamplerOrder1::resampleMono16(int32_t* out, size_t outFrameCount,
- AudioBufferProvider* provider) {
-
- int32_t vl = mVolume[0];
- int32_t vr = mVolume[1];
-
- size_t inputIndex = mInputIndex;
- uint32_t phaseFraction = mPhaseFraction;
- uint32_t phaseIncrement = mPhaseIncrement;
- size_t outputIndex = 0;
- size_t outputSampleCount = outFrameCount * 2;
- size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
-
- // LOGE("starting resample %d frames, inputIndex=%d, phaseFraction=%d, phaseIncrement=%d\n",
- // outFrameCount, inputIndex, phaseFraction, phaseIncrement);
- while (outputIndex < outputSampleCount) {
- // buffer is empty, fetch a new one
- while (mBuffer.frameCount == 0) {
- mBuffer.frameCount = inFrameCount;
- provider->getNextBuffer(&mBuffer);
- if (mBuffer.raw == NULL) {
- mInputIndex = inputIndex;
- mPhaseFraction = phaseFraction;
- goto resampleMono16_exit;
- }
- // LOGE("New buffer fetched: %d frames\n", mBuffer.frameCount);
- if (mBuffer.frameCount > inputIndex) break;
-
- inputIndex -= mBuffer.frameCount;
- mX0L = mBuffer.i16[mBuffer.frameCount-1];
- provider->releaseBuffer(&mBuffer);
- // mBuffer.frameCount == 0 now so we reload a new buffer
- }
- int16_t *in = mBuffer.i16;
-
- // handle boundary case
- while (inputIndex == 0) {
- // LOGE("boundary case\n");
- int32_t sample = Interp(mX0L, in[0], phaseFraction);
- out[outputIndex++] += vl * sample;
- out[outputIndex++] += vr * sample;
- Advance(&inputIndex, &phaseFraction, phaseIncrement);
- if (outputIndex == outputSampleCount)
- break;
- }
-
- // process input samples
- // LOGE("general case\n");
-
-#ifdef ASM_ARM_RESAMP1 // asm optimisation for ResamplerOrder1
- if (inputIndex + 2 < mBuffer.frameCount) {
- int32_t* maxOutPt;
- int32_t maxInIdx;
-
- maxOutPt = out + (outputSampleCount - 2);
- maxInIdx = (int32_t)mBuffer.frameCount - 2;
- AsmMono16Loop(in, maxOutPt, maxInIdx, outputIndex, out, inputIndex, vl, vr,
- phaseFraction, phaseIncrement);
- }
-#endif // ASM_ARM_RESAMP1
-
- while (outputIndex < outputSampleCount && inputIndex < mBuffer.frameCount) {
- int32_t sample = Interp(in[inputIndex-1], in[inputIndex],
- phaseFraction);
- out[outputIndex++] += vl * sample;
- out[outputIndex++] += vr * sample;
- Advance(&inputIndex, &phaseFraction, phaseIncrement);
- }
-
-
- // LOGE("loop done - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
-
- // if done with buffer, save samples
- if (inputIndex >= mBuffer.frameCount) {
- inputIndex -= mBuffer.frameCount;
-
- // LOGE("buffer done, new input index %d", inputIndex);
-
- mX0L = mBuffer.i16[mBuffer.frameCount-1];
- provider->releaseBuffer(&mBuffer);
-
- // verify that the releaseBuffer resets the buffer frameCount
- // LOG_ASSERT(mBuffer.frameCount == 0);
- }
- }
-
- // LOGE("output buffer full - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
-
-resampleMono16_exit:
- // save state
- mInputIndex = inputIndex;
- mPhaseFraction = phaseFraction;
-}
-
-#ifdef ASM_ARM_RESAMP1 // asm optimisation for ResamplerOrder1
-
-/*******************************************************************
-*
-* AsmMono16Loop
-* asm optimized monotonic loop version; one loop is 2 frames
-* Input:
-* in : pointer on input samples
-* maxOutPt : pointer on first not filled
-* maxInIdx : index on first not used
-* outputIndex : pointer on current output index
-* out : pointer on output buffer
-* inputIndex : pointer on current input index
-* vl, vr : left and right gain
-* phaseFraction : pointer on current phase fraction
-* phaseIncrement
-* Ouput:
-* outputIndex :
-* out : updated buffer
-* inputIndex : index of next to use
-* phaseFraction : phase fraction for next interpolation
-*
-*******************************************************************/
-void AudioResamplerOrder1::AsmMono16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
- size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
- uint32_t &phaseFraction, uint32_t phaseIncrement)
-{
-#define MO_PARAM5 "36" // offset of parameter 5 (outputIndex)
-
- asm(
- "stmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n"
- // get parameters
- " ldr r6, [sp, #" MO_PARAM5 " + 20]\n" // &phaseFraction
- " ldr r6, [r6]\n" // phaseFraction
- " ldr r7, [sp, #" MO_PARAM5 " + 8]\n" // &inputIndex
- " ldr r7, [r7]\n" // inputIndex
- " ldr r8, [sp, #" MO_PARAM5 " + 4]\n" // out
- " ldr r0, [sp, #" MO_PARAM5 " + 0]\n" // &outputIndex
- " ldr r0, [r0]\n" // outputIndex
- " add r8, r0, asl #2\n" // curOut
- " ldr r9, [sp, #" MO_PARAM5 " + 24]\n" // phaseIncrement
- " ldr r10, [sp, #" MO_PARAM5 " + 12]\n" // vl
- " ldr r11, [sp, #" MO_PARAM5 " + 16]\n" // vr
-
- // r0 pin, x0, Samp
-
- // r1 in
- // r2 maxOutPt
- // r3 maxInIdx
-
- // r4 x1, i1, i3, Out1
- // r5 out0
-
- // r6 frac
- // r7 inputIndex
- // r8 curOut
-
- // r9 inc
- // r10 vl
- // r11 vr
-
- // r12
- // r13 sp
- // r14
-
- // the following loop works on 2 frames
-
- ".Y4L01:\n"
- " cmp r8, r2\n" // curOut - maxCurOut
- " bcs .Y4L02\n"
-
-#define MO_ONE_FRAME \
- " add r0, r1, r7, asl #1\n" /* in + inputIndex */\
- " ldrsh r4, [r0]\n" /* in[inputIndex] */\
- " ldr r5, [r8]\n" /* out[outputIndex] */\
- " ldrsh r0, [r0, #-2]\n" /* in[inputIndex-1] */\
- " bic r6, r6, #0xC0000000\n" /* phaseFraction & ... */\
- " sub r4, r4, r0\n" /* in[inputIndex] - in[inputIndex-1] */\
- " mov r4, r4, lsl #2\n" /* <<2 */\
- " smulwt r4, r4, r6\n" /* (x1-x0)*.. */\
- " add r6, r6, r9\n" /* phaseFraction + phaseIncrement */\
- " add r0, r0, r4\n" /* x0 - (..) */\
- " mla r5, r0, r10, r5\n" /* vl*interp + out[] */\
- " ldr r4, [r8, #4]\n" /* out[outputIndex+1] */\
- " str r5, [r8], #4\n" /* out[outputIndex++] = ... */\
- " mla r4, r0, r11, r4\n" /* vr*interp + out[] */\
- " add r7, r7, r6, lsr #30\n" /* inputIndex + phaseFraction>>30 */\
- " str r4, [r8], #4\n" /* out[outputIndex++] = ... */
-
- MO_ONE_FRAME // frame 1
- MO_ONE_FRAME // frame 2
-
- " cmp r7, r3\n" // inputIndex - maxInIdx
- " bcc .Y4L01\n"
- ".Y4L02:\n"
-
- " bic r6, r6, #0xC0000000\n" // phaseFraction & ...
- // save modified values
- " ldr r0, [sp, #" MO_PARAM5 " + 20]\n" // &phaseFraction
- " str r6, [r0]\n" // phaseFraction
- " ldr r0, [sp, #" MO_PARAM5 " + 8]\n" // &inputIndex
- " str r7, [r0]\n" // inputIndex
- " ldr r0, [sp, #" MO_PARAM5 " + 4]\n" // out
- " sub r8, r0\n" // curOut - out
- " asr r8, #2\n" // new outputIndex
- " ldr r0, [sp, #" MO_PARAM5 " + 0]\n" // &outputIndex
- " str r8, [r0]\n" // save outputIndex
-
- " ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc}\n"
- );
-}
-
-/*******************************************************************
-*
-* AsmStereo16Loop
-* asm optimized stereo loop version; one loop is 2 frames
-* Input:
-* in : pointer on input samples
-* maxOutPt : pointer on first not filled
-* maxInIdx : index on first not used
-* outputIndex : pointer on current output index
-* out : pointer on output buffer
-* inputIndex : pointer on current input index
-* vl, vr : left and right gain
-* phaseFraction : pointer on current phase fraction
-* phaseIncrement
-* Ouput:
-* outputIndex :
-* out : updated buffer
-* inputIndex : index of next to use
-* phaseFraction : phase fraction for next interpolation
-*
-*******************************************************************/
-void AudioResamplerOrder1::AsmStereo16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
- size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
- uint32_t &phaseFraction, uint32_t phaseIncrement)
-{
-#define ST_PARAM5 "40" // offset of parameter 5 (outputIndex)
- asm(
- "stmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}\n"
- // get parameters
- " ldr r6, [sp, #" ST_PARAM5 " + 20]\n" // &phaseFraction
- " ldr r6, [r6]\n" // phaseFraction
- " ldr r7, [sp, #" ST_PARAM5 " + 8]\n" // &inputIndex
- " ldr r7, [r7]\n" // inputIndex
- " ldr r8, [sp, #" ST_PARAM5 " + 4]\n" // out
- " ldr r0, [sp, #" ST_PARAM5 " + 0]\n" // &outputIndex
- " ldr r0, [r0]\n" // outputIndex
- " add r8, r0, asl #2\n" // curOut
- " ldr r9, [sp, #" ST_PARAM5 " + 24]\n" // phaseIncrement
- " ldr r10, [sp, #" ST_PARAM5 " + 12]\n" // vl
- " ldr r11, [sp, #" ST_PARAM5 " + 16]\n" // vr
-
- // r0 pin, x0, Samp
-
- // r1 in
- // r2 maxOutPt
- // r3 maxInIdx
-
- // r4 x1, i1, i3, out1
- // r5 out0
-
- // r6 frac
- // r7 inputIndex
- // r8 curOut
-
- // r9 inc
- // r10 vl
- // r11 vr
-
- // r12 temporary
- // r13 sp
- // r14
-
- ".Y5L01:\n"
- " cmp r8, r2\n" // curOut - maxCurOut
- " bcs .Y5L02\n"
-
-#define ST_ONE_FRAME \
- " bic r6, r6, #0xC0000000\n" /* phaseFraction & ... */\
-\
- " add r0, r1, r7, asl #2\n" /* in + 2*inputIndex */\
-\
- " ldrsh r4, [r0]\n" /* in[2*inputIndex] */\
- " ldr r5, [r8]\n" /* out[outputIndex] */\
- " ldrsh r12, [r0, #-4]\n" /* in[2*inputIndex-2] */\
- " sub r4, r4, r12\n" /* in[2*InputIndex] - in[2*InputIndex-2] */\
- " mov r4, r4, lsl #2\n" /* <<2 */\
- " smulwt r4, r4, r6\n" /* (x1-x0)*.. */\
- " add r12, r12, r4\n" /* x0 - (..) */\
- " mla r5, r12, r10, r5\n" /* vl*interp + out[] */\
- " ldr r4, [r8, #4]\n" /* out[outputIndex+1] */\
- " str r5, [r8], #4\n" /* out[outputIndex++] = ... */\
-\
- " ldrsh r12, [r0, #+2]\n" /* in[2*inputIndex+1] */\
- " ldrsh r0, [r0, #-2]\n" /* in[2*inputIndex-1] */\
- " sub r12, r12, r0\n" /* in[2*InputIndex] - in[2*InputIndex-2] */\
- " mov r12, r12, lsl #2\n" /* <<2 */\
- " smulwt r12, r12, r6\n" /* (x1-x0)*.. */\
- " add r12, r0, r12\n" /* x0 - (..) */\
- " mla r4, r12, r11, r4\n" /* vr*interp + out[] */\
- " str r4, [r8], #4\n" /* out[outputIndex++] = ... */\
-\
- " add r6, r6, r9\n" /* phaseFraction + phaseIncrement */\
- " add r7, r7, r6, lsr #30\n" /* inputIndex + phaseFraction>>30 */
-
- ST_ONE_FRAME // frame 1
- ST_ONE_FRAME // frame 1
-
- " cmp r7, r3\n" // inputIndex - maxInIdx
- " bcc .Y5L01\n"
- ".Y5L02:\n"
-
- " bic r6, r6, #0xC0000000\n" // phaseFraction & ...
- // save modified values
- " ldr r0, [sp, #" ST_PARAM5 " + 20]\n" // &phaseFraction
- " str r6, [r0]\n" // phaseFraction
- " ldr r0, [sp, #" ST_PARAM5 " + 8]\n" // &inputIndex
- " str r7, [r0]\n" // inputIndex
- " ldr r0, [sp, #" ST_PARAM5 " + 4]\n" // out
- " sub r8, r0\n" // curOut - out
- " asr r8, #2\n" // new outputIndex
- " ldr r0, [sp, #" ST_PARAM5 " + 0]\n" // &outputIndex
- " str r8, [r0]\n" // save outputIndex
-
- " ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r12, pc}\n"
- );
-}
-
-#endif // ASM_ARM_RESAMP1
-
-
-// ----------------------------------------------------------------------------
-}
-; // namespace android
-
diff --git a/libs/audioflinger/AudioResampler.h b/libs/audioflinger/AudioResampler.h
deleted file mode 100644
index 39656c0..0000000
--- a/libs/audioflinger/AudioResampler.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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_AUDIO_RESAMPLER_H
-#define ANDROID_AUDIO_RESAMPLER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "AudioBufferProvider.h"
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-class AudioResampler {
-public:
- // Determines quality of SRC.
- // LOW_QUALITY: linear interpolator (1st order)
- // MED_QUALITY: cubic interpolator (3rd order)
- // HIGH_QUALITY: fixed multi-tap FIR (e.g. 48KHz->44.1KHz)
- // NOTE: high quality SRC will only be supported for
- // certain fixed rate conversions. Sample rate cannot be
- // changed dynamically.
- enum src_quality {
- DEFAULT=0,
- LOW_QUALITY=1,
- MED_QUALITY=2,
- HIGH_QUALITY=3
- };
-
- static AudioResampler* create(int bitDepth, int inChannelCount,
- int32_t sampleRate, int quality=DEFAULT);
-
- virtual ~AudioResampler();
-
- virtual void init() = 0;
- virtual void setSampleRate(int32_t inSampleRate);
- virtual void setVolume(int16_t left, int16_t right);
-
- virtual void resample(int32_t* out, size_t outFrameCount,
- AudioBufferProvider* provider) = 0;
-
-protected:
- // number of bits for phase fraction - 30 bits allows nearly 2x downsampling
- static const int kNumPhaseBits = 30;
-
- // phase mask for fraction
- static const uint32_t kPhaseMask = (1LU<<kNumPhaseBits)-1;
-
- // multiplier to calculate fixed point phase increment
- static const double kPhaseMultiplier = 1L << kNumPhaseBits;
-
- enum format {MONO_16_BIT, STEREO_16_BIT};
- AudioResampler(int bitDepth, int inChannelCount, int32_t sampleRate);
-
- // prevent copying
- AudioResampler(const AudioResampler&);
- AudioResampler& operator=(const AudioResampler&);
-
- int32_t mBitDepth;
- int32_t mChannelCount;
- int32_t mSampleRate;
- int32_t mInSampleRate;
- AudioBufferProvider::Buffer mBuffer;
- union {
- int16_t mVolume[2];
- uint32_t mVolumeRL;
- };
- int16_t mTargetVolume[2];
- format mFormat;
- size_t mInputIndex;
- int32_t mPhaseIncrement;
- uint32_t mPhaseFraction;
-};
-
-// ----------------------------------------------------------------------------
-}
-; // namespace android
-
-#endif // ANDROID_AUDIO_RESAMPLER_H
diff --git a/libs/audioflinger/AudioResamplerCubic.cpp b/libs/audioflinger/AudioResamplerCubic.cpp
deleted file mode 100644
index 1d247bd..0000000
--- a/libs/audioflinger/AudioResamplerCubic.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * 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.
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <sys/types.h>
-#include <cutils/log.h>
-
-#include "AudioResampler.h"
-#include "AudioResamplerCubic.h"
-
-#define LOG_TAG "AudioSRC"
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-void AudioResamplerCubic::init() {
- memset(&left, 0, sizeof(state));
- memset(&right, 0, sizeof(state));
-}
-
-void AudioResamplerCubic::resample(int32_t* out, size_t outFrameCount,
- AudioBufferProvider* provider) {
-
- // should never happen, but we overflow if it does
- // LOG_ASSERT(outFrameCount < 32767);
-
- // select the appropriate resampler
- switch (mChannelCount) {
- case 1:
- resampleMono16(out, outFrameCount, provider);
- break;
- case 2:
- resampleStereo16(out, outFrameCount, provider);
- break;
- }
-}
-
-void AudioResamplerCubic::resampleStereo16(int32_t* out, size_t outFrameCount,
- AudioBufferProvider* provider) {
-
- int32_t vl = mVolume[0];
- int32_t vr = mVolume[1];
-
- size_t inputIndex = mInputIndex;
- uint32_t phaseFraction = mPhaseFraction;
- uint32_t phaseIncrement = mPhaseIncrement;
- size_t outputIndex = 0;
- size_t outputSampleCount = outFrameCount * 2;
- size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
-
- // fetch first buffer
- if (mBuffer.frameCount == 0) {
- mBuffer.frameCount = inFrameCount;
- provider->getNextBuffer(&mBuffer);
- if (mBuffer.raw == NULL)
- return;
- // LOGW("New buffer: offset=%p, frames=%dn", mBuffer.raw, mBuffer.frameCount);
- }
- int16_t *in = mBuffer.i16;
-
- while (outputIndex < outputSampleCount) {
- int32_t sample;
- int32_t x;
-
- // calculate output sample
- x = phaseFraction >> kPreInterpShift;
- out[outputIndex++] += vl * interp(&left, x);
- out[outputIndex++] += vr * interp(&right, x);
- // out[outputIndex++] += vr * in[inputIndex*2];
-
- // increment phase
- phaseFraction += phaseIncrement;
- uint32_t indexIncrement = (phaseFraction >> kNumPhaseBits);
- phaseFraction &= kPhaseMask;
-
- // time to fetch another sample
- while (indexIncrement--) {
-
- inputIndex++;
- if (inputIndex == mBuffer.frameCount) {
- inputIndex = 0;
- provider->releaseBuffer(&mBuffer);
- mBuffer.frameCount = inFrameCount;
- provider->getNextBuffer(&mBuffer);
- if (mBuffer.raw == NULL)
- goto save_state; // ugly, but efficient
- in = mBuffer.i16;
- // LOGW("New buffer: offset=%p, frames=%d\n", mBuffer.raw, mBuffer.frameCount);
- }
-
- // advance sample state
- advance(&left, in[inputIndex*2]);
- advance(&right, in[inputIndex*2+1]);
- }
- }
-
-save_state:
- // LOGW("Done: index=%d, fraction=%u", inputIndex, phaseFraction);
- mInputIndex = inputIndex;
- mPhaseFraction = phaseFraction;
-}
-
-void AudioResamplerCubic::resampleMono16(int32_t* out, size_t outFrameCount,
- AudioBufferProvider* provider) {
-
- int32_t vl = mVolume[0];
- int32_t vr = mVolume[1];
-
- size_t inputIndex = mInputIndex;
- uint32_t phaseFraction = mPhaseFraction;
- uint32_t phaseIncrement = mPhaseIncrement;
- size_t outputIndex = 0;
- size_t outputSampleCount = outFrameCount * 2;
- size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
-
- // fetch first buffer
- if (mBuffer.frameCount == 0) {
- mBuffer.frameCount = inFrameCount;
- provider->getNextBuffer(&mBuffer);
- if (mBuffer.raw == NULL)
- return;
- // LOGW("New buffer: offset=%p, frames=%d\n", mBuffer.raw, mBuffer.frameCount);
- }
- int16_t *in = mBuffer.i16;
-
- while (outputIndex < outputSampleCount) {
- int32_t sample;
- int32_t x;
-
- // calculate output sample
- x = phaseFraction >> kPreInterpShift;
- sample = interp(&left, x);
- out[outputIndex++] += vl * sample;
- out[outputIndex++] += vr * sample;
-
- // increment phase
- phaseFraction += phaseIncrement;
- uint32_t indexIncrement = (phaseFraction >> kNumPhaseBits);
- phaseFraction &= kPhaseMask;
-
- // time to fetch another sample
- while (indexIncrement--) {
-
- inputIndex++;
- if (inputIndex == mBuffer.frameCount) {
- inputIndex = 0;
- provider->releaseBuffer(&mBuffer);
- mBuffer.frameCount = inFrameCount;
- provider->getNextBuffer(&mBuffer);
- if (mBuffer.raw == NULL)
- goto save_state; // ugly, but efficient
- // LOGW("New buffer: offset=%p, frames=%dn", mBuffer.raw, mBuffer.frameCount);
- in = mBuffer.i16;
- }
-
- // advance sample state
- advance(&left, in[inputIndex]);
- }
- }
-
-save_state:
- // LOGW("Done: index=%d, fraction=%u", inputIndex, phaseFraction);
- mInputIndex = inputIndex;
- mPhaseFraction = phaseFraction;
-}
-
-// ----------------------------------------------------------------------------
-}
-; // namespace android
-
diff --git a/libs/audioflinger/AudioResamplerCubic.h b/libs/audioflinger/AudioResamplerCubic.h
deleted file mode 100644
index b72b62a..0000000
--- a/libs/audioflinger/AudioResamplerCubic.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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_AUDIO_RESAMPLER_CUBIC_H
-#define ANDROID_AUDIO_RESAMPLER_CUBIC_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <cutils/log.h>
-
-#include "AudioResampler.h"
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-class AudioResamplerCubic : public AudioResampler {
-public:
- AudioResamplerCubic(int bitDepth, int inChannelCount, int32_t sampleRate) :
- AudioResampler(bitDepth, inChannelCount, sampleRate) {
- }
- virtual void resample(int32_t* out, size_t outFrameCount,
- AudioBufferProvider* provider);
-private:
- // number of bits used in interpolation multiply - 14 bits avoids overflow
- static const int kNumInterpBits = 14;
-
- // bits to shift the phase fraction down to avoid overflow
- static const int kPreInterpShift = kNumPhaseBits - kNumInterpBits;
- typedef struct {
- int32_t a, b, c, y0, y1, y2, y3;
- } state;
- void init();
- void resampleMono16(int32_t* out, size_t outFrameCount,
- AudioBufferProvider* provider);
- void resampleStereo16(int32_t* out, size_t outFrameCount,
- AudioBufferProvider* provider);
- static inline int32_t interp(state* p, int32_t x) {
- return (((((p->a * x >> 14) + p->b) * x >> 14) + p->c) * x >> 14) + p->y1;
- }
- static inline void advance(state* p, int16_t in) {
- p->y0 = p->y1;
- p->y1 = p->y2;
- p->y2 = p->y3;
- p->y3 = in;
- p->a = (3 * (p->y1 - p->y2) - p->y0 + p->y3) >> 1;
- p->b = (p->y2 << 1) + p->y0 - (((5 * p->y1 + p->y3)) >> 1);
- p->c = (p->y2 - p->y0) >> 1;
- }
- state left, right;
-};
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-
-#endif /*ANDROID_AUDIO_RESAMPLER_CUBIC_H*/
diff --git a/libs/audioflinger/AudioResamplerSinc.cpp b/libs/audioflinger/AudioResamplerSinc.cpp
deleted file mode 100644
index 9e5e254..0000000
--- a/libs/audioflinger/AudioResamplerSinc.cpp
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * 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.
- */
-
-#include <string.h>
-#include "AudioResamplerSinc.h"
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-
-/*
- * These coeficients are computed with the "fir" utility found in
- * tools/resampler_tools
- * TODO: A good optimization would be to transpose this matrix, to take
- * better advantage of the data-cache.
- */
-const int32_t AudioResamplerSinc::mFirCoefsUp[] = {
- 0x7fffffff, 0x7f15d078, 0x7c5e0da6, 0x77ecd867, 0x71e2e251, 0x6a6c304a, 0x61be7269, 0x58170412, 0x4db8ab05, 0x42e92ea6, 0x37eee214, 0x2d0e3bb1, 0x22879366, 0x18951e95, 0x0f693d0d, 0x072d2621,
- 0x00000000, 0xf9f66655, 0xf51a5fd7, 0xf16bbd84, 0xeee0d9ac, 0xed67a922, 0xece70de6, 0xed405897, 0xee50e505, 0xeff3be30, 0xf203370f, 0xf45a6741, 0xf6d67d53, 0xf957db66, 0xfbc2f647, 0xfe00f2b9,
- 0x00000000, 0x01b37218, 0x0313a0c6, 0x041d930d, 0x04d28057, 0x053731b0, 0x05534dff, 0x05309bfd, 0x04da440d, 0x045c1aee, 0x03c1fcdd, 0x03173ef5, 0x02663ae8, 0x01b7f736, 0x0113ec79, 0x007fe6a9,
- 0x00000000, 0xff96b229, 0xff44f99f, 0xff0a86be, 0xfee5f803, 0xfed518fd, 0xfed521fd, 0xfee2f4fd, 0xfefb54f8, 0xff1b159b, 0xff3f4203, 0xff6539e0, 0xff8ac502, 0xffae1ddd, 0xffcdf3f9, 0xffe96798,
- 0x00000000, 0x00119de6, 0x001e6b7e, 0x0026cb7a, 0x002b4830, 0x002c83d6, 0x002b2a82, 0x0027e67a, 0x002356f9, 0x001e098e, 0x001875e4, 0x0012fbbe, 0x000de2d1, 0x00095c10, 0x00058414, 0x00026636,
- 0x00000000, 0xfffe44a9, 0xfffd206d, 0xfffc7b7f, 0xfffc3c8f, 0xfffc4ac2, 0xfffc8f2b, 0xfffcf5c4, 0xfffd6df3, 0xfffdeab2, 0xfffe6275, 0xfffececf, 0xffff2c07, 0xffff788c, 0xffffb471, 0xffffe0f2,
- 0x00000000, 0x000013e6, 0x00001f03, 0x00002396, 0x00002399, 0x000020b6, 0x00001c3c, 0x00001722, 0x00001216, 0x00000d81, 0x0000099c, 0x0000067c, 0x00000419, 0x0000025f, 0x00000131, 0x00000070,
- 0x00000000, 0xffffffc7, 0xffffffb3, 0xffffffb3, 0xffffffbe, 0xffffffcd, 0xffffffdb, 0xffffffe7, 0xfffffff0, 0xfffffff7, 0xfffffffb, 0xfffffffe, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000 // this one is needed for lerping the last coefficient
-};
-
-/*
- * These coefficients are optimized for 48KHz -> 44.1KHz (stop-band at 22.050KHz)
- * It's possible to use the above coefficient for any down-sampling
- * at the expense of a slower processing loop (we can interpolate
- * these coefficient from the above by "Stretching" them in time).
- */
-const int32_t AudioResamplerSinc::mFirCoefsDown[] = {
- 0x7fffffff, 0x7f55e46d, 0x7d5b4c60, 0x7a1b4b98, 0x75a7fb14, 0x7019f0bd, 0x698f875a, 0x622bfd59, 0x5a167256, 0x5178cc54, 0x487e8e6c, 0x3f53aae8, 0x36235ad4, 0x2d17047b, 0x245539ab, 0x1c00d540,
- 0x14383e57, 0x0d14d5ca, 0x06aa910b, 0x0107c38b, 0xfc351654, 0xf835abae, 0xf5076b45, 0xf2a37202, 0xf0fe9faa, 0xf00a3bbd, 0xefb4aa81, 0xefea2b05, 0xf0959716, 0xf1a11e83, 0xf2f6f7a0, 0xf481fff4,
- 0xf62e48ce, 0xf7e98ca5, 0xf9a38b4c, 0xfb4e4bfa, 0xfcde456f, 0xfe4a6d30, 0xff8c2fdf, 0x009f5555, 0x0181d393, 0x0233940f, 0x02b62f06, 0x030ca07d, 0x033afa62, 0x03461725, 0x03334f83, 0x030835fa,
- 0x02ca59cc, 0x027f12d1, 0x022b570d, 0x01d39a49, 0x017bb78f, 0x0126e414, 0x00d7aaaf, 0x008feec7, 0x0050f584, 0x001b73e3, 0xffefa063, 0xffcd46ed, 0xffb3ddcd, 0xffa29aaa, 0xff988691, 0xff949066,
- 0xff959d24, 0xff9a959e, 0xffa27195, 0xffac4011, 0xffb72d2b, 0xffc28569, 0xffcdb706, 0xffd85171, 0xffe20364, 0xffea97e9, 0xfff1f2b2, 0xfff80c06, 0xfffcec92, 0x0000a955, 0x00035fd8, 0x000532cf,
- 0x00064735, 0x0006c1f9, 0x0006c62d, 0x000673ba, 0x0005e68f, 0x00053630, 0x000475a3, 0x0003b397, 0x0002fac1, 0x00025257, 0x0001be9e, 0x0001417a, 0x0000dafd, 0x000089eb, 0x00004c28, 0x00001f1d,
- 0x00000000, 0xffffec10, 0xffffe0be, 0xffffdbc5, 0xffffdb39, 0xffffdd8b, 0xffffe182, 0xffffe638, 0xffffeb0a, 0xffffef8f, 0xfffff38b, 0xfffff6e3, 0xfffff993, 0xfffffba6, 0xfffffd30, 0xfffffe4a,
- 0xffffff09, 0xffffff85, 0xffffffd1, 0xfffffffb, 0x0000000f, 0x00000016, 0x00000015, 0x00000012, 0x0000000d, 0x00000009, 0x00000006, 0x00000003, 0x00000002, 0x00000001, 0x00000000, 0x00000000,
- 0x00000000 // this one is needed for lerping the last coefficient
-};
-
-// ----------------------------------------------------------------------------
-
-static inline
-int32_t mulRL(int left, int32_t in, uint32_t vRL)
-{
-#if defined(__arm__) && !defined(__thumb__)
- int32_t out;
- if (left) {
- asm( "smultb %[out], %[in], %[vRL] \n"
- : [out]"=r"(out)
- : [in]"%r"(in), [vRL]"r"(vRL)
- : );
- } else {
- asm( "smultt %[out], %[in], %[vRL] \n"
- : [out]"=r"(out)
- : [in]"%r"(in), [vRL]"r"(vRL)
- : );
- }
- return out;
-#else
- if (left) {
- return int16_t(in>>16) * int16_t(vRL&0xFFFF);
- } else {
- return int16_t(in>>16) * int16_t(vRL>>16);
- }
-#endif
-}
-
-static inline
-int32_t mulAdd(int16_t in, int32_t v, int32_t a)
-{
-#if defined(__arm__) && !defined(__thumb__)
- int32_t out;
- asm( "smlawb %[out], %[v], %[in], %[a] \n"
- : [out]"=r"(out)
- : [in]"%r"(in), [v]"r"(v), [a]"r"(a)
- : );
- return out;
-#else
- return a + in * (v>>16);
- // improved precision
- // return a + in * (v>>16) + ((in * (v & 0xffff)) >> 16);
-#endif
-}
-
-static inline
-int32_t mulAddRL(int left, uint32_t inRL, int32_t v, int32_t a)
-{
-#if defined(__arm__) && !defined(__thumb__)
- int32_t out;
- if (left) {
- asm( "smlawb %[out], %[v], %[inRL], %[a] \n"
- : [out]"=r"(out)
- : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a)
- : );
- } else {
- asm( "smlawt %[out], %[v], %[inRL], %[a] \n"
- : [out]"=r"(out)
- : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a)
- : );
- }
- return out;
-#else
- if (left) {
- return a + (int16_t(inRL&0xFFFF) * (v>>16));
- //improved precision
- // return a + (int16_t(inRL&0xFFFF) * (v>>16)) + ((int16_t(inRL&0xFFFF) * (v & 0xffff)) >> 16);
- } else {
- return a + (int16_t(inRL>>16) * (v>>16));
- }
-#endif
-}
-
-// ----------------------------------------------------------------------------
-
-AudioResamplerSinc::AudioResamplerSinc(int bitDepth,
- int inChannelCount, int32_t sampleRate)
- : AudioResampler(bitDepth, inChannelCount, sampleRate),
- mState(0)
-{
- /*
- * Layout of the state buffer for 32 tap:
- *
- * "present" sample beginning of 2nd buffer
- * v v
- * 0 01 2 23 3
- * 0 F0 0 F0 F
- * [pppppppppppppppInnnnnnnnnnnnnnnnpppppppppppppppInnnnnnnnnnnnnnnn]
- * ^ ^ head
- *
- * p = past samples, convoluted with the (p)ositive side of sinc()
- * n = future samples, convoluted with the (n)egative side of sinc()
- * r = extra space for implementing the ring buffer
- *
- */
-
- const size_t numCoefs = 2*halfNumCoefs;
- const size_t stateSize = numCoefs * inChannelCount * 2;
- mState = new int16_t[stateSize];
- memset(mState, 0, sizeof(int16_t)*stateSize);
- mImpulse = mState + (halfNumCoefs-1)*inChannelCount;
- mRingFull = mImpulse + (numCoefs+1)*inChannelCount;
-}
-
-AudioResamplerSinc::~AudioResamplerSinc()
-{
- delete [] mState;
-}
-
-void AudioResamplerSinc::init() {
-}
-
-void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount,
- AudioBufferProvider* provider)
-{
- mFirCoefs = (mInSampleRate <= mSampleRate) ? mFirCoefsUp : mFirCoefsDown;
-
- // select the appropriate resampler
- switch (mChannelCount) {
- case 1:
- resample<1>(out, outFrameCount, provider);
- break;
- case 2:
- resample<2>(out, outFrameCount, provider);
- break;
- }
-}
-
-
-template<int CHANNELS>
-void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount,
- AudioBufferProvider* provider)
-{
- int16_t* impulse = mImpulse;
- uint32_t vRL = mVolumeRL;
- size_t inputIndex = mInputIndex;
- uint32_t phaseFraction = mPhaseFraction;
- uint32_t phaseIncrement = mPhaseIncrement;
- size_t outputIndex = 0;
- size_t outputSampleCount = outFrameCount * 2;
- size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
-
- AudioBufferProvider::Buffer& buffer(mBuffer);
- while (outputIndex < outputSampleCount) {
- // buffer is empty, fetch a new one
- while (buffer.frameCount == 0) {
- buffer.frameCount = inFrameCount;
- provider->getNextBuffer(&buffer);
- if (buffer.raw == NULL) {
- goto resample_exit;
- }
- const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
- if (phaseIndex == 1) {
- // read one frame
- read<CHANNELS>(impulse, phaseFraction, buffer.i16, inputIndex);
- } else if (phaseIndex == 2) {
- // read 2 frames
- read<CHANNELS>(impulse, phaseFraction, buffer.i16, inputIndex);
- inputIndex++;
- if (inputIndex >= mBuffer.frameCount) {
- inputIndex -= mBuffer.frameCount;
- provider->releaseBuffer(&buffer);
- } else {
- read<CHANNELS>(impulse, phaseFraction, buffer.i16, inputIndex);
- }
- }
- }
- int16_t *in = buffer.i16;
- const size_t frameCount = buffer.frameCount;
-
- // Always read-in the first samples from the input buffer
- int16_t* head = impulse + halfNumCoefs*CHANNELS;
- head[0] = in[inputIndex*CHANNELS + 0];
- if (CHANNELS == 2)
- head[1] = in[inputIndex*CHANNELS + 1];
-
- // handle boundary case
- int32_t l, r;
- while (outputIndex < outputSampleCount) {
- filterCoefficient<CHANNELS>(l, r, phaseFraction, impulse);
- out[outputIndex++] += 2 * mulRL(1, l, vRL);
- out[outputIndex++] += 2 * mulRL(0, r, vRL);
-
- phaseFraction += phaseIncrement;
- const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
- if (phaseIndex == 1) {
- inputIndex++;
- if (inputIndex >= frameCount)
- break; // need a new buffer
- read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
- } else if(phaseIndex == 2) { // maximum value
- inputIndex++;
- if (inputIndex >= frameCount)
- break; // 0 frame available, 2 frames needed
- // read first frame
- read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
- inputIndex++;
- if (inputIndex >= frameCount)
- break; // 0 frame available, 1 frame needed
- // read second frame
- read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
- }
- }
-
- // if done with buffer, save samples
- if (inputIndex >= frameCount) {
- inputIndex -= frameCount;
- provider->releaseBuffer(&buffer);
- }
- }
-
-resample_exit:
- mImpulse = impulse;
- mInputIndex = inputIndex;
- mPhaseFraction = phaseFraction;
-}
-
-template<int CHANNELS>
-/***
-* read()
-*
-* This function reads only one frame from input buffer and writes it in
-* state buffer
-*
-**/
-void AudioResamplerSinc::read(
- int16_t*& impulse, uint32_t& phaseFraction,
- int16_t const* in, size_t inputIndex)
-{
- const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
- impulse += CHANNELS;
- phaseFraction -= 1LU<<kNumPhaseBits;
- if (impulse >= mRingFull) {
- const size_t stateSize = (halfNumCoefs*2)*CHANNELS;
- memcpy(mState, mState+stateSize, sizeof(int16_t)*stateSize);
- impulse -= stateSize;
- }
- int16_t* head = impulse + halfNumCoefs*CHANNELS;
- head[0] = in[inputIndex*CHANNELS + 0];
- if (CHANNELS == 2)
- head[1] = in[inputIndex*CHANNELS + 1];
-}
-
-template<int CHANNELS>
-void AudioResamplerSinc::filterCoefficient(
- int32_t& l, int32_t& r, uint32_t phase, int16_t const *samples)
-{
- // compute the index of the coefficient on the positive side and
- // negative side
- uint32_t indexP = (phase & cMask) >> cShift;
- uint16_t lerpP = (phase & pMask) >> pShift;
- uint32_t indexN = (-phase & cMask) >> cShift;
- uint16_t lerpN = (-phase & pMask) >> pShift;
- if ((indexP == 0) && (lerpP == 0)) {
- indexN = cMask >> cShift;
- lerpN = pMask >> pShift;
- }
-
- l = 0;
- r = 0;
- int32_t const* coefs = mFirCoefs;
- int16_t const *sP = samples;
- int16_t const *sN = samples+CHANNELS;
- for (unsigned int i=0 ; i<halfNumCoefs/4 ; i++) {
- interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
- interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
- sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
- interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
- interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
- sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
- interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
- interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
- sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
- interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
- interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
- sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
- }
-}
-
-template<int CHANNELS>
-void AudioResamplerSinc::interpolate(
- int32_t& l, int32_t& r,
- int32_t const* coefs, int16_t lerp, int16_t const* samples)
-{
- int32_t c0 = coefs[0];
- int32_t c1 = coefs[1];
- int32_t sinc = mulAdd(lerp, (c1-c0)<<1, c0);
- if (CHANNELS == 2) {
- uint32_t rl = *reinterpret_cast<uint32_t const*>(samples);
- l = mulAddRL(1, rl, sinc, l);
- r = mulAddRL(0, rl, sinc, r);
- } else {
- r = l = mulAdd(samples[0], sinc, l);
- }
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-
diff --git a/libs/audioflinger/AudioResamplerSinc.h b/libs/audioflinger/AudioResamplerSinc.h
deleted file mode 100644
index e6cb90b..0000000
--- a/libs/audioflinger/AudioResamplerSinc.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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_AUDIO_RESAMPLER_SINC_H
-#define ANDROID_AUDIO_RESAMPLER_SINC_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <cutils/log.h>
-
-#include "AudioResampler.h"
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class AudioResamplerSinc : public AudioResampler {
-public:
- AudioResamplerSinc(int bitDepth, int inChannelCount, int32_t sampleRate);
-
- ~AudioResamplerSinc();
-
- virtual void resample(int32_t* out, size_t outFrameCount,
- AudioBufferProvider* provider);
-private:
- void init();
-
- template<int CHANNELS>
- void resample(int32_t* out, size_t outFrameCount,
- AudioBufferProvider* provider);
-
- template<int CHANNELS>
- inline void filterCoefficient(
- int32_t& l, int32_t& r, uint32_t phase, int16_t const *samples);
-
- template<int CHANNELS>
- inline void interpolate(
- int32_t& l, int32_t& r,
- int32_t const* coefs, int16_t lerp, int16_t const* samples);
-
- template<int CHANNELS>
- inline void read(int16_t*& impulse, uint32_t& phaseFraction,
- int16_t const* in, size_t inputIndex);
-
- int16_t *mState;
- int16_t *mImpulse;
- int16_t *mRingFull;
-
- int32_t const * mFirCoefs;
- static const int32_t mFirCoefsDown[];
- static const int32_t mFirCoefsUp[];
-
- // ----------------------------------------------------------------------------
- static const int32_t RESAMPLE_FIR_NUM_COEF = 8;
- static const int32_t RESAMPLE_FIR_LERP_INT_BITS = 4;
-
- // we have 16 coefs samples per zero-crossing
- static const int coefsBits = RESAMPLE_FIR_LERP_INT_BITS; // 4
- static const int cShift = kNumPhaseBits - coefsBits; // 26
- static const uint32_t cMask = ((1<<coefsBits)-1) << cShift; // 0xf<<26 = 3c00 0000
-
- // and we use 15 bits to interpolate between these samples
- // this cannot change because the mul below rely on it.
- static const int pLerpBits = 15;
- static const int pShift = kNumPhaseBits - coefsBits - pLerpBits; // 11
- static const uint32_t pMask = ((1<<pLerpBits)-1) << pShift; // 0x7fff << 11
-
- // number of zero-crossing on each side
- static const unsigned int halfNumCoefs = RESAMPLE_FIR_NUM_COEF;
-};
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-
-#endif /*ANDROID_AUDIO_RESAMPLER_SINC_H*/
diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk
deleted file mode 100644
index 496e271..0000000
--- a/libs/surfaceflinger/Android.mk
+++ /dev/null
@@ -1,49 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- clz.cpp.arm \
- DisplayHardware/DisplayHardware.cpp \
- DisplayHardware/DisplayHardwareBase.cpp \
- GPUHardware/GPUHardware.cpp \
- BootAnimation.cpp \
- BlurFilter.cpp.arm \
- CPUGauge.cpp \
- Layer.cpp \
- LayerBase.cpp \
- LayerBuffer.cpp \
- LayerBlur.cpp \
- LayerBitmap.cpp \
- LayerDim.cpp \
- LayerOrientationAnim.cpp \
- OrientationAnimation.cpp \
- SurfaceFlinger.cpp \
- Tokenizer.cpp \
- Transform.cpp \
- VRamHeap.cpp
-
-
-# need "-lrt" on Linux simulator to pick up clock_gettime
-ifeq ($(TARGET_SIMULATOR),true)
- ifeq ($(HOST_OS),linux)
- LOCAL_LDLIBS += -lrt
- endif
-endif
-
-LOCAL_SHARED_LIBRARIES := \
- libhardware \
- libutils \
- libcutils \
- libui \
- libcorecg \
- libsgl \
- libpixelflinger \
- libEGL \
- libGLESv1_CM
-
-LOCAL_C_INCLUDES := \
- $(call include-path-for, corecg graphics)
-
-LOCAL_MODULE:= libsurfaceflinger
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/surfaceflinger/Barrier.h b/libs/surfaceflinger/Barrier.h
deleted file mode 100644
index e2bcf6a..0000000
--- a/libs/surfaceflinger/Barrier.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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_BARRIER_H
-#define ANDROID_BARRIER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/threads.h>
-
-namespace android {
-
-class Barrier
-{
-public:
- inline Barrier() : state(CLOSED) { }
- inline ~Barrier() { }
- void open() {
- // gcc memory barrier, this makes sure all memory writes
- // have been issued by gcc. On an SMP system we'd need a real
- // h/w barrier.
- asm volatile ("":::"memory");
- Mutex::Autolock _l(lock);
- state = OPENED;
- cv.broadcast();
- }
- void close() {
- Mutex::Autolock _l(lock);
- state = CLOSED;
- }
- void wait() const {
- Mutex::Autolock _l(lock);
- while (state == CLOSED) {
- cv.wait(lock);
- }
- }
-private:
- enum { OPENED, CLOSED };
- mutable Mutex lock;
- mutable Condition cv;
- volatile int state;
-};
-
-}; // namespace android
-
-#endif // ANDROID_BARRIER_H
diff --git a/libs/surfaceflinger/BlurFilter.cpp b/libs/surfaceflinger/BlurFilter.cpp
deleted file mode 100644
index 5dc0ba0..0000000
--- a/libs/surfaceflinger/BlurFilter.cpp
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
-**
-** Copyright 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.
-*/
-
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <utils/Errors.h>
-
-#include <pixelflinger/pixelflinger.h>
-
-#include "clz.h"
-
-#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
-#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
-
-namespace android {
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-inline uint32_t BLUR_RGBA_TO_HOST(uint32_t v) {
- return v;
-}
-inline uint32_t BLUR_HOST_TO_RGBA(uint32_t v) {
- return v;
-}
-#else
-inline uint32_t BLUR_RGBA_TO_HOST(uint32_t v) {
- return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00);
-}
-inline uint32_t BLUR_HOST_TO_RGBA(uint32_t v) {
- return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00);
-}
-#endif
-
-const int BLUR_DITHER_BITS = 6; // dither weights stored on 6 bits
-const int BLUR_DITHER_ORDER_SHIFT= 3;
-const int BLUR_DITHER_ORDER = (1<<BLUR_DITHER_ORDER_SHIFT);
-const int BLUR_DITHER_SIZE = BLUR_DITHER_ORDER * BLUR_DITHER_ORDER;
-const int BLUR_DITHER_MASK = BLUR_DITHER_ORDER-1;
-
-static const uint8_t gDitherMatrix[BLUR_DITHER_SIZE] = {
- 0, 32, 8, 40, 2, 34, 10, 42,
- 48, 16, 56, 24, 50, 18, 58, 26,
- 12, 44, 4, 36, 14, 46, 6, 38,
- 60, 28, 52, 20, 62, 30, 54, 22,
- 3, 35, 11, 43, 1, 33, 9, 41,
- 51, 19, 59, 27, 49, 17, 57, 25,
- 15, 47, 7, 39, 13, 45, 5, 37,
- 63, 31, 55, 23, 61, 29, 53, 21
-};
-
-
-template <int FACTOR = 0>
-struct BlurColor565
-{
- typedef uint16_t type;
- int r, g, b;
- inline BlurColor565() { }
- inline BlurColor565(uint16_t v) {
- r = v >> 11;
- g = (v >> 5) & 0x3E;
- b = v & 0x1F;
- }
- inline void clear() { r=g=b=0; }
- inline uint16_t to(int shift, int last, int dither) const {
- int R = r;
- int G = g;
- int B = b;
- if (UNLIKELY(last)) {
- if (FACTOR>0) {
- int L = (R+G+B)>>1;
- R += (((L>>1) - R) * FACTOR) >> 8;
- G += (((L ) - G) * FACTOR) >> 8;
- B += (((L>>1) - B) * FACTOR) >> 8;
- }
- R += (dither << shift) >> BLUR_DITHER_BITS;
- G += (dither << shift) >> BLUR_DITHER_BITS;
- B += (dither << shift) >> BLUR_DITHER_BITS;
- }
- R >>= shift;
- G >>= shift;
- B >>= shift;
- return (R<<11) | (G<<5) | B;
- }
- inline BlurColor565& operator += (const BlurColor565& rhs) {
- r += rhs.r;
- g += rhs.g;
- b += rhs.b;
- return *this;
- }
- inline BlurColor565& operator -= (const BlurColor565& rhs) {
- r -= rhs.r;
- g -= rhs.g;
- b -= rhs.b;
- return *this;
- }
-};
-
-struct BlurGray565
-{
- typedef uint16_t type;
- int l;
- inline BlurGray565() { }
- inline BlurGray565(uint16_t v) {
- int r = v >> 11;
- int g = (v >> 5) & 0x3F;
- int b = v & 0x1F;
- l = (r + g + b + 1)>>1;
- }
- inline void clear() { l=0; }
- inline uint16_t to(int shift, int last, int dither) const {
- int L = l;
- if (UNLIKELY(last)) {
- L += (dither << shift) >> BLUR_DITHER_BITS;
- }
- L >>= shift;
- return ((L>>1)<<11) | (L<<5) | (L>>1);
- }
- inline BlurGray565& operator += (const BlurGray565& rhs) {
- l += rhs.l;
- return *this;
- }
- inline BlurGray565& operator -= (const BlurGray565& rhs) {
- l -= rhs.l;
- return *this;
- }
-};
-
-struct BlurGray8888
-{
- typedef uint32_t type;
- int l, a;
- inline BlurGray8888() { }
- inline BlurGray8888(uint32_t v) {
- v = BLUR_RGBA_TO_HOST(v);
- int r = v & 0xFF;
- int g = (v >> 8) & 0xFF;
- int b = (v >> 16) & 0xFF;
- a = v >> 24;
- l = r + g + g + b;
- }
- inline void clear() { l=a=0; }
- inline uint32_t to(int shift, int last, int dither) const {
- int L = l;
- int A = a;
- if (UNLIKELY(last)) {
- L += (dither << (shift+2)) >> BLUR_DITHER_BITS;
- A += (dither << shift) >> BLUR_DITHER_BITS;
- }
- L >>= (shift+2);
- A >>= shift;
- return BLUR_HOST_TO_RGBA((A<<24) | (L<<16) | (L<<8) | L);
- }
- inline BlurGray8888& operator += (const BlurGray8888& rhs) {
- l += rhs.l;
- a += rhs.a;
- return *this;
- }
- inline BlurGray8888& operator -= (const BlurGray8888& rhs) {
- l -= rhs.l;
- a -= rhs.a;
- return *this;
- }
-};
-
-
-template<typename PIXEL>
-static status_t blurFilter(
- GGLSurface const* dst,
- GGLSurface const* src,
- int kernelSizeUser,
- int repeat)
-{
- typedef typename PIXEL::type TYPE;
-
- const int shift = 31 - clz(kernelSizeUser);
- const int areaShift = shift*2;
- const int kernelSize = 1<<shift;
- const int kernelHalfSize = kernelSize/2;
- const int mask = kernelSize-1;
- const int w = src->width;
- const int h = src->height;
- const uint8_t* ditherMatrix = gDitherMatrix;
-
- // we need a temporary buffer to store one line of blurred columns
- // as well as kernelSize lines of source pixels organized as a ring buffer.
- void* const temporary_buffer = malloc(
- (w + kernelSize) * sizeof(PIXEL) +
- (src->stride * kernelSize) * sizeof(TYPE));
- if (!temporary_buffer)
- return NO_MEMORY;
-
- PIXEL* const sums = (PIXEL*)temporary_buffer;
- TYPE* const scratch = (TYPE*)(sums + w + kernelSize);
-
- // Apply the blur 'repeat' times, this is used to approximate
- // gaussian blurs. 3 times gives good results.
- for (int k=0 ; k<repeat ; k++) {
-
- // Clear the columns sums for this round
- memset(sums, 0, (w + kernelSize) * sizeof(PIXEL));
- TYPE* head;
- TYPE pixel;
- PIXEL current;
-
- // Since we're going to override the source data we need
- // to copy it in a temporary buffer. Only kernelSize lines are
- // required. But since we start in the center of the kernel,
- // we only copy half of the data, and fill the rest with zeros
- // (assuming black/transparent pixels).
- memcpy( scratch + src->stride*kernelHalfSize,
- src->data,
- src->stride*kernelHalfSize*sizeof(TYPE));
-
- // sum half of each column, because we assume the first half is
- // zeros (black/transparent).
- for (int y=0 ; y<kernelHalfSize ; y++) {
- head = (TYPE*)src->data + y*src->stride;
- for (int x=0 ; x<w ; x++)
- sums[x] += PIXEL( *head++ );
- }
-
- for (int y=0 ; y<h ; y++) {
- TYPE* fb = (TYPE*)dst->data + y*dst->stride;
-
- // compute the dither matrix line
- uint8_t const * ditherY = ditherMatrix
- + (y & BLUR_DITHER_MASK)*BLUR_DITHER_ORDER;
-
- // Horizontal blur pass on the columns sums
- int count, dither, x=0;
- PIXEL const * out= sums;
- PIXEL const * in = sums;
- current.clear();
-
- count = kernelHalfSize;
- do {
- current += *in;
- in++;
- } while (--count);
-
- count = kernelHalfSize;
- do {
- current += *in;
- dither = *(ditherY + ((x++)&BLUR_DITHER_MASK));
- *fb++ = current.to(areaShift, k==repeat-1, dither);
- in++;
- } while (--count);
-
- count = w-kernelSize;
- do {
- current += *in;
- current -= *out;
- dither = *(ditherY + ((x++)&BLUR_DITHER_MASK));
- *fb++ = current.to(areaShift, k==repeat-1, dither);
- in++, out++;
- } while (--count);
-
- count = kernelHalfSize;
- do {
- current -= *out;
- dither = *(ditherY + ((x++)&BLUR_DITHER_MASK));
- *fb++ = current.to(areaShift, k==repeat-1, dither);
- out++;
- } while (--count);
-
- // vertical blur pass, subtract the oldest line from each columns
- // and add a new line. Subtract or add zeros at the top
- // and bottom edges.
- TYPE* const tail = scratch + (y & mask) * src->stride;
- if (y >= kernelHalfSize) {
- for (int x=0 ; x<w ; x++)
- sums[x] -= PIXEL( tail[x] );
- }
- if (y < h-kernelSize) {
- memcpy( tail,
- (TYPE*)src->data + (y+kernelHalfSize)*src->stride,
- src->stride*sizeof(TYPE));
- for (int x=0 ; x<w ; x++)
- sums[x] += PIXEL( tail[x] );
- }
- }
-
- // The subsequent passes are always done in-place.
- src = dst;
- }
-
- free(temporary_buffer);
-
- return NO_ERROR;
-}
-
-template status_t blurFilter< BlurColor565<0x80> >(
- GGLSurface const* dst,
- GGLSurface const* src,
- int kernelSizeUser,
- int repeat);
-
-status_t blurFilter(
- GGLSurface const* image,
- int kernelSizeUser,
- int repeat)
-{
- return blurFilter< BlurColor565<0x80> >(image, image, kernelSizeUser, repeat);
-}
-
-} // namespace android
-
-//err = blur< BlurColor565<0x80> >(dst, src, kernelSizeUser, repeat);
-//err = blur<BlurGray565>(dst, src, kernelSizeUser, repeat);
-//err = blur<BlurGray8888>(dst, src, kernelSizeUser, repeat);
diff --git a/libs/surfaceflinger/BlurFilter.h b/libs/surfaceflinger/BlurFilter.h
deleted file mode 100644
index 294db43..0000000
--- a/libs/surfaceflinger/BlurFilter.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-**
-** Copyright 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_BLUR_FILTER_H
-#define ANDROID_BLUR_FILTER_H
-
-#include <stdint.h>
-#include <utils/Errors.h>
-
-#include <pixelflinger/pixelflinger.h>
-
-namespace android {
-
-status_t blurFilter(
- GGLSurface const* image,
- int kernelSizeUser,
- int repeat);
-
-} // namespace android
-
-#endif // ANDROID_BLUR_FILTER_H
diff --git a/libs/surfaceflinger/BootAnimation.cpp b/libs/surfaceflinger/BootAnimation.cpp
deleted file mode 100644
index 2b30336..0000000
--- a/libs/surfaceflinger/BootAnimation.cpp
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "BootAnimation"
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <math.h>
-#include <fcntl.h>
-#include <utils/misc.h>
-
-#include <utils/threads.h>
-#include <utils/Atomic.h>
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <utils/AssetManager.h>
-
-#include <ui/PixelFormat.h>
-#include <ui/Rect.h>
-#include <ui/Region.h>
-#include <ui/DisplayInfo.h>
-#include <ui/ISurfaceComposer.h>
-#include <ui/ISurfaceFlingerClient.h>
-#include <ui/EGLNativeWindowSurface.h>
-
-#include <core/SkBitmap.h>
-#include <images/SkImageDecoder.h>
-
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#include <EGL/eglext.h>
-
-#include "BootAnimation.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-BootAnimation::BootAnimation(const sp<ISurfaceComposer>& composer) :
- Thread(false) {
- mSession = SurfaceComposerClient::clientForConnection(
- composer->createConnection()->asBinder());
-}
-
-BootAnimation::~BootAnimation() {
-}
-
-void BootAnimation::onFirstRef() {
- run("BootAnimation", PRIORITY_DISPLAY);
-}
-
-const sp<SurfaceComposerClient>& BootAnimation::session() const {
- return mSession;
-}
-
-status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
- const char* name) {
- Asset* asset = assets.open(name, Asset::ACCESS_BUFFER);
- if (!asset)
- return NO_INIT;
- SkBitmap bitmap;
- SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(),
- &bitmap, SkBitmap::kNo_Config, SkImageDecoder::kDecodePixels_Mode);
- asset->close();
- delete asset;
-
- // ensure we can call getPixels(). No need to call unlock, since the
- // bitmap will go out of scope when we return from this method.
- bitmap.lockPixels();
-
- const int w = bitmap.width();
- const int h = bitmap.height();
- const void* p = bitmap.getPixels();
-
- GLint crop[4] = { 0, h, w, -h };
- texture->w = w;
- texture->h = h;
-
- glGenTextures(1, &texture->name);
- glBindTexture(GL_TEXTURE_2D, texture->name);
-
- switch (bitmap.getConfig()) {
- case SkBitmap::kA8_Config:
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_ALPHA,
- GL_UNSIGNED_BYTE, p);
- break;
- case SkBitmap::kARGB_4444_Config:
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA,
- GL_UNSIGNED_SHORT_4_4_4_4, p);
- break;
- case SkBitmap::kARGB_8888_Config:
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, p);
- break;
- case SkBitmap::kRGB_565_Config:
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB,
- GL_UNSIGNED_SHORT_5_6_5, p);
- break;
- default:
- break;
- }
-
- glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- return NO_ERROR;
-}
-
-status_t BootAnimation::readyToRun() {
- mAssets.addDefaultAssets();
-
- DisplayInfo dinfo;
- status_t status = session()->getDisplayInfo(0, &dinfo);
- if (status)
- return -1;
-
- // create the native surface
- sp<Surface> s = session()->createSurface(getpid(), 0, dinfo.w, dinfo.h,
- PIXEL_FORMAT_RGB_565);
- session()->openTransaction();
- s->setLayer(0x40000000);
- session()->closeTransaction();
-
- // initialize opengl and egl
- const EGLint attribs[] = { EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6,
- EGL_BLUE_SIZE, 5, EGL_DEPTH_SIZE, 0, EGL_NONE };
- EGLint w, h, dummy;
- EGLint numConfigs;
- EGLConfig config;
- EGLSurface surface;
- EGLContext context;
- EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- eglChooseConfig(display, attribs, &config, 1, &numConfigs);
-
- mNativeWindowSurface = new EGLNativeWindowSurface(s);
- surface = eglCreateWindowSurface(display, config,
- mNativeWindowSurface.get(), NULL);
-
- context = eglCreateContext(display, config, NULL, NULL);
- eglQuerySurface(display, surface, EGL_WIDTH, &w);
- eglQuerySurface(display, surface, EGL_HEIGHT, &h);
- eglMakeCurrent(display, surface, surface, context);
- mDisplay = display;
- mContext = context;
- mSurface = surface;
- mWidth = w;
- mHeight = h;
- mFlingerSurface = s;
-
- // initialize GL
- glShadeModel(GL_FLAT);
- glEnable(GL_DITHER);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_SCISSOR_TEST);
- glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
- return NO_ERROR;
-}
-
-void BootAnimation::requestExit() {
- mBarrier.open();
- Thread::requestExit();
-}
-
-bool BootAnimation::threadLoop() {
- bool r = android();
- eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- eglDestroyContext(mDisplay, mContext);
- eglDestroySurface(mDisplay, mSurface);
- mNativeWindowSurface.clear();
- return r;
-}
-
-bool BootAnimation::android() {
- initTexture(&mAndroid[0], mAssets, "images/android_320x480.png");
- initTexture(&mAndroid[1], mAssets, "images/boot_robot.png");
- initTexture(&mAndroid[2], mAssets, "images/boot_robot_glow.png");
-
- // erase screen
- glDisable(GL_SCISSOR_TEST);
- glBindTexture(GL_TEXTURE_2D, mAndroid[0].name);
-
- // clear screen
- glClear(GL_COLOR_BUFFER_BIT);
- eglSwapBuffers(mDisplay, mSurface);
-
- // wait ~1s
- usleep(800000);
-
- // fade in
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- const int steps = 8;
- for (int i = 1; i < steps; i++) {
- float fade = i / float(steps);
- glColor4f(1, 1, 1, fade * fade);
- glClear(GL_COLOR_BUFFER_BIT);
- glDrawTexiOES(0, 0, 0, mAndroid[0].w, mAndroid[0].h);
- eglSwapBuffers(mDisplay, mSurface);
- }
-
- // draw last frame
- glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glDisable(GL_BLEND);
- glDrawTexiOES(0, 0, 0, mAndroid[0].w, mAndroid[0].h);
- eglSwapBuffers(mDisplay, mSurface);
-
- // update rect for the robot
- const int x = mWidth - mAndroid[1].w - 33;
- const int y = (mHeight - mAndroid[1].h) / 2 - 1;
- const Rect updateRect(x, y, x + mAndroid[1].w, y + mAndroid[1].h);
-
- // draw and update only what we need
- mNativeWindowSurface->setSwapRectangle(updateRect.left,
- updateRect.top, updateRect.width(), updateRect.height());
-
- glEnable(GL_SCISSOR_TEST);
- glScissor(updateRect.left, mHeight - updateRect.bottom, updateRect.width(),
- updateRect.height());
-
- const nsecs_t startTime = systemTime();
- do {
- // glow speed and shape
- nsecs_t time = systemTime() - startTime;
- float t = ((4.0f / (360.0f * us2ns(16667))) * time);
- t = t - floorf(t);
- const float fade = 0.5f + 0.5f * sinf(t * 2 * M_PI);
-
- // fade the glow in and out
- glDisable(GL_BLEND);
- glBindTexture(GL_TEXTURE_2D, mAndroid[2].name);
- glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glColor4f(fade, fade, fade, fade);
- glDrawTexiOES(updateRect.left, mHeight - updateRect.bottom, 0,
- updateRect.width(), updateRect.height());
-
- // draw the robot
- glEnable(GL_BLEND);
- glBindTexture(GL_TEXTURE_2D, mAndroid[1].name);
- glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glDrawTexiOES(updateRect.left, mHeight - updateRect.bottom, 0,
- updateRect.width(), updateRect.height());
-
- // make sure sleep a lot to not take too much CPU away from
- // the boot process. With this "glow" animation there is no
- // visible difference.
- usleep(16667 * 4);
-
- eglSwapBuffers(mDisplay, mSurface);
- } while (!exitPending());
-
- glDeleteTextures(1, &mAndroid[0].name);
- glDeleteTextures(1, &mAndroid[1].name);
- glDeleteTextures(1, &mAndroid[2].name);
- return false;
-}
-
-bool BootAnimation::cylon() {
- // initialize the textures...
- initTexture(&mLeftTrail, mAssets, "images/cylon_left.png");
- initTexture(&mRightTrail, mAssets, "images/cylon_right.png");
- initTexture(&mBrightSpot, mAssets, "images/cylon_dot.png");
-
- int w = mWidth;
- int h = mHeight;
-
- const Point c(w / 2, h / 2);
- const GLint amplitude = 60;
- const int scx = c.x - amplitude - mBrightSpot.w / 2;
- const int scy = c.y - mBrightSpot.h / 2;
- const int scw = amplitude * 2 + mBrightSpot.w;
- const int sch = mBrightSpot.h;
- const Rect updateRect(scx, h - scy - sch, scx + scw, h - scy);
-
- // erase screen
- glDisable(GL_SCISSOR_TEST);
- glClear(GL_COLOR_BUFFER_BIT);
-
- eglSwapBuffers(mDisplay, mSurface);
-
- glClear(GL_COLOR_BUFFER_BIT);
-
- mNativeWindowSurface->setSwapRectangle(updateRect.left,
- updateRect.top, updateRect.width(), updateRect.height());
-
- glEnable(GL_SCISSOR_TEST);
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-
- // clear the screen to white
- Point p;
- float t = 0;
- float alpha = 1.0f;
- const nsecs_t startTime = systemTime();
- nsecs_t fadeTime = 0;
-
- do {
- // Set scissor in interesting area
- glScissor(scx, scy, scw, sch);
-
- // erase screen
- glClear(GL_COLOR_BUFFER_BIT);
-
- // compute wave
- const float a = (t * 2 * M_PI) - M_PI / 2;
- const float sn = sinf(a);
- const float cs = cosf(a);
- GLint x = GLint(amplitude * sn);
- float derivative = cs;
-
- glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
- if (derivative > 0) {
- // vanishing trail...
- p.x = (-amplitude + c.x) - mBrightSpot.w / 2;
- p.y = c.y - mLeftTrail.h / 2;
- float fade = 2.0f * (0.5f - t);
- //fade *= fade;
- glColor4f(fade, fade, fade, fade);
- glBindTexture(GL_TEXTURE_2D, mLeftTrail.name);
- glDrawTexiOES(p.x, p.y, 0, mLeftTrail.w, mLeftTrail.h);
-
- // trail...
- p.x = (x + c.x) - (mRightTrail.w + mBrightSpot.w / 2) + 16;
- p.y = c.y - mRightTrail.h / 2;
- fade = t < 0.25f ? t * 4.0f : 1.0f;
- fade *= fade;
- glColor4f(fade, fade, fade, fade);
- glBindTexture(GL_TEXTURE_2D, mRightTrail.name);
- glDrawTexiOES(p.x, p.y, 0, mRightTrail.w, mRightTrail.h);
- } else {
- // vanishing trail..
- p.x = (amplitude + c.x) - (mRightTrail.w + mBrightSpot.w / 2) + 16;
- p.y = c.y - mRightTrail.h / 2;
- float fade = 2.0f * (0.5f - (t - 0.5f));
- //fade *= fade;
- glColor4f(fade, fade, fade, fade);
- glBindTexture(GL_TEXTURE_2D, mRightTrail.name);
- glDrawTexiOES(p.x, p.y, 0, mRightTrail.w, mRightTrail.h);
-
- // trail...
- p.x = (x + c.x) - mBrightSpot.w / 2;
- p.y = c.y - mLeftTrail.h / 2;
- fade = t < 0.5f + 0.25f ? (t - 0.5f) * 4.0f : 1.0f;
- fade *= fade;
- glColor4f(fade, fade, fade, fade);
- glBindTexture(GL_TEXTURE_2D, mLeftTrail.name);
- glDrawTexiOES(p.x, p.y, 0, mLeftTrail.w, mLeftTrail.h);
- }
-
- const Point p(x + c.x - mBrightSpot.w / 2, c.y - mBrightSpot.h / 2);
- glBindTexture(GL_TEXTURE_2D, mBrightSpot.name);
- glColor4f(1, 0.5, 0.5, 1);
- glDrawTexiOES(p.x, p.y, 0, mBrightSpot.w, mBrightSpot.h);
-
- // update animation
- nsecs_t time = systemTime() - startTime;
- t = ((4.0f / (360.0f * us2ns(16667))) * time);
- t = t - floorf(t);
-
- eglSwapBuffers(mDisplay, mSurface);
-
- if (exitPending()) {
- if (fadeTime == 0) {
- fadeTime = time;
- }
- time -= fadeTime;
- alpha = 1.0f - ((float(time) * 6.0f) / float(s2ns(1)));
-
- session()->openTransaction();
- mFlingerSurface->setAlpha(alpha * alpha);
- session()->closeTransaction();
- }
- } while (alpha > 0);
-
- // cleanup
- glFinish();
- glDeleteTextures(1, &mLeftTrail.name);
- glDeleteTextures(1, &mRightTrail.name);
- glDeleteTextures(1, &mBrightSpot.name);
- return false;
-}
-
-// ---------------------------------------------------------------------------
-
-}
-; // namespace android
diff --git a/libs/surfaceflinger/BootAnimation.h b/libs/surfaceflinger/BootAnimation.h
deleted file mode 100644
index b20cea0..0000000
--- a/libs/surfaceflinger/BootAnimation.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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_BOOTANIMATION_H
-#define ANDROID_BOOTANIMATION_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/threads.h>
-#include <utils/AssetManager.h>
-
-#include <ui/ISurfaceComposer.h>
-#include <ui/SurfaceComposerClient.h>
-
-#include <EGL/egl.h>
-#include <GLES/gl.h>
-
-#include "Barrier.h"
-
-class SkBitmap;
-
-namespace android {
-
-class AssetManager;
-class EGLNativeWindowSurface;
-
-// ---------------------------------------------------------------------------
-
-class BootAnimation : public Thread
-{
-public:
- BootAnimation(const sp<ISurfaceComposer>& composer);
- virtual ~BootAnimation();
-
- const sp<SurfaceComposerClient>& session() const;
- virtual void requestExit();
-
-private:
- virtual bool threadLoop();
- virtual status_t readyToRun();
- virtual void onFirstRef();
-
- struct Texture {
- GLint w;
- GLint h;
- GLuint name;
- };
-
- status_t initTexture(Texture* texture, AssetManager& asset, const char* name);
- bool android();
- bool cylon();
-
- sp<SurfaceComposerClient> mSession;
- AssetManager mAssets;
- Texture mLeftTrail;
- Texture mRightTrail;
- Texture mBrightSpot;
- Texture mAndroid[3];
- int mWidth;
- int mHeight;
- EGLDisplay mDisplay;
- EGLDisplay mContext;
- EGLDisplay mSurface;
- sp<Surface> mFlingerSurface;
- sp<EGLNativeWindowSurface> mNativeWindowSurface;
- Barrier mBarrier;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_BOOTANIMATION_H
diff --git a/libs/surfaceflinger/CPUGauge.cpp b/libs/surfaceflinger/CPUGauge.cpp
deleted file mode 100644
index 74a9270..0000000
--- a/libs/surfaceflinger/CPUGauge.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "CPUGauge"
-
-#include <stdint.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <math.h>
-
-#include <utils/threads.h>
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-#include <ui/PixelFormat.h>
-#include <ui/Rect.h>
-#include <ui/Region.h>
-#include <ui/DisplayInfo.h>
-#include <ui/ISurfaceComposer.h>
-#include <ui/ISurfaceFlingerClient.h>
-
-#include <pixelflinger/pixelflinger.h>
-
-#include "CPUGauge.h"
-
-namespace android {
-
-CPUGauge::CPUGauge( const sp<ISurfaceComposer>& composer,
- nsecs_t interval,
- int clock,
- int refclock)
- : Thread(false),
- mInterval(interval), mClock(clock), mRefClock(refclock),
- mReferenceTime(0),
- mReferenceWorkingTime(0), mCpuUsage(0),
- mRefIdleTime(0), mIdleTime(0)
-{
- mFd = fopen("/proc/stat", "r");
- setvbuf(mFd, NULL, _IONBF, 0);
-
- mSession = SurfaceComposerClient::clientForConnection(
- composer->createConnection()->asBinder());
-}
-
-CPUGauge::~CPUGauge()
-{
- fclose(mFd);
-}
-
-const sp<SurfaceComposerClient>& CPUGauge::session() const
-{
- return mSession;
-}
-
-void CPUGauge::onFirstRef()
-{
- run("CPU Gauge");
-}
-
-status_t CPUGauge::readyToRun()
-{
- LOGI("Starting CPU gauge...");
- return NO_ERROR;
-}
-
-bool CPUGauge::threadLoop()
-{
- DisplayInfo dinfo;
- session()->getDisplayInfo(0, &dinfo);
- sp<Surface> s(session()->createSurface(getpid(), 0, dinfo.w, 4, PIXEL_FORMAT_OPAQUE));
- session()->openTransaction();
- s->setLayer(INT_MAX);
- session()->closeTransaction();
-
- static const GGLfixed colors[4][4] = {
- { 0x00000, 0x10000, 0x00000, 0x10000 },
- { 0x10000, 0x10000, 0x00000, 0x10000 },
- { 0x10000, 0x00000, 0x00000, 0x10000 },
- { 0x00000, 0x00000, 0x00000, 0x10000 },
- };
-
- GGLContext* gl;
- gglInit(&gl);
- gl->activeTexture(gl, 0);
- gl->disable(gl, GGL_TEXTURE_2D);
- gl->disable(gl, GGL_BLEND);
-
- const int w = dinfo.w;
-
- while(!exitPending())
- {
- mLock.lock();
- const float cpuUsage = this->cpuUsage();
- const float totalCpuUsage = 1.0f - idle();
- mLock.unlock();
-
- Surface::SurfaceInfo info;
- s->lock(&info);
- GGLSurface fb;
- fb.version = sizeof(GGLSurface);
- fb.width = info.w;
- fb.height = info.h;
- fb.stride = info.w;
- fb.format = info.format;
- fb.data = (GGLubyte*)info.bits;
-
- gl->colorBuffer(gl, &fb);
- gl->color4xv(gl, colors[3]);
- gl->recti(gl, 0, 0, w, 4);
- gl->color4xv(gl, colors[2]); // red
- gl->recti(gl, 0, 0, int(totalCpuUsage*w), 2);
- gl->color4xv(gl, colors[0]); // green
- gl->recti(gl, 0, 2, int(cpuUsage*w), 4);
-
- s->unlockAndPost();
-
- usleep(ns2us(mInterval));
- }
-
- gglUninit(gl);
- return false;
-}
-
-void CPUGauge::sample()
-{
- if (mLock.tryLock() == NO_ERROR) {
- const nsecs_t now = systemTime(mRefClock);
- const nsecs_t referenceTime = now-mReferenceTime;
- if (referenceTime >= mInterval) {
- const float reftime = 1.0f / referenceTime;
- const nsecs_t nowWorkingTime = systemTime(mClock);
-
- char buf[256];
- fgets(buf, 256, mFd);
- rewind(mFd);
- char *str = buf+5;
- char const * const usermode = strsep(&str, " "); (void)usermode;
- char const * const usernice = strsep(&str, " "); (void)usernice;
- char const * const systemmode = strsep(&str, " ");(void)systemmode;
- char const * const idle = strsep(&str, " ");
- const nsecs_t nowIdleTime = atoi(idle) * 10000000LL;
- mIdleTime = float(nowIdleTime - mRefIdleTime) * reftime;
- mRefIdleTime = nowIdleTime;
-
- const nsecs_t workingTime = nowWorkingTime - mReferenceWorkingTime;
- const float newCpuUsage = float(workingTime) * reftime;
- if (mCpuUsage != newCpuUsage) {
- mCpuUsage = newCpuUsage;
- mReferenceWorkingTime = nowWorkingTime;
- mReferenceTime = now;
- }
- }
- mLock.unlock();
- }
-}
-
-
-}; // namespace android
diff --git a/libs/surfaceflinger/CPUGauge.h b/libs/surfaceflinger/CPUGauge.h
deleted file mode 100644
index 5bb53c0..0000000
--- a/libs/surfaceflinger/CPUGauge.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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_CPUGAUGE_H
-#define ANDROID_CPUGAUGE_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Timers.h>
-
-#include <ui/SurfaceComposerClient.h>
-
-namespace android {
-
-class CPUGauge : public Thread
-{
-public:
- CPUGauge( const sp<ISurfaceComposer>& composer,
- nsecs_t interval=s2ns(1),
- int clock=SYSTEM_TIME_THREAD,
- int refclock=SYSTEM_TIME_MONOTONIC);
-
- ~CPUGauge();
-
- const sp<SurfaceComposerClient>& session() const;
-
- void sample();
-
- inline float cpuUsage() const { return mCpuUsage; }
- inline float idle() const { return mIdleTime; }
-
-private:
- virtual void onFirstRef();
- virtual status_t readyToRun();
- virtual bool threadLoop();
-
- Mutex mLock;
-
- sp<SurfaceComposerClient> mSession;
-
- const nsecs_t mInterval;
- const int mClock;
- const int mRefClock;
-
- nsecs_t mReferenceTime;
- nsecs_t mReferenceWorkingTime;
- float mCpuUsage;
- nsecs_t mRefIdleTime;
- float mIdleTime;
- FILE* mFd;
-};
-
-
-}; // namespace android
-
-#endif // ANDROID_CPUGAUGE_H
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
deleted file mode 100644
index f14d7e9..0000000
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-
-#include <cutils/properties.h>
-
-#include <utils/Log.h>
-
-#include <ui/EGLDisplaySurface.h>
-
-#include <GLES/gl.h>
-#include <EGL/eglext.h>
-
-
-#include "DisplayHardware/DisplayHardware.h"
-
-#include <hardware/copybit.h>
-#include <hardware/overlay.h>
-
-using namespace android;
-
-static __attribute__((noinline))
-const char *egl_strerror(EGLint err)
-{
- switch (err){
- case EGL_SUCCESS: return "EGL_SUCCESS";
- case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED";
- case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS";
- case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC";
- case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE";
- case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG";
- case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT";
- case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
- case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY";
- case EGL_BAD_MATCH: return "EGL_BAD_MATCH";
- case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
- case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
- case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER";
- case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE";
- case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST";
- default: return "UNKNOWN";
- }
-}
-
-static __attribute__((noinline))
-void checkGLErrors()
-{
- GLenum error = glGetError();
- if (error != GL_NO_ERROR)
- LOGE("GL error 0x%04x", int(error));
-}
-
-static __attribute__((noinline))
-void checkEGLErrors(const char* token)
-{
- EGLint error = eglGetError();
- // GLESonGL seems to be returning 0 when there is no errors?
- if (error && error != EGL_SUCCESS)
- LOGE("%s error 0x%04x (%s)",
- token, int(error), egl_strerror(error));
-}
-
-
-/*
- * Initialize the display to the specified values.
- *
- */
-
-DisplayHardware::DisplayHardware(
- const sp<SurfaceFlinger>& flinger,
- uint32_t dpy)
- : DisplayHardwareBase(flinger, dpy)
-{
- init(dpy);
-}
-
-DisplayHardware::~DisplayHardware()
-{
- fini();
-}
-
-float DisplayHardware::getDpiX() const { return mDpiX; }
-float DisplayHardware::getDpiY() const { return mDpiY; }
-float DisplayHardware::getDensity() const { return mDensity; }
-float DisplayHardware::getRefreshRate() const { return mRefreshRate; }
-int DisplayHardware::getWidth() const { return mWidth; }
-int DisplayHardware::getHeight() const { return mHeight; }
-PixelFormat DisplayHardware::getFormat() const { return mFormat; }
-
-void DisplayHardware::init(uint32_t dpy)
-{
- // initialize EGL
- const EGLint attribs[] = {
- EGL_RED_SIZE, 5,
- EGL_GREEN_SIZE, 6,
- EGL_BLUE_SIZE, 5,
- EGL_DEPTH_SIZE, 0,
- EGL_NONE
- };
- EGLint w, h, dummy;
- EGLint numConfigs, n;
- EGLConfig config;
- EGLSurface surface;
- EGLContext context;
- mFlags = 0;
-
- // TODO: all the extensions below should be queried through
- // eglGetProcAddress().
-
- EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- eglInitialize(display, NULL, NULL);
- eglGetConfigs(display, NULL, 0, &numConfigs);
- eglChooseConfig(display, attribs, &config, 1, &n);
-
- /*
- * Gather EGL extensions
- */
-
- const char* const egl_extensions = eglQueryString(
- display, EGL_EXTENSIONS);
-
- LOGI("EGL informations:");
- LOGI("# of configs : %d", numConfigs);
- LOGI("vendor : %s", eglQueryString(display, EGL_VENDOR));
- LOGI("version : %s", eglQueryString(display, EGL_VERSION));
- LOGI("extensions: %s", egl_extensions);
- LOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
-
- // TODO: get this from the devfb driver (probably should be HAL module)
- mFlags |= SWAP_RECTANGLE_EXTENSION;
-
- // TODO: get the real "update_on_demand" behavior (probably should be HAL module)
- mFlags |= UPDATE_ON_DEMAND;
-
- if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
- if (dummy == EGL_SLOW_CONFIG)
- mFlags |= SLOW_CONFIG;
- }
-
- /*
- * Create our main surface
- */
-
- mDisplaySurface = new EGLDisplaySurface();
-
- surface = eglCreateWindowSurface(display, config, mDisplaySurface.get(), NULL);
- //checkEGLErrors("eglCreateDisplaySurfaceANDROID");
-
- if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) {
- if (dummy == EGL_BUFFER_PRESERVED) {
- mFlags |= BUFFER_PRESERVED;
- }
- }
-
- GLint value = EGL_UNKNOWN;
- eglQuerySurface(display, surface, EGL_HORIZONTAL_RESOLUTION, &value);
- if (value == EGL_UNKNOWN) {
- mDpiX = 160.0f;
- } else {
- mDpiX = 25.4f * float(value)/EGL_DISPLAY_SCALING;
- }
- value = EGL_UNKNOWN;
- eglQuerySurface(display, surface, EGL_VERTICAL_RESOLUTION, &value);
- if (value == EGL_UNKNOWN) {
- mDpiY = 160.0f;
- } else {
- mDpiY = 25.4f * float(value)/EGL_DISPLAY_SCALING;
- }
- mRefreshRate = 60.f; // TODO: get the real refresh rate
-
-
- char property[PROPERTY_VALUE_MAX];
- if (property_get("ro.sf.lcd_density", property, NULL) <= 0) {
- LOGW("ro.sf.lcd_density not defined, using 160 dpi by default.");
- strcpy(property, "160");
- }
- mDensity = atoi(property) * (1.0f/160.0f);
-
-
- /*
- * Create our OpenGL ES context
- */
-
- context = eglCreateContext(display, config, NULL, NULL);
- //checkEGLErrors("eglCreateContext");
-
- eglQuerySurface(display, surface, EGL_WIDTH, &mWidth);
- eglQuerySurface(display, surface, EGL_HEIGHT, &mHeight);
-
-
- /*
- * Gather OpenGL ES extensions
- */
-
- eglMakeCurrent(display, surface, surface, context);
- const char* const gl_extensions = (const char*)glGetString(GL_EXTENSIONS);
- LOGI("OpenGL informations:");
- LOGI("vendor : %s", glGetString(GL_VENDOR));
- LOGI("renderer : %s", glGetString(GL_RENDERER));
- LOGI("version : %s", glGetString(GL_VERSION));
- LOGI("extensions: %s", gl_extensions);
-
- if (strstr(gl_extensions, "GL_ARB_texture_non_power_of_two")) {
- mFlags |= NPOT_EXTENSION;
- }
- if (strstr(gl_extensions, "GL_OES_draw_texture")) {
- mFlags |= DRAW_TEXTURE_EXTENSION;
- }
- if (strstr(gl_extensions, "GL_ANDROID_direct_texture")) {
- mFlags |= DIRECT_TEXTURE;
- }
-
- // Unbind the context from this thread
- eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
- mDisplay = display;
- mConfig = config;
- mSurface = surface;
- mContext = context;
- mFormat = GGL_PIXEL_FORMAT_RGB_565;
-
- hw_module_t const* module;
-
- mBlitEngine = NULL;
- if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
- copybit_open(module, &mBlitEngine);
- }
-
- mOverlayEngine = NULL;
- if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {
- overlay_control_open(module, &mOverlayEngine);
- }
-}
-
-/*
- * Clean up. Throw out our local state.
- *
- * (It's entirely possible we'll never get here, since this is meant
- * for real hardware, which doesn't restart.)
- */
-
-void DisplayHardware::fini()
-{
- eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- eglTerminate(mDisplay);
- copybit_close(mBlitEngine);
- overlay_control_close(mOverlayEngine);
-}
-
-void DisplayHardware::releaseScreen() const
-{
- DisplayHardwareBase::releaseScreen();
-}
-
-void DisplayHardware::acquireScreen() const
-{
- DisplayHardwareBase::acquireScreen();
-}
-
-void DisplayHardware::getDisplaySurface(copybit_image_t* img) const
-{
- img->w = mDisplaySurface->stride;
- img->h = mDisplaySurface->height;
- img->format = mDisplaySurface->format;
- img->offset = mDisplaySurface->offset;
- img->base = (void*)mDisplaySurface->base;
- img->fd = mDisplaySurface->fd;
-}
-
-void DisplayHardware::getDisplaySurface(GGLSurface* fb) const
-{
- fb->version= sizeof(GGLSurface);
- fb->width = mDisplaySurface->width;
- fb->height = mDisplaySurface->height;
- fb->stride = mDisplaySurface->stride;
- fb->format = mDisplaySurface->format;
- fb->data = (GGLubyte*)mDisplaySurface->base + mDisplaySurface->offset;
-}
-
-uint32_t DisplayHardware::getPageFlipCount() const {
- return mDisplaySurface->getPageFlipCount();
-}
-
-/*
- * "Flip" the front and back buffers.
- */
-
-void DisplayHardware::flip(const Region& dirty) const
-{
- checkGLErrors();
-
- EGLDisplay dpy = mDisplay;
- EGLSurface surface = mSurface;
-
- Region newDirty(dirty);
- newDirty.andSelf(Rect(mWidth, mHeight));
-
- if (mFlags & BUFFER_PRESERVED) {
- const Region copyback(mDirty.subtract(newDirty));
- mDirty = newDirty;
- mDisplaySurface->copyFrontToBack(copyback);
- }
-
- if (mFlags & SWAP_RECTANGLE_EXTENSION) {
- const Rect& b(newDirty.bounds());
- mDisplaySurface->setSwapRectangle(
- b.left, b.top, b.width(), b.height());
- }
-
- eglSwapBuffers(dpy, surface);
- checkEGLErrors("eglSwapBuffers");
-
- // for debugging
- //glClearColor(1,0,0,0);
- //glClear(GL_COLOR_BUFFER_BIT);
-}
-
-uint32_t DisplayHardware::getFlags() const
-{
- return mFlags;
-}
-
-void DisplayHardware::makeCurrent() const
-{
- eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
-}
-
-void DisplayHardware::copyFrontToImage(const copybit_image_t& front) const {
- mDisplaySurface->copyFrontToImage(front);
-}
-
-void DisplayHardware::copyBackToImage(const copybit_image_t& front) const {
- mDisplaySurface->copyBackToImage(front);
-}
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
deleted file mode 100644
index 550a4d1..0000000
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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_DISPLAY_HARDWARE_H
-#define ANDROID_DISPLAY_HARDWARE_H
-
-#include <stdlib.h>
-
-#include <ui/PixelFormat.h>
-#include <ui/Region.h>
-
-#include <EGL/egl.h>
-
-#include "DisplayHardware/DisplayHardwareBase.h"
-
-struct overlay_control_device_t;
-struct copybit_device_t;
-struct copybit_image_t;
-struct copybit_t;
-
-namespace android {
-
-class EGLDisplaySurface;
-
-class DisplayHardware : public DisplayHardwareBase
-{
-public:
- enum {
- DIRECT_TEXTURE = 0x00000002,
- SWAP_RECTANGLE_EXTENSION= 0x00000004,
- COPY_BITS_EXTENSION = 0x00000008,
- NPOT_EXTENSION = 0x00000100,
- DRAW_TEXTURE_EXTENSION = 0x00000200,
- BUFFER_PRESERVED = 0x00010000,
- UPDATE_ON_DEMAND = 0x00020000, // video driver feature
- SLOW_CONFIG = 0x00040000, // software
- };
-
- DisplayHardware(
- const sp<SurfaceFlinger>& flinger,
- uint32_t displayIndex);
-
- ~DisplayHardware();
-
- void releaseScreen() const;
- void acquireScreen() const;
-
- // Flip the front and back buffers if the back buffer is "dirty". Might
- // be instantaneous, might involve copying the frame buffer around.
- void flip(const Region& dirty) const;
-
- float getDpiX() const;
- float getDpiY() const;
- float getRefreshRate() const;
- float getDensity() const;
- int getWidth() const;
- int getHeight() const;
- PixelFormat getFormat() const;
- uint32_t getFlags() const;
- void makeCurrent() const;
-
- uint32_t getPageFlipCount() const;
- void getDisplaySurface(copybit_image_t* img) const;
- void getDisplaySurface(GGLSurface* fb) const;
- EGLDisplay getEGLDisplay() const { return mDisplay; }
- copybit_device_t* getBlitEngine() const { return mBlitEngine; }
- overlay_control_device_t* getOverlayEngine() const { return mOverlayEngine; }
-
- void copyFrontToImage(const copybit_image_t& front) const;
- void copyBackToImage(const copybit_image_t& front) const;
-
- Rect bounds() const {
- return Rect(mWidth, mHeight);
- }
-
-private:
- void init(uint32_t displayIndex) __attribute__((noinline));
- void fini() __attribute__((noinline));
-
- EGLDisplay mDisplay;
- EGLSurface mSurface;
- EGLContext mContext;
- EGLConfig mConfig;
- float mDpiX;
- float mDpiY;
- float mRefreshRate;
- float mDensity;
- int mWidth;
- int mHeight;
- PixelFormat mFormat;
- uint32_t mFlags;
- mutable Region mDirty;
- sp<EGLDisplaySurface> mDisplaySurface;
- copybit_device_t* mBlitEngine;
- overlay_control_device_t* mOverlayEngine;
-};
-
-}; // namespace android
-
-#endif // ANDROID_DISPLAY_HARDWARE_H
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
deleted file mode 100644
index f75e5c2..0000000
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "SurfaceFlinger"
-
-#include <assert.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <termios.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/resource.h>
-
-#include <linux/unistd.h>
-
-#include <utils/Log.h>
-
-#include "DisplayHardware/DisplayHardwareBase.h"
-#include "SurfaceFlinger.h"
-
-// ----------------------------------------------------------------------------
-// the sim build doesn't have gettid
-
-#ifndef HAVE_GETTID
-# define gettid getpid
-#endif
-
-// ----------------------------------------------------------------------------
-namespace android {
-
-static char const * kSleepFileName = "/sys/power/wait_for_fb_sleep";
-static char const * kWakeFileName = "/sys/power/wait_for_fb_wake";
-static char const * const kOldSleepFileName = "/sys/android_power/wait_for_fb_sleep";
-static char const * const kOldWakeFileName = "/sys/android_power/wait_for_fb_wake";
-
-// This dir exists if the framebuffer console is present, either built into
-// the kernel or loaded as a module.
-static char const * const kFbconSysDir = "/sys/class/graphics/fbcon";
-
-// ----------------------------------------------------------------------------
-
-DisplayHardwareBase::DisplayEventThreadBase::DisplayEventThreadBase(
- const sp<SurfaceFlinger>& flinger)
- : Thread(false), mFlinger(flinger) {
-}
-
-DisplayHardwareBase::DisplayEventThreadBase::~DisplayEventThreadBase() {
-}
-
-// ----------------------------------------------------------------------------
-
-DisplayHardwareBase::DisplayEventThread::DisplayEventThread(
- const sp<SurfaceFlinger>& flinger)
- : DisplayEventThreadBase(flinger)
-{
-}
-
-DisplayHardwareBase::DisplayEventThread::~DisplayEventThread()
-{
-}
-
-bool DisplayHardwareBase::DisplayEventThread::threadLoop()
-{
- int err = 0;
- char buf;
- int fd;
-
- fd = open(kSleepFileName, O_RDONLY, 0);
- do {
- err = read(fd, &buf, 1);
- } while (err < 0 && errno == EINTR);
- close(fd);
- LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_SLEEP failed (%s)", strerror(errno));
- if (err >= 0) {
- sp<SurfaceFlinger> flinger = mFlinger.promote();
- LOGD("About to give-up screen, flinger = %p", flinger.get());
- if (flinger != 0) {
- mBarrier.close();
- flinger->screenReleased(0);
- mBarrier.wait();
- }
- }
- fd = open(kWakeFileName, O_RDONLY, 0);
- do {
- err = read(fd, &buf, 1);
- } while (err < 0 && errno == EINTR);
- close(fd);
- LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_WAKE failed (%s)", strerror(errno));
- if (err >= 0) {
- sp<SurfaceFlinger> flinger = mFlinger.promote();
- LOGD("Screen about to return, flinger = %p", flinger.get());
- if (flinger != 0)
- flinger->screenAcquired(0);
- }
- return true;
-}
-
-status_t DisplayHardwareBase::DisplayEventThread::releaseScreen() const
-{
- mBarrier.open();
- return NO_ERROR;
-}
-
-status_t DisplayHardwareBase::DisplayEventThread::readyToRun()
-{
- if (access(kSleepFileName, R_OK) || access(kWakeFileName, R_OK)) {
- if (access(kOldSleepFileName, R_OK) || access(kOldWakeFileName, R_OK)) {
- LOGE("Couldn't open %s or %s", kSleepFileName, kWakeFileName);
- return NO_INIT;
- }
- kSleepFileName = kOldSleepFileName;
- kWakeFileName = kOldWakeFileName;
- }
- return NO_ERROR;
-}
-
-status_t DisplayHardwareBase::DisplayEventThread::initCheck() const
-{
- return (((access(kSleepFileName, R_OK) == 0 &&
- access(kWakeFileName, R_OK) == 0) ||
- (access(kOldSleepFileName, R_OK) == 0 &&
- access(kOldWakeFileName, R_OK) == 0)) &&
- access(kFbconSysDir, F_OK) != 0) ? NO_ERROR : NO_INIT;
-}
-
-// ----------------------------------------------------------------------------
-
-pid_t DisplayHardwareBase::ConsoleManagerThread::sSignalCatcherPid = 0;
-
-DisplayHardwareBase::ConsoleManagerThread::ConsoleManagerThread(
- const sp<SurfaceFlinger>& flinger)
- : DisplayEventThreadBase(flinger), consoleFd(-1)
-{
- sSignalCatcherPid = 0;
-
- // create a new console
- char const * const ttydev = "/dev/tty0";
- int fd = open(ttydev, O_RDWR | O_SYNC);
- if (fd<0) {
- LOGE("Can't open %s", ttydev);
- this->consoleFd = -errno;
- return;
- }
-
- // to make sure that we are in text mode
- int res = ioctl(fd, KDSETMODE, (void*) KD_TEXT);
- if (res<0) {
- LOGE("ioctl(%d, KDSETMODE, ...) failed, res %d (%s)",
- fd, res, strerror(errno));
- }
-
- // get the current console
- struct vt_stat vs;
- res = ioctl(fd, VT_GETSTATE, &vs);
- if (res<0) {
- LOGE("ioctl(%d, VT_GETSTATE, ...) failed, res %d (%s)",
- fd, res, strerror(errno));
- this->consoleFd = -errno;
- return;
- }
-
- // switch to console 7 (which is what X normaly uses)
- int vtnum = 7;
- do {
- res = ioctl(fd, VT_ACTIVATE, (void*)vtnum);
- } while(res < 0 && errno == EINTR);
- if (res<0) {
- LOGE("ioctl(%d, VT_ACTIVATE, ...) failed, %d (%s) for %d",
- fd, errno, strerror(errno), vtnum);
- this->consoleFd = -errno;
- return;
- }
-
- do {
- res = ioctl(fd, VT_WAITACTIVE, (void*)vtnum);
- } while(res < 0 && errno == EINTR);
- if (res<0) {
- LOGE("ioctl(%d, VT_WAITACTIVE, ...) failed, %d %d %s for %d",
- fd, res, errno, strerror(errno), vtnum);
- this->consoleFd = -errno;
- return;
- }
-
- // open the new console
- close(fd);
- fd = open(ttydev, O_RDWR | O_SYNC);
- if (fd<0) {
- LOGE("Can't open new console %s", ttydev);
- this->consoleFd = -errno;
- return;
- }
-
- /* disable console line buffer, echo, ... */
- struct termios ttyarg;
- ioctl(fd, TCGETS , &ttyarg);
- ttyarg.c_iflag = 0;
- ttyarg.c_lflag = 0;
- ioctl(fd, TCSETS , &ttyarg);
-
- // set up signals so we're notified when the console changes
- // we can't use SIGUSR1 because it's used by the java-vm
- vm.mode = VT_PROCESS;
- vm.waitv = 0;
- vm.relsig = SIGUSR2;
- vm.acqsig = SIGUNUSED;
- vm.frsig = 0;
-
- struct sigaction act;
- sigemptyset(&act.sa_mask);
- act.sa_handler = sigHandler;
- act.sa_flags = 0;
- sigaction(vm.relsig, &act, NULL);
-
- sigemptyset(&act.sa_mask);
- act.sa_handler = sigHandler;
- act.sa_flags = 0;
- sigaction(vm.acqsig, &act, NULL);
-
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask, vm.relsig);
- sigaddset(&mask, vm.acqsig);
- sigprocmask(SIG_BLOCK, &mask, NULL);
-
- // switch to graphic mode
- res = ioctl(fd, KDSETMODE, (void*)KD_GRAPHICS);
- LOGW_IF(res<0,
- "ioctl(%d, KDSETMODE, KD_GRAPHICS) failed, res %d", fd, res);
-
- this->prev_vt_num = vs.v_active;
- this->vt_num = vtnum;
- this->consoleFd = fd;
-}
-
-DisplayHardwareBase::ConsoleManagerThread::~ConsoleManagerThread()
-{
- if (this->consoleFd >= 0) {
- int fd = this->consoleFd;
- int prev_vt_num = this->prev_vt_num;
- int res;
- ioctl(fd, KDSETMODE, (void*)KD_TEXT);
- do {
- res = ioctl(fd, VT_ACTIVATE, (void*)prev_vt_num);
- } while(res < 0 && errno == EINTR);
- do {
- res = ioctl(fd, VT_WAITACTIVE, (void*)prev_vt_num);
- } while(res < 0 && errno == EINTR);
- close(fd);
- char const * const ttydev = "/dev/tty0";
- fd = open(ttydev, O_RDWR | O_SYNC);
- ioctl(fd, VT_DISALLOCATE, 0);
- close(fd);
- }
-}
-
-status_t DisplayHardwareBase::ConsoleManagerThread::readyToRun()
-{
- if (this->consoleFd >= 0) {
- sSignalCatcherPid = gettid();
-
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask, vm.relsig);
- sigaddset(&mask, vm.acqsig);
- sigprocmask(SIG_BLOCK, &mask, NULL);
-
- int res = ioctl(this->consoleFd, VT_SETMODE, &vm);
- if (res<0) {
- LOGE("ioctl(%d, VT_SETMODE, ...) failed, %d (%s)",
- this->consoleFd, errno, strerror(errno));
- }
- return NO_ERROR;
- }
- return this->consoleFd;
-}
-
-void DisplayHardwareBase::ConsoleManagerThread::requestExit()
-{
- Thread::requestExit();
- if (sSignalCatcherPid != 0) {
- // wake the thread up
- kill(sSignalCatcherPid, SIGINT);
- // wait for it...
- }
-}
-
-void DisplayHardwareBase::ConsoleManagerThread::sigHandler(int sig)
-{
- // resend the signal to our signal catcher thread
- LOGW("received signal %d in thread %d, resending to %d",
- sig, gettid(), sSignalCatcherPid);
-
- // we absolutely need the delays below because without them
- // our main thread never gets a chance to handle the signal.
- usleep(10000);
- kill(sSignalCatcherPid, sig);
- usleep(10000);
-}
-
-status_t DisplayHardwareBase::ConsoleManagerThread::releaseScreen() const
-{
- int fd = this->consoleFd;
- int err = ioctl(fd, VT_RELDISP, (void*)1);
- LOGE_IF(err<0, "ioctl(%d, VT_RELDISP, 1) failed %d (%s)",
- fd, errno, strerror(errno));
- return (err<0) ? (-errno) : status_t(NO_ERROR);
-}
-
-bool DisplayHardwareBase::ConsoleManagerThread::threadLoop()
-{
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask, vm.relsig);
- sigaddset(&mask, vm.acqsig);
-
- int sig = 0;
- sigwait(&mask, &sig);
-
- if (sig == vm.relsig) {
- sp<SurfaceFlinger> flinger = mFlinger.promote();
- //LOGD("About to give-up screen, flinger = %p", flinger.get());
- if (flinger != 0)
- flinger->screenReleased(0);
- } else if (sig == vm.acqsig) {
- sp<SurfaceFlinger> flinger = mFlinger.promote();
- //LOGD("Screen about to return, flinger = %p", flinger.get());
- if (flinger != 0)
- flinger->screenAcquired(0);
- }
-
- return true;
-}
-
-status_t DisplayHardwareBase::ConsoleManagerThread::initCheck() const
-{
- return consoleFd >= 0 ? NO_ERROR : NO_INIT;
-}
-
-// ----------------------------------------------------------------------------
-
-DisplayHardwareBase::DisplayHardwareBase(const sp<SurfaceFlinger>& flinger,
- uint32_t displayIndex)
- : mCanDraw(true)
-{
- mDisplayEventThread = new DisplayEventThread(flinger);
- if (mDisplayEventThread->initCheck() != NO_ERROR) {
- // fall-back on the console
- mDisplayEventThread = new ConsoleManagerThread(flinger);
- }
-}
-
-DisplayHardwareBase::~DisplayHardwareBase()
-{
- // request exit
- mDisplayEventThread->requestExitAndWait();
-}
-
-
-bool DisplayHardwareBase::canDraw() const
-{
- return mCanDraw;
-}
-
-void DisplayHardwareBase::releaseScreen() const
-{
- status_t err = mDisplayEventThread->releaseScreen();
- if (err >= 0) {
- //LOGD("screen given-up");
- mCanDraw = false;
- }
-}
-
-void DisplayHardwareBase::acquireScreen() const
-{
- status_t err = mDisplayEventThread->acquireScreen();
- if (err >= 0) {
- //LOGD("screen returned");
- mCanDraw = true;
- }
-}
-
-}; // namespace android
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
deleted file mode 100644
index 8369bb8..0000000
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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_DISPLAY_HARDWARE_BASE_H
-#define ANDROID_DISPLAY_HARDWARE_BASE_H
-
-#include <stdint.h>
-#include <utils/RefBase.h>
-#include <utils/threads.h>
-#include <linux/kd.h>
-#include <linux/vt.h>
-#include "Barrier.h"
-
-namespace android {
-
-class SurfaceFlinger;
-
-class DisplayHardwareBase
-{
-public:
- DisplayHardwareBase(
- const sp<SurfaceFlinger>& flinger,
- uint32_t displayIndex);
-
- ~DisplayHardwareBase();
-
- // console managment
- void releaseScreen() const;
- void acquireScreen() const;
- bool canDraw() const;
-
-private:
- class DisplayEventThreadBase : public Thread {
- protected:
- wp<SurfaceFlinger> mFlinger;
- public:
- DisplayEventThreadBase(const sp<SurfaceFlinger>& flinger);
- virtual ~DisplayEventThreadBase();
- virtual void onFirstRef() {
- run("DisplayEventThread", PRIORITY_URGENT_DISPLAY);
- }
- virtual status_t acquireScreen() const { return NO_ERROR; };
- virtual status_t releaseScreen() const { return NO_ERROR; };
- virtual status_t initCheck() const = 0;
- };
-
- class DisplayEventThread : public DisplayEventThreadBase
- {
- mutable Barrier mBarrier;
- public:
- DisplayEventThread(const sp<SurfaceFlinger>& flinger);
- virtual ~DisplayEventThread();
- virtual bool threadLoop();
- virtual status_t readyToRun();
- virtual status_t releaseScreen() const;
- virtual status_t initCheck() const;
- };
-
- class ConsoleManagerThread : public DisplayEventThreadBase
- {
- int consoleFd;
- int vt_num;
- int prev_vt_num;
- vt_mode vm;
- static void sigHandler(int sig);
- static pid_t sSignalCatcherPid;
- public:
- ConsoleManagerThread(const sp<SurfaceFlinger>& flinger);
- virtual ~ConsoleManagerThread();
- virtual bool threadLoop();
- virtual status_t readyToRun();
- virtual void requestExit();
- virtual status_t releaseScreen() const;
- virtual status_t initCheck() const;
- };
-
- sp<DisplayEventThreadBase> mDisplayEventThread;
- mutable int mCanDraw;
-};
-
-}; // namespace android
-
-#endif // ANDROID_DISPLAY_HARDWARE_BASE_H
diff --git a/libs/surfaceflinger/GPUHardware/GPUHardware.cpp b/libs/surfaceflinger/GPUHardware/GPUHardware.cpp
deleted file mode 100644
index eb75f99..0000000
--- a/libs/surfaceflinger/GPUHardware/GPUHardware.cpp
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <math.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-
-#include <cutils/log.h>
-#include <cutils/properties.h>
-
-#include <utils/IBinder.h>
-#include <utils/MemoryDealer.h>
-#include <utils/MemoryBase.h>
-#include <utils/MemoryHeapPmem.h>
-#include <utils/MemoryHeapBase.h>
-#include <utils/IPCThreadState.h>
-#include <utils/StopWatch.h>
-
-#include <ui/ISurfaceComposer.h>
-
-#include "VRamHeap.h"
-#include "GPUHardware.h"
-
-#if HAVE_ANDROID_OS
-#include <linux/android_pmem.h>
-#endif
-
-#include "GPUHardware/GPUHardware.h"
-
-
-/*
- * Manage the GPU. This implementation is very specific to the G1.
- * There are no abstraction here.
- *
- * All this code will soon go-away and be replaced by a new architecture
- * for managing graphics accelerators.
- *
- * In the meantime, it is conceptually possible to instantiate a
- * GPUHardwareInterface for another GPU (see GPUFactory at the bottom
- * of this file); practically... doubtful.
- *
- */
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class GPUClientHeap;
-class GPUAreaHeap;
-
-class GPUHardware : public GPUHardwareInterface, public IBinder::DeathRecipient
-{
-public:
- static const int GPU_RESERVED_SIZE;
- static const int GPUR_SIZE;
-
- GPUHardware();
- virtual ~GPUHardware();
-
- virtual void revoke(int pid);
- virtual sp<MemoryDealer> request(int pid);
- virtual status_t request(int pid,
- const sp<IGPUCallback>& callback,
- ISurfaceComposer::gpu_info_t* gpu);
-
- virtual status_t friendlyRevoke();
- virtual void unconditionalRevoke();
-
- virtual pid_t getOwner() const { return mOwner; }
-
- // used for debugging only...
- virtual sp<SimpleBestFitAllocator> getAllocator() const;
-
-private:
-
-
- enum {
- NO_OWNER = -1,
- };
-
- struct GPUArea {
- sp<GPUAreaHeap> heap;
- sp<MemoryHeapPmem> clientHeap;
- sp<IMemory> map();
- };
-
- struct Client {
- pid_t pid;
- GPUArea smi;
- GPUArea ebi;
- GPUArea reg;
- void createClientHeaps();
- void revokeAllHeaps();
- };
-
- Client& getClientLocked(pid_t pid);
- status_t requestLocked(int pid);
- void releaseLocked();
- void takeBackGPULocked();
- void registerCallbackLocked(const sp<IGPUCallback>& callback,
- Client& client);
-
- virtual void binderDied(const wp<IBinder>& who);
-
- mutable Mutex mLock;
- sp<GPUAreaHeap> mSMIHeap;
- sp<GPUAreaHeap> mEBIHeap;
- sp<GPUAreaHeap> mREGHeap;
-
- KeyedVector<pid_t, Client> mClients;
- DefaultKeyedVector< wp<IBinder>, pid_t > mRegisteredClients;
-
- pid_t mOwner;
-
- sp<MemoryDealer> mCurrentAllocator;
- sp<IGPUCallback> mCallback;
-
- sp<SimpleBestFitAllocator> mAllocator;
-
- Condition mCondition;
-};
-
-// size reserved for GPU surfaces
-// 1200 KB fits exactly:
-// - two 320*480 16-bits double-buffered surfaces
-// - one 320*480 32-bits double-buffered surface
-// - one 320*240 16-bits double-buffered, 4x anti-aliased surface
-const int GPUHardware::GPU_RESERVED_SIZE = 1200 * 1024;
-const int GPUHardware::GPUR_SIZE = 1 * 1024 * 1024;
-
-// ---------------------------------------------------------------------------
-
-/*
- * GPUHandle is a special IMemory given to the client. It represents their
- * handle to the GPU. Once they give it up, they loose GPU access, or if
- * they explicitly revoke their access through the binder code 1000.
- * In both cases, this triggers a callback to revoke()
- * first, and then actually powers down the chip.
- *
- * In the case of a misbehaving app, GPUHardware can ask for an immediate
- * release of the GPU to the target process which should answer by calling
- * code 1000 on GPUHandle. If it doesn't in a timely manner, the GPU will
- * be revoked from under their feet.
- *
- * We should never hold a strong reference on GPUHandle. In practice this
- * shouldn't be a big issue though because clients should use code 1000 and
- * not rely on the dtor being called.
- *
- */
-
-class GPUClientHeap : public MemoryHeapPmem
-{
-public:
- GPUClientHeap(const wp<GPUHardware>& gpu,
- const sp<MemoryHeapBase>& heap)
- : MemoryHeapPmem(heap), mGPU(gpu) { }
-protected:
- wp<GPUHardware> mGPU;
-};
-
-class GPUAreaHeap : public MemoryHeapBase
-{
-public:
- GPUAreaHeap(const wp<GPUHardware>& gpu,
- const char* const vram, size_t size=0, size_t reserved=0)
- : MemoryHeapBase(vram, size), mGPU(gpu) {
- if (base() != MAP_FAILED) {
- if (reserved == 0)
- reserved = virtualSize();
- mAllocator = new SimpleBestFitAllocator(reserved);
- }
- }
- virtual sp<MemoryHeapPmem> createClientHeap() {
- sp<MemoryHeapBase> parentHeap(this);
- return new GPUClientHeap(mGPU, parentHeap);
- }
- virtual const sp<SimpleBestFitAllocator>& getAllocator() const {
- return mAllocator;
- }
-private:
- sp<SimpleBestFitAllocator> mAllocator;
-protected:
- wp<GPUHardware> mGPU;
-};
-
-class GPURegisterHeap : public GPUAreaHeap
-{
-public:
- GPURegisterHeap(const sp<GPUHardware>& gpu)
- : GPUAreaHeap(gpu, "/dev/hw3d", GPUHardware::GPUR_SIZE) { }
- virtual sp<MemoryHeapPmem> createClientHeap() {
- sp<MemoryHeapBase> parentHeap(this);
- return new MemoryHeapRegs(mGPU, parentHeap);
- }
-private:
- class MemoryHeapRegs : public GPUClientHeap {
- public:
- MemoryHeapRegs(const wp<GPUHardware>& gpu,
- const sp<MemoryHeapBase>& heap)
- : GPUClientHeap(gpu, heap) { }
- sp<MemoryHeapPmem::MemoryPmem> createMemory(size_t offset, size_t size);
- virtual void revoke();
- private:
- class GPUHandle : public MemoryHeapPmem::MemoryPmem {
- public:
- GPUHandle(const sp<GPUHardware>& gpu,
- const sp<MemoryHeapPmem>& heap)
- : MemoryHeapPmem::MemoryPmem(heap),
- mGPU(gpu), mOwner(gpu->getOwner()) { }
- virtual ~GPUHandle();
- virtual sp<IMemoryHeap> getMemory(
- ssize_t* offset, size_t* size) const;
- virtual void revoke() { };
- virtual status_t onTransact(
- uint32_t code, const Parcel& data,
- Parcel* reply, uint32_t flags);
- private:
- void revokeNotification();
- wp<GPUHardware> mGPU;
- pid_t mOwner;
- };
- };
-};
-
-GPURegisterHeap::MemoryHeapRegs::GPUHandle::~GPUHandle() {
- //LOGD("GPUHandle %p released, revoking GPU", this);
- revokeNotification();
-}
-void GPURegisterHeap::MemoryHeapRegs::GPUHandle::revokeNotification() {
- sp<GPUHardware> hw(mGPU.promote());
- if (hw != 0) {
- hw->revoke(mOwner);
- }
-}
-sp<IMemoryHeap> GPURegisterHeap::MemoryHeapRegs::GPUHandle::getMemory(
- ssize_t* offset, size_t* size) const
-{
- sp<MemoryHeapPmem> heap = getHeap();
- if (offset) *offset = 0;
- if (size) *size = heap !=0 ? heap->virtualSize() : 0;
- return heap;
-}
-status_t GPURegisterHeap::MemoryHeapRegs::GPUHandle::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- status_t err = BnMemory::onTransact(code, data, reply, flags);
- if (err == UNKNOWN_TRANSACTION && code == 1000) {
- int callingPid = IPCThreadState::self()->getCallingPid();
- //LOGD("pid %d voluntarily revoking gpu", callingPid);
- if (callingPid == mOwner) {
- revokeNotification();
- // we've revoked the GPU, don't do it again later when we
- // are destroyed.
- mGPU.clear();
- } else {
- LOGW("%d revoking someone else's gpu? (owner=%d)",
- callingPid, mOwner);
- }
- err = NO_ERROR;
- }
- return err;
-}
-
-// ---------------------------------------------------------------------------
-
-
-sp<MemoryHeapPmem::MemoryPmem> GPURegisterHeap::MemoryHeapRegs::createMemory(
- size_t offset, size_t size)
-{
- sp<GPUHandle> memory;
- sp<GPUHardware> gpu = mGPU.promote();
- if (heapID()>0 && gpu!=0) {
-#if HAVE_ANDROID_OS
- /* this is where the GPU is powered on and the registers are mapped
- * in the client */
- //LOGD("ioctl(HW3D_GRANT_GPU)");
- int err = ioctl(heapID(), HW3D_GRANT_GPU, base());
- if (err) {
- // it can happen if the master heap has been closed already
- // in which case the GPU already is revoked (app crash for
- // instance).
- LOGW("HW3D_GRANT_GPU failed (%s), mFD=%d, base=%p",
- strerror(errno), heapID(), base());
- }
- memory = new GPUHandle(gpu, this);
-#endif
- }
- return memory;
-}
-
-void GPURegisterHeap::MemoryHeapRegs::revoke()
-{
- MemoryHeapPmem::revoke();
-#if HAVE_ANDROID_OS
- if (heapID() > 0) {
- //LOGD("ioctl(HW3D_REVOKE_GPU)");
- int err = ioctl(heapID(), HW3D_REVOKE_GPU, base());
- LOGE_IF(err, "HW3D_REVOKE_GPU failed (%s), mFD=%d, base=%p",
- strerror(errno), heapID(), base());
- }
-#endif
-}
-
-/*****************************************************************************/
-
-GPUHardware::GPUHardware()
- : mOwner(NO_OWNER)
-{
-}
-
-GPUHardware::~GPUHardware()
-{
-}
-
-status_t GPUHardware::requestLocked(int pid)
-{
- const int self_pid = getpid();
- if (pid == self_pid) {
- // can't use GPU from surfaceflinger's process
- return PERMISSION_DENIED;
- }
-
- if (mOwner != pid) {
- if (mREGHeap != 0) {
- if (mOwner != NO_OWNER) {
- // someone already has the gpu.
- takeBackGPULocked();
- releaseLocked();
- }
- } else {
- // first time, initialize the stuff.
- if (mSMIHeap == 0)
- mSMIHeap = new GPUAreaHeap(this, "/dev/pmem_gpu0");
- if (mEBIHeap == 0)
- mEBIHeap = new GPUAreaHeap(this,
- "/dev/pmem_gpu1", 0, GPU_RESERVED_SIZE);
- mREGHeap = new GPURegisterHeap(this);
- mAllocator = mEBIHeap->getAllocator();
- if (mAllocator == NULL) {
- // something went terribly wrong.
- mSMIHeap.clear();
- mEBIHeap.clear();
- mREGHeap.clear();
- return INVALID_OPERATION;
- }
- }
- Client& client = getClientLocked(pid);
- mCurrentAllocator = new MemoryDealer(client.ebi.clientHeap, mAllocator);
- mOwner = pid;
- }
- return NO_ERROR;
-}
-
-sp<MemoryDealer> GPUHardware::request(int pid)
-{
- sp<MemoryDealer> dealer;
- Mutex::Autolock _l(mLock);
- Client* client;
- LOGD("pid %d requesting gpu surface (current owner = %d)", pid, mOwner);
- if (requestLocked(pid) == NO_ERROR) {
- dealer = mCurrentAllocator;
- LOGD_IF(dealer!=0, "gpu surface granted to pid %d", mOwner);
- }
- return dealer;
-}
-
-status_t GPUHardware::request(int pid, const sp<IGPUCallback>& callback,
- ISurfaceComposer::gpu_info_t* gpu)
-{
- if (callback == 0)
- return BAD_VALUE;
-
- sp<IMemory> gpuHandle;
- LOGD("pid %d requesting gpu core (owner = %d)", pid, mOwner);
- Mutex::Autolock _l(mLock);
- status_t err = requestLocked(pid);
- if (err == NO_ERROR) {
- // it's guaranteed to be there, be construction
- Client& client = mClients.editValueFor(pid);
- registerCallbackLocked(callback, client);
- gpu->count = 2;
- gpu->regions[0].region = client.smi.map();
- gpu->regions[1].region = client.ebi.map();
- gpu->regs = client.reg.map();
- gpu->regions[0].reserved = 0;
- gpu->regions[1].reserved = GPU_RESERVED_SIZE;
- if (gpu->regs != 0) {
- //LOGD("gpu core granted to pid %d, handle base=%p",
- // mOwner, gpu->regs->pointer());
- }
- mCallback = callback;
- } else {
- LOGW("couldn't grant gpu core to pid %d", pid);
- }
- return err;
-}
-
-void GPUHardware::revoke(int pid)
-{
- Mutex::Autolock _l(mLock);
- if (mOwner > 0) {
- if (pid != mOwner) {
- LOGW("GPU owned by %d, revoke from %d", mOwner, pid);
- return;
- }
- //LOGD("revoke pid=%d, owner=%d", pid, mOwner);
- // mOwner could be <0 if the same process acquired the GPU
- // several times without releasing it first.
- mCondition.signal();
- releaseLocked();
- }
-}
-
-status_t GPUHardware::friendlyRevoke()
-{
- Mutex::Autolock _l(mLock);
- //LOGD("friendlyRevoke owner=%d", mOwner);
- takeBackGPULocked();
- releaseLocked();
- return NO_ERROR;
-}
-
-void GPUHardware::takeBackGPULocked()
-{
- sp<IGPUCallback> callback = mCallback;
- mCallback.clear();
- if (callback != 0) {
- callback->gpuLost(); // one-way
- mCondition.waitRelative(mLock, ms2ns(250));
- }
-}
-
-void GPUHardware::releaseLocked()
-{
- //LOGD("revoking gpu from pid %d", mOwner);
- if (mOwner != NO_OWNER) {
- // this may fail because the client might have died, and have
- // been removed from the list.
- ssize_t index = mClients.indexOfKey(mOwner);
- if (index >= 0) {
- Client& client(mClients.editValueAt(index));
- client.revokeAllHeaps();
- }
- mOwner = NO_OWNER;
- mCurrentAllocator.clear();
- mCallback.clear();
- }
-}
-
-GPUHardware::Client& GPUHardware::getClientLocked(pid_t pid)
-{
- ssize_t index = mClients.indexOfKey(pid);
- if (index < 0) {
- Client client;
- client.pid = pid;
- client.smi.heap = mSMIHeap;
- client.ebi.heap = mEBIHeap;
- client.reg.heap = mREGHeap;
- index = mClients.add(pid, client);
- }
- Client& client(mClients.editValueAt(index));
- client.createClientHeaps();
- return client;
-}
-
-// ----------------------------------------------------------------------------
-// for debugging / testing ...
-
-sp<SimpleBestFitAllocator> GPUHardware::getAllocator() const {
- Mutex::Autolock _l(mLock);
- return mAllocator;
-}
-
-void GPUHardware::unconditionalRevoke()
-{
- Mutex::Autolock _l(mLock);
- releaseLocked();
-}
-
-// ---------------------------------------------------------------------------
-
-sp<IMemory> GPUHardware::GPUArea::map() {
- sp<IMemory> memory;
- if (clientHeap != 0 && heap != 0) {
- memory = clientHeap->mapMemory(0, heap->virtualSize());
- }
- return memory;
-}
-
-void GPUHardware::Client::createClientHeaps()
-{
- if (smi.clientHeap == 0)
- smi.clientHeap = smi.heap->createClientHeap();
- if (ebi.clientHeap == 0)
- ebi.clientHeap = ebi.heap->createClientHeap();
- if (reg.clientHeap == 0)
- reg.clientHeap = reg.heap->createClientHeap();
-}
-
-void GPUHardware::Client::revokeAllHeaps()
-{
- if (smi.clientHeap != 0)
- smi.clientHeap->revoke();
- if (ebi.clientHeap != 0)
- ebi.clientHeap->revoke();
- if (reg.clientHeap != 0)
- reg.clientHeap->revoke();
-}
-
-void GPUHardware::registerCallbackLocked(const sp<IGPUCallback>& callback,
- Client& client)
-{
- sp<IBinder> binder = callback->asBinder();
- if (mRegisteredClients.add(binder, client.pid) >= 0) {
- binder->linkToDeath(this);
- }
-}
-
-void GPUHardware::binderDied(const wp<IBinder>& who)
-{
- Mutex::Autolock _l(mLock);
- pid_t pid = mRegisteredClients.valueFor(who);
- if (pid != 0) {
- ssize_t index = mClients.indexOfKey(pid);
- if (index >= 0) {
- //LOGD("*** removing client at %d", index);
- Client& client(mClients.editValueAt(index));
- client.revokeAllHeaps(); // not really needed in theory
- mClients.removeItemsAt(index);
- if (mClients.size() == 0) {
- //LOGD("*** was last client closing everything");
- mCallback.clear();
- mAllocator.clear();
- mCurrentAllocator.clear();
- mSMIHeap.clear();
- mREGHeap.clear();
-
- // NOTE: we cannot clear the EBI heap because surfaceflinger
- // itself may be using it, since this is where surfaces
- // are allocated. if we're in the middle of compositing
- // a surface (even if its process just died), we cannot
- // rip the heap under our feet.
-
- mOwner = NO_OWNER;
- }
- }
- }
-}
-
-// ---------------------------------------------------------------------------
-
-sp<GPUHardwareInterface> GPUFactory::getGPU()
-{
- return new GPUHardware();
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-
diff --git a/libs/surfaceflinger/GPUHardware/GPUHardware.h b/libs/surfaceflinger/GPUHardware/GPUHardware.h
deleted file mode 100644
index 3354528..0000000
--- a/libs/surfaceflinger/GPUHardware/GPUHardware.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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_GPU_HARDWARE_H
-#define ANDROID_GPU_HARDWARE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/RefBase.h>
-#include <utils/threads.h>
-#include <utils/KeyedVector.h>
-
-#include <ui/ISurfaceComposer.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class IGPUCallback;
-
-class GPUHardwareInterface : public virtual RefBase
-{
-public:
- virtual void revoke(int pid) = 0;
- virtual sp<MemoryDealer> request(int pid) = 0;
- virtual status_t request(int pid, const sp<IGPUCallback>& callback,
- ISurfaceComposer::gpu_info_t* gpu) = 0;
-
- virtual status_t friendlyRevoke() = 0;
-
- // used for debugging only...
- virtual sp<SimpleBestFitAllocator> getAllocator() const = 0;
- virtual pid_t getOwner() const = 0;
- virtual void unconditionalRevoke() = 0;
-};
-
-// ---------------------------------------------------------------------------
-
-class GPUFactory
-{
-public:
- // the gpu factory
- static sp<GPUHardwareInterface> getGPU();
-};
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-
-#endif // ANDROID_GPU_HARDWARE_H
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
deleted file mode 100644
index f65d669..0000000
--- a/libs/surfaceflinger/Layer.cpp
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <cutils/properties.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <utils/StopWatch.h>
-
-#include <ui/PixelFormat.h>
-#include <ui/EGLDisplaySurface.h>
-
-#include "clz.h"
-#include "Layer.h"
-#include "LayerBitmap.h"
-#include "SurfaceFlinger.h"
-#include "VRamHeap.h"
-#include "DisplayHardware/DisplayHardware.h"
-
-
-#define DEBUG_RESIZE 0
-
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-const uint32_t Layer::typeInfo = LayerBaseClient::typeInfo | 4;
-const char* const Layer::typeID = "Layer";
-
-// ---------------------------------------------------------------------------
-
-Layer::Layer(SurfaceFlinger* flinger, DisplayID display, Client* c, int32_t i)
- : LayerBaseClient(flinger, display, c, i),
- mSecure(false),
- mFrontBufferIndex(1),
- mNeedsBlending(true),
- mResizeTransactionDone(false),
- mTextureName(-1U), mTextureWidth(0), mTextureHeight(0)
-{
- // no OpenGL operation is possible here, since we might not be
- // in the OpenGL thread.
-}
-
-Layer::~Layer()
-{
- client->free(clientIndex());
- // this should always be called from the OpenGL thread
- if (mTextureName != -1U) {
- //glDeleteTextures(1, &mTextureName);
- deletedTextures.add(mTextureName);
- }
-}
-
-void Layer::initStates(uint32_t w, uint32_t h, uint32_t flags)
-{
- LayerBase::initStates(w,h,flags);
-
- if (flags & ISurfaceComposer::eDestroyBackbuffer)
- lcblk->flags |= eNoCopyBack;
-}
-
-sp<LayerBaseClient::Surface> Layer::getSurface() const
-{
- return mSurface;
-}
-
-status_t Layer::setBuffers( Client* client,
- uint32_t w, uint32_t h,
- PixelFormat format, uint32_t flags)
-{
- PixelFormatInfo info;
- status_t err = getPixelFormatInfo(format, &info);
- if (err) return err;
-
- // TODO: if eHardware is explicitly requested, we should fail
- // on systems where we can't allocate memory that can be used with
- // DMA engines for instance.
-
- // FIXME: we always ask for hardware for now (this should come from copybit)
- flags |= ISurfaceComposer::eHardware;
-
- const uint32_t memory_flags = flags &
- (ISurfaceComposer::eGPU |
- ISurfaceComposer::eHardware |
- ISurfaceComposer::eSecure);
-
- // pixel-alignment. the final alignment may be bigger because
- // we always force a 4-byte aligned bpr.
- uint32_t alignment = 1;
-
- if (flags & ISurfaceComposer::eGPU) {
- // FIXME: this value should come from the h/w
- alignment = 8;
- // FIXME: this is msm7201A specific, as its GPU only supports
- // BGRA_8888.
- if (format == PIXEL_FORMAT_RGBA_8888) {
- format = PIXEL_FORMAT_BGRA_8888;
- }
- }
-
- mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
- mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
- sp<MemoryDealer> allocators[2];
- for (int i=0 ; i<2 ; i++) {
- allocators[i] = client->createAllocator(memory_flags);
- if (allocators[i] == 0)
- return NO_MEMORY;
- mBuffers[i].init(allocators[i]);
- int err = mBuffers[i].setBits(w, h, alignment, format, LayerBitmap::SECURE_BITS);
- if (err != NO_ERROR)
- return err;
- mBuffers[i].clear(); // clear the bits for security
- mBuffers[i].getInfo(lcblk->surface + i);
- }
-
- mSurface = new Surface(clientIndex(),
- allocators[0]->getMemoryHeap(),
- allocators[1]->getMemoryHeap(),
- mIdentity);
-
- return NO_ERROR;
-}
-
-void Layer::reloadTexture(const Region& dirty)
-{
- if (UNLIKELY(mTextureName == -1U)) {
- // create the texture name the first time
- // can't do that in the ctor, because it runs in another thread.
- mTextureName = createTexture();
- }
- const GGLSurface& t(frontBuffer().surface());
- loadTexture(dirty, mTextureName, t, mTextureWidth, mTextureHeight);
-}
-
-
-void Layer::onDraw(const Region& clip) const
-{
- if (UNLIKELY(mTextureName == -1LU)) {
- //LOGW("Layer %p doesn't have a texture", this);
- // the texture has not been created yet, this Layer has
- // in fact never been drawn into. this happens frequently with
- // SurfaceView.
- clearWithOpenGL(clip);
- return;
- }
-
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- const LayerBitmap& front(frontBuffer());
- const GGLSurface& t(front.surface());
-
- status_t err = NO_ERROR;
- const int can_use_copybit = canUseCopybit();
- if (can_use_copybit) {
- // StopWatch watch("copybit");
- const State& s(drawingState());
-
- copybit_image_t dst;
- hw.getDisplaySurface(&dst);
- const copybit_rect_t& drect
- = reinterpret_cast<const copybit_rect_t&>(mTransformedBounds);
-
- copybit_image_t src;
- front.getBitmapSurface(&src);
- copybit_rect_t srect = { 0, 0, t.width, t.height };
-
- copybit_device_t* copybit = mFlinger->getBlitEngine();
- copybit->set_parameter(copybit, COPYBIT_TRANSFORM, getOrientation());
- copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
- copybit->set_parameter(copybit, COPYBIT_DITHER,
- s.flags & ISurfaceComposer::eLayerDither ?
- COPYBIT_ENABLE : COPYBIT_DISABLE);
-
- region_iterator it(clip);
- err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
- }
-
- if (!can_use_copybit || err) {
- drawWithOpenGL(clip, mTextureName, t);
- }
-}
-
-status_t Layer::reallocateBuffer(int32_t index, uint32_t w, uint32_t h)
-{
- LOGD_IF(DEBUG_RESIZE,
- "reallocateBuffer (layer=%p), "
- "requested (%dx%d), "
- "index=%d, (%dx%d), (%dx%d)",
- this,
- int(w), int(h),
- int(index),
- int(mBuffers[0].width()), int(mBuffers[0].height()),
- int(mBuffers[1].width()), int(mBuffers[1].height()));
-
- status_t err = mBuffers[index].resize(w, h);
- if (err == NO_ERROR) {
- mBuffers[index].getInfo(lcblk->surface + index);
- } else {
- LOGE("resizing buffer %d to (%u,%u) failed [%08x] %s",
- index, w, h, err, strerror(err));
- // XXX: what to do, what to do? We could try to free some
- // hidden surfaces, instead of killing this one?
- }
- return err;
-}
-
-uint32_t Layer::doTransaction(uint32_t flags)
-{
- const Layer::State& front(drawingState());
- const Layer::State& temp(currentState());
-
- // the test front.{w|h} != temp.{w|h} is not enough because it is possible
- // that the size changed back to its previous value before the buffer
- // was resized (in the eLocked case below), in which case, we still
- // need to execute the code below so the clients have a chance to be
- // release. resze() deals with the fact that the size can be the same.
-
- /*
- * Various states we could be in...
-
- resize = state & eResizeRequested;
- if (backbufferChanged) {
- if (resize == 0) {
- // ERROR, the resized buffer doesn't have its resize flag set
- } else if (resize == mask) {
- // ERROR one of the buffer has already been resized
- } else if (resize == mask ^ eResizeRequested) {
- // ERROR, the resized buffer doesn't have its resize flag set
- } else if (resize == eResizeRequested) {
- // OK, Normal case, proceed with resize
- }
- } else {
- if (resize == 0) {
- // OK, nothing special, do nothing
- } else if (resize == mask) {
- // restarted transaction, do nothing
- } else if (resize == mask ^ eResizeRequested) {
- // restarted transaction, do nothing
- } else if (resize == eResizeRequested) {
- // OK, size reset to previous value, proceed with resize
- }
- }
- */
-
- // Index of the back buffer
- const bool backbufferChanged = (front.w != temp.w) || (front.h != temp.h);
- const uint32_t state = lcblk->swapState;
- const int32_t clientBackBufferIndex = layer_cblk_t::backBuffer(state);
- const uint32_t mask = clientBackBufferIndex ? eResizeBuffer1 : eResizeBuffer0;
- uint32_t resizeFlags = state & eResizeRequested;
-
- if (UNLIKELY(backbufferChanged && (resizeFlags != eResizeRequested))) {
- LOGE( "backbuffer size changed, but both resize flags are not set! "
- "(layer=%p), state=%08x, requested (%dx%d), drawing (%d,%d), "
- "index=%d, (%dx%d), (%dx%d)",
- this, state,
- int(temp.w), int(temp.h),
- int(drawingState().w), int(drawingState().h),
- int(clientBackBufferIndex),
- int(mBuffers[0].width()), int(mBuffers[0].height()),
- int(mBuffers[1].width()), int(mBuffers[1].height()));
- // if we get there we're pretty screwed. the only reasonable
- // thing to do is to pretend we should do the resize since
- // backbufferChanged is set (this also will give a chance to
- // client to get unblocked)
- resizeFlags = eResizeRequested;
- }
-
- if (resizeFlags == eResizeRequested) {
- // NOTE: asserting that clientBackBufferIndex!=mFrontBufferIndex
- // here, would be wrong and misleading because by this point
- // mFrontBufferIndex has not been updated yet.
-
- LOGD_IF(DEBUG_RESIZE,
- "resize (layer=%p), state=%08x, "
- "requested (%dx%d), "
- "drawing (%d,%d), "
- "index=%d, (%dx%d), (%dx%d)",
- this, state,
- int(temp.w), int(temp.h),
- int(drawingState().w), int(drawingState().h),
- int(clientBackBufferIndex),
- int(mBuffers[0].width()), int(mBuffers[0].height()),
- int(mBuffers[1].width()), int(mBuffers[1].height()));
-
- if (state & eLocked) {
- // if the buffer is locked, we can't resize anything because
- // - the backbuffer is currently in use by the user
- // - the front buffer is being shown
- // We just act as if the transaction didn't happen and we
- // reschedule it later...
- flags |= eRestartTransaction;
- } else {
- // This buffer needs to be resized
- status_t err =
- resize(clientBackBufferIndex, temp.w, temp.h, "transaction");
- if (err == NO_ERROR) {
- const uint32_t mask = clientBackBufferIndex ? eResizeBuffer1 : eResizeBuffer0;
- android_atomic_and(~mask, &(lcblk->swapState));
- // since a buffer became available, we can let the client go...
- mFlinger->scheduleBroadcast(client);
- mResizeTransactionDone = true;
-
- // we're being resized and there is a freeze display request,
- // acquire a freeze lock, so that the screen stays put
- // until we've redrawn at the new size; this is to avoid
- // glitches upon orientation changes.
- if (mFlinger->hasFreezeRequest()) {
- // if the surface is hidden, don't try to acquire the
- // freeze lock, since hidden surfaces may never redraw
- if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
- mFreezeLock = mFlinger->getFreezeLock();
- }
- }
- }
- }
- }
-
- if (temp.sequence != front.sequence) {
- if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
- // this surface is now hidden, so it shouldn't hold a freeze lock
- // (it may never redraw, which is fine if it is hidden)
- mFreezeLock.clear();
- }
- }
-
- return LayerBase::doTransaction(flags);
-}
-
-status_t Layer::resize(
- int32_t clientBackBufferIndex,
- uint32_t width, uint32_t height,
- const char* what)
-{
- /*
- * handle resize (backbuffer and frontbuffer reallocation)
- */
-
- const LayerBitmap& clientBackBuffer(mBuffers[clientBackBufferIndex]);
-
- // if the new (transaction) size is != from the the backbuffer
- // then we need to reallocate the backbuffer
- bool backbufferChanged = (clientBackBuffer.width() != width) ||
- (clientBackBuffer.height() != height);
-
- LOGD_IF(!backbufferChanged,
- "(%s) eResizeRequested (layer=%p), but size not changed: "
- "requested (%dx%d), drawing (%d,%d), current (%d,%d),"
- "state=%08lx, index=%d, (%dx%d), (%dx%d)",
- what, this,
- int(width), int(height),
- int(drawingState().w), int(drawingState().h),
- int(currentState().w), int(currentState().h),
- long(lcblk->swapState),
- int(clientBackBufferIndex),
- int(mBuffers[0].width()), int(mBuffers[0].height()),
- int(mBuffers[1].width()), int(mBuffers[1].height()));
-
- // this can happen when changing the size back and forth quickly
- status_t err = NO_ERROR;
- if (backbufferChanged) {
- err = reallocateBuffer(clientBackBufferIndex, width, height);
- }
- if (UNLIKELY(err != NO_ERROR)) {
- // couldn't reallocate the surface
- android_atomic_write(eInvalidSurface, &lcblk->swapState);
- memset(lcblk->surface+clientBackBufferIndex, 0, sizeof(surface_info_t));
- }
- return err;
-}
-
-void Layer::setSizeChanged(uint32_t w, uint32_t h)
-{
- LOGD_IF(DEBUG_RESIZE,
- "setSizeChanged w=%d, h=%d (old: w=%d, h=%d)",
- w, h, mCurrentState.w, mCurrentState.h);
- android_atomic_or(eResizeRequested, &(lcblk->swapState));
-}
-
-// ----------------------------------------------------------------------------
-// pageflip handling...
-// ----------------------------------------------------------------------------
-
-void Layer::lockPageFlip(bool& recomputeVisibleRegions)
-{
- uint32_t state = android_atomic_or(eBusy, &(lcblk->swapState));
- // preemptively block the client, because he might set
- // eFlipRequested at any time and want to use this buffer
- // for the next frame. This will be unset below if it
- // turns out we didn't need it.
-
- uint32_t mask = eInvalidSurface | eFlipRequested | eResizeRequested;
- if (!(state & mask))
- return;
-
- if (UNLIKELY(state & eInvalidSurface)) {
- // if eInvalidSurface is set, this means the surface
- // became invalid during a transaction (NO_MEMORY for instance)
- mFlinger->scheduleBroadcast(client);
- return;
- }
-
- if (UNLIKELY(state & eFlipRequested)) {
- uint32_t oldState;
- mPostedDirtyRegion = post(&oldState, recomputeVisibleRegions);
- if (oldState & eNextFlipPending) {
- // Process another round (we know at least a buffer
- // is ready for that client).
- mFlinger->signalEvent();
- }
- }
-}
-
-Region Layer::post(uint32_t* previousSate, bool& recomputeVisibleRegions)
-{
- // atomically swap buffers and (re)set eFlipRequested
- int32_t oldValue, newValue;
- layer_cblk_t * const lcblk = this->lcblk;
- do {
- oldValue = lcblk->swapState;
- // get the current value
-
- LOG_ASSERT(oldValue&eFlipRequested,
- "eFlipRequested not set, yet we're flipping! (state=0x%08lx)",
- long(oldValue));
-
- newValue = (oldValue ^ eIndex);
- // swap buffers
-
- newValue &= ~(eFlipRequested | eNextFlipPending);
- // clear eFlipRequested and eNextFlipPending
-
- if (oldValue & eNextFlipPending)
- newValue |= eFlipRequested;
- // if eNextFlipPending is set (second buffer already has something
- // in it) we need to reset eFlipRequested because the client
- // might never do it
-
- } while(android_atomic_cmpxchg(oldValue, newValue, &(lcblk->swapState)));
- *previousSate = oldValue;
-
- const int32_t index = (newValue & eIndex) ^ 1;
- mFrontBufferIndex = index;
-
- // ... post the new front-buffer
- Region dirty(lcblk->region + index);
- dirty.andSelf(frontBuffer().bounds());
-
- //LOGI("Did post oldValue=%08lx, newValue=%08lx, mFrontBufferIndex=%u\n",
- // oldValue, newValue, mFrontBufferIndex);
- //dirty.dump("dirty");
-
- if (UNLIKELY(oldValue & eResizeRequested)) {
-
- LOGD_IF(DEBUG_RESIZE,
- "post (layer=%p), state=%08x, "
- "index=%d, (%dx%d), (%dx%d)",
- this, newValue,
- int(1-index),
- int(mBuffers[0].width()), int(mBuffers[0].height()),
- int(mBuffers[1].width()), int(mBuffers[1].height()));
-
- // here, we just posted the surface and we have resolved
- // the front/back buffer indices. The client is blocked, so
- // it cannot start using the new backbuffer.
-
- // If the backbuffer was resized in THIS round, we actually cannot
- // resize the frontbuffer because it has *just* been drawn (and we
- // would have nothing to draw). In this case we just skip the resize
- // it'll happen after the next page flip or during the next
- // transaction.
-
- const uint32_t mask = (1-index) ? eResizeBuffer1 : eResizeBuffer0;
- if (mResizeTransactionDone && (newValue & mask)) {
- // Resize the layer's second buffer only if the transaction
- // happened. It may not have happened yet if eResizeRequested
- // was set immediately after the "transactionRequested" test,
- // in which case the drawing state's size would be wrong.
- mFreezeLock.clear();
- const Layer::State& s(drawingState());
- if (resize(1-index, s.w, s.h, "post") == NO_ERROR) {
- do {
- oldValue = lcblk->swapState;
- if ((oldValue & eResizeRequested) == eResizeRequested) {
- // ugh, another resize was requested since we processed
- // the first buffer, don't free the client, and let
- // the next transaction handle everything.
- break;
- }
- newValue = oldValue & ~mask;
- } while(android_atomic_cmpxchg(oldValue, newValue, &(lcblk->swapState)));
- }
- mResizeTransactionDone = false;
- recomputeVisibleRegions = true;
- this->contentDirty = true;
- }
- }
-
- reloadTexture(dirty);
-
- return dirty;
-}
-
-Point Layer::getPhysicalSize() const
-{
- const LayerBitmap& front(frontBuffer());
- return Point(front.width(), front.height());
-}
-
-void Layer::unlockPageFlip(
- const Transform& planeTransform, Region& outDirtyRegion)
-{
- Region dirtyRegion(mPostedDirtyRegion);
- if (!dirtyRegion.isEmpty()) {
- mPostedDirtyRegion.clear();
- // The dirty region is given in the layer's coordinate space
- // transform the dirty region by the surface's transformation
- // and the global transformation.
- const Layer::State& s(drawingState());
- const Transform tr(planeTransform * s.transform);
- dirtyRegion = tr.transform(dirtyRegion);
-
- // At this point, the dirty region is in screen space.
- // Make sure it's constrained by the visible region (which
- // is in screen space as well).
- dirtyRegion.andSelf(visibleRegionScreen);
- outDirtyRegion.orSelf(dirtyRegion);
-
- // client could be blocked, so signal them so they get a
- // chance to reevaluate their condition.
- mFlinger->scheduleBroadcast(client);
- }
-}
-
-void Layer::finishPageFlip()
-{
- if (LIKELY(!(lcblk->swapState & eInvalidSurface))) {
- LOGE_IF(!(lcblk->swapState & eBusy),
- "layer %p wasn't locked!", this);
- android_atomic_and(~eBusy, &(lcblk->swapState));
- }
- mFlinger->scheduleBroadcast(client);
-}
-
-
-// ---------------------------------------------------------------------------
-
-
-}; // namespace android
diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h
deleted file mode 100644
index 2867f2b..0000000
--- a/libs/surfaceflinger/Layer.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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_LAYER_H
-#define ANDROID_LAYER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <ui/PixelFormat.h>
-
-#include <private/ui/SharedState.h>
-#include <private/ui/LayerState.h>
-
-#include <pixelflinger/pixelflinger.h>
-
-#include "LayerBitmap.h"
-#include "LayerBase.h"
-#include "Transform.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class Client;
-class LayerBitmap;
-class MemoryDealer;
-class FreezeLock;
-
-// ---------------------------------------------------------------------------
-
-class Layer : public LayerBaseClient
-{
-public:
- static const uint32_t typeInfo;
- static const char* const typeID;
- virtual char const* getTypeID() const { return typeID; }
- virtual uint32_t getTypeInfo() const { return typeInfo; }
-
- Layer(SurfaceFlinger* flinger, DisplayID display,
- Client* c, int32_t i);
-
- virtual ~Layer();
-
- inline PixelFormat pixelFormat() const {
- return frontBuffer().pixelFormat();
- }
-
- status_t setBuffers( Client* client,
- uint32_t w, uint32_t h,
- PixelFormat format, uint32_t flags=0);
-
- virtual void onDraw(const Region& clip) const;
- virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
- virtual void setSizeChanged(uint32_t w, uint32_t h);
- virtual uint32_t doTransaction(uint32_t transactionFlags);
- virtual Point getPhysicalSize() const;
- virtual void lockPageFlip(bool& recomputeVisibleRegions);
- virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
- virtual void finishPageFlip();
- virtual bool needsBlending() const { return mNeedsBlending; }
- virtual bool isSecure() const { return mSecure; }
- virtual GLuint getTextureName() const { return mTextureName; }
- virtual sp<Surface> getSurface() const;
-
- const LayerBitmap& getBuffer(int i) const { return mBuffers[i]; }
- LayerBitmap& getBuffer(int i) { return mBuffers[i]; }
-
- // only for debugging
- const sp<FreezeLock>& getFreezeLock() const { return mFreezeLock; }
-
-private:
- inline const LayerBitmap&
- frontBuffer() const { return getBuffer(mFrontBufferIndex); }
- inline LayerBitmap&
- frontBuffer() { return getBuffer(mFrontBufferIndex); }
- inline const LayerBitmap&
- backBuffer() const { return getBuffer(1-mFrontBufferIndex); }
- inline LayerBitmap&
- backBuffer() { return getBuffer(1-mFrontBufferIndex); }
-
- void reloadTexture(const Region& dirty);
-
- status_t resize(int32_t index, uint32_t w, uint32_t h, const char* what);
- Region post(uint32_t* oldState, bool& recomputeVisibleRegions);
- status_t reallocateBuffer(int32_t index, uint32_t w, uint32_t h);
-
- sp<Surface> mSurface;
-
- bool mSecure;
- LayerBitmap mBuffers[2];
- int32_t mFrontBufferIndex;
- bool mNeedsBlending;
- bool mResizeTransactionDone;
- Region mPostedDirtyRegion;
- sp<FreezeLock> mFreezeLock;
-
- GLuint mTextureName;
- GLuint mTextureWidth;
- GLuint mTextureHeight;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_H
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
deleted file mode 100644
index 0cf53f7..0000000
--- a/libs/surfaceflinger/LayerBase.cpp
+++ /dev/null
@@ -1,740 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-
-#include <hardware/hardware.h>
-
-#include "clz.h"
-#include "LayerBase.h"
-#include "LayerBlur.h"
-#include "SurfaceFlinger.h"
-#include "DisplayHardware/DisplayHardware.h"
-
-
-// We don't honor the premultiplied alpha flags, which means that
-// premultiplied surface may be composed using a non-premultiplied
-// equation. We do this because it may be a lot faster on some hardware
-// The correct value is HONOR_PREMULTIPLIED_ALPHA = 1
-#define HONOR_PREMULTIPLIED_ALPHA 0
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-const uint32_t LayerBase::typeInfo = 1;
-const char* const LayerBase::typeID = "LayerBase";
-
-const uint32_t LayerBaseClient::typeInfo = LayerBase::typeInfo | 2;
-const char* const LayerBaseClient::typeID = "LayerBaseClient";
-
-// ---------------------------------------------------------------------------
-
-Vector<GLuint> LayerBase::deletedTextures;
-
-int32_t LayerBase::sIdentity = 0;
-
-LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
- : dpy(display), contentDirty(false),
- mFlinger(flinger),
- mTransformed(false),
- mOrientation(0),
- mCanUseCopyBit(false),
- mTransactionFlags(0),
- mPremultipliedAlpha(true),
- mIdentity(uint32_t(android_atomic_inc(&sIdentity))),
- mInvalidate(0)
-{
- const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
- mFlags = hw.getFlags();
-}
-
-LayerBase::~LayerBase()
-{
-}
-
-const GraphicPlane& LayerBase::graphicPlane(int dpy) const
-{
- return mFlinger->graphicPlane(dpy);
-}
-
-GraphicPlane& LayerBase::graphicPlane(int dpy)
-{
- return mFlinger->graphicPlane(dpy);
-}
-
-void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags)
-{
- uint32_t layerFlags = 0;
- if (flags & ISurfaceComposer::eHidden)
- layerFlags = ISurfaceComposer::eLayerHidden;
-
- if (flags & ISurfaceComposer::eNonPremultiplied)
- mPremultipliedAlpha = false;
-
- mCurrentState.z = 0;
- mCurrentState.w = w;
- mCurrentState.h = h;
- mCurrentState.alpha = 0xFF;
- mCurrentState.flags = layerFlags;
- mCurrentState.sequence = 0;
- mCurrentState.transform.set(0, 0);
-
- // drawing state & current state are identical
- mDrawingState = mCurrentState;
-}
-
-void LayerBase::commitTransaction(bool skipSize) {
- const uint32_t w = mDrawingState.w;
- const uint32_t h = mDrawingState.h;
- mDrawingState = mCurrentState;
- if (skipSize) {
- mDrawingState.w = w;
- mDrawingState.h = h;
- }
-}
-void LayerBase::forceVisibilityTransaction() {
- // this can be called without SurfaceFlinger.mStateLock, but if we
- // can atomically increment the sequence number, it doesn't matter.
- android_atomic_inc(&mCurrentState.sequence);
- requestTransaction();
-}
-bool LayerBase::requestTransaction() {
- int32_t old = setTransactionFlags(eTransactionNeeded);
- return ((old & eTransactionNeeded) == 0);
-}
-uint32_t LayerBase::getTransactionFlags(uint32_t flags) {
- return android_atomic_and(~flags, &mTransactionFlags) & flags;
-}
-uint32_t LayerBase::setTransactionFlags(uint32_t flags) {
- return android_atomic_or(flags, &mTransactionFlags);
-}
-
-void LayerBase::setSizeChanged(uint32_t w, uint32_t h) {
-}
-
-bool LayerBase::setPosition(int32_t x, int32_t y) {
- if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
- return false;
- mCurrentState.sequence++;
- mCurrentState.transform.set(x, y);
- requestTransaction();
- return true;
-}
-bool LayerBase::setLayer(uint32_t z) {
- if (mCurrentState.z == z)
- return false;
- mCurrentState.sequence++;
- mCurrentState.z = z;
- requestTransaction();
- return true;
-}
-bool LayerBase::setSize(uint32_t w, uint32_t h) {
- if (mCurrentState.w == w && mCurrentState.h == h)
- return false;
- setSizeChanged(w, h);
- mCurrentState.w = w;
- mCurrentState.h = h;
- requestTransaction();
- return true;
-}
-bool LayerBase::setAlpha(uint8_t alpha) {
- if (mCurrentState.alpha == alpha)
- return false;
- mCurrentState.sequence++;
- mCurrentState.alpha = alpha;
- requestTransaction();
- return true;
-}
-bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) {
- // TODO: check the matrix has changed
- mCurrentState.sequence++;
- mCurrentState.transform.set(
- matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
- requestTransaction();
- return true;
-}
-bool LayerBase::setTransparentRegionHint(const Region& transparent) {
- // TODO: check the region has changed
- mCurrentState.sequence++;
- mCurrentState.transparentRegion = transparent;
- requestTransaction();
- return true;
-}
-bool LayerBase::setFlags(uint8_t flags, uint8_t mask) {
- const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
- if (mCurrentState.flags == newFlags)
- return false;
- mCurrentState.sequence++;
- mCurrentState.flags = newFlags;
- requestTransaction();
- return true;
-}
-
-Rect LayerBase::visibleBounds() const
-{
- return mTransformedBounds;
-}
-
-void LayerBase::setVisibleRegion(const Region& visibleRegion) {
- // always called from main thread
- visibleRegionScreen = visibleRegion;
-}
-
-void LayerBase::setCoveredRegion(const Region& coveredRegion) {
- // always called from main thread
- coveredRegionScreen = coveredRegion;
-}
-
-uint32_t LayerBase::doTransaction(uint32_t flags)
-{
- const Layer::State& front(drawingState());
- const Layer::State& temp(currentState());
-
- if (temp.sequence != front.sequence) {
- // invalidate and recompute the visible regions if needed
- flags |= eVisibleRegion;
- this->contentDirty = true;
- }
-
- // Commit the transaction
- commitTransaction(flags & eRestartTransaction);
- return flags;
-}
-
-Point LayerBase::getPhysicalSize() const
-{
- const Layer::State& front(drawingState());
- return Point(front.w, front.h);
-}
-
-void LayerBase::validateVisibility(const Transform& planeTransform)
-{
- const Layer::State& s(drawingState());
- const Transform tr(planeTransform * s.transform);
- const bool transformed = tr.transformed();
-
- const Point size(getPhysicalSize());
- uint32_t w = size.x;
- uint32_t h = size.y;
- tr.transform(mVertices[0], 0, 0);
- tr.transform(mVertices[1], 0, h);
- tr.transform(mVertices[2], w, h);
- tr.transform(mVertices[3], w, 0);
- if (UNLIKELY(transformed)) {
- // NOTE: here we could also punt if we have too many rectangles
- // in the transparent region
- if (tr.preserveRects()) {
- // transform the transparent region
- transparentRegionScreen = tr.transform(s.transparentRegion);
- } else {
- // transformation too complex, can't do the transparent region
- // optimization.
- transparentRegionScreen.clear();
- }
- } else {
- transparentRegionScreen = s.transparentRegion;
- }
-
- // cache a few things...
- mOrientation = tr.getOrientation();
- mTransformedBounds = tr.makeBounds(w, h);
- mTransformed = transformed;
- mLeft = tr.tx();
- mTop = tr.ty();
-
- // see if we can/should use 2D h/w with the new configuration
- mCanUseCopyBit = false;
- copybit_device_t* copybit = mFlinger->getBlitEngine();
- if (copybit) {
- const int step = copybit->get(copybit, COPYBIT_ROTATION_STEP_DEG);
- const int scaleBits = copybit->get(copybit, COPYBIT_SCALING_FRAC_BITS);
- mCanUseCopyBit = true;
- if ((mOrientation < 0) && (step > 1)) {
- // arbitrary orientations not supported
- mCanUseCopyBit = false;
- } else if ((mOrientation > 0) && (step > 90)) {
- // 90 deg rotations not supported
- mCanUseCopyBit = false;
- } else if ((tr.getType() & SkMatrix::kScale_Mask) && (scaleBits < 12)) {
- // arbitrary scaling not supported
- mCanUseCopyBit = false;
- }
-#if HONOR_PREMULTIPLIED_ALPHA
- else if (needsBlending() && mPremultipliedAlpha) {
- // pre-multiplied alpha not supported
- mCanUseCopyBit = false;
- }
-#endif
- else {
- // here, we determined we can use copybit
- if (tr.getType() & SkMatrix::kScale_Mask) {
- // and we have scaling
- if (!transparentRegionScreen.isRect()) {
- // we punt because blending is cheap (h/w) and the region is
- // complex, which may causes artifacts when copying
- // scaled content
- transparentRegionScreen.clear();
- }
- }
- }
- }
-}
-
-void LayerBase::lockPageFlip(bool& recomputeVisibleRegions)
-{
-}
-
-void LayerBase::unlockPageFlip(
- const Transform& planeTransform, Region& outDirtyRegion)
-{
- if ((android_atomic_and(~1, &mInvalidate)&1) == 1) {
- outDirtyRegion.orSelf(visibleRegionScreen);
- }
-}
-
-void LayerBase::finishPageFlip()
-{
-}
-
-void LayerBase::invalidate()
-{
- if ((android_atomic_or(1, &mInvalidate)&1) == 0) {
- mFlinger->signalEvent();
- }
-}
-
-void LayerBase::drawRegion(const Region& reg) const
-{
- Region::iterator iterator(reg);
- if (iterator) {
- Rect r;
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- const int32_t fbWidth = hw.getWidth();
- const int32_t fbHeight = hw.getHeight();
- const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 },
- { fbWidth, fbHeight }, { 0, fbHeight } };
- glVertexPointer(2, GL_SHORT, 0, vertices);
- while (iterator.iterate(&r)) {
- const GLint sy = fbHeight - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
- }
-}
-
-void LayerBase::draw(const Region& inClip) const
-{
- // invalidate the region we'll update
- Region clip(inClip); // copy-on-write, so no-op most of the time
-
- // Remove the transparent area from the clipping region
- const State& s = drawingState();
- if (LIKELY(!s.transparentRegion.isEmpty())) {
- clip.subtract(transparentRegionScreen);
- if (clip.isEmpty()) {
- // usually this won't happen because this should be taken care of
- // by SurfaceFlinger::computeVisibleRegions()
- return;
- }
- }
-
- // reset GL state
- glEnable(GL_SCISSOR_TEST);
-
- onDraw(clip);
-
- /*
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_DITHER);
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- glColor4x(0, 0x8000, 0, 0x10000);
- drawRegion(transparentRegionScreen);
- glDisable(GL_BLEND);
- */
-}
-
-GLuint LayerBase::createTexture() const
-{
- GLuint textureName = -1;
- glGenTextures(1, &textureName);
- glBindTexture(GL_TEXTURE_2D, textureName);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- if (mFlags & DisplayHardware::SLOW_CONFIG) {
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- } else {
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- }
- return textureName;
-}
-
-void LayerBase::clearWithOpenGL(const Region& clip) const
-{
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- const uint32_t fbHeight = hw.getHeight();
- glColor4x(0,0,0,0);
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
- glDisable(GL_DITHER);
- Rect r;
- Region::iterator iterator(clip);
- if (iterator) {
- glEnable(GL_SCISSOR_TEST);
- glVertexPointer(2, GL_FIXED, 0, mVertices);
- while (iterator.iterate(&r)) {
- const GLint sy = fbHeight - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
- }
-}
-
-void LayerBase::drawWithOpenGL(const Region& clip,
- GLint textureName, const GGLSurface& t, int transform) const
-{
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- const uint32_t fbHeight = hw.getHeight();
- const State& s(drawingState());
-
- // bind our texture
- validateTexture(textureName);
- glEnable(GL_TEXTURE_2D);
-
- // Dithering...
- if (s.flags & ISurfaceComposer::eLayerDither) {
- glEnable(GL_DITHER);
- } else {
- glDisable(GL_DITHER);
- }
-
- if (UNLIKELY(s.alpha < 0xFF)) {
- // We have an alpha-modulation. We need to modulate all
- // texture components by alpha because we're always using
- // premultiplied alpha.
-
- // If the texture doesn't have an alpha channel we can
- // use REPLACE and switch to non premultiplied alpha
- // blending (SRCA/ONE_MINUS_SRCA).
-
- GLenum env, src;
- if (needsBlending()) {
- env = GL_MODULATE;
- src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
- } else {
- env = GL_REPLACE;
- src = GL_SRC_ALPHA;
- }
- const GGLfixed alpha = (s.alpha << 16)/255;
- glColor4x(alpha, alpha, alpha, alpha);
- glEnable(GL_BLEND);
- glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
- glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env);
- } else {
- glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
- if (needsBlending()) {
- GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
- glEnable(GL_BLEND);
- glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
- } else {
- glDisable(GL_BLEND);
- }
- }
-
- if (UNLIKELY(transformed()
- || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) ))
- {
- //StopWatch watch("GL transformed");
- Region::iterator iterator(clip);
- if (iterator) {
- // always use high-quality filtering with fast configurations
- bool fast = !(mFlags & DisplayHardware::SLOW_CONFIG);
- if (!fast && s.flags & ISurfaceComposer::eLayerFilter) {
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- }
- const GLfixed texCoords[4][2] = {
- { 0, 0 },
- { 0, 0x10000 },
- { 0x10000, 0x10000 },
- { 0x10000, 0 }
- };
-
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
-
- if (transform == HAL_TRANSFORM_ROT_90) {
- glTranslatef(0, 1, 0);
- glRotatef(-90, 0, 0, 1);
- }
-
- if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) {
- // find the smallest power-of-two that will accommodate our surface
- GLuint tw = 1 << (31 - clz(t.width));
- GLuint th = 1 << (31 - clz(t.height));
- if (tw < t.width) tw <<= 1;
- if (th < t.height) th <<= 1;
- // this divide should be relatively fast because it's
- // a power-of-two (optimized path in libgcc)
- GLfloat ws = GLfloat(t.width) /tw;
- GLfloat hs = GLfloat(t.height)/th;
- glScalef(ws, hs, 1.0f);
- }
-
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glVertexPointer(2, GL_FIXED, 0, mVertices);
- glTexCoordPointer(2, GL_FIXED, 0, texCoords);
-
- Rect r;
- while (iterator.iterate(&r)) {
- const GLint sy = fbHeight - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
-
- if (!fast && s.flags & ISurfaceComposer::eLayerFilter) {
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- }
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- }
- } else {
- Region::iterator iterator(clip);
- if (iterator) {
- Rect r;
- GLint crop[4] = { 0, t.height, t.width, -t.height };
- glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
- int x = tx();
- int y = ty();
- y = fbHeight - (y + t.height);
- while (iterator.iterate(&r)) {
- const GLint sy = fbHeight - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glDrawTexiOES(x, y, 0, t.width, t.height);
- }
- }
- }
-}
-
-void LayerBase::validateTexture(GLint textureName) const
-{
- glBindTexture(GL_TEXTURE_2D, textureName);
- // TODO: reload the texture if needed
- // this is currently done in loadTexture() below
-}
-
-void LayerBase::loadTexture(const Region& dirty,
- GLint textureName, const GGLSurface& t,
- GLuint& textureWidth, GLuint& textureHeight) const
-{
- // TODO: defer the actual texture reload until LayerBase::validateTexture
- // is called.
-
- uint32_t flags = mFlags;
- glBindTexture(GL_TEXTURE_2D, textureName);
-
- GLuint tw = t.width;
- GLuint th = t.height;
-
- /*
- * In OpenGL ES we can't specify a stride with glTexImage2D (however,
- * GL_UNPACK_ALIGNMENT is 4, which in essence allows a limited form of
- * stride).
- * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we
- * need to do something reasonable (here creating a bigger texture).
- *
- * extra pixels = (((stride - width) * pixelsize) / GL_UNPACK_ALIGNMENT);
- *
- * This situation doesn't happen often, but some h/w have a limitation
- * for their framebuffer (eg: must be multiple of 8 pixels), and
- * we need to take that into account when using these buffers as
- * textures.
- *
- * This should never be a problem with POT textures
- */
-
- tw += (((t.stride - tw) * bytesPerPixel(t.format)) / 4);
-
- /*
- * round to POT if needed
- */
-
- GLuint texture_w = tw;
- GLuint texture_h = th;
- if (!(flags & DisplayHardware::NPOT_EXTENSION)) {
- // find the smallest power-of-two that will accommodate our surface
- texture_w = 1 << (31 - clz(t.width));
- texture_h = 1 << (31 - clz(t.height));
- if (texture_w < t.width) texture_w <<= 1;
- if (texture_h < t.height) texture_h <<= 1;
- if (texture_w != tw || texture_h != th) {
- // we can't use DIRECT_TEXTURE since we changed the size
- // of the texture
- flags &= ~DisplayHardware::DIRECT_TEXTURE;
- }
- }
-
- if (flags & DisplayHardware::DIRECT_TEXTURE) {
- // here we're guaranteed that texture_{w|h} == t{w|h}
- if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
- glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
- GL_RGB, tw, th, 0,
- GL_RGB, GL_UNSIGNED_SHORT_5_6_5, t.data);
- } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
- glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
- GL_RGBA, tw, th, 0,
- GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, t.data);
- } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
- glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
- GL_RGBA, tw, th, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, t.data);
- } else if (t.format == GGL_PIXEL_FORMAT_BGRA_8888) {
- // TODO: add GL_BGRA extension
- } else {
- // oops, we don't handle this format, try the regular path
- goto regular;
- }
- textureWidth = tw;
- textureHeight = th;
- } else {
-regular:
- Rect bounds(dirty.bounds());
- GLvoid* data = 0;
- if (texture_w!=textureWidth || texture_h!=textureHeight) {
- // texture size changed, we need to create a new one
-
- if (!textureWidth || !textureHeight) {
- // this is the first time, load the whole texture
- if (texture_w==tw && texture_h==th) {
- // we can do it one pass
- data = t.data;
- } else {
- // we have to create the texture first because it
- // doesn't match the size of the buffer
- bounds.set(Rect(tw, th));
- }
- }
-
- if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
- glTexImage2D(GL_TEXTURE_2D, 0,
- GL_RGB, texture_w, texture_h, 0,
- GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
- } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
- glTexImage2D(GL_TEXTURE_2D, 0,
- GL_RGBA, texture_w, texture_h, 0,
- GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
- } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
- glTexImage2D(GL_TEXTURE_2D, 0,
- GL_RGBA, texture_w, texture_h, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, data);
- } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP ||
- t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) {
- // just show the Y plane of YUV buffers
- data = t.data;
- glTexImage2D(GL_TEXTURE_2D, 0,
- GL_LUMINANCE, texture_w, texture_h, 0,
- GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
- } else {
- // oops, we don't handle this format!
- LOGE("layer %p, texture=%d, using format %d, which is not "
- "supported by the GL", this, textureName, t.format);
- textureName = -1;
- }
- textureWidth = texture_w;
- textureHeight = texture_h;
- }
- if (!data && textureName>=0) {
- if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
- glTexSubImage2D(GL_TEXTURE_2D, 0,
- 0, bounds.top, t.width, bounds.height(),
- GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
- t.data + bounds.top*t.width*2);
- } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
- glTexSubImage2D(GL_TEXTURE_2D, 0,
- 0, bounds.top, t.width, bounds.height(),
- GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
- t.data + bounds.top*t.width*2);
- } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
- glTexSubImage2D(GL_TEXTURE_2D, 0,
- 0, bounds.top, t.width, bounds.height(),
- GL_RGBA, GL_UNSIGNED_BYTE,
- t.data + bounds.top*t.width*4);
- }
- }
- }
-}
-
-bool LayerBase::canUseCopybit() const
-{
- return mCanUseCopyBit;
-}
-
-// ---------------------------------------------------------------------------
-
-LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
- Client* c, int32_t i)
- : LayerBase(flinger, display), client(c),
- lcblk( c ? &(c->ctrlblk->layers[i]) : 0 ),
- mIndex(i)
-{
- if (client) {
- client->bindLayer(this, i);
-
- // Initialize this layer's control block
- memset(this->lcblk, 0, sizeof(layer_cblk_t));
- this->lcblk->identity = mIdentity;
- Region::writeEmpty(&(this->lcblk->region[0]), sizeof(flat_region_t));
- Region::writeEmpty(&(this->lcblk->region[1]), sizeof(flat_region_t));
- }
-}
-
-LayerBaseClient::~LayerBaseClient()
-{
- if (client) {
- client->free(mIndex);
- }
-}
-
-int32_t LayerBaseClient::serverIndex() const {
- if (client) {
- return (client->cid<<16)|mIndex;
- }
- return 0xFFFF0000 | mIndex;
-}
-
-sp<LayerBaseClient::Surface> LayerBaseClient::getSurface() const
-{
- return new Surface(clientIndex(), mIdentity);
-}
-
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
deleted file mode 100644
index a020f44..0000000
--- a/libs/surfaceflinger/LayerBase.h
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * 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_LAYER_BASE_H
-#define ANDROID_LAYER_BASE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <private/ui/LayerState.h>
-
-#include <ui/Region.h>
-#include <ui/Overlay.h>
-
-#include <pixelflinger/pixelflinger.h>
-
-#include "Transform.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class SurfaceFlinger;
-class DisplayHardware;
-class GraphicPlane;
-class Client;
-
-// ---------------------------------------------------------------------------
-
-class LayerBase
-{
- // poor man's dynamic_cast below
- template<typename T>
- struct getTypeInfoOfAnyType {
- static uint32_t get() { return T::typeInfo; }
- };
-
- template<typename T>
- struct getTypeInfoOfAnyType<T*> {
- static uint32_t get() { return getTypeInfoOfAnyType<T>::get(); }
- };
-
-public:
- static const uint32_t typeInfo;
- static const char* const typeID;
- virtual char const* getTypeID() const { return typeID; }
- virtual uint32_t getTypeInfo() const { return typeInfo; }
-
- template<typename T>
- static T dynamicCast(LayerBase* base) {
- uint32_t mostDerivedInfo = base->getTypeInfo();
- uint32_t castToInfo = getTypeInfoOfAnyType<T>::get();
- if ((mostDerivedInfo & castToInfo) == castToInfo)
- return static_cast<T>(base);
- return 0;
- }
-
-
- static Vector<GLuint> deletedTextures;
-
- LayerBase(SurfaceFlinger* flinger, DisplayID display);
- virtual ~LayerBase();
-
- DisplayID dpy;
- mutable bool contentDirty;
- Region visibleRegionScreen;
- Region transparentRegionScreen;
- Region coveredRegionScreen;
-
- struct State {
- uint32_t w;
- uint32_t h;
- uint32_t z;
- uint8_t alpha;
- uint8_t flags;
- uint8_t reserved[2];
- int32_t sequence; // changes when visible regions can change
- uint32_t tint;
- Transform transform;
- Region transparentRegion;
- };
-
- // modify current state
- bool setPosition(int32_t x, int32_t y);
- bool setLayer(uint32_t z);
- bool setSize(uint32_t w, uint32_t h);
- bool setAlpha(uint8_t alpha);
- bool setMatrix(const layer_state_t::matrix22_t& matrix);
- bool setTransparentRegionHint(const Region& opaque);
- bool setFlags(uint8_t flags, uint8_t mask);
-
- void commitTransaction(bool skipSize);
- bool requestTransaction();
- void forceVisibilityTransaction();
-
- uint32_t getTransactionFlags(uint32_t flags);
- uint32_t setTransactionFlags(uint32_t flags);
-
- Rect visibleBounds() const;
- void drawRegion(const Region& reg) const;
-
- void invalidate();
-
- /**
- * draw - performs some global clipping optimizations
- * and calls onDraw().
- * Typically this method is not overridden, instead implement onDraw()
- * to perform the actual drawing.
- */
- virtual void draw(const Region& clip) const;
-
- /**
- * onDraw - draws the surface.
- */
- virtual void onDraw(const Region& clip) const = 0;
-
- /**
- * initStates - called just after construction
- */
- virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
-
- /**
- * setSizeChanged - called when the *current* state's size is changed.
- */
- virtual void setSizeChanged(uint32_t w, uint32_t h);
-
- /**
- * doTransaction - process the transaction. This is a good place to figure
- * out which attributes of the surface have changed.
- */
- virtual uint32_t doTransaction(uint32_t transactionFlags);
-
- /**
- * setVisibleRegion - called to set the new visible region. This gives
- * a chance to update the new visible region or record the fact it changed.
- */
- virtual void setVisibleRegion(const Region& visibleRegion);
-
- /**
- * setCoveredRegion - called when the covered region changes. The covered
- * region correspond to any area of the surface that is covered
- * (transparently or not) by another surface.
- */
- virtual void setCoveredRegion(const Region& coveredRegion);
-
- /**
- * getPhysicalSize - returns the physical size of the drawing state of
- * the surface. If the surface is backed by a bitmap, this is the size of
- * the bitmap (as opposed to the size of the drawing state).
- */
- virtual Point getPhysicalSize() const;
-
- /**
- * validateVisibility - cache a bunch of things
- */
- virtual void validateVisibility(const Transform& globalTransform);
-
- /**
- * lockPageFlip - called each time the screen is redrawn and returns whether
- * the visible regions need to be recomputed (this is a fairly heavy
- * operation, so this should be set only if needed). Typically this is used
- * to figure out if the content or size of a surface has changed.
- */
- virtual void lockPageFlip(bool& recomputeVisibleRegions);
-
- /**
- * unlockPageFlip - called each time the screen is redrawn. updates the
- * final dirty region wrt the planeTransform.
- * At this point, all visible regions, surface position and size, etc... are
- * correct.
- */
- virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
-
- /**
- * finishPageFlip - called after all surfaces have drawn.
- */
- virtual void finishPageFlip();
-
- /**
- * needsBlending - true if this surface needs blending
- */
- virtual bool needsBlending() const { return false; }
-
- /**
- * transformed -- true is this surface needs a to be transformed
- */
- virtual bool transformed() const { return mTransformed; }
-
- /**
- * isSecure - true if this surface is secure, that is if it prevents
- * screenshots or vns servers.
- */
- virtual bool isSecure() const { return false; }
-
- enum { // flags for doTransaction()
- eVisibleRegion = 0x00000002,
- eRestartTransaction = 0x00000008
- };
-
-
- inline const State& drawingState() const { return mDrawingState; }
- inline const State& currentState() const { return mCurrentState; }
- inline State& currentState() { return mCurrentState; }
-
- static int compareCurrentStateZ(LayerBase*const* layerA, LayerBase*const* layerB) {
- return layerA[0]->currentState().z - layerB[0]->currentState().z;
- }
-
- int32_t getOrientation() const { return mOrientation; }
- int tx() const { return mLeft; }
- int ty() const { return mTop; }
-
-protected:
- const GraphicPlane& graphicPlane(int dpy) const;
- GraphicPlane& graphicPlane(int dpy);
-
- GLuint createTexture() const;
-
- void drawWithOpenGL(const Region& clip,
- GLint textureName,
- const GGLSurface& surface,
- int transform = 0) const;
-
- void clearWithOpenGL(const Region& clip) const;
-
- void loadTexture(const Region& dirty,
- GLint textureName, const GGLSurface& t,
- GLuint& textureWidth, GLuint& textureHeight) const;
-
- bool canUseCopybit() const;
-
- SurfaceFlinger* mFlinger;
- uint32_t mFlags;
-
- // cached during validateVisibility()
- bool mTransformed;
- int32_t mOrientation;
- GLfixed mVertices[4][2];
- Rect mTransformedBounds;
- bool mCanUseCopyBit;
- int mLeft;
- int mTop;
-
- // these are protected by an external lock
- State mCurrentState;
- State mDrawingState;
- volatile int32_t mTransactionFlags;
-
- // don't change, don't need a lock
- bool mPremultipliedAlpha;
-
- // only read
- const uint32_t mIdentity;
-
- // atomic
- volatile int32_t mInvalidate;
-
-
-private:
- void validateTexture(GLint textureName) const;
- static int32_t sIdentity;
-};
-
-
-// ---------------------------------------------------------------------------
-
-class LayerBaseClient : public LayerBase
-{
-public:
- class Surface;
- static const uint32_t typeInfo;
- static const char* const typeID;
- virtual char const* getTypeID() const { return typeID; }
- virtual uint32_t getTypeInfo() const { return typeInfo; }
-
- LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
- Client* client, int32_t i);
- virtual ~LayerBaseClient();
-
-
- Client* const client;
- layer_cblk_t* const lcblk;
-
- inline int32_t clientIndex() const { return mIndex; }
- int32_t serverIndex() const;
-
- virtual sp<Surface> getSurface() const;
-
- uint32_t getIdentity() const { return mIdentity; }
-
- class Surface : public BnSurface
- {
- public:
- Surface(SurfaceID id, int identity) {
- mParams.token = id;
- mParams.identity = identity;
- }
- Surface(SurfaceID id,
- const sp<IMemoryHeap>& heap0,
- const sp<IMemoryHeap>& heap1,
- int identity)
- {
- mParams.token = id;
- mParams.identity = identity;
- mParams.heap[0] = heap0;
- mParams.heap[1] = heap1;
- }
- virtual ~Surface() {
- // TODO: We now have a point here were we can clean-up the
- // client's mess.
- // This is also where surface id should be recycled.
- //LOGD("Surface %d, heaps={%p, %p} destroyed",
- // mId, mHeap[0].get(), mHeap[1].get());
- }
-
- virtual void getSurfaceData(
- ISurfaceFlingerClient::surface_data_t* params) const {
- *params = mParams;
- }
-
- virtual status_t registerBuffers(const ISurface::BufferHeap& buffers)
- { return INVALID_OPERATION; }
- virtual void postBuffer(ssize_t offset) { }
- virtual void unregisterBuffers() { };
- virtual sp<OverlayRef> createOverlay(
- uint32_t w, uint32_t h, int32_t format) {
- return NULL;
- };
-
- private:
- ISurfaceFlingerClient::surface_data_t mParams;
- };
-
-private:
- int32_t mIndex;
-
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_BASE_H
diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp
deleted file mode 100644
index e844350..0000000
--- a/libs/surfaceflinger/LayerBitmap.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <cutils/memory.h>
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <utils/MemoryDealer.h>
-#include <utils/IMemory.h>
-#include <ui/PixelFormat.h>
-#include <pixelflinger/pixelflinger.h>
-
-#include "LayerBitmap.h"
-#include "SurfaceFlinger.h"
-#include "VRamHeap.h"
-
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-LayerBitmap::LayerBitmap()
- : mAllocFlags(0), mOffset(0), mSize(-1U), mAlignment(2)
-{
- memset(&mSurface, 0, sizeof(mSurface));
-}
-
-LayerBitmap::~LayerBitmap()
-{
- mSurface.data = 0;
-}
-
-status_t LayerBitmap::init(const sp<MemoryDealer>& allocator)
-{
- if (mAllocator != NULL)
- return BAD_VALUE;
- mAllocator = allocator;
- return NO_ERROR;
-}
-
-status_t LayerBitmap::setBits(uint32_t w, uint32_t h, uint32_t alignment,
- PixelFormat format, uint32_t flags)
-{
- const sp<MemoryDealer>& allocator(mAllocator);
- if (allocator == NULL)
- return NO_INIT;
-
- if (UNLIKELY(w == mSurface.width && h == mSurface.height &&
- format == mSurface.format))
- { // same format and size, do nothing.
- return NO_ERROR;
- }
-
- PixelFormatInfo info;
- getPixelFormatInfo(format, &info);
-
- uint32_t allocFlags = MemoryDealer::PAGE_ALIGNED;
- const uint32_t align = 4; // must match GL_UNPACK_ALIGNMENT
- const uint32_t Bpp = info.bytesPerPixel;
- uint32_t stride = (w + (alignment-1)) & ~(alignment-1);
- stride = ((stride * Bpp + (align-1)) & ~(align-1)) / Bpp;
- size_t size = info.getScanlineSize(stride) * h;
- if (allocFlags & MemoryDealer::PAGE_ALIGNED) {
- size_t pagesize = getpagesize();
- size = (size + (pagesize-1)) & ~(pagesize-1);
- }
-
- /* FIXME: we should be able to have a h/v stride because the user of the
- * surface might have stride limitation (for instance h/w codecs often do)
- */
- int32_t vstride = 0;
-
- mAlignment = alignment;
- mAllocFlags = allocFlags;
- mOffset = 0;
- if (mSize != size) {
- // would be nice to have a reallocate() api
- mBitsMemory.clear(); // free-memory
- mBitsMemory = allocator->allocate(size, allocFlags);
- mSize = size;
- } else {
- // don't erase memory if we didn't have to reallocate
- flags &= ~SECURE_BITS;
- }
- if (mBitsMemory != 0) {
- mOffset = mBitsMemory->offset();
- mSurface.data = static_cast<GGLubyte*>(mBitsMemory->pointer());
- mSurface.version = sizeof(GGLSurface);
- mSurface.width = w;
- mSurface.height = h;
- mSurface.stride = stride;
- mSurface.vstride = vstride;
- mSurface.format = format;
- if (flags & SECURE_BITS)
- clear();
- }
-
- if (mBitsMemory==0 || mSurface.data==0) {
- LOGE("not enough memory for layer bitmap size=%u", size);
- allocator->dump("LayerBitmap");
- mSurface.data = 0;
- mSize = -1U;
- return NO_MEMORY;
- }
- return NO_ERROR;
-}
-
-void LayerBitmap::clear()
-{
- // NOTE: this memset should not be necessary, at least for
- // opaque surface. However, for security reasons it's better to keep it
- // (in the case of pmem, it's possible that the memory contains old
- // data)
- if (mSurface.data) {
- memset(mSurface.data, 0, mSize);
- //if (bytesPerPixel(mSurface.format) == 4) {
- // android_memset32((uint32_t*)mSurface.data, 0xFF0000FF, mSize);
- //} else {
- // android_memset16((uint16_t*)mSurface.data, 0xF800, mSize);
- //}
- }
-}
-
-status_t LayerBitmap::getInfo(surface_info_t* info) const
-{
- if (mSurface.data == 0) {
- memset(info, 0, sizeof(surface_info_t));
- info->bits_offset = NO_MEMORY;
- return NO_MEMORY;
- }
- info->w = uint16_t(width());
- info->h = uint16_t(height());
- info->stride= uint16_t(stride());
- info->bpr = uint16_t(stride() * bytesPerPixel(pixelFormat()));
- info->format= uint8_t(pixelFormat());
- info->flags = surface_info_t::eBufferDirty;
- info->bits_offset = ssize_t(mOffset);
- return NO_ERROR;
-}
-
-status_t LayerBitmap::resize(uint32_t w, uint32_t h)
-{
- int err = setBits(w, h, mAlignment, pixelFormat(), SECURE_BITS);
- return err;
-}
-
-size_t LayerBitmap::size() const
-{
- return mSize;
-}
-
-void LayerBitmap::getBitmapSurface(copybit_image_t* img) const
-{
- const sp<IMemoryHeap>& mh(getAllocator()->getMemoryHeap());
- void* sbase = mh->base();
- const GGLSurface& t(surface());
- img->w = t.stride ?: t.width;
- img->h = t.vstride ?: t.height;
- img->format = t.format;
- img->offset = intptr_t(t.data) - intptr_t(sbase);
- img->base = sbase;
- img->fd = mh->heapID();
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h
deleted file mode 100644
index 9ad64c4..0000000
--- a/libs/surfaceflinger/LayerBitmap.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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_LAYER_BITMAP_H
-#define ANDROID_LAYER_BITMAP_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Atomic.h>
-#include <ui/PixelFormat.h>
-#include <ui/Rect.h>
-#include <private/ui/SharedState.h>
-#include <pixelflinger/pixelflinger.h>
-
-class copybit_image_t;
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class IMemory;
-class MemoryDealer;
-class LayerBitmap;
-
-// ---------------------------------------------------------------------------
-
-class LayerBitmap
-{
-public:
-
- enum {
- // erase memory to ensure security when necessary
- SECURE_BITS = 0x00000001
- };
-
- LayerBitmap();
- ~LayerBitmap();
- status_t init(const sp<MemoryDealer>& allocator);
-
- status_t setBits(uint32_t w, uint32_t h, uint32_t alignment,
- PixelFormat format, uint32_t flags = 0);
- void clear();
-
- status_t getInfo(surface_info_t* info) const;
- status_t resize(uint32_t w, uint32_t h);
-
- const GGLSurface& surface() const { return mSurface; }
- Rect bounds() const { return Rect(width(), height()); }
- uint32_t width() const { return surface().width; }
- uint32_t height() const { return surface().height; }
- uint32_t stride() const { return surface().stride; }
- PixelFormat pixelFormat() const { return surface().format; }
- void* serverBits() const { return surface().data; }
- size_t size() const;
- const sp<MemoryDealer>& getAllocator() const { return mAllocator; }
- void getBitmapSurface(copybit_image_t* img) const;
-
-private:
- sp<MemoryDealer> mAllocator;
- sp<IMemory> mBitsMemory;
- uint32_t mAllocFlags;
- ssize_t mOffset;
- GGLSurface mSurface;
- size_t mSize;
- uint32_t mAlignment;
-};
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_BITMAP_H
diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp
deleted file mode 100644
index d3e456f..0000000
--- a/libs/surfaceflinger/LayerBlur.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-
-#include "BlurFilter.h"
-#include "LayerBlur.h"
-#include "SurfaceFlinger.h"
-#include "DisplayHardware/DisplayHardware.h"
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-const uint32_t LayerBlur::typeInfo = LayerBaseClient::typeInfo | 8;
-const char* const LayerBlur::typeID = "LayerBlur";
-
-// ---------------------------------------------------------------------------
-
-LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display,
- Client* client, int32_t i)
- : LayerBaseClient(flinger, display, client, i), mCacheDirty(true),
- mRefreshCache(true), mCacheAge(0), mTextureName(-1U)
-{
-}
-
-LayerBlur::~LayerBlur()
-{
- if (mTextureName != -1U) {
- //glDeleteTextures(1, &mTextureName);
- deletedTextures.add(mTextureName);
- }
-}
-
-void LayerBlur::setVisibleRegion(const Region& visibleRegion)
-{
- LayerBaseClient::setVisibleRegion(visibleRegion);
- if (visibleRegionScreen.isEmpty()) {
- if (mTextureName != -1U) {
- // We're not visible, free the texture up.
- glBindTexture(GL_TEXTURE_2D, 0);
- glDeleteTextures(1, &mTextureName);
- mTextureName = -1U;
- }
- }
-}
-
-uint32_t LayerBlur::doTransaction(uint32_t flags)
-{
- // we're doing a transaction, refresh the cache!
- if (!mFlinger->isFrozen()) {
- mRefreshCache = true;
- mCacheDirty = true;
- flags |= eVisibleRegion;
- this->contentDirty = true;
- }
- return LayerBase::doTransaction(flags);
-}
-
-void LayerBlur::unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion)
-{
- // this code-path must be as tight as possible, it's called each time
- // the screen is composited.
- if (UNLIKELY(!visibleRegionScreen.isEmpty())) {
- // if anything visible below us is invalidated, the cache becomes dirty
- if (!mCacheDirty &&
- !visibleRegionScreen.intersect(outDirtyRegion).isEmpty()) {
- mCacheDirty = true;
- }
- if (mCacheDirty) {
- if (!mFlinger->isFrozen()) {
- // update everything below us that is visible
- outDirtyRegion.orSelf(visibleRegionScreen);
- nsecs_t now = systemTime();
- if ((now - mCacheAge) >= ms2ns(500)) {
- mCacheAge = now;
- mRefreshCache = true;
- mCacheDirty = false;
- } else {
- if (!mAutoRefreshPending) {
- mFlinger->signalDelayedEvent(ms2ns(500));
- mAutoRefreshPending = true;
- }
- }
- }
- }
- }
- LayerBase::unlockPageFlip(planeTransform, outDirtyRegion);
-}
-
-void LayerBlur::onDraw(const Region& clip) const
-{
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- const uint32_t fbHeight = hw.getHeight();
- int x = mTransformedBounds.left;
- int y = mTransformedBounds.top;
- int w = mTransformedBounds.width();
- int h = mTransformedBounds.height();
- GLint X = x;
- GLint Y = fbHeight - (y + h);
- if (X < 0) {
- w += X;
- X = 0;
- }
- if (Y < 0) {
- h += Y;
- Y = 0;
- }
- if (w<0 || h<0) {
- // we're outside of the framebuffer
- return;
- }
-
- if (mTextureName == -1U) {
- // create the texture name the first time
- // can't do that in the ctor, because it runs in another thread.
- glGenTextures(1, &mTextureName);
- }
-
- Region::iterator iterator(clip);
- if (iterator) {
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, mTextureName);
-
- if (mRefreshCache) {
- mRefreshCache = false;
- mAutoRefreshPending = false;
-
- // allocate enough memory for 4-bytes (2 pixels) aligned data
- const int32_t s = (w + 1) & ~1;
- uint16_t* const pixels = (uint16_t*)malloc(s*h*2);
-
- // This reads the frame-buffer, so a h/w GL would have to
- // finish() its rendering first. we don't want to do that
- // too often. Read data is 4-bytes aligned.
- glReadPixels(X, Y, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
-
- // blur that texture.
- GGLSurface bl;
- bl.version = sizeof(GGLSurface);
- bl.width = w;
- bl.height = h;
- bl.stride = s;
- bl.format = GGL_PIXEL_FORMAT_RGB_565;
- bl.data = (GGLubyte*)pixels;
- blurFilter(&bl, 8, 2);
-
- // NOTE: this works only because we have POT. we'd have to round the
- // texture size up, otherwise.
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0,
- GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
-
- free((void*)pixels);
- }
-
- const State& s = drawingState();
- if (UNLIKELY(s.alpha < 0xFF)) {
- const GGLfixed alpha = (s.alpha << 16)/255;
- glColor4x(0, 0, 0, alpha);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- } else {
- glDisable(GL_BLEND);
- }
-
- glDisable(GL_DITHER);
- glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
- if (UNLIKELY(transformed()
- || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) {
- // This is a very rare scenario.
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glScalef(1.0f/w, -1.0f/h, 1);
- glTranslatef(-x, -y, 0);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glVertexPointer(2, GL_FIXED, 0, mVertices);
- glTexCoordPointer(2, GL_FIXED, 0, mVertices);
- Rect r;
- while (iterator.iterate(&r)) {
- const GLint sy = fbHeight - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
- } else {
- Region::iterator iterator(clip);
- if (iterator) {
- // NOTE: this is marginally faster with the software gl, because
- // glReadPixels() reads the fb bottom-to-top, however we'll
- // skip all the jaccobian computations.
- Rect r;
- GLint crop[4] = { 0, 0, w, h };
- glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
- y = fbHeight - (y + h);
- while (iterator.iterate(&r)) {
- const GLint sy = fbHeight - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glDrawTexiOES(x, y, 0, w, h);
- }
- }
- }
- }
-
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/surfaceflinger/LayerBlur.h b/libs/surfaceflinger/LayerBlur.h
deleted file mode 100644
index 24b1156..0000000
--- a/libs/surfaceflinger/LayerBlur.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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_LAYER_BLUR_H
-#define ANDROID_LAYER_BLUR_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <private/ui/LayerState.h>
-
-#include <ui/Region.h>
-
-#include "LayerBase.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class LayerBlur : public LayerBaseClient
-{
-public:
- static const uint32_t typeInfo;
- static const char* const typeID;
- virtual char const* getTypeID() const { return typeID; }
- virtual uint32_t getTypeInfo() const { return typeInfo; }
-
- LayerBlur(SurfaceFlinger* flinger, DisplayID display,
- Client* client, int32_t i);
- virtual ~LayerBlur();
-
- virtual void onDraw(const Region& clip) const;
- virtual bool needsBlending() const { return true; }
- virtual bool isSecure() const { return false; }
-
- virtual uint32_t doTransaction(uint32_t flags);
- virtual void setVisibleRegion(const Region& visibleRegion);
- virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
-
-private:
- bool mCacheDirty;
- mutable bool mRefreshCache;
- mutable bool mAutoRefreshPending;
- nsecs_t mCacheAge;
- mutable GLuint mTextureName;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_BLUR_H
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
deleted file mode 100644
index 00fab70..0000000
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <math.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <utils/StopWatch.h>
-
-#include <utils/IPCThreadState.h>
-#include <utils/IServiceManager.h>
-
-#include <ui/PixelFormat.h>
-#include <ui/EGLDisplaySurface.h>
-
-#include "LayerBuffer.h"
-#include "SurfaceFlinger.h"
-#include "VRamHeap.h"
-#include "DisplayHardware/DisplayHardware.h"
-
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-const uint32_t LayerBuffer::typeInfo = LayerBaseClient::typeInfo | 0x20;
-const char* const LayerBuffer::typeID = "LayerBuffer";
-
-// ---------------------------------------------------------------------------
-
-LayerBuffer::LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
- Client* client, int32_t i)
- : LayerBaseClient(flinger, display, client, i),
- mNeedsBlending(false)
-{
-}
-
-LayerBuffer::~LayerBuffer()
-{
- sp<SurfaceBuffer> s(getClientSurface());
- if (s != 0) {
- s->disown();
- mClientSurface.clear();
- }
-}
-
-sp<LayerBuffer::SurfaceBuffer> LayerBuffer::getClientSurface() const
-{
- Mutex::Autolock _l(mLock);
- return mClientSurface.promote();
-}
-
-sp<LayerBaseClient::Surface> LayerBuffer::getSurface() const
-{
- sp<SurfaceBuffer> s;
- Mutex::Autolock _l(mLock);
- s = mClientSurface.promote();
- if (s == 0) {
- s = new SurfaceBuffer(clientIndex(),
- const_cast<LayerBuffer *>(this));
- mClientSurface = s;
- }
- return s;
-}
-
-bool LayerBuffer::needsBlending() const {
- return mNeedsBlending;
-}
-
-void LayerBuffer::setNeedsBlending(bool blending) {
- mNeedsBlending = blending;
-}
-
-void LayerBuffer::postBuffer(ssize_t offset)
-{
- sp<Source> source(getSource());
- if (source != 0)
- source->postBuffer(offset);
-}
-
-void LayerBuffer::unregisterBuffers()
-{
- sp<Source> source(clearSource());
- if (source != 0)
- source->unregisterBuffers();
-}
-
-uint32_t LayerBuffer::doTransaction(uint32_t flags)
-{
- sp<Source> source(getSource());
- if (source != 0)
- source->onTransaction(flags);
- return LayerBase::doTransaction(flags);
-}
-
-void LayerBuffer::unlockPageFlip(const Transform& planeTransform,
- Region& outDirtyRegion)
-{
- // this code-path must be as tight as possible, it's called each time
- // the screen is composited.
- sp<Source> source(getSource());
- if (source != 0)
- source->onVisibilityResolved(planeTransform);
- LayerBase::unlockPageFlip(planeTransform, outDirtyRegion);
-}
-
-void LayerBuffer::onDraw(const Region& clip) const
-{
- sp<Source> source(getSource());
- if (LIKELY(source != 0)) {
- source->onDraw(clip);
- } else {
- clearWithOpenGL(clip);
- }
-}
-
-bool LayerBuffer::transformed() const
-{
- sp<Source> source(getSource());
- if (LIKELY(source != 0))
- return source->transformed();
- return false;
-}
-
-/**
- * This creates a "buffer" source for this surface
- */
-status_t LayerBuffer::registerBuffers(const ISurface::BufferHeap& buffers)
-{
- Mutex::Autolock _l(mLock);
- if (mSource != 0)
- return INVALID_OPERATION;
-
- sp<BufferSource> source = new BufferSource(*this, buffers);
-
- status_t result = source->getStatus();
- if (result == NO_ERROR) {
- mSource = source;
- }
- return result;
-}
-
-/**
- * This creates an "overlay" source for this surface
- */
-sp<OverlayRef> LayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t f)
-{
- sp<OverlayRef> result;
- Mutex::Autolock _l(mLock);
- if (mSource != 0)
- return result;
-
- sp<OverlaySource> source = new OverlaySource(*this, &result, w, h, f);
- if (result != 0) {
- mSource = source;
- }
- return result;
-}
-
-sp<LayerBuffer::Source> LayerBuffer::getSource() const {
- Mutex::Autolock _l(mLock);
- return mSource;
-}
-
-sp<LayerBuffer::Source> LayerBuffer::clearSource() {
- sp<Source> source;
- Mutex::Autolock _l(mLock);
- source = mSource;
- mSource.clear();
- return source;
-}
-
-// ============================================================================
-// LayerBuffer::SurfaceBuffer
-// ============================================================================
-
-LayerBuffer::SurfaceBuffer::SurfaceBuffer(SurfaceID id, LayerBuffer* owner)
-: LayerBaseClient::Surface(id, owner->getIdentity()), mOwner(owner)
-{
-}
-
-LayerBuffer::SurfaceBuffer::~SurfaceBuffer()
-{
- unregisterBuffers();
- mOwner = 0;
-}
-
-status_t LayerBuffer::SurfaceBuffer::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch (code) {
- case REGISTER_BUFFERS:
- case UNREGISTER_BUFFERS:
- case CREATE_OVERLAY:
- {
- // codes that require permission check
- IPCThreadState* ipc = IPCThreadState::self();
- const int pid = ipc->getCallingPid();
- const int self_pid = getpid();
- if (LIKELY(pid != self_pid)) {
- // we're called from a different process, do the real check
- if (!checkCallingPermission(
- String16("android.permission.ACCESS_SURFACE_FLINGER")))
- {
- const int uid = ipc->getCallingUid();
- LOGE("Permission Denial: "
- "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
- return PERMISSION_DENIED;
- }
- }
- }
- }
- return LayerBaseClient::Surface::onTransact(code, data, reply, flags);
-}
-
-status_t LayerBuffer::SurfaceBuffer::registerBuffers(const ISurface::BufferHeap& buffers)
-{
- LayerBuffer* owner(getOwner());
- if (owner)
- return owner->registerBuffers(buffers);
- return NO_INIT;
-}
-
-void LayerBuffer::SurfaceBuffer::postBuffer(ssize_t offset)
-{
- LayerBuffer* owner(getOwner());
- if (owner)
- owner->postBuffer(offset);
-}
-
-void LayerBuffer::SurfaceBuffer::unregisterBuffers()
-{
- LayerBuffer* owner(getOwner());
- if (owner)
- owner->unregisterBuffers();
-}
-
-sp<OverlayRef> LayerBuffer::SurfaceBuffer::createOverlay(
- uint32_t w, uint32_t h, int32_t format) {
- sp<OverlayRef> result;
- LayerBuffer* owner(getOwner());
- if (owner)
- result = owner->createOverlay(w, h, format);
- return result;
-}
-
-void LayerBuffer::SurfaceBuffer::disown()
-{
- Mutex::Autolock _l(mLock);
- mOwner = 0;
-}
-
-// ============================================================================
-// LayerBuffer::Buffer
-// ============================================================================
-
-LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers, ssize_t offset)
- : mBufferHeap(buffers)
-{
- NativeBuffer& src(mNativeBuffer);
- src.crop.l = 0;
- src.crop.t = 0;
- src.crop.r = buffers.w;
- src.crop.b = buffers.h;
- src.img.w = buffers.hor_stride ?: buffers.w;
- src.img.h = buffers.ver_stride ?: buffers.h;
- src.img.format = buffers.format;
- src.img.offset = offset;
- src.img.base = buffers.heap->base();
- src.img.fd = buffers.heap->heapID();
-}
-
-LayerBuffer::Buffer::~Buffer()
-{
-}
-
-// ============================================================================
-// LayerBuffer::Source
-// LayerBuffer::BufferSource
-// LayerBuffer::OverlaySource
-// ============================================================================
-
-LayerBuffer::Source::Source(LayerBuffer& layer)
- : mLayer(layer)
-{
-}
-LayerBuffer::Source::~Source() {
-}
-void LayerBuffer::Source::onDraw(const Region& clip) const {
-}
-void LayerBuffer::Source::onTransaction(uint32_t flags) {
-}
-void LayerBuffer::Source::onVisibilityResolved(
- const Transform& planeTransform) {
-}
-void LayerBuffer::Source::postBuffer(ssize_t offset) {
-}
-void LayerBuffer::Source::unregisterBuffers() {
-}
-bool LayerBuffer::Source::transformed() const {
- return mLayer.mTransformed;
-}
-
-// ---------------------------------------------------------------------------
-
-LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer,
- const ISurface::BufferHeap& buffers)
- : Source(layer), mStatus(NO_ERROR),
- mBufferSize(0), mTextureName(-1U)
-{
- if (buffers.heap == NULL) {
- // this is allowed, but in this case, it is illegal to receive
- // postBuffer(). The surface just erases the framebuffer with
- // fully transparent pixels.
- mBufferHeap = buffers;
- mLayer.setNeedsBlending(false);
- return;
- }
-
- status_t err = (buffers.heap->heapID() >= 0) ? NO_ERROR : NO_INIT;
- if (err != NO_ERROR) {
- LOGE("LayerBuffer::BufferSource: invalid heap (%s)", strerror(err));
- mStatus = err;
- return;
- }
-
- PixelFormatInfo info;
- err = getPixelFormatInfo(buffers.format, &info);
- if (err != NO_ERROR) {
- LOGE("LayerBuffer::BufferSource: invalid format %d (%s)",
- buffers.format, strerror(err));
- mStatus = err;
- return;
- }
-
- if (buffers.hor_stride<0 || buffers.ver_stride<0) {
- LOGE("LayerBuffer::BufferSource: invalid parameters "
- "(w=%d, h=%d, xs=%d, ys=%d)",
- buffers.w, buffers.h, buffers.hor_stride, buffers.ver_stride);
- mStatus = BAD_VALUE;
- return;
- }
-
- mBufferHeap = buffers;
- mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0);
- mBufferSize = info.getScanlineSize(buffers.hor_stride)*buffers.ver_stride;
- mLayer.forceVisibilityTransaction();
-
-}
-
-LayerBuffer::BufferSource::~BufferSource()
-{
- if (mTextureName != -1U) {
- LayerBase::deletedTextures.add(mTextureName);
- }
-}
-
-void LayerBuffer::BufferSource::postBuffer(ssize_t offset)
-{
- ISurface::BufferHeap buffers;
- { // scope for the lock
- Mutex::Autolock _l(mLock);
- buffers = mBufferHeap;
- if (buffers.heap != 0) {
- const size_t memorySize = buffers.heap->getSize();
- if ((size_t(offset) + mBufferSize) > memorySize) {
- LOGE("LayerBuffer::BufferSource::postBuffer() "
- "invalid buffer (offset=%d, size=%d, heap-size=%d",
- int(offset), int(mBufferSize), int(memorySize));
- return;
- }
- }
- }
-
- sp<Buffer> buffer;
- if (buffers.heap != 0) {
- buffer = new LayerBuffer::Buffer(buffers, offset);
- if (buffer->getStatus() != NO_ERROR)
- buffer.clear();
- setBuffer(buffer);
- mLayer.invalidate();
- }
-}
-
-void LayerBuffer::BufferSource::unregisterBuffers()
-{
- Mutex::Autolock _l(mLock);
- mBufferHeap.heap.clear();
- mBuffer.clear();
- mLayer.invalidate();
-}
-
-sp<LayerBuffer::Buffer> LayerBuffer::BufferSource::getBuffer() const
-{
- Mutex::Autolock _l(mLock);
- return mBuffer;
-}
-
-void LayerBuffer::BufferSource::setBuffer(const sp<LayerBuffer::Buffer>& buffer)
-{
- Mutex::Autolock _l(mLock);
- mBuffer = buffer;
-}
-
-bool LayerBuffer::BufferSource::transformed() const
-{
- return mBufferHeap.transform ? true : Source::transformed();
-}
-
-void LayerBuffer::BufferSource::onDraw(const Region& clip) const
-{
- sp<Buffer> buffer(getBuffer());
- if (UNLIKELY(buffer == 0)) {
- // nothing to do, we don't have a buffer
- mLayer.clearWithOpenGL(clip);
- return;
- }
-
- status_t err = NO_ERROR;
- NativeBuffer src(buffer->getBuffer());
- const Rect& transformedBounds = mLayer.getTransformedBounds();
- const int can_use_copybit = mLayer.canUseCopybit();
-
- if (can_use_copybit) {
- const int src_width = src.crop.r - src.crop.l;
- const int src_height = src.crop.b - src.crop.t;
- int W = transformedBounds.width();
- int H = transformedBounds.height();
- if (mLayer.getOrientation() & Transform::ROT_90) {
- int t(W); W=H; H=t;
- }
-
- /* With LayerBuffer, it is likely that we'll have to rescale the
- * surface, because this is often used for video playback or
- * camera-preview. Since we want these operation as fast as possible
- * we make sure we can use the 2D H/W even if it doesn't support
- * the requested scale factor, in which case we perform the scaling
- * in several passes. */
-
- copybit_device_t* copybit = mLayer.mFlinger->getBlitEngine();
- const float min = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT);
- const float mag = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT);
-
- float xscale = 1.0f;
- if (src_width > W*min) xscale = 1.0f / min;
- else if (src_width*mag < W) xscale = mag;
-
- float yscale = 1.0f;
- if (src_height > H*min) yscale = 1.0f / min;
- else if (src_height*mag < H) yscale = mag;
-
- if (UNLIKELY(xscale!=1.0f || yscale!=1.0f)) {
- if (UNLIKELY(mTemporaryDealer == 0)) {
- // allocate a memory-dealer for this the first time
- mTemporaryDealer = mLayer.mFlinger->getSurfaceHeapManager()
- ->createHeap(ISurfaceComposer::eHardware);
- mTempBitmap.init(mTemporaryDealer);
- }
-
- const int tmp_w = floorf(src_width * xscale);
- const int tmp_h = floorf(src_height * yscale);
- err = mTempBitmap.setBits(tmp_w, tmp_h, 1, src.img.format);
-
- if (LIKELY(err == NO_ERROR)) {
- NativeBuffer tmp;
- mTempBitmap.getBitmapSurface(&tmp.img);
- tmp.crop.l = 0;
- tmp.crop.t = 0;
- tmp.crop.r = tmp.img.w;
- tmp.crop.b = tmp.img.h;
-
- region_iterator tmp_it(Region(Rect(tmp.crop.r, tmp.crop.b)));
- copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
- copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
- copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
- err = copybit->stretch(copybit,
- &tmp.img, &src.img, &tmp.crop, &src.crop, &tmp_it);
- src = tmp;
- }
- }
-
- const DisplayHardware& hw(mLayer.graphicPlane(0).displayHardware());
- copybit_image_t dst;
- hw.getDisplaySurface(&dst);
- const copybit_rect_t& drect
- = reinterpret_cast<const copybit_rect_t&>(transformedBounds);
- const State& s(mLayer.drawingState());
- region_iterator it(clip);
-
- // pick the right orientation for this buffer
- int orientation = mLayer.getOrientation();
- if (UNLIKELY(mBufferHeap.transform)) {
- Transform rot90;
- GraphicPlane::orientationToTransfrom(
- ISurfaceComposer::eOrientation90, 0, 0, &rot90);
- const Transform& planeTransform(mLayer.graphicPlane(0).transform());
- const Layer::State& s(mLayer.drawingState());
- Transform tr(planeTransform * s.transform * rot90);
- orientation = tr.getOrientation();
- }
-
- copybit->set_parameter(copybit, COPYBIT_TRANSFORM, orientation);
- copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
- copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
-
- err = copybit->stretch(copybit,
- &dst, &src.img, &drect, &src.crop, &it);
- if (err != NO_ERROR) {
- LOGE("copybit failed (%s)", strerror(err));
- }
- }
-
- if (!can_use_copybit || err) {
- if (UNLIKELY(mTextureName == -1LU)) {
- mTextureName = mLayer.createTexture();
- }
- GLuint w = 0;
- GLuint h = 0;
- GGLSurface t;
- t.version = sizeof(GGLSurface);
- t.width = src.crop.r;
- t.height = src.crop.b;
- t.stride = src.img.w;
- t.vstride= src.img.h;
- t.format = src.img.format;
- t.data = (GGLubyte*)(intptr_t(src.img.base) + src.img.offset);
- const Region dirty(Rect(t.width, t.height));
- mLayer.loadTexture(dirty, mTextureName, t, w, h);
- mLayer.drawWithOpenGL(clip, mTextureName, t, mBufferHeap.transform);
- }
-}
-
-
-// ---------------------------------------------------------------------------
-
-LayerBuffer::OverlaySource::OverlaySource(LayerBuffer& layer,
- sp<OverlayRef>* overlayRef,
- uint32_t w, uint32_t h, int32_t format)
- : Source(layer), mVisibilityChanged(false),
- mOverlay(0), mOverlayHandle(0), mOverlayDevice(0)
-{
- overlay_control_device_t* overlay_dev = mLayer.mFlinger->getOverlayEngine();
- if (overlay_dev == NULL) {
- // overlays not supported
- return;
- }
-
- mOverlayDevice = overlay_dev;
- overlay_t* overlay = overlay_dev->createOverlay(overlay_dev, w, h, format);
- if (overlay == NULL) {
- // couldn't create the overlay (no memory? no more overlays?)
- return;
- }
-
- // enable dithering...
- overlay_dev->setParameter(overlay_dev, overlay,
- OVERLAY_DITHER, OVERLAY_ENABLE);
-
- mOverlay = overlay;
- mWidth = overlay->w;
- mHeight = overlay->h;
- mFormat = overlay->format;
- mWidthStride = overlay->w_stride;
- mHeightStride = overlay->h_stride;
-
- mOverlayHandle = overlay->getHandleRef(overlay);
-
- // NOTE: here it's okay to acquire a reference to "this"m as long as
- // the reference is not released before we leave the ctor.
- sp<OverlayChannel> channel = new OverlayChannel(this);
-
- *overlayRef = new OverlayRef(mOverlayHandle, channel,
- mWidth, mHeight, mFormat, mWidthStride, mHeightStride);
-}
-
-LayerBuffer::OverlaySource::~OverlaySource()
-{
- if (mOverlay && mOverlayDevice) {
- overlay_control_device_t* overlay_dev = mOverlayDevice;
- overlay_dev->destroyOverlay(overlay_dev, mOverlay);
- }
-}
-
-void LayerBuffer::OverlaySource::onTransaction(uint32_t flags)
-{
- const Layer::State& front(mLayer.drawingState());
- const Layer::State& temp(mLayer.currentState());
- if (temp.sequence != front.sequence) {
- mVisibilityChanged = true;
- }
-}
-
-void LayerBuffer::OverlaySource::onVisibilityResolved(
- const Transform& planeTransform)
-{
- // this code-path must be as tight as possible, it's called each time
- // the screen is composited.
- if (UNLIKELY(mOverlay != 0)) {
- if (mVisibilityChanged) {
- mVisibilityChanged = false;
- const Rect& bounds = mLayer.getTransformedBounds();
- int x = bounds.left;
- int y = bounds.top;
- int w = bounds.width();
- int h = bounds.height();
-
- // we need a lock here to protect "destroy"
- Mutex::Autolock _l(mLock);
- if (mOverlay) {
- overlay_control_device_t* overlay_dev = mOverlayDevice;
- overlay_dev->setPosition(overlay_dev, mOverlay, x,y,w,h);
- overlay_dev->setParameter(overlay_dev, mOverlay,
- OVERLAY_TRANSFORM, mLayer.getOrientation());
- }
- }
- }
-}
-
-void LayerBuffer::OverlaySource::serverDestroy()
-{
- mLayer.clearSource();
- destroyOverlay();
-}
-
-void LayerBuffer::OverlaySource::destroyOverlay()
-{
- // we need a lock here to protect "onVisibilityResolved"
- Mutex::Autolock _l(mLock);
- if (mOverlay) {
- overlay_control_device_t* overlay_dev = mOverlayDevice;
- overlay_dev->destroyOverlay(overlay_dev, mOverlay);
- mOverlay = 0;
- }
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
deleted file mode 100644
index 2dc77f1..0000000
--- a/libs/surfaceflinger/LayerBuffer.h
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * 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_LAYER_BUFFER_H
-#define ANDROID_LAYER_BUFFER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/IMemory.h>
-#include <private/ui/LayerState.h>
-#include <EGL/eglnatives.h>
-
-#include "LayerBase.h"
-#include "LayerBitmap.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class MemoryDealer;
-class Region;
-class OverlayRef;
-
-class LayerBuffer : public LayerBaseClient
-{
- class Source : public LightRefBase<Source> {
- public:
- Source(LayerBuffer& layer);
- virtual ~Source();
- virtual void onDraw(const Region& clip) const;
- virtual void onTransaction(uint32_t flags);
- virtual void onVisibilityResolved(const Transform& planeTransform);
- virtual void postBuffer(ssize_t offset);
- virtual void unregisterBuffers();
- virtual bool transformed() const;
- protected:
- LayerBuffer& mLayer;
- };
-
-
-public:
- static const uint32_t typeInfo;
- static const char* const typeID;
- virtual char const* getTypeID() const { return typeID; }
- virtual uint32_t getTypeInfo() const { return typeInfo; }
-
- LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
- Client* client, int32_t i);
- virtual ~LayerBuffer();
-
- virtual bool needsBlending() const;
-
- virtual sp<LayerBaseClient::Surface> getSurface() const;
- virtual void onDraw(const Region& clip) const;
- virtual uint32_t doTransaction(uint32_t flags);
- virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
- virtual bool transformed() const;
-
- status_t registerBuffers(const ISurface::BufferHeap& buffers);
- void postBuffer(ssize_t offset);
- void unregisterBuffers();
- sp<OverlayRef> createOverlay(uint32_t w, uint32_t h, int32_t format);
-
- sp<Source> getSource() const;
- sp<Source> clearSource();
- void setNeedsBlending(bool blending);
- const Rect& getTransformedBounds() const {
- return mTransformedBounds;
- }
-
-private:
- struct NativeBuffer {
- copybit_image_t img;
- copybit_rect_t crop;
- };
-
- class Buffer : public LightRefBase<Buffer> {
- public:
- Buffer(const ISurface::BufferHeap& buffers, ssize_t offset);
- inline status_t getStatus() const {
- return mBufferHeap.heap!=0 ? NO_ERROR : NO_INIT;
- }
- inline const NativeBuffer& getBuffer() const {
- return mNativeBuffer;
- }
- protected:
- friend class LightRefBase<Buffer>;
- Buffer& operator = (const Buffer& rhs);
- Buffer(const Buffer& rhs);
- ~Buffer();
- private:
- ISurface::BufferHeap mBufferHeap;
- NativeBuffer mNativeBuffer;
- };
-
- class BufferSource : public Source {
- public:
- BufferSource(LayerBuffer& layer, const ISurface::BufferHeap& buffers);
- virtual ~BufferSource();
-
- status_t getStatus() const { return mStatus; }
- sp<Buffer> getBuffer() const;
- void setBuffer(const sp<Buffer>& buffer);
-
- virtual void onDraw(const Region& clip) const;
- virtual void postBuffer(ssize_t offset);
- virtual void unregisterBuffers();
- virtual bool transformed() const;
- private:
- mutable Mutex mLock;
- sp<Buffer> mBuffer;
- status_t mStatus;
- ISurface::BufferHeap mBufferHeap;
- size_t mBufferSize;
- mutable sp<MemoryDealer> mTemporaryDealer;
- mutable LayerBitmap mTempBitmap;
- mutable GLuint mTextureName;
- };
-
- class OverlaySource : public Source {
- public:
- OverlaySource(LayerBuffer& layer,
- sp<OverlayRef>* overlayRef,
- uint32_t w, uint32_t h, int32_t format);
- virtual ~OverlaySource();
- virtual void onTransaction(uint32_t flags);
- virtual void onVisibilityResolved(const Transform& planeTransform);
- private:
- void serverDestroy();
- void destroyOverlay();
- class OverlayChannel : public BnOverlay {
- mutable Mutex mLock;
- sp<OverlaySource> mSource;
- virtual void destroy() {
- sp<OverlaySource> source;
- { // scope for the lock;
- Mutex::Autolock _l(mLock);
- source = mSource;
- mSource.clear();
- }
- if (source != 0) {
- source->serverDestroy();
- }
- }
- public:
- OverlayChannel(const sp<OverlaySource>& source)
- : mSource(source) {
- }
- };
- friend class OverlayChannel;
- bool mVisibilityChanged;
-
- overlay_t* mOverlay;
- overlay_handle_t mOverlayHandle;
- overlay_control_device_t* mOverlayDevice;
- uint32_t mWidth;
- uint32_t mHeight;
- int32_t mFormat;
- int32_t mWidthStride;
- int32_t mHeightStride;
- mutable Mutex mLock;
- };
-
-
- class SurfaceBuffer : public LayerBaseClient::Surface
- {
- public:
- SurfaceBuffer(SurfaceID id, LayerBuffer* owner);
- virtual ~SurfaceBuffer();
- virtual status_t onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
- virtual status_t registerBuffers(const ISurface::BufferHeap& buffers);
- virtual void postBuffer(ssize_t offset);
- virtual void unregisterBuffers();
- virtual sp<OverlayRef> createOverlay(
- uint32_t w, uint32_t h, int32_t format);
- void disown();
- private:
- LayerBuffer* getOwner() const {
- Mutex::Autolock _l(mLock);
- return mOwner;
- }
- mutable Mutex mLock;
- LayerBuffer* mOwner;
- };
-
- friend class SurfaceFlinger;
- sp<SurfaceBuffer> getClientSurface() const;
-
- mutable Mutex mLock;
- sp<Source> mSource;
-
- bool mInvalidate;
- bool mNeedsBlending;
- mutable wp<SurfaceBuffer> mClientSurface;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_BUFFER_H
diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp
deleted file mode 100644
index 0c347cc..0000000
--- a/libs/surfaceflinger/LayerDim.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-#include "LayerDim.h"
-#include "SurfaceFlinger.h"
-#include "VRamHeap.h"
-#include "DisplayHardware/DisplayHardware.h"
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-const uint32_t LayerDim::typeInfo = LayerBaseClient::typeInfo | 0x10;
-const char* const LayerDim::typeID = "LayerDim";
-sp<MemoryDealer> LayerDim::mDimmerDealer;
-LayerBitmap LayerDim::mDimmerBitmap;
-
-// ---------------------------------------------------------------------------
-
-LayerDim::LayerDim(SurfaceFlinger* flinger, DisplayID display,
- Client* client, int32_t i)
- : LayerBaseClient(flinger, display, client, i)
-{
-}
-
-void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h)
-{
- // must only be called once.
- mDimmerDealer = flinger->getSurfaceHeapManager()
- ->createHeap(ISurfaceComposer::eHardware);
- if (mDimmerDealer != 0) {
- mDimmerBitmap.init(mDimmerDealer);
- mDimmerBitmap.setBits(w, h, 1, PIXEL_FORMAT_RGB_565);
- mDimmerBitmap.clear();
- }
-}
-
-LayerDim::~LayerDim()
-{
-}
-
-void LayerDim::onDraw(const Region& clip) const
-{
- const State& s(drawingState());
-
- Region::iterator iterator(clip);
- if (s.alpha>0 && iterator) {
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
-
- status_t err = NO_ERROR;
- const int can_use_copybit = canUseCopybit();
- if (can_use_copybit) {
- // StopWatch watch("copybit");
- copybit_image_t dst;
- hw.getDisplaySurface(&dst);
- const copybit_rect_t& drect
- = reinterpret_cast<const copybit_rect_t&>(mTransformedBounds);
-
- copybit_image_t src;
- mDimmerBitmap.getBitmapSurface(&src);
- const copybit_rect_t& srect(drect);
-
- copybit_device_t* copybit = mFlinger->getBlitEngine();
- copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
- copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
- copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
- region_iterator it(clip);
- err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
- }
-
- if (!can_use_copybit || err) {
- const GGLfixed alpha = (s.alpha << 16)/255;
- const uint32_t fbHeight = hw.getHeight();
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_DITHER);
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- glColor4x(0, 0, 0, alpha);
- glVertexPointer(2, GL_FIXED, 0, mVertices);
- Rect r;
- while (iterator.iterate(&r)) {
- const GLint sy = fbHeight - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
- }
- }
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/surfaceflinger/LayerDim.h b/libs/surfaceflinger/LayerDim.h
deleted file mode 100644
index 3e37a47..0000000
--- a/libs/surfaceflinger/LayerDim.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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_LAYER_DIM_H
-#define ANDROID_LAYER_DIM_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "LayerBase.h"
-#include "LayerBitmap.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class LayerDim : public LayerBaseClient
-{
-public:
- static const uint32_t typeInfo;
- static const char* const typeID;
- virtual char const* getTypeID() const { return typeID; }
- virtual uint32_t getTypeInfo() const { return typeInfo; }
-
- LayerDim(SurfaceFlinger* flinger, DisplayID display,
- Client* client, int32_t i);
- virtual ~LayerDim();
-
- virtual void onDraw(const Region& clip) const;
- virtual bool needsBlending() const { return true; }
- virtual bool isSecure() const { return false; }
-
- static void initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h);
-
-private:
- static sp<MemoryDealer> mDimmerDealer;
- static LayerBitmap mDimmerBitmap;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_DIM_H
diff --git a/libs/surfaceflinger/LayerOrientationAnim.cpp b/libs/surfaceflinger/LayerOrientationAnim.cpp
deleted file mode 100644
index 2b72d7c..0000000
--- a/libs/surfaceflinger/LayerOrientationAnim.cpp
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-#include <core/SkBitmap.h>
-
-#include <ui/EGLDisplaySurface.h>
-
-#include "LayerBase.h"
-#include "LayerOrientationAnim.h"
-#include "SurfaceFlinger.h"
-#include "DisplayHardware/DisplayHardware.h"
-#include "OrientationAnimation.h"
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-const uint32_t LayerOrientationAnim::typeInfo = LayerBase::typeInfo | 0x80;
-const char* const LayerOrientationAnim::typeID = "LayerOrientationAnim";
-
-// ---------------------------------------------------------------------------
-
-LayerOrientationAnim::LayerOrientationAnim(
- SurfaceFlinger* flinger, DisplayID display,
- OrientationAnimation* anim,
- const LayerBitmap& bitmap,
- const LayerBitmap& bitmapIn)
- : LayerBase(flinger, display), mAnim(anim),
- mBitmap(bitmap), mBitmapIn(bitmapIn),
- mTextureName(-1), mTextureNameIn(-1)
-{
- mStartTime = systemTime();
- mFinishTime = 0;
- mOrientationCompleted = false;
- mFirstRedraw = false;
- mLastNormalizedTime = 0;
- mLastScale = 0;
- mNeedsBlending = false;
-}
-
-LayerOrientationAnim::~LayerOrientationAnim()
-{
- if (mTextureName != -1U) {
- LayerBase::deletedTextures.add(mTextureName);
- }
- if (mTextureNameIn != -1U) {
- LayerBase::deletedTextures.add(mTextureNameIn);
- }
-}
-
-bool LayerOrientationAnim::needsBlending() const
-{
- return mNeedsBlending;
-}
-
-Point LayerOrientationAnim::getPhysicalSize() const
-{
- const GraphicPlane& plane(graphicPlane(0));
- const DisplayHardware& hw(plane.displayHardware());
- return Point(hw.getWidth(), hw.getHeight());
-}
-
-void LayerOrientationAnim::validateVisibility(const Transform&)
-{
- const Layer::State& s(drawingState());
- const Transform tr(s.transform);
- const Point size(getPhysicalSize());
- uint32_t w = size.x;
- uint32_t h = size.y;
- mTransformedBounds = tr.makeBounds(w, h);
- mLeft = tr.tx();
- mTop = tr.ty();
- transparentRegionScreen.clear();
- mTransformed = true;
- mCanUseCopyBit = false;
- copybit_device_t* copybit = mFlinger->getBlitEngine();
- if (copybit) {
- mCanUseCopyBit = true;
- }
-}
-
-void LayerOrientationAnim::onOrientationCompleted()
-{
- mFinishTime = systemTime();
- mOrientationCompleted = true;
- mFirstRedraw = true;
- mNeedsBlending = true;
- mFlinger->invalidateLayerVisibility(this);
-}
-
-void LayerOrientationAnim::onDraw(const Region& clip) const
-{
- // Animation...
- const float MIN_SCALE = 0.5f;
- const float DURATION = ms2ns(200);
- const float BOUNCES_PER_SECOND = 1.618f;
- const float BOUNCES_AMPLITUDE = 1.0f/32.0f;
-
- const nsecs_t now = systemTime();
- float scale, alpha;
-
- if (mOrientationCompleted) {
- if (mFirstRedraw) {
- mFirstRedraw = false;
-
- // make a copy of what's on screen
- copybit_image_t image;
- mBitmapIn.getBitmapSurface(&image);
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- hw.copyBackToImage(image);
-
- // and erase the screen for this round
- glDisable(GL_BLEND);
- glDisable(GL_DITHER);
- glDisable(GL_SCISSOR_TEST);
- glClearColor(0,0,0,0);
- glClear(GL_COLOR_BUFFER_BIT);
-
- // FIXME: code below is gross
- mNeedsBlending = false;
- LayerOrientationAnim* self(const_cast<LayerOrientationAnim*>(this));
- mFlinger->invalidateLayerVisibility(self);
- }
-
- // make sure pick-up where we left off
- const float duration = DURATION * mLastNormalizedTime;
- const float normalizedTime = (float(now - mFinishTime) / duration);
- if (normalizedTime <= 1.0f) {
- const float squaredTime = normalizedTime*normalizedTime;
- scale = (1.0f - mLastScale)*squaredTime + mLastScale;
- alpha = (1.0f - normalizedTime);
- alpha *= alpha;
- alpha *= alpha;
- } else {
- mAnim->onAnimationFinished();
- scale = 1.0f;
- alpha = 0.0f;
- }
- } else {
- const float normalizedTime = float(now - mStartTime) / DURATION;
- if (normalizedTime <= 1.0f) {
- mLastNormalizedTime = normalizedTime;
- const float squaredTime = normalizedTime*normalizedTime;
- scale = (MIN_SCALE-1.0f)*squaredTime + 1.0f;
- alpha = 1.0f;
- } else {
- mLastNormalizedTime = 1.0f;
- const float to_seconds = DURATION / seconds(1);
- const float phi = BOUNCES_PER_SECOND *
- (((normalizedTime - 1.0f) * to_seconds)*M_PI*2);
- scale = MIN_SCALE + BOUNCES_AMPLITUDE * (1.0f - cosf(phi));
- alpha = 1.0f;
- }
- mLastScale = scale;
- }
- drawScaled(scale, alpha);
-}
-
-void LayerOrientationAnim::drawScaled(float f, float alpha) const
-{
- copybit_image_t dst;
- const GraphicPlane& plane(graphicPlane(0));
- const DisplayHardware& hw(plane.displayHardware());
- hw.getDisplaySurface(&dst);
-
- // clear screen
- // TODO: with update on demand, we may be able
- // to not erase the screen at all during the animation
- if (!mOrientationCompleted) {
- glDisable(GL_BLEND);
- glDisable(GL_DITHER);
- glDisable(GL_SCISSOR_TEST);
- glClearColor(0,0,0,0);
- glClear(GL_COLOR_BUFFER_BIT);
- }
-
- const int w = dst.w*f;
- const int h = dst.h*f;
- const int xc = uint32_t(dst.w-w)/2;
- const int yc = uint32_t(dst.h-h)/2;
- const copybit_rect_t drect = { xc, yc, xc+w, yc+h };
-
- copybit_image_t src;
- mBitmap.getBitmapSurface(&src);
- const copybit_rect_t srect = { 0, 0, src.w, src.h };
-
- int err = NO_ERROR;
- const int can_use_copybit = canUseCopybit();
- if (can_use_copybit) {
- copybit_device_t* copybit = mFlinger->getBlitEngine();
- copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
- copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
-
- if (alpha < 1.0f) {
- copybit_image_t srcIn;
- mBitmapIn.getBitmapSurface(&srcIn);
- region_iterator it(Region(Rect( drect.l, drect.t, drect.r, drect.b )));
- copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
- err = copybit->stretch(copybit, &dst, &srcIn, &drect, &srect, &it);
- }
-
- if (!err && alpha > 0.0f) {
- region_iterator it(Region(Rect( drect.l, drect.t, drect.r, drect.b )));
- copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, int(alpha*255));
- err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
- }
- LOGE_IF(err != NO_ERROR, "copybit failed (%s)", strerror(err));
- }
- if (!can_use_copybit || err) {
- GGLSurface t;
- t.version = sizeof(GGLSurface);
- t.width = src.w;
- t.height = src.h;
- t.stride = src.w;
- t.vstride= src.h;
- t.format = src.format;
- t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
-
- Transform tr;
- tr.set(f,0,0,f);
- tr.set(xc, yc);
-
- // FIXME: we should not access mVertices and mDrawingState like that,
- // but since we control the animation, we know it's going to work okay.
- // eventually we'd need a more formal way of doing things like this.
- LayerOrientationAnim& self(const_cast<LayerOrientationAnim&>(*this));
- tr.transform(self.mVertices[0], 0, 0);
- tr.transform(self.mVertices[1], 0, src.h);
- tr.transform(self.mVertices[2], src.w, src.h);
- tr.transform(self.mVertices[3], src.w, 0);
- if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
- // Too slow to do this in software
- self.mDrawingState.flags |= ISurfaceComposer::eLayerFilter;
- }
-
- if (alpha < 1.0f) {
- copybit_image_t src;
- mBitmapIn.getBitmapSurface(&src);
- t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
- if (UNLIKELY(mTextureNameIn == -1LU)) {
- mTextureNameIn = createTexture();
- GLuint w=0, h=0;
- const Region dirty(Rect(t.width, t.height));
- loadTexture(dirty, mTextureNameIn, t, w, h);
- }
- self.mDrawingState.alpha = 255;
- const Region clip(Rect( drect.l, drect.t, drect.r, drect.b ));
- drawWithOpenGL(clip, mTextureName, t);
- }
-
- t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
- if (UNLIKELY(mTextureName == -1LU)) {
- mTextureName = createTexture();
- GLuint w=0, h=0;
- const Region dirty(Rect(t.width, t.height));
- loadTexture(dirty, mTextureName, t, w, h);
- }
- self.mDrawingState.alpha = int(alpha*255);
- const Region clip(Rect( drect.l, drect.t, drect.r, drect.b ));
- drawWithOpenGL(clip, mTextureName, t);
- }
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/surfaceflinger/LayerOrientationAnim.h b/libs/surfaceflinger/LayerOrientationAnim.h
deleted file mode 100644
index 73676859..0000000
--- a/libs/surfaceflinger/LayerOrientationAnim.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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_LAYER_ORIENTATION_ANIM_H
-#define ANDROID_LAYER_ORIENTATION_ANIM_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/threads.h>
-#include <utils/Parcel.h>
-
-#include "LayerBase.h"
-#include "LayerBitmap.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-class OrientationAnimation;
-
-class LayerOrientationAnim : public LayerBase
-{
-public:
- static const uint32_t typeInfo;
- static const char* const typeID;
- virtual char const* getTypeID() const { return typeID; }
- virtual uint32_t getTypeInfo() const { return typeInfo; }
-
- LayerOrientationAnim(SurfaceFlinger* flinger, DisplayID display,
- OrientationAnimation* anim,
- const LayerBitmap& zoomOut,
- const LayerBitmap& zoomIn);
- virtual ~LayerOrientationAnim();
-
- void onOrientationCompleted();
-
- virtual void onDraw(const Region& clip) const;
- virtual Point getPhysicalSize() const;
- virtual void validateVisibility(const Transform& globalTransform);
- virtual bool needsBlending() const;
- virtual bool isSecure() const { return false; }
-private:
- void drawScaled(float scale, float alpha) const;
-
- OrientationAnimation* mAnim;
- LayerBitmap mBitmap;
- LayerBitmap mBitmapIn;
- nsecs_t mStartTime;
- nsecs_t mFinishTime;
- bool mOrientationCompleted;
- mutable bool mFirstRedraw;
- mutable float mLastNormalizedTime;
- mutable float mLastScale;
- mutable GLuint mTextureName;
- mutable GLuint mTextureNameIn;
- mutable bool mNeedsBlending;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_ORIENTATION_ANIM_H
diff --git a/libs/surfaceflinger/MODULE_LICENSE_APACHE2 b/libs/surfaceflinger/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/libs/surfaceflinger/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/libs/surfaceflinger/OrientationAnimation.cpp b/libs/surfaceflinger/OrientationAnimation.cpp
deleted file mode 100644
index f6f1326..0000000
--- a/libs/surfaceflinger/OrientationAnimation.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <limits.h>
-
-#include "LayerOrientationAnim.h"
-#include "OrientationAnimation.h"
-#include "SurfaceFlinger.h"
-#include "VRamHeap.h"
-
-#include "DisplayHardware/DisplayHardware.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-OrientationAnimation::OrientationAnimation(const sp<SurfaceFlinger>& flinger)
- : mFlinger(flinger), mLayerOrientationAnim(NULL), mState(DONE)
-{
- // allocate a memory-dealer for this the first time
- mTemporaryDealer = mFlinger->getSurfaceHeapManager()->createHeap(
- ISurfaceComposer::eHardware);
-}
-
-OrientationAnimation::~OrientationAnimation()
-{
-}
-
-void OrientationAnimation::onOrientationChanged()
-{
- if (mState == DONE)
- mState = PREPARE;
-}
-
-void OrientationAnimation::onAnimationFinished()
-{
- if (mState != DONE)
- mState = FINISH;
-}
-
-bool OrientationAnimation::run_impl()
-{
- bool skip_frame;
- switch (mState) {
- default:
- case DONE:
- skip_frame = done();
- break;
- case PREPARE:
- skip_frame = prepare();
- break;
- case PHASE1:
- skip_frame = phase1();
- break;
- case PHASE2:
- skip_frame = phase2();
- break;
- case FINISH:
- skip_frame = finished();
- break;
- }
- return skip_frame;
-}
-
-bool OrientationAnimation::done()
-{
- if (mFlinger->isFrozen()) {
- // we are not allowed to draw, but pause a bit to make sure
- // apps don't end up using the whole CPU, if they depend on
- // surfaceflinger for synchronization.
- usleep(8333); // 8.3ms ~ 120fps
- return true;
- }
- return false;
-}
-
-bool OrientationAnimation::prepare()
-{
- mState = PHASE1;
-
- const GraphicPlane& plane(mFlinger->graphicPlane(0));
- const DisplayHardware& hw(plane.displayHardware());
- const uint32_t w = hw.getWidth();
- const uint32_t h = hw.getHeight();
-
- LayerBitmap bitmap;
- bitmap.init(mTemporaryDealer);
- bitmap.setBits(w, h, 1, hw.getFormat());
-
- LayerBitmap bitmapIn;
- bitmapIn.init(mTemporaryDealer);
- bitmapIn.setBits(w, h, 1, hw.getFormat());
-
- copybit_image_t front;
- bitmap.getBitmapSurface(&front);
- hw.copyFrontToImage(front);
-
- LayerOrientationAnim* l = new LayerOrientationAnim(
- mFlinger.get(), 0, this, bitmap, bitmapIn);
- l->initStates(w, h, 0);
- l->setLayer(INT_MAX-1);
- mFlinger->addLayer(l);
- mLayerOrientationAnim = l;
- return true;
-}
-
-bool OrientationAnimation::phase1()
-{
- if (mFlinger->isFrozen() == false) {
- // start phase 2
- mState = PHASE2;
- mLayerOrientationAnim->onOrientationCompleted();
- mLayerOrientationAnim->invalidate();
- return true;
-
- }
- mLayerOrientationAnim->invalidate();
- return false;
-}
-
-bool OrientationAnimation::phase2()
-{
- // do the 2nd phase of the animation
- mLayerOrientationAnim->invalidate();
- return false;
-}
-
-bool OrientationAnimation::finished()
-{
- mState = DONE;
- mFlinger->removeLayer(mLayerOrientationAnim);
- mLayerOrientationAnim = NULL;
- return true;
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/surfaceflinger/OrientationAnimation.h b/libs/surfaceflinger/OrientationAnimation.h
deleted file mode 100644
index ba33fce..0000000
--- a/libs/surfaceflinger/OrientationAnimation.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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_ORIENTATION_ANIMATION_H
-#define ANDROID_ORIENTATION_ANIMATION_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "SurfaceFlinger.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class SurfaceFlinger;
-class MemoryDealer;
-class LayerOrientationAnim;
-
-class OrientationAnimation
-{
-public:
- OrientationAnimation(const sp<SurfaceFlinger>& flinger);
- virtual ~OrientationAnimation();
-
- void onOrientationChanged();
- void onAnimationFinished();
- inline bool run() {
- if (LIKELY(mState == DONE))
- return false;
- return run_impl();
- }
-
-private:
- enum {
- DONE = 0,
- PREPARE,
- PHASE1,
- PHASE2,
- FINISH
- };
-
- bool run_impl();
- bool done();
- bool prepare();
- bool phase1();
- bool phase2();
- bool finished();
-
- sp<SurfaceFlinger> mFlinger;
- sp<MemoryDealer> mTemporaryDealer;
- LayerOrientationAnim* mLayerOrientationAnim;
- int mState;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_ORIENTATION_ANIMATION_H
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
deleted file mode 100644
index 900282a..0000000
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ /dev/null
@@ -1,1840 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <math.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-
-#include <cutils/log.h>
-#include <cutils/properties.h>
-
-#include <utils/IPCThreadState.h>
-#include <utils/IServiceManager.h>
-#include <utils/MemoryDealer.h>
-#include <utils/MemoryBase.h>
-#include <utils/String8.h>
-#include <utils/String16.h>
-#include <utils/StopWatch.h>
-
-#include <ui/PixelFormat.h>
-#include <ui/DisplayInfo.h>
-#include <ui/EGLDisplaySurface.h>
-
-#include <pixelflinger/pixelflinger.h>
-#include <GLES/gl.h>
-
-#include "clz.h"
-#include "CPUGauge.h"
-#include "Layer.h"
-#include "LayerBlur.h"
-#include "LayerBuffer.h"
-#include "LayerDim.h"
-#include "LayerBitmap.h"
-#include "LayerOrientationAnim.h"
-#include "OrientationAnimation.h"
-#include "SurfaceFlinger.h"
-#include "VRamHeap.h"
-
-#include "DisplayHardware/DisplayHardware.h"
-#include "GPUHardware/GPUHardware.h"
-
-
-#define DISPLAY_COUNT 1
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-void SurfaceFlinger::instantiate() {
- defaultServiceManager()->addService(
- String16("SurfaceFlinger"), new SurfaceFlinger());
-}
-
-void SurfaceFlinger::shutdown() {
- // we should unregister here, but not really because
- // when (if) the service manager goes away, all the services
- // it has a reference to will leave too.
-}
-
-// ---------------------------------------------------------------------------
-
-SurfaceFlinger::LayerVector::LayerVector(const SurfaceFlinger::LayerVector& rhs)
- : lookup(rhs.lookup), layers(rhs.layers)
-{
-}
-
-ssize_t SurfaceFlinger::LayerVector::indexOf(
- LayerBase* key, size_t guess) const
-{
- if (guess<size() && lookup.keyAt(guess) == key)
- return guess;
- const ssize_t i = lookup.indexOfKey(key);
- if (i>=0) {
- const size_t idx = lookup.valueAt(i);
- LOG_ASSERT(layers[idx]==key,
- "LayerVector[%p]: layers[%d]=%p, key=%p",
- this, int(idx), layers[idx], key);
- return idx;
- }
- return i;
-}
-
-ssize_t SurfaceFlinger::LayerVector::add(
- LayerBase* layer,
- Vector<LayerBase*>::compar_t cmp)
-{
- size_t count = layers.size();
- ssize_t l = 0;
- ssize_t h = count-1;
- ssize_t mid;
- LayerBase* const* a = layers.array();
- while (l <= h) {
- mid = l + (h - l)/2;
- const int c = cmp(a+mid, &layer);
- if (c == 0) { l = mid; break; }
- else if (c<0) { l = mid+1; }
- else { h = mid-1; }
- }
- size_t order = l;
- while (order<count && !cmp(&layer, a+order)) {
- order++;
- }
- count = lookup.size();
- for (size_t i=0 ; i<count ; i++) {
- if (lookup.valueAt(i) >= order) {
- lookup.editValueAt(i)++;
- }
- }
- layers.insertAt(layer, order);
- lookup.add(layer, order);
- return order;
-}
-
-ssize_t SurfaceFlinger::LayerVector::remove(LayerBase* layer)
-{
- const ssize_t keyIndex = lookup.indexOfKey(layer);
- if (keyIndex >= 0) {
- const size_t index = lookup.valueAt(keyIndex);
- LOG_ASSERT(layers[index]==layer,
- "LayerVector[%p]: layers[%u]=%p, layer=%p",
- this, int(index), layers[index], layer);
- layers.removeItemsAt(index);
- lookup.removeItemsAt(keyIndex);
- const size_t count = lookup.size();
- for (size_t i=0 ; i<count ; i++) {
- if (lookup.valueAt(i) >= size_t(index)) {
- lookup.editValueAt(i)--;
- }
- }
- return index;
- }
- return NAME_NOT_FOUND;
-}
-
-ssize_t SurfaceFlinger::LayerVector::reorder(
- LayerBase* layer,
- Vector<LayerBase*>::compar_t cmp)
-{
- // XXX: it's a little lame. but oh well...
- ssize_t err = remove(layer);
- if (err >=0)
- err = add(layer, cmp);
- return err;
-}
-
-// ---------------------------------------------------------------------------
-#if 0
-#pragma mark -
-#endif
-
-SurfaceFlinger::SurfaceFlinger()
- : BnSurfaceComposer(), Thread(false),
- mTransactionFlags(0),
- mTransactionCount(0),
- mBootTime(systemTime()),
- mLastScheduledBroadcast(NULL),
- mVisibleRegionsDirty(false),
- mDeferReleaseConsole(false),
- mFreezeDisplay(false),
- mFreezeCount(0),
- mDebugRegion(0),
- mDebugCpu(0),
- mDebugFps(0),
- mDebugBackground(0),
- mDebugNoBootAnimation(0),
- mSyncObject(),
- mDeplayedTransactionPending(0),
- mConsoleSignals(0),
- mSecureFrameBuffer(0)
-{
- init();
-}
-
-void SurfaceFlinger::init()
-{
- LOGI("SurfaceFlinger is starting");
-
- // debugging stuff...
- char value[PROPERTY_VALUE_MAX];
- property_get("debug.sf.showupdates", value, "0");
- mDebugRegion = atoi(value);
- property_get("debug.sf.showcpu", value, "0");
- mDebugCpu = atoi(value);
- property_get("debug.sf.showbackground", value, "0");
- mDebugBackground = atoi(value);
- property_get("debug.sf.showfps", value, "0");
- mDebugFps = atoi(value);
- property_get("debug.sf.nobootanimation", value, "0");
- mDebugNoBootAnimation = atoi(value);
-
- LOGI_IF(mDebugRegion, "showupdates enabled");
- LOGI_IF(mDebugCpu, "showcpu enabled");
- LOGI_IF(mDebugBackground, "showbackground enabled");
- LOGI_IF(mDebugFps, "showfps enabled");
- LOGI_IF(mDebugNoBootAnimation, "boot animation disabled");
-}
-
-SurfaceFlinger::~SurfaceFlinger()
-{
- glDeleteTextures(1, &mWormholeTexName);
- delete mOrientationAnimation;
-}
-
-copybit_device_t* SurfaceFlinger::getBlitEngine() const
-{
- return graphicPlane(0).displayHardware().getBlitEngine();
-}
-
-overlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
-{
- return graphicPlane(0).displayHardware().getOverlayEngine();
-}
-
-sp<IMemory> SurfaceFlinger::getCblk() const
-{
- return mServerCblkMemory;
-}
-
-status_t SurfaceFlinger::requestGPU(const sp<IGPUCallback>& callback,
- gpu_info_t* gpu)
-{
- IPCThreadState* ipc = IPCThreadState::self();
- const int pid = ipc->getCallingPid();
- status_t err = mGPU->request(pid, callback, gpu);
- return err;
-}
-
-status_t SurfaceFlinger::revokeGPU()
-{
- return mGPU->friendlyRevoke();
-}
-
-sp<ISurfaceFlingerClient> SurfaceFlinger::createConnection()
-{
- Mutex::Autolock _l(mStateLock);
- uint32_t token = mTokens.acquire();
-
- Client* client = new Client(token, this);
- if ((client == 0) || (client->ctrlblk == 0)) {
- mTokens.release(token);
- return 0;
- }
- status_t err = mClientsMap.add(token, client);
- if (err < 0) {
- delete client;
- mTokens.release(token);
- return 0;
- }
- sp<BClient> bclient =
- new BClient(this, token, client->controlBlockMemory());
- return bclient;
-}
-
-void SurfaceFlinger::destroyConnection(ClientID cid)
-{
- Mutex::Autolock _l(mStateLock);
- Client* const client = mClientsMap.valueFor(cid);
- if (client) {
- // free all the layers this client owns
- const Vector<LayerBaseClient*>& layers = client->getLayers();
- const size_t count = layers.size();
- for (size_t i=0 ; i<count ; i++) {
- LayerBaseClient* const layer = layers[i];
- removeLayer_l(layer);
- }
-
- // the resources associated with this client will be freed
- // during the next transaction, after these surfaces have been
- // properly removed from the screen
-
- // remove this client from our ClientID->Client mapping.
- mClientsMap.removeItem(cid);
-
- // and add it to the list of disconnected clients
- mDisconnectedClients.add(client);
-
- // request a transaction
- setTransactionFlags(eTransactionNeeded);
- }
-}
-
-const GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
-{
- LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
- const GraphicPlane& plane(mGraphicPlanes[dpy]);
- return plane;
-}
-
-GraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
-{
- return const_cast<GraphicPlane&>(
- const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
-}
-
-void SurfaceFlinger::bootFinished()
-{
- const nsecs_t now = systemTime();
- const nsecs_t duration = now - mBootTime;
- LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
- if (mBootAnimation != 0) {
- mBootAnimation->requestExit();
- mBootAnimation.clear();
- }
-}
-
-void SurfaceFlinger::onFirstRef()
-{
- run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
-
- // Wait for the main thread to be done with its initialization
- mReadyToRunBarrier.wait();
-}
-
-
-static inline uint16_t pack565(int r, int g, int b) {
- return (r<<11)|(g<<5)|b;
-}
-
-// this is defined in libGLES_CM.so
-extern ISurfaceComposer* GLES_localSurfaceManager;
-
-status_t SurfaceFlinger::readyToRun()
-{
- LOGI( "SurfaceFlinger's main thread ready to run. "
- "Initializing graphics H/W...");
-
- // create the shared control-block
- mServerHeap = new MemoryDealer(4096, MemoryDealer::READ_ONLY);
- LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
-
- mServerCblkMemory = mServerHeap->allocate(4096);
- LOGE_IF(mServerCblkMemory==0, "can't create shared control block");
-
- mServerCblk = static_cast<surface_flinger_cblk_t *>(mServerCblkMemory->pointer());
- LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
- new(mServerCblk) surface_flinger_cblk_t;
-
- // get a reference to the GPU if we have one
- mGPU = GPUFactory::getGPU();
-
- // create the surface Heap manager, which manages the heaps
- // (be it in RAM or VRAM) where surfaces are allocated
- // We give 8 MB per client.
- mSurfaceHeapManager = new SurfaceHeapManager(this, 8 << 20);
-
-
- GLES_localSurfaceManager = static_cast<ISurfaceComposer*>(this);
-
- // we only support one display currently
- int dpy = 0;
-
- {
- // initialize the main display
- GraphicPlane& plane(graphicPlane(dpy));
- DisplayHardware* const hw = new DisplayHardware(this, dpy);
- plane.setDisplayHardware(hw);
- }
-
- // initialize primary screen
- // (other display should be initialized in the same manner, but
- // asynchronously, as they could come and go. None of this is supported
- // yet).
- const GraphicPlane& plane(graphicPlane(dpy));
- const DisplayHardware& hw = plane.displayHardware();
- const uint32_t w = hw.getWidth();
- const uint32_t h = hw.getHeight();
- const uint32_t f = hw.getFormat();
- hw.makeCurrent();
-
- // initialize the shared control block
- mServerCblk->connected |= 1<<dpy;
- display_cblk_t* dcblk = mServerCblk->displays + dpy;
- memset(dcblk, 0, sizeof(display_cblk_t));
- dcblk->w = w;
- dcblk->h = h;
- dcblk->format = f;
- dcblk->orientation = ISurfaceComposer::eOrientationDefault;
- dcblk->xdpi = hw.getDpiX();
- dcblk->ydpi = hw.getDpiY();
- dcblk->fps = hw.getRefreshRate();
- dcblk->density = hw.getDensity();
- asm volatile ("":::"memory");
-
- // Initialize OpenGL|ES
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, 0);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- glPixelStorei(GL_PACK_ALIGNMENT, 4);
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnable(GL_SCISSOR_TEST);
- glShadeModel(GL_FLAT);
- glDisable(GL_DITHER);
- glDisable(GL_CULL_FACE);
-
- const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
- const uint16_t g1 = pack565(0x17,0x2f,0x17);
- const uint16_t textureData[4] = { g0, g1, g1, g0 };
- glGenTextures(1, &mWormholeTexName);
- glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
- GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData);
-
- glViewport(0, 0, w, h);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrthof(0, w, h, 0, 0, 1);
-
- LayerDim::initDimmer(this, w, h);
-
- mReadyToRunBarrier.open();
-
- /*
- * We're now ready to accept clients...
- */
-
- mOrientationAnimation = new OrientationAnimation(this);
-
- // start CPU gauge display
- if (mDebugCpu)
- mCpuGauge = new CPUGauge(this, ms2ns(500));
-
- // the boot animation!
- if (mDebugNoBootAnimation == false)
- mBootAnimation = new BootAnimation(this);
-
- return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-#if 0
-#pragma mark -
-#pragma mark Events Handler
-#endif
-
-void SurfaceFlinger::waitForEvent()
-{
- // wait for something to do
- if (UNLIKELY(isFrozen())) {
- // wait 5 seconds
- int err = mSyncObject.wait(ms2ns(5000));
- if (err != NO_ERROR) {
- if (isFrozen()) {
- // we timed out and are still frozen
- LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
- mFreezeDisplay, mFreezeCount);
- mFreezeCount = 0;
- }
- }
- } else {
- mSyncObject.wait();
- }
-}
-
-void SurfaceFlinger::signalEvent() {
- mSyncObject.open();
-}
-
-void SurfaceFlinger::signal() const {
- mSyncObject.open();
-}
-
-void SurfaceFlinger::signalDelayedEvent(nsecs_t delay)
-{
- if (android_atomic_or(1, &mDeplayedTransactionPending) == 0) {
- sp<DelayedTransaction> delayedEvent(new DelayedTransaction(this, delay));
- delayedEvent->run("DelayedeEvent", PRIORITY_URGENT_DISPLAY);
- }
-}
-
-// ----------------------------------------------------------------------------
-#if 0
-#pragma mark -
-#pragma mark Main loop
-#endif
-
-bool SurfaceFlinger::threadLoop()
-{
- waitForEvent();
-
- // check for transactions
- if (UNLIKELY(mConsoleSignals)) {
- handleConsoleEvents();
- }
-
- if (LIKELY(mTransactionCount == 0)) {
- // if we're in a global transaction, don't do anything.
- const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
- uint32_t transactionFlags = getTransactionFlags(mask);
- if (LIKELY(transactionFlags)) {
- handleTransaction(transactionFlags);
- }
- }
-
- // post surfaces (if needed)
- handlePageFlip();
-
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- if (LIKELY(hw.canDraw())) {
- // repaint the framebuffer (if needed)
- handleRepaint();
-
- // release the clients before we flip ('cause flip might block)
- unlockClients();
- executeScheduledBroadcasts();
-
- // sample the cpu gauge
- if (UNLIKELY(mDebugCpu)) {
- handleDebugCpu();
- }
-
- postFramebuffer();
- } else {
- // pretend we did the post
- unlockClients();
- executeScheduledBroadcasts();
- usleep(16667); // 60 fps period
- }
- return true;
-}
-
-void SurfaceFlinger::postFramebuffer()
-{
- const bool skip = mOrientationAnimation->run();
- if (UNLIKELY(skip)) {
- return;
- }
-
- if (!mInvalidRegion.isEmpty()) {
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
-
- if (UNLIKELY(mDebugFps)) {
- debugShowFPS();
- }
-
- hw.flip(mInvalidRegion);
-
- mInvalidRegion.clear();
-
- if (Layer::deletedTextures.size()) {
- glDeleteTextures(
- Layer::deletedTextures.size(),
- Layer::deletedTextures.array());
- Layer::deletedTextures.clear();
- }
- }
-}
-
-void SurfaceFlinger::handleConsoleEvents()
-{
- // something to do with the console
- const DisplayHardware& hw = graphicPlane(0).displayHardware();
-
- int what = android_atomic_and(0, &mConsoleSignals);
- if (what & eConsoleAcquired) {
- hw.acquireScreen();
- }
-
- if (mDeferReleaseConsole && hw.canDraw()) {
- // We got the release signal before the aquire signal
- mDeferReleaseConsole = false;
- revokeGPU();
- hw.releaseScreen();
- }
-
- if (what & eConsoleReleased) {
- if (hw.canDraw()) {
- revokeGPU();
- hw.releaseScreen();
- } else {
- mDeferReleaseConsole = true;
- }
- }
-
- mDirtyRegion.set(hw.bounds());
-}
-
-void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
-{
- Mutex::Autolock _l(mStateLock);
-
- const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
- const size_t count = currentLayers.size();
-
- /*
- * Traversal of the children
- * (perform the transaction for each of them if needed)
- */
-
- const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
- if (layersNeedTransaction) {
- for (size_t i=0 ; i<count ; i++) {
- LayerBase* const layer = currentLayers[i];
- uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
- if (!trFlags) continue;
-
- const uint32_t flags = layer->doTransaction(0);
- if (flags & Layer::eVisibleRegion)
- mVisibleRegionsDirty = true;
-
- if (flags & Layer::eRestartTransaction) {
- // restart the transaction, but back-off a little
- layer->setTransactionFlags(eTransactionNeeded);
- setTransactionFlags(eTraversalNeeded, ms2ns(8));
- }
- }
- }
-
- /*
- * Perform our own transaction if needed
- */
-
- if (transactionFlags & eTransactionNeeded) {
- if (mCurrentState.orientation != mDrawingState.orientation) {
- // the orientation has changed, recompute all visible regions
- // and invalidate everything.
-
- const int dpy = 0;
- const int orientation = mCurrentState.orientation;
- GraphicPlane& plane(graphicPlane(dpy));
- plane.setOrientation(orientation);
-
- // update the shared control block
- const DisplayHardware& hw(plane.displayHardware());
- volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
- dcblk->orientation = orientation;
- if (orientation & eOrientationSwapMask) {
- // 90 or 270 degrees orientation
- dcblk->w = hw.getHeight();
- dcblk->h = hw.getWidth();
- } else {
- dcblk->w = hw.getWidth();
- dcblk->h = hw.getHeight();
- }
-
- mVisibleRegionsDirty = true;
- mDirtyRegion.set(hw.bounds());
-
- mOrientationAnimation->onOrientationChanged();
- }
-
- if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
- // freezing or unfreezing the display -> trigger animation if needed
- mFreezeDisplay = mCurrentState.freezeDisplay;
- const nsecs_t now = systemTime();
- if (mFreezeDisplay) {
- mFreezeDisplayTime = now;
- } else {
- //LOGD("Screen was frozen for %llu us",
- // ns2us(now-mFreezeDisplayTime));
- }
- }
-
- // some layers might have been removed, so
- // we need to update the regions they're exposing.
- size_t c = mRemovedLayers.size();
- if (c) {
- mVisibleRegionsDirty = true;
- }
-
- const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
- if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
- // layers have been added
- mVisibleRegionsDirty = true;
- }
-
- // get rid of all resources we don't need anymore
- // (layers and clients)
- free_resources_l();
- }
-
- commitTransaction();
-}
-
-sp<FreezeLock> SurfaceFlinger::getFreezeLock() const
-{
- return new FreezeLock(const_cast<SurfaceFlinger *>(this));
-}
-
-void SurfaceFlinger::computeVisibleRegions(
- LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
-{
- const GraphicPlane& plane(graphicPlane(0));
- const Transform& planeTransform(plane.transform());
-
- Region aboveOpaqueLayers;
- Region aboveCoveredLayers;
- Region dirty;
-
- bool secureFrameBuffer = false;
-
- size_t i = currentLayers.size();
- while (i--) {
- LayerBase* const layer = currentLayers[i];
- layer->validateVisibility(planeTransform);
-
- // start with the whole surface at its current location
- const Layer::State& s = layer->drawingState();
- const Rect bounds(layer->visibleBounds());
-
- // handle hidden surfaces by setting the visible region to empty
- Region opaqueRegion;
- Region visibleRegion;
- Region coveredRegion;
- if (UNLIKELY((s.flags & ISurfaceComposer::eLayerHidden) || !s.alpha)) {
- visibleRegion.clear();
- } else {
- const bool translucent = layer->needsBlending();
- visibleRegion.set(bounds);
- coveredRegion = visibleRegion;
-
- // Remove the transparent area from the visible region
- if (translucent) {
- visibleRegion.subtractSelf(layer->transparentRegionScreen);
- }
-
- // compute the opaque region
- if (s.alpha==255 && !translucent && layer->getOrientation()>=0) {
- // the opaque region is the visible region
- opaqueRegion = visibleRegion;
- }
- }
-
- // subtract the opaque region covered by the layers above us
- visibleRegion.subtractSelf(aboveOpaqueLayers);
- coveredRegion.andSelf(aboveCoveredLayers);
-
- // compute this layer's dirty region
- if (layer->contentDirty) {
- // we need to invalidate the whole region
- dirty = visibleRegion;
- // as well, as the old visible region
- dirty.orSelf(layer->visibleRegionScreen);
- layer->contentDirty = false;
- } else {
- // compute the exposed region
- // dirty = what's visible now - what's wasn't covered before
- // = what's visible now & what's was covered before
- dirty = visibleRegion.intersect(layer->coveredRegionScreen);
- }
- dirty.subtractSelf(aboveOpaqueLayers);
-
- // accumulate to the screen dirty region
- dirtyRegion.orSelf(dirty);
-
- // updade aboveOpaqueLayers/aboveCoveredLayers for next (lower) layer
- aboveOpaqueLayers.orSelf(opaqueRegion);
- aboveCoveredLayers.orSelf(bounds);
-
- // Store the visible region is screen space
- layer->setVisibleRegion(visibleRegion);
- layer->setCoveredRegion(coveredRegion);
-
- // If a secure layer is partially visible, lockdown the screen!
- if (layer->isSecure() && !visibleRegion.isEmpty()) {
- secureFrameBuffer = true;
- }
- }
-
- mSecureFrameBuffer = secureFrameBuffer;
- opaqueRegion = aboveOpaqueLayers;
-}
-
-
-void SurfaceFlinger::commitTransaction()
-{
- mDrawingState = mCurrentState;
- mTransactionCV.signal();
-}
-
-void SurfaceFlinger::handlePageFlip()
-{
- bool visibleRegions = mVisibleRegionsDirty;
- LayerVector& currentLayers = const_cast<LayerVector&>(mDrawingState.layersSortedByZ);
- visibleRegions |= lockPageFlip(currentLayers);
-
- const DisplayHardware& hw = graphicPlane(0).displayHardware();
- const Region screenRegion(hw.bounds());
- if (visibleRegions) {
- Region opaqueRegion;
- computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
- mWormholeRegion = screenRegion.subtract(opaqueRegion);
- mVisibleRegionsDirty = false;
- }
-
- unlockPageFlip(currentLayers);
- mDirtyRegion.andSelf(screenRegion);
-}
-
-bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
-{
- bool recomputeVisibleRegions = false;
- size_t count = currentLayers.size();
- LayerBase* const* layers = currentLayers.array();
- for (size_t i=0 ; i<count ; i++) {
- LayerBase* const layer = layers[i];
- layer->lockPageFlip(recomputeVisibleRegions);
- }
- return recomputeVisibleRegions;
-}
-
-void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
-{
- const GraphicPlane& plane(graphicPlane(0));
- const Transform& planeTransform(plane.transform());
- size_t count = currentLayers.size();
- LayerBase* const* layers = currentLayers.array();
- for (size_t i=0 ; i<count ; i++) {
- LayerBase* const layer = layers[i];
- layer->unlockPageFlip(planeTransform, mDirtyRegion);
- }
-}
-
-void SurfaceFlinger::handleRepaint()
-{
- // set the frame buffer
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- if (UNLIKELY(mDebugRegion)) {
- debugFlashRegions();
- }
-
- // compute the invalid region
- mInvalidRegion.orSelf(mDirtyRegion);
-
- uint32_t flags = hw.getFlags();
- if (flags & DisplayHardware::BUFFER_PRESERVED) {
- // here we assume DisplayHardware::flip()'s implementation
- // performs the copy-back optimization.
- } else {
- if (flags & DisplayHardware::UPDATE_ON_DEMAND) {
- // we need to fully redraw the part that will be updated
- mDirtyRegion.set(mInvalidRegion.bounds());
- } else {
- // we need to redraw everything
- mDirtyRegion.set(hw.bounds());
- mInvalidRegion = mDirtyRegion;
- }
- }
-
- // compose all surfaces
- composeSurfaces(mDirtyRegion);
-
- // clear the dirty regions
- mDirtyRegion.clear();
-}
-
-void SurfaceFlinger::composeSurfaces(const Region& dirty)
-{
- if (UNLIKELY(!mWormholeRegion.isEmpty())) {
- // should never happen unless the window manager has a bug
- // draw something...
- drawWormhole();
- }
- const SurfaceFlinger& flinger(*this);
- const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
- const size_t count = drawingLayers.size();
- LayerBase const* const* const layers = drawingLayers.array();
- for (size_t i=0 ; i<count ; ++i) {
- LayerBase const * const layer = layers[i];
- const Region& visibleRegion(layer->visibleRegionScreen);
- if (!visibleRegion.isEmpty()) {
- const Region clip(dirty.intersect(visibleRegion));
- if (!clip.isEmpty()) {
- layer->draw(clip);
- }
- }
- }
-}
-
-void SurfaceFlinger::unlockClients()
-{
- const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
- const size_t count = drawingLayers.size();
- LayerBase* const* const layers = drawingLayers.array();
- for (size_t i=0 ; i<count ; ++i) {
- LayerBase* const layer = layers[i];
- layer->finishPageFlip();
- }
-}
-
-void SurfaceFlinger::scheduleBroadcast(Client* client)
-{
- if (mLastScheduledBroadcast != client) {
- mLastScheduledBroadcast = client;
- mScheduledBroadcasts.add(client);
- }
-}
-
-void SurfaceFlinger::executeScheduledBroadcasts()
-{
- SortedVector<Client*>& list = mScheduledBroadcasts;
- size_t count = list.size();
- while (count--) {
- per_client_cblk_t* const cblk = list[count]->ctrlblk;
- if (cblk->lock.tryLock() == NO_ERROR) {
- cblk->cv.broadcast();
- list.removeAt(count);
- cblk->lock.unlock();
- } else {
- // schedule another round
- LOGW("executeScheduledBroadcasts() skipped, "
- "contention on the client. We'll try again later...");
- signalDelayedEvent(ms2ns(4));
- }
- }
- mLastScheduledBroadcast = 0;
-}
-
-void SurfaceFlinger::handleDebugCpu()
-{
- Mutex::Autolock _l(mDebugLock);
- if (mCpuGauge != 0)
- mCpuGauge->sample();
-}
-
-void SurfaceFlinger::debugFlashRegions()
-{
- if (UNLIKELY(!mDirtyRegion.isRect())) {
- // TODO: do this only if we don't have preserving
- // swapBuffer. If we don't have update-on-demand,
- // redraw everything.
- composeSurfaces(Region(mDirtyRegion.bounds()));
- }
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
- glDisable(GL_DITHER);
- glDisable(GL_SCISSOR_TEST);
-
- glColor4x(0x10000, 0, 0x10000, 0x10000);
-
- Rect r;
- Region::iterator iterator(mDirtyRegion);
- while (iterator.iterate(&r)) {
- GLfloat vertices[][2] = {
- { r.left, r.top },
- { r.left, r.bottom },
- { r.right, r.bottom },
- { r.right, r.top }
- };
- glVertexPointer(2, GL_FLOAT, 0, vertices);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
-
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- hw.flip(mDirtyRegion.merge(mInvalidRegion));
- mInvalidRegion.clear();
-
- if (mDebugRegion > 1)
- usleep(mDebugRegion * 1000);
-
- glEnable(GL_SCISSOR_TEST);
- //mDirtyRegion.dump("mDirtyRegion");
-}
-
-void SurfaceFlinger::drawWormhole() const
-{
- const Region region(mWormholeRegion.intersect(mDirtyRegion));
- if (region.isEmpty())
- return;
-
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- const int32_t width = hw.getWidth();
- const int32_t height = hw.getHeight();
-
- glDisable(GL_BLEND);
- glDisable(GL_DITHER);
-
- if (LIKELY(!mDebugBackground)) {
- glClearColorx(0,0,0,0);
- Rect r;
- Region::iterator iterator(region);
- while (iterator.iterate(&r)) {
- const GLint sy = height - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glClear(GL_COLOR_BUFFER_BIT);
- }
- } else {
- const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
- { width, height }, { 0, height } };
- const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } };
- glVertexPointer(2, GL_SHORT, 0, vertices);
- glTexCoordPointer(2, GL_SHORT, 0, tcoords);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
- glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
- Rect r;
- Region::iterator iterator(region);
- while (iterator.iterate(&r)) {
- const GLint sy = height - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- }
-}
-
-void SurfaceFlinger::debugShowFPS() const
-{
- static int mFrameCount;
- static int mLastFrameCount = 0;
- static nsecs_t mLastFpsTime = 0;
- static float mFps = 0;
- mFrameCount++;
- nsecs_t now = systemTime();
- nsecs_t diff = now - mLastFpsTime;
- if (diff > ms2ns(250)) {
- mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
- mLastFpsTime = now;
- mLastFrameCount = mFrameCount;
- }
- // XXX: mFPS has the value we want
- }
-
-status_t SurfaceFlinger::addLayer(LayerBase* layer)
-{
- Mutex::Autolock _l(mStateLock);
- addLayer_l(layer);
- setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
- return NO_ERROR;
-}
-
-status_t SurfaceFlinger::removeLayer(LayerBase* layer)
-{
- Mutex::Autolock _l(mStateLock);
- removeLayer_l(layer);
- setTransactionFlags(eTransactionNeeded);
- return NO_ERROR;
-}
-
-status_t SurfaceFlinger::invalidateLayerVisibility(LayerBase* layer)
-{
- layer->forceVisibilityTransaction();
- setTransactionFlags(eTraversalNeeded);
- return NO_ERROR;
-}
-
-status_t SurfaceFlinger::addLayer_l(LayerBase* layer)
-{
- ssize_t i = mCurrentState.layersSortedByZ.add(
- layer, &LayerBase::compareCurrentStateZ);
- LayerBaseClient* lbc = LayerBase::dynamicCast<LayerBaseClient*>(layer);
- if (lbc) {
- mLayerMap.add(lbc->serverIndex(), lbc);
- }
- mRemovedLayers.remove(layer);
- return NO_ERROR;
-}
-
-status_t SurfaceFlinger::removeLayer_l(LayerBase* layerBase)
-{
- ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
- if (index >= 0) {
- mRemovedLayers.add(layerBase);
- LayerBaseClient* layer = LayerBase::dynamicCast<LayerBaseClient*>(layerBase);
- if (layer) {
- mLayerMap.removeItem(layer->serverIndex());
- }
- return NO_ERROR;
- }
- // it's possible that we don't find a layer, because it might
- // have been destroyed already -- this is not technically an error
- // from the user because there is a race between destroySurface,
- // destroyclient and destroySurface-from-a-transaction.
- return (index == NAME_NOT_FOUND) ? status_t(NO_ERROR) : index;
-}
-
-void SurfaceFlinger::free_resources_l()
-{
- // Destroy layers that were removed
- destroy_all_removed_layers_l();
-
- // free resources associated with disconnected clients
- SortedVector<Client*>& scheduledBroadcasts(mScheduledBroadcasts);
- Vector<Client*>& disconnectedClients(mDisconnectedClients);
- const size_t count = disconnectedClients.size();
- for (size_t i=0 ; i<count ; i++) {
- Client* client = disconnectedClients[i];
- // if this client is the scheduled broadcast list,
- // remove it from there (and we don't need to signal it
- // since it is dead).
- int32_t index = scheduledBroadcasts.indexOf(client);
- if (index >= 0) {
- scheduledBroadcasts.removeItemsAt(index);
- }
- mTokens.release(client->cid);
- delete client;
- }
- disconnectedClients.clear();
-}
-
-void SurfaceFlinger::destroy_all_removed_layers_l()
-{
- size_t c = mRemovedLayers.size();
- while (c--) {
- LayerBase* const removed_layer = mRemovedLayers[c];
-
- LOGE_IF(mCurrentState.layersSortedByZ.indexOf(removed_layer) >= 0,
- "layer %p removed but still in the current state list",
- removed_layer);
-
- delete removed_layer;
- }
- mRemovedLayers.clear();
-}
-
-
-uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
-{
- return android_atomic_and(~flags, &mTransactionFlags) & flags;
-}
-
-uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags, nsecs_t delay)
-{
- uint32_t old = android_atomic_or(flags, &mTransactionFlags);
- if ((old & flags)==0) { // wake the server up
- if (delay > 0) {
- signalDelayedEvent(delay);
- } else {
- signalEvent();
- }
- }
- return old;
-}
-
-void SurfaceFlinger::openGlobalTransaction()
-{
- android_atomic_inc(&mTransactionCount);
-}
-
-void SurfaceFlinger::closeGlobalTransaction()
-{
- if (android_atomic_dec(&mTransactionCount) == 1) {
- signalEvent();
- }
-}
-
-status_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
-{
- if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
- return BAD_VALUE;
-
- Mutex::Autolock _l(mStateLock);
- mCurrentState.freezeDisplay = 1;
- setTransactionFlags(eTransactionNeeded);
-
- // flags is intended to communicate some sort of animation behavior
- // (for instance fadding)
- return NO_ERROR;
-}
-
-status_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
-{
- if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
- return BAD_VALUE;
-
- Mutex::Autolock _l(mStateLock);
- mCurrentState.freezeDisplay = 0;
- setTransactionFlags(eTransactionNeeded);
-
- // flags is intended to communicate some sort of animation behavior
- // (for instance fadding)
- return NO_ERROR;
-}
-
-int SurfaceFlinger::setOrientation(DisplayID dpy, int orientation)
-{
- if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
- return BAD_VALUE;
-
- Mutex::Autolock _l(mStateLock);
- if (mCurrentState.orientation != orientation) {
- if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
- mCurrentState.orientation = orientation;
- setTransactionFlags(eTransactionNeeded);
- mTransactionCV.wait(mStateLock);
- } else {
- orientation = BAD_VALUE;
- }
- }
- return orientation;
-}
-
-sp<ISurface> SurfaceFlinger::createSurface(ClientID clientId, int pid,
- ISurfaceFlingerClient::surface_data_t* params,
- DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
- uint32_t flags)
-{
- LayerBaseClient* layer = 0;
- sp<LayerBaseClient::Surface> surfaceHandle;
- Mutex::Autolock _l(mStateLock);
- Client* const c = mClientsMap.valueFor(clientId);
- if (UNLIKELY(!c)) {
- LOGE("createSurface() failed, client not found (id=%d)", clientId);
- return surfaceHandle;
- }
-
- //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
- int32_t id = c->generateId(pid);
- if (uint32_t(id) >= NUM_LAYERS_MAX) {
- LOGE("createSurface() failed, generateId = %d", id);
- return surfaceHandle;
- }
-
- switch (flags & eFXSurfaceMask) {
- case eFXSurfaceNormal:
- if (UNLIKELY(flags & ePushBuffers)) {
- layer = createPushBuffersSurfaceLocked(c, d, id, w, h, flags);
- } else {
- layer = createNormalSurfaceLocked(c, d, id, w, h, format, flags);
- }
- break;
- case eFXSurfaceBlur:
- layer = createBlurSurfaceLocked(c, d, id, w, h, flags);
- break;
- case eFXSurfaceDim:
- layer = createDimSurfaceLocked(c, d, id, w, h, flags);
- break;
- }
-
- if (layer) {
- setTransactionFlags(eTransactionNeeded);
- surfaceHandle = layer->getSurface();
- if (surfaceHandle != 0)
- surfaceHandle->getSurfaceData(params);
- }
-
- return surfaceHandle;
-}
-
-LayerBaseClient* SurfaceFlinger::createNormalSurfaceLocked(
- Client* client, DisplayID display,
- int32_t id, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
-{
- // initialize the surfaces
- switch (format) { // TODO: take h/w into account
- case PIXEL_FORMAT_TRANSPARENT:
- case PIXEL_FORMAT_TRANSLUCENT:
- format = PIXEL_FORMAT_RGBA_8888;
- break;
- case PIXEL_FORMAT_OPAQUE:
- format = PIXEL_FORMAT_RGB_565;
- break;
- }
-
- Layer* layer = new Layer(this, display, client, id);
- status_t err = layer->setBuffers(client, w, h, format, flags);
- if (LIKELY(err == NO_ERROR)) {
- layer->initStates(w, h, flags);
- addLayer_l(layer);
- } else {
- LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
- delete layer;
- return 0;
- }
- return layer;
-}
-
-LayerBaseClient* SurfaceFlinger::createBlurSurfaceLocked(
- Client* client, DisplayID display,
- int32_t id, uint32_t w, uint32_t h, uint32_t flags)
-{
- LayerBlur* layer = new LayerBlur(this, display, client, id);
- layer->initStates(w, h, flags);
- addLayer_l(layer);
- return layer;
-}
-
-LayerBaseClient* SurfaceFlinger::createDimSurfaceLocked(
- Client* client, DisplayID display,
- int32_t id, uint32_t w, uint32_t h, uint32_t flags)
-{
- LayerDim* layer = new LayerDim(this, display, client, id);
- layer->initStates(w, h, flags);
- addLayer_l(layer);
- return layer;
-}
-
-LayerBaseClient* SurfaceFlinger::createPushBuffersSurfaceLocked(
- Client* client, DisplayID display,
- int32_t id, uint32_t w, uint32_t h, uint32_t flags)
-{
- LayerBuffer* layer = new LayerBuffer(this, display, client, id);
- layer->initStates(w, h, flags);
- addLayer_l(layer);
- return layer;
-}
-
-status_t SurfaceFlinger::destroySurface(SurfaceID index)
-{
- Mutex::Autolock _l(mStateLock);
- LayerBaseClient* const layer = getLayerUser_l(index);
- status_t err = removeLayer_l(layer);
- if (err < 0)
- return err;
- setTransactionFlags(eTransactionNeeded);
- return NO_ERROR;
-}
-
-status_t SurfaceFlinger::setClientState(
- ClientID cid,
- int32_t count,
- const layer_state_t* states)
-{
- Mutex::Autolock _l(mStateLock);
- uint32_t flags = 0;
- cid <<= 16;
- for (int i=0 ; i<count ; i++) {
- const layer_state_t& s = states[i];
- LayerBaseClient* layer = getLayerUser_l(s.surface | cid);
- if (layer) {
- const uint32_t what = s.what;
- // check if it has been destroyed first
- if (what & eDestroyed) {
- if (removeLayer_l(layer) == NO_ERROR) {
- flags |= eTransactionNeeded;
- // we skip everything else... well, no, not really
- // we skip ONLY that transaction.
- continue;
- }
- }
- if (what & ePositionChanged) {
- if (layer->setPosition(s.x, s.y))
- flags |= eTraversalNeeded;
- }
- if (what & eLayerChanged) {
- if (layer->setLayer(s.z)) {
- mCurrentState.layersSortedByZ.reorder(
- layer, &Layer::compareCurrentStateZ);
- // we need traversal (state changed)
- // AND transaction (list changed)
- flags |= eTransactionNeeded|eTraversalNeeded;
- }
- }
- if (what & eSizeChanged) {
- if (layer->setSize(s.w, s.h))
- flags |= eTraversalNeeded;
- }
- if (what & eAlphaChanged) {
- if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
- flags |= eTraversalNeeded;
- }
- if (what & eMatrixChanged) {
- if (layer->setMatrix(s.matrix))
- flags |= eTraversalNeeded;
- }
- if (what & eTransparentRegionChanged) {
- if (layer->setTransparentRegionHint(s.transparentRegion))
- flags |= eTraversalNeeded;
- }
- if (what & eVisibilityChanged) {
- if (layer->setFlags(s.flags, s.mask))
- flags |= eTraversalNeeded;
- }
- }
- }
- if (flags) {
- setTransactionFlags(flags);
- }
- return NO_ERROR;
-}
-
-LayerBaseClient* SurfaceFlinger::getLayerUser_l(SurfaceID s) const
-{
- return mLayerMap.valueFor(s);
-}
-
-void SurfaceFlinger::screenReleased(int dpy)
-{
- // this may be called by a signal handler, we can't do too much in here
- android_atomic_or(eConsoleReleased, &mConsoleSignals);
- signalEvent();
-}
-
-void SurfaceFlinger::screenAcquired(int dpy)
-{
- // this may be called by a signal handler, we can't do too much in here
- android_atomic_or(eConsoleAcquired, &mConsoleSignals);
- signalEvent();
-}
-
-status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
-{
- const size_t SIZE = 1024;
- char buffer[SIZE];
- String8 result;
- if (checkCallingPermission(
- String16("android.permission.DUMP")) == false)
- { // not allowed
- snprintf(buffer, SIZE, "Permission Denial: "
- "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
- IPCThreadState::self()->getCallingPid(),
- IPCThreadState::self()->getCallingUid());
- result.append(buffer);
- } else {
- Mutex::Autolock _l(mStateLock);
- size_t s = mClientsMap.size();
- char name[64];
- for (size_t i=0 ; i<s ; i++) {
- Client* client = mClientsMap.valueAt(i);
- sprintf(name, " Client (id=0x%08x)", client->cid);
- client->dump(name);
- }
- const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
- const size_t count = currentLayers.size();
- for (size_t i=0 ; i<count ; i++) {
- /*** LayerBase ***/
- LayerBase const * const layer = currentLayers[i];
- const Layer::State& s = layer->drawingState();
- snprintf(buffer, SIZE,
- "+ %s %p\n"
- " "
- "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), "
- "needsBlending=%1d, invalidate=%1d, "
- "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
- layer->getTypeID(), layer,
- s.z, layer->tx(), layer->ty(), s.w, s.h,
- layer->needsBlending(), layer->contentDirty,
- s.alpha, s.flags,
- s.transform[0], s.transform[1],
- s.transform[2], s.transform[3]);
- result.append(buffer);
- buffer[0] = 0;
- /*** LayerBaseClient ***/
- LayerBaseClient* const lbc =
- LayerBase::dynamicCast<LayerBaseClient*>((LayerBase*)layer);
- if (lbc) {
- snprintf(buffer, SIZE,
- " "
- "id=0x%08x, client=0x%08x, identity=%u\n",
- lbc->clientIndex(), lbc->client ? lbc->client->cid : 0,
- lbc->getIdentity());
- }
- result.append(buffer);
- buffer[0] = 0;
- /*** Layer ***/
- Layer* const l = LayerBase::dynamicCast<Layer*>((LayerBase*)layer);
- if (l) {
- const LayerBitmap& buf0(l->getBuffer(0));
- const LayerBitmap& buf1(l->getBuffer(1));
- snprintf(buffer, SIZE,
- " "
- "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u], mTextureName=%d,"
- " freezeLock=%p, swapState=0x%08x\n",
- l->pixelFormat(),
- buf0.width(), buf0.height(), buf0.stride(),
- buf1.width(), buf1.height(), buf1.stride(),
- l->getTextureName(), l->getFreezeLock().get(),
- l->lcblk->swapState);
- }
- result.append(buffer);
- buffer[0] = 0;
- s.transparentRegion.dump(result, "transparentRegion");
- layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
- layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
- }
- mWormholeRegion.dump(result, "WormholeRegion");
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- snprintf(buffer, SIZE,
- " display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
- mFreezeDisplay?"yes":"no", mFreezeCount,
- mCurrentState.orientation, hw.canDraw());
- result.append(buffer);
-
- sp<AllocatorInterface> allocator;
- if (mGPU != 0) {
- snprintf(buffer, SIZE, " GPU owner: %d\n", mGPU->getOwner());
- result.append(buffer);
- allocator = mGPU->getAllocator();
- if (allocator != 0) {
- allocator->dump(result, "GPU Allocator");
- }
- }
- allocator = mSurfaceHeapManager->getAllocator(NATIVE_MEMORY_TYPE_PMEM);
- if (allocator != 0) {
- allocator->dump(result, "PMEM Allocator");
- }
- }
- write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-status_t SurfaceFlinger::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch (code) {
- case CREATE_CONNECTION:
- case OPEN_GLOBAL_TRANSACTION:
- case CLOSE_GLOBAL_TRANSACTION:
- case SET_ORIENTATION:
- case FREEZE_DISPLAY:
- case UNFREEZE_DISPLAY:
- case BOOT_FINISHED:
- case REVOKE_GPU:
- {
- // codes that require permission check
- IPCThreadState* ipc = IPCThreadState::self();
- const int pid = ipc->getCallingPid();
- const int self_pid = getpid();
- if (UNLIKELY(pid != self_pid)) {
- // we're called from a different process, do the real check
- if (!checkCallingPermission(
- String16("android.permission.ACCESS_SURFACE_FLINGER")))
- {
- const int uid = ipc->getCallingUid();
- LOGE("Permission Denial: "
- "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
- return PERMISSION_DENIED;
- }
- }
- }
- }
-
- status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
- if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
- // HARDWARE_TEST stuff...
- if (UNLIKELY(checkCallingPermission(
- String16("android.permission.HARDWARE_TEST")) == false))
- { // not allowed
- LOGE("Permission Denial: pid=%d, uid=%d\n",
- IPCThreadState::self()->getCallingPid(),
- IPCThreadState::self()->getCallingUid());
- return PERMISSION_DENIED;
- }
- int n;
- switch (code) {
- case 1000: // SHOW_CPU
- n = data.readInt32();
- mDebugCpu = n ? 1 : 0;
- if (mDebugCpu) {
- if (mCpuGauge == 0) {
- mCpuGauge = new CPUGauge(this, ms2ns(500));
- }
- } else {
- if (mCpuGauge != 0) {
- mCpuGauge->requestExitAndWait();
- Mutex::Autolock _l(mDebugLock);
- mCpuGauge.clear();
- }
- }
- return NO_ERROR;
- case 1001: // SHOW_FPS
- n = data.readInt32();
- mDebugFps = n ? 1 : 0;
- return NO_ERROR;
- case 1002: // SHOW_UPDATES
- n = data.readInt32();
- mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
- return NO_ERROR;
- case 1003: // SHOW_BACKGROUND
- n = data.readInt32();
- mDebugBackground = n ? 1 : 0;
- return NO_ERROR;
- case 1004:{ // repaint everything
- Mutex::Autolock _l(mStateLock);
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
- signalEvent();
- }
- return NO_ERROR;
- case 1005: // ask GPU revoke
- mGPU->friendlyRevoke();
- return NO_ERROR;
- case 1006: // revoke GPU
- mGPU->unconditionalRevoke();
- return NO_ERROR;
- case 1007: // set mFreezeCount
- mFreezeCount = data.readInt32();
- return NO_ERROR;
- case 1010: // interrogate.
- reply->writeInt32(mDebugCpu);
- reply->writeInt32(0);
- reply->writeInt32(mDebugRegion);
- reply->writeInt32(mDebugBackground);
- return NO_ERROR;
- case 1013: {
- Mutex::Autolock _l(mStateLock);
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- reply->writeInt32(hw.getPageFlipCount());
- }
- return NO_ERROR;
- }
- }
- return err;
-}
-
-// ---------------------------------------------------------------------------
-#if 0
-#pragma mark -
-#endif
-
-Client::Client(ClientID clientID, const sp<SurfaceFlinger>& flinger)
- : ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger)
-{
- mSharedHeapAllocator = getSurfaceHeapManager()->createHeap();
- const int pgsize = getpagesize();
- const int cblksize=((sizeof(per_client_cblk_t)+(pgsize-1))&~(pgsize-1));
- mCblkHeap = new MemoryDealer(cblksize);
- mCblkMemory = mCblkHeap->allocate(cblksize);
- if (mCblkMemory != 0) {
- ctrlblk = static_cast<per_client_cblk_t *>(mCblkMemory->pointer());
- if (ctrlblk) { // construct the shared structure in-place.
- new(ctrlblk) per_client_cblk_t;
- }
- }
-}
-
-Client::~Client() {
- if (ctrlblk) {
- const int pgsize = getpagesize();
- ctrlblk->~per_client_cblk_t(); // destroy our shared-structure.
- }
-}
-
-const sp<SurfaceHeapManager>& Client::getSurfaceHeapManager() const {
- return mFlinger->getSurfaceHeapManager();
-}
-
-int32_t Client::generateId(int pid)
-{
- const uint32_t i = clz( ~mBitmap );
- if (i >= NUM_LAYERS_MAX) {
- return NO_MEMORY;
- }
- mPid = pid;
- mInUse.add(uint8_t(i));
- mBitmap |= 1<<(31-i);
- return i;
-}
-status_t Client::bindLayer(LayerBaseClient* layer, int32_t id)
-{
- ssize_t idx = mInUse.indexOf(id);
- if (idx < 0)
- return NAME_NOT_FOUND;
- return mLayers.insertAt(layer, idx);
-}
-void Client::free(int32_t id)
-{
- ssize_t idx = mInUse.remove(uint8_t(id));
- if (idx >= 0) {
- mBitmap &= ~(1<<(31-id));
- mLayers.removeItemsAt(idx);
- }
-}
-
-sp<MemoryDealer> Client::createAllocator(uint32_t flags)
-{
- sp<MemoryDealer> allocator;
- allocator = getSurfaceHeapManager()->createHeap(
- flags, getClientPid(), mSharedHeapAllocator);
- return allocator;
-}
-
-bool Client::isValid(int32_t i) const {
- return (uint32_t(i)<NUM_LAYERS_MAX) && (mBitmap & (1<<(31-i)));
-}
-const uint8_t* Client::inUseArray() const {
- return mInUse.array();
-}
-size_t Client::numActiveLayers() const {
- return mInUse.size();
-}
-LayerBaseClient* Client::getLayerUser(int32_t i) const {
- ssize_t idx = mInUse.indexOf(uint8_t(i));
- if (idx<0) return 0;
- return mLayers[idx];
-}
-
-void Client::dump(const char* what)
-{
-}
-
-// ---------------------------------------------------------------------------
-#if 0
-#pragma mark -
-#endif
-
-BClient::BClient(SurfaceFlinger *flinger, ClientID cid, const sp<IMemory>& cblk)
- : mId(cid), mFlinger(flinger), mCblk(cblk)
-{
-}
-
-BClient::~BClient() {
- // destroy all resources attached to this client
- mFlinger->destroyConnection(mId);
-}
-
-void BClient::getControlBlocks(sp<IMemory>* ctrl) const {
- *ctrl = mCblk;
-}
-
-sp<ISurface> BClient::createSurface(
- ISurfaceFlingerClient::surface_data_t* params, int pid,
- DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
- uint32_t flags)
-{
- return mFlinger->createSurface(mId, pid, params, display, w, h, format, flags);
-}
-
-status_t BClient::destroySurface(SurfaceID sid)
-{
- sid |= (mId << 16); // add the client-part to id
- return mFlinger->destroySurface(sid);
-}
-
-status_t BClient::setState(int32_t count, const layer_state_t* states)
-{
- return mFlinger->setClientState(mId, count, states);
-}
-
-// ---------------------------------------------------------------------------
-
-GraphicPlane::GraphicPlane()
- : mHw(0)
-{
-}
-
-GraphicPlane::~GraphicPlane() {
- delete mHw;
-}
-
-bool GraphicPlane::initialized() const {
- return mHw ? true : false;
-}
-
-void GraphicPlane::setDisplayHardware(DisplayHardware *hw) {
- mHw = hw;
-}
-
-void GraphicPlane::setTransform(const Transform& tr) {
- mTransform = tr;
- mGlobalTransform = mOrientationTransform * mTransform;
-}
-
-status_t GraphicPlane::orientationToTransfrom(
- int orientation, int w, int h, Transform* tr)
-{
- float a, b, c, d, x, y;
- switch (orientation) {
- case ISurfaceComposer::eOrientationDefault:
- a=1; b=0; c=0; d=1; x=0; y=0;
- break;
- case ISurfaceComposer::eOrientation90:
- a=0; b=-1; c=1; d=0; x=w; y=0;
- break;
- case ISurfaceComposer::eOrientation180:
- a=-1; b=0; c=0; d=-1; x=w; y=h;
- break;
- case ISurfaceComposer::eOrientation270:
- a=0; b=1; c=-1; d=0; x=0; y=h;
- break;
- default:
- return BAD_VALUE;
- }
- tr->set(a, b, c, d);
- tr->set(x, y);
- return NO_ERROR;
-}
-
-status_t GraphicPlane::setOrientation(int orientation)
-{
- const DisplayHardware& hw(displayHardware());
- const float w = hw.getWidth();
- const float h = hw.getHeight();
-
- if (orientation == ISurfaceComposer::eOrientationDefault) {
- // make sure the default orientation is optimal
- mOrientationTransform.reset();
- mGlobalTransform = mTransform;
- return NO_ERROR;
- }
-
- // If the rotation can be handled in hardware, this is where
- // the magic should happen.
- if (UNLIKELY(orientation == 42)) {
- float a, b, c, d, x, y;
- const float r = (3.14159265f / 180.0f) * 42.0f;
- const float si = sinf(r);
- const float co = cosf(r);
- a=co; b=-si; c=si; d=co;
- x = si*(h*0.5f) + (1-co)*(w*0.5f);
- y =-si*(w*0.5f) + (1-co)*(h*0.5f);
- mOrientationTransform.set(a, b, c, d);
- mOrientationTransform.set(x, y);
- } else {
- GraphicPlane::orientationToTransfrom(orientation, w, h,
- &mOrientationTransform);
- }
-
- mGlobalTransform = mOrientationTransform * mTransform;
- return NO_ERROR;
-}
-
-const DisplayHardware& GraphicPlane::displayHardware() const {
- return *mHw;
-}
-
-const Transform& GraphicPlane::transform() const {
- return mGlobalTransform;
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
deleted file mode 100644
index f7d7764..0000000
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * 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_SURFACE_FLINGER_H
-#define ANDROID_SURFACE_FLINGER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/SortedVector.h>
-#include <utils/KeyedVector.h>
-#include <utils/threads.h>
-#include <utils/Atomic.h>
-#include <utils/Errors.h>
-#include <utils/MemoryDealer.h>
-
-#include <ui/PixelFormat.h>
-#include <ui/ISurfaceComposer.h>
-#include <ui/ISurfaceFlingerClient.h>
-
-#include <private/ui/SharedState.h>
-#include <private/ui/LayerState.h>
-#include <private/ui/SurfaceFlingerSynchro.h>
-
-#include "Barrier.h"
-#include "BootAnimation.h"
-#include "CPUGauge.h"
-#include "Layer.h"
-#include "Tokenizer.h"
-
-struct copybit_device_t;
-struct overlay_device_t;
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class Client;
-class BClient;
-class DisplayHardware;
-class FreezeLock;
-class GPUHardwareInterface;
-class IGPUCallback;
-class Layer;
-class LayerBuffer;
-class LayerOrientationAnim;
-class OrientationAnimation;
-class SurfaceHeapManager;
-
-typedef int32_t ClientID;
-
-#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
-#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
-
-// ---------------------------------------------------------------------------
-
-class Client
-{
-public:
- Client(ClientID cid, const sp<SurfaceFlinger>& flinger);
- ~Client();
-
- int32_t generateId(int pid);
- void free(int32_t id);
- status_t bindLayer(LayerBaseClient* layer, int32_t id);
- sp<MemoryDealer> createAllocator(uint32_t memory_type);
-
- inline bool isValid(int32_t i) const;
- inline const uint8_t* inUseArray() const;
- inline size_t numActiveLayers() const;
- LayerBaseClient* getLayerUser(int32_t i) const;
- const Vector<LayerBaseClient*>& getLayers() const { return mLayers; }
- const sp<IMemory>& controlBlockMemory() const { return mCblkMemory; }
- void dump(const char* what);
- const sp<SurfaceHeapManager>& getSurfaceHeapManager() const;
-
- // pointer to this client's control block
- per_client_cblk_t* ctrlblk;
- ClientID cid;
-
-
-private:
- int getClientPid() const { return mPid; }
-
- int mPid;
- uint32_t mBitmap;
- SortedVector<uint8_t> mInUse;
- Vector<LayerBaseClient*> mLayers;
- sp<MemoryDealer> mCblkHeap;
- sp<SurfaceFlinger> mFlinger;
- sp<MemoryDealer> mSharedHeapAllocator;
- sp<MemoryDealer> mPMemAllocator;
- sp<IMemory> mCblkMemory;
-};
-
-// ---------------------------------------------------------------------------
-
-class GraphicPlane
-{
-public:
- static status_t orientationToTransfrom(int orientation, int w, int h,
- Transform* tr);
-
- GraphicPlane();
- ~GraphicPlane();
-
- bool initialized() const;
-
- void setDisplayHardware(DisplayHardware *);
- void setTransform(const Transform& tr);
- status_t setOrientation(int orientation);
-
- const DisplayHardware& displayHardware() const;
- const Transform& transform() const;
-private:
- GraphicPlane(const GraphicPlane&);
- GraphicPlane operator = (const GraphicPlane&);
-
- DisplayHardware* mHw;
- Transform mTransform;
- Transform mOrientationTransform;
- Transform mGlobalTransform;
-};
-
-// ---------------------------------------------------------------------------
-
-enum {
- eTransactionNeeded = 0x01,
- eTraversalNeeded = 0x02
-};
-
-class SurfaceFlinger : public BnSurfaceComposer, protected Thread
-{
-public:
- static void instantiate();
- static void shutdown();
-
- SurfaceFlinger();
- virtual ~SurfaceFlinger();
- void init();
-
- virtual status_t onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
-
- virtual status_t dump(int fd, const Vector<String16>& args);
-
- // ISurfaceComposer interface
- virtual sp<ISurfaceFlingerClient> createConnection();
- virtual sp<IMemory> getCblk() const;
- virtual void bootFinished();
- virtual void openGlobalTransaction();
- virtual void closeGlobalTransaction();
- virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags);
- virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags);
- virtual int setOrientation(DisplayID dpy, int orientation);
- virtual void signal() const;
- virtual status_t requestGPU(const sp<IGPUCallback>& callback,
- gpu_info_t* gpu);
- virtual status_t revokeGPU();
-
- void screenReleased(DisplayID dpy);
- void screenAcquired(DisplayID dpy);
-
- const sp<SurfaceHeapManager>& getSurfaceHeapManager() const {
- return mSurfaceHeapManager;
- }
-
- const sp<GPUHardwareInterface>& getGPU() const {
- return mGPU;
- }
-
- copybit_device_t* getBlitEngine() const;
- overlay_control_device_t* getOverlayEngine() const;
-
-
- status_t removeLayer(LayerBase* layer);
- status_t addLayer(LayerBase* layer);
- status_t invalidateLayerVisibility(LayerBase* layer);
-
-private:
- friend class BClient;
- friend class LayerBase;
- friend class LayerBuffer;
- friend class LayerBaseClient;
- friend class Layer;
- friend class LayerBlur;
-
- sp<ISurface> createSurface(ClientID client, int pid,
- ISurfaceFlingerClient::surface_data_t* params,
- DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
- uint32_t flags);
-
- LayerBaseClient* createNormalSurfaceLocked(Client* client, DisplayID display,
- int32_t id, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
-
- LayerBaseClient* createBlurSurfaceLocked(Client* client, DisplayID display,
- int32_t id, uint32_t w, uint32_t h, uint32_t flags);
-
- LayerBaseClient* createDimSurfaceLocked(Client* client, DisplayID display,
- int32_t id, uint32_t w, uint32_t h, uint32_t flags);
-
- LayerBaseClient* createPushBuffersSurfaceLocked(Client* client, DisplayID display,
- int32_t id, uint32_t w, uint32_t h, uint32_t flags);
-
- status_t destroySurface(SurfaceID surface_id);
- status_t setClientState(ClientID cid, int32_t count, const layer_state_t* states);
-
-
- class LayerVector {
- public:
- inline LayerVector() { }
- LayerVector(const LayerVector&);
- inline size_t size() const { return layers.size(); }
- inline LayerBase*const* array() const { return layers.array(); }
- ssize_t add(LayerBase*, Vector<LayerBase*>::compar_t);
- ssize_t remove(LayerBase*);
- ssize_t reorder(LayerBase*, Vector<LayerBase*>::compar_t);
- ssize_t indexOf(LayerBase* key, size_t guess=0) const;
- inline LayerBase* operator [] (size_t i) const { return layers[i]; }
- private:
- KeyedVector<LayerBase*, size_t> lookup;
- Vector<LayerBase*> layers;
- };
-
- struct State {
- State() {
- orientation = ISurfaceComposer::eOrientationDefault;
- freezeDisplay = 0;
- }
- LayerVector layersSortedByZ;
- uint8_t orientation;
- uint8_t freezeDisplay;
- };
-
- class DelayedTransaction : public Thread
- {
- friend class SurfaceFlinger;
- sp<SurfaceFlinger> mFlinger;
- nsecs_t mDelay;
- public:
- DelayedTransaction(const sp<SurfaceFlinger>& flinger, nsecs_t delay)
- : Thread(false), mFlinger(flinger), mDelay(delay) {
- }
- virtual bool threadLoop() {
- usleep(mDelay / 1000);
- if (android_atomic_and(~1,
- &mFlinger->mDeplayedTransactionPending) == 1) {
- mFlinger->signalEvent();
- }
- return false;
- }
- };
-
- virtual bool threadLoop();
- virtual status_t readyToRun();
- virtual void onFirstRef();
-
- const GraphicPlane& graphicPlane(int dpy) const;
- GraphicPlane& graphicPlane(int dpy);
-
- void waitForEvent();
- void signalEvent();
- void signalDelayedEvent(nsecs_t delay);
-
- void handleConsoleEvents();
- void handleTransaction(uint32_t transactionFlags);
-
- void computeVisibleRegions(
- LayerVector& currentLayers,
- Region& dirtyRegion,
- Region& wormholeRegion);
-
- void handlePageFlip();
- bool lockPageFlip(const LayerVector& currentLayers);
- void unlockPageFlip(const LayerVector& currentLayers);
- void handleRepaint();
- void handleDebugCpu();
- void scheduleBroadcast(Client* client);
- void executeScheduledBroadcasts();
- void postFramebuffer();
- void composeSurfaces(const Region& dirty);
- void unlockClients();
-
-
- void destroyConnection(ClientID cid);
- LayerBaseClient* getLayerUser_l(SurfaceID index) const;
- status_t addLayer_l(LayerBase* layer);
- status_t removeLayer_l(LayerBase* layer);
- void destroy_all_removed_layers_l();
- void free_resources_l();
-
- uint32_t getTransactionFlags(uint32_t flags);
- uint32_t setTransactionFlags(uint32_t flags, nsecs_t delay = 0);
- void commitTransaction();
-
-
- friend class FreezeLock;
- sp<FreezeLock> getFreezeLock() const;
- inline void incFreezeCount() { mFreezeCount++; }
- inline void decFreezeCount() { if (mFreezeCount > 0) mFreezeCount--; }
- inline bool hasFreezeRequest() const { return mFreezeDisplay; }
- inline bool isFrozen() const {
- return mFreezeDisplay || mFreezeCount>0;
- }
-
-
- void debugFlashRegions();
- void debugShowFPS() const;
- void drawWormhole() const;
-
- // access must be protected by mStateLock
- mutable Mutex mStateLock;
- State mCurrentState;
- State mDrawingState;
- volatile int32_t mTransactionFlags;
- volatile int32_t mTransactionCount;
- Condition mTransactionCV;
-
- // protected by mStateLock (but we could use another lock)
- Tokenizer mTokens;
- DefaultKeyedVector<ClientID, Client*> mClientsMap;
- DefaultKeyedVector<SurfaceID, LayerBaseClient*> mLayerMap;
- GraphicPlane mGraphicPlanes[1];
- SortedVector<LayerBase*> mRemovedLayers;
- Vector<Client*> mDisconnectedClients;
-
- // constant members (no synchronization needed for access)
- sp<MemoryDealer> mServerHeap;
- sp<IMemory> mServerCblkMemory;
- surface_flinger_cblk_t* mServerCblk;
- sp<SurfaceHeapManager> mSurfaceHeapManager;
- sp<GPUHardwareInterface> mGPU;
- GLuint mWormholeTexName;
- sp<BootAnimation> mBootAnimation;
- nsecs_t mBootTime;
-
- // Can only accessed from the main thread, these members
- // don't need synchronization
- Region mDirtyRegion;
- Region mInvalidRegion;
- Region mWormholeRegion;
- Client* mLastScheduledBroadcast;
- SortedVector<Client*> mScheduledBroadcasts;
- bool mVisibleRegionsDirty;
- bool mDeferReleaseConsole;
- bool mFreezeDisplay;
- int32_t mFreezeCount;
- nsecs_t mFreezeDisplayTime;
- friend class OrientationAnimation;
- OrientationAnimation* mOrientationAnimation;
-
- // access protected by mDebugLock
- mutable Mutex mDebugLock;
- sp<CPUGauge> mCpuGauge;
-
- // don't use a lock for these, we don't care
- int mDebugRegion;
- int mDebugCpu;
- int mDebugFps;
- int mDebugBackground;
- int mDebugNoBootAnimation;
-
- // these are thread safe
- mutable Barrier mReadyToRunBarrier;
- mutable SurfaceFlingerSynchro mSyncObject;
- volatile int32_t mDeplayedTransactionPending;
-
- // atomic variables
- enum {
- eConsoleReleased = 1,
- eConsoleAcquired = 2
- };
- volatile int32_t mConsoleSignals;
-
- // only written in the main thread, only read in other threads
- volatile int32_t mSecureFrameBuffer;
-};
-
-// ---------------------------------------------------------------------------
-
-class FreezeLock : public LightRefBase<FreezeLock> {
- SurfaceFlinger* mFlinger;
-public:
- FreezeLock(SurfaceFlinger* flinger)
- : mFlinger(flinger) {
- mFlinger->incFreezeCount();
- }
- ~FreezeLock() {
- mFlinger->decFreezeCount();
- }
-};
-
-// ---------------------------------------------------------------------------
-
-class BClient : public BnSurfaceFlingerClient
-{
-public:
- BClient(SurfaceFlinger *flinger, ClientID cid,
- const sp<IMemory>& cblk);
- ~BClient();
-
- // ISurfaceFlingerClient interface
- virtual void getControlBlocks(sp<IMemory>* ctrl) const;
-
- virtual sp<ISurface> createSurface(
- surface_data_t* params, int pid,
- DisplayID display, uint32_t w, uint32_t h,PixelFormat format,
- uint32_t flags);
-
- virtual status_t destroySurface(SurfaceID surfaceId);
- virtual status_t setState(int32_t count, const layer_state_t* states);
-
-private:
- ClientID mId;
- SurfaceFlinger* mFlinger;
- sp<IMemory> mCblk;
-};
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-
-#endif // ANDROID_SURFACE_FLINGER_H
diff --git a/libs/surfaceflinger/Tokenizer.cpp b/libs/surfaceflinger/Tokenizer.cpp
deleted file mode 100644
index ef51d6a..0000000
--- a/libs/surfaceflinger/Tokenizer.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * 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.
- */
-
-#include <stdio.h>
-
-#include "Tokenizer.h"
-
-// ----------------------------------------------------------------------------
-
-namespace android {
-
-ANDROID_BASIC_TYPES_TRAITS(Tokenizer::run_t)
-
-Tokenizer::Tokenizer()
-{
-}
-
-Tokenizer::Tokenizer(const Tokenizer& other)
- : mRanges(other.mRanges)
-{
-}
-
-Tokenizer::~Tokenizer()
-{
-}
-
-uint32_t Tokenizer::acquire()
-{
- if (!mRanges.size() || mRanges[0].first) {
- _insertTokenAt(0,0);
- return 0;
- }
-
- // just extend the first run
- const run_t& run = mRanges[0];
- uint32_t token = run.first + run.length;
- _insertTokenAt(token, 1);
- return token;
-}
-
-bool Tokenizer::isAcquired(uint32_t token) const
-{
- return (_indexOrderOf(token) >= 0);
-}
-
-status_t Tokenizer::reserve(uint32_t token)
-{
- size_t o;
- const ssize_t i = _indexOrderOf(token, &o);
- if (i >= 0) {
- return BAD_VALUE; // this token is already taken
- }
- ssize_t err = _insertTokenAt(token, o);
- return (err<0) ? err : status_t(NO_ERROR);
-}
-
-status_t Tokenizer::release(uint32_t token)
-{
- const ssize_t i = _indexOrderOf(token);
- if (i >= 0) {
- const run_t& run = mRanges[i];
- if ((token >= run.first) && (token < run.first+run.length)) {
- // token in this range, we need to split
- run_t& run = mRanges.editItemAt(i);
- if ((token == run.first) || (token == run.first+run.length-1)) {
- if (token == run.first) {
- run.first += 1;
- }
- run.length -= 1;
- if (run.length == 0) {
- // XXX: should we systematically remove a run that's empty?
- mRanges.removeItemsAt(i);
- }
- } else {
- // split the run
- run_t new_run;
- new_run.first = token+1;
- new_run.length = run.first+run.length - new_run.first;
- run.length = token - run.first;
- mRanges.insertAt(new_run, i+1);
- }
- return NO_ERROR;
- }
- }
- return NAME_NOT_FOUND;
-}
-
-ssize_t Tokenizer::_indexOrderOf(uint32_t token, size_t* order) const
-{
- // binary search
- ssize_t err = NAME_NOT_FOUND;
- ssize_t l = 0;
- ssize_t h = mRanges.size()-1;
- ssize_t mid;
- const run_t* a = mRanges.array();
- while (l <= h) {
- mid = l + (h - l)/2;
- const run_t* const curr = a + mid;
- int c = 0;
- if (token < curr->first) c = 1;
- else if (token >= curr->first+curr->length) c = -1;
- if (c == 0) {
- err = l = mid;
- break;
- } else if (c < 0) {
- l = mid + 1;
- } else {
- h = mid - 1;
- }
- }
- if (order) *order = l;
- return err;
-}
-
-ssize_t Tokenizer::_insertTokenAt(uint32_t token, size_t index)
-{
- const size_t c = mRanges.size();
-
- if (index >= 1) {
- // do we need to merge with the previous run?
- run_t& p = mRanges.editItemAt(index-1);
- if (p.first+p.length == token) {
- p.length += 1;
- if (index < c) {
- const run_t& n = mRanges[index];
- if (token+1 == n.first) {
- p.length += n.length;
- mRanges.removeItemsAt(index);
- }
- }
- return index;
- }
- }
-
- if (index < c) {
- // do we need to merge with the next run?
- run_t& n = mRanges.editItemAt(index);
- if (token+1 == n.first) {
- n.first -= 1;
- n.length += 1;
- return index;
- }
- }
-
- return mRanges.insertAt(run_t(token,1), index);
-}
-
-void Tokenizer::dump() const
-{
- const run_t* ranges = mRanges.array();
- const size_t c = mRanges.size();
- printf("Tokenizer (%p, size = %lu)\n", this, c);
- for (size_t i=0 ; i<c ; i++) {
- printf("%lu: (%u, %u)\n", i, ranges[i].first, ranges[i].length);
- }
-}
-
-}; // namespace android
-
diff --git a/libs/surfaceflinger/Tokenizer.h b/libs/surfaceflinger/Tokenizer.h
deleted file mode 100644
index 6b3057d..0000000
--- a/libs/surfaceflinger/Tokenizer.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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_TOKENIZER_H
-#define ANDROID_TOKENIZER_H
-
-#include <utils/Vector.h>
-#include <utils/Errors.h>
-
-// ----------------------------------------------------------------------------
-
-namespace android {
-
-class Tokenizer
-{
-public:
- Tokenizer();
- Tokenizer(const Tokenizer& other);
- ~Tokenizer();
-
- uint32_t acquire();
- status_t reserve(uint32_t token);
- status_t release(uint32_t token);
- bool isAcquired(uint32_t token) const;
-
- void dump() const;
-
- struct run_t {
- run_t() {};
- run_t(uint32_t f, uint32_t l) : first(f), length(l) {}
- uint32_t first;
- uint32_t length;
- };
-private:
- ssize_t _indexOrderOf(uint32_t token, size_t* order=0) const;
- ssize_t _insertTokenAt(uint32_t token, size_t index);
- Vector<run_t> mRanges;
-};
-
-}; // namespace android
-
-// ----------------------------------------------------------------------------
-
-#endif // ANDROID_TOKENIZER_H
diff --git a/libs/surfaceflinger/Transform.cpp b/libs/surfaceflinger/Transform.cpp
deleted file mode 100644
index bec7a64..0000000
--- a/libs/surfaceflinger/Transform.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * 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.
- */
-
-#include <ui/Region.h>
-
-#include <private/pixelflinger/ggl_fixed.h>
-
-#include "Transform.h"
-
-// ---------------------------------------------------------------------------
-
-#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
-#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-Transform::Transform()
- : mType(0)
-{
- mTransform.reset();
-}
-
-Transform::Transform(const Transform& other)
- : mTransform(other.mTransform), mType(other.mType)
-{
-}
-
-Transform::~Transform() {
-}
-
-Transform Transform::operator * (const Transform& rhs) const
-{
- if (LIKELY(mType == 0))
- return rhs;
-
- Transform r(*this);
- r.mTransform.preConcat(rhs.mTransform);
- r.mType |= rhs.mType;
- return r;
-}
-
-float Transform::operator [] (int i) const
-{
- float r = 0;
- switch(i) {
- case 0: r = SkScalarToFloat( mTransform[SkMatrix::kMScaleX] ); break;
- case 1: r = SkScalarToFloat( mTransform[SkMatrix::kMSkewX] ); break;
- case 2: r = SkScalarToFloat( mTransform[SkMatrix::kMSkewY] ); break;
- case 3: r = SkScalarToFloat( mTransform[SkMatrix::kMScaleY] ); break;
- }
- return r;
-}
-
-uint8_t Transform::type() const
-{
- if (UNLIKELY(mType & 0x80000000)) {
- mType = mTransform.getType();
- }
- return uint8_t(mType & 0xFF);
-}
-
-bool Transform::transformed() const {
- return type() > SkMatrix::kTranslate_Mask;
-}
-
-int Transform::tx() const {
- return SkScalarRound( mTransform[SkMatrix::kMTransX] );
-}
-
-int Transform::ty() const {
- return SkScalarRound( mTransform[SkMatrix::kMTransY] );
-}
-
-void Transform::reset() {
- mTransform.reset();
- mType = 0;
-}
-
-void Transform::set( float xx, float xy,
- float yx, float yy)
-{
- mTransform.set(SkMatrix::kMScaleX, SkFloatToScalar(xx));
- mTransform.set(SkMatrix::kMSkewX, SkFloatToScalar(xy));
- mTransform.set(SkMatrix::kMSkewY, SkFloatToScalar(yx));
- mTransform.set(SkMatrix::kMScaleY, SkFloatToScalar(yy));
- mType |= 0x80000000;
-}
-
-void Transform::set(int tx, int ty)
-{
- if (tx | ty) {
- mTransform.set(SkMatrix::kMTransX, SkIntToScalar(tx));
- mTransform.set(SkMatrix::kMTransY, SkIntToScalar(ty));
- mType |= SkMatrix::kTranslate_Mask;
- } else {
- mTransform.set(SkMatrix::kMTransX, 0);
- mTransform.set(SkMatrix::kMTransY, 0);
- mType &= ~SkMatrix::kTranslate_Mask;
- }
-}
-
-void Transform::transform(GLfixed* point, int x, int y) const
-{
- SkPoint s;
- mTransform.mapXY(SkIntToScalar(x), SkIntToScalar(y), &s);
- point[0] = SkScalarToFixed(s.fX);
- point[1] = SkScalarToFixed(s.fY);
-}
-
-Rect Transform::makeBounds(int w, int h) const
-{
- Rect r;
- SkRect d, s;
- s.set(0, 0, SkIntToScalar(w), SkIntToScalar(h));
- mTransform.mapRect(&d, s);
- r.left = SkScalarRound( d.fLeft );
- r.top = SkScalarRound( d.fTop );
- r.right = SkScalarRound( d.fRight );
- r.bottom = SkScalarRound( d.fBottom );
- return r;
-}
-
-Rect Transform::transform(const Rect& bounds) const
-{
- Rect r;
- SkRect d, s;
- s.set( SkIntToScalar( bounds.left ),
- SkIntToScalar( bounds.top ),
- SkIntToScalar( bounds.right ),
- SkIntToScalar( bounds.bottom ));
- mTransform.mapRect(&d, s);
- r.left = SkScalarRound( d.fLeft );
- r.top = SkScalarRound( d.fTop );
- r.right = SkScalarRound( d.fRight );
- r.bottom = SkScalarRound( d.fBottom );
- return r;
-}
-
-Region Transform::transform(const Region& reg) const
-{
- Region out;
- if (UNLIKELY(transformed())) {
- if (LIKELY(preserveRects())) {
- Rect r;
- Region::iterator iterator(reg);
- while (iterator.iterate(&r)) {
- out.orSelf(transform(r));
- }
- } else {
- out.set(transform(reg.bounds()));
- }
- } else {
- out = reg.translate(tx(), ty());
- }
- return out;
-}
-
-int32_t Transform::getOrientation() const
-{
- uint32_t flags = 0;
- if (UNLIKELY(transformed())) {
- SkScalar a = mTransform[SkMatrix::kMScaleX];
- SkScalar b = mTransform[SkMatrix::kMSkewX];
- SkScalar c = mTransform[SkMatrix::kMSkewY];
- SkScalar d = mTransform[SkMatrix::kMScaleY];
- if (b==0 && c==0 && a && d) {
- if (a<0) flags |= FLIP_H;
- if (d<0) flags |= FLIP_V;
- } else if (b && c && a==0 && d==0) {
- flags |= ROT_90;
- if (b>0) flags |= FLIP_H;
- if (c<0) flags |= FLIP_V;
- } else {
- flags = 0x80000000;
- }
- }
- return flags;
-}
-
-bool Transform::preserveRects() const
-{
- return mTransform.rectStaysRect();
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/surfaceflinger/Transform.h b/libs/surfaceflinger/Transform.h
deleted file mode 100644
index 0b4835e..0000000
--- a/libs/surfaceflinger/Transform.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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_TRANSFORM_H
-#define ANDROID_TRANSFORM_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <ui/Point.h>
-#include <ui/Rect.h>
-
-#include <GLES/gl.h>
-
-#include <core/SkMatrix.h>
-
-namespace android {
-
-class Region;
-
-// ---------------------------------------------------------------------------
-
-class Transform
-{
-public:
- Transform();
- Transform(const Transform& other);
- ~Transform();
-
- enum orientation_flags {
- ROT_0 = 0x00000000,
- FLIP_H = 0x00000001,
- FLIP_V = 0x00000002,
- ROT_90 = 0x00000004,
- ROT_180 = FLIP_H|FLIP_V,
- ROT_270 = ROT_180|ROT_90,
- ROT_INVALID = 0x80000000
- };
-
- bool transformed() const;
- int32_t getOrientation() const;
- bool preserveRects() const;
-
- int tx() const;
- int ty() const;
-
- void reset();
- void set(float xx, float xy, float yx, float yy);
- void set(int tx, int ty);
-
- Rect makeBounds(int w, int h) const;
- void transform(GLfixed* point, int x, int y) const;
- Region transform(const Region& reg) const;
- Rect transform(const Rect& bounds) const;
-
- Transform operator * (const Transform& rhs) const;
- float operator [] (int i) const;
-
- inline uint32_t getType() const { return type(); }
-
- inline Transform(bool) : mType(0xFF) { };
-
-private:
- uint8_t type() const;
-
-private:
- SkMatrix mTransform;
- mutable uint32_t mType;
-};
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-
-#endif /* ANDROID_TRANSFORM_H */
diff --git a/libs/surfaceflinger/VRamHeap.cpp b/libs/surfaceflinger/VRamHeap.cpp
deleted file mode 100644
index 0ccd71f..0000000
--- a/libs/surfaceflinger/VRamHeap.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <math.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-
-#include <cutils/log.h>
-#include <cutils/properties.h>
-
-#include <utils/MemoryDealer.h>
-#include <utils/MemoryBase.h>
-#include <utils/MemoryHeapPmem.h>
-#include <utils/MemoryHeapBase.h>
-
-#include "GPUHardware/GPUHardware.h"
-#include "SurfaceFlinger.h"
-#include "VRamHeap.h"
-
-#if HAVE_ANDROID_OS
-#include <linux/android_pmem.h>
-#endif
-
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-/*
- * Amount of memory we reserve for surface, per client in PMEM
- * (PMEM is used for 2D acceleration)
- * 8 MB of address space per client should be enough.
- */
-static const int PMEM_SIZE = int(8 * 1024 * 1024);
-
-int SurfaceHeapManager::global_pmem_heap = 0;
-
-// ---------------------------------------------------------------------------
-
-SurfaceHeapManager::SurfaceHeapManager(const sp<SurfaceFlinger>& flinger,
- size_t clientHeapSize)
- : mFlinger(flinger), mClientHeapSize(clientHeapSize)
-{
- SurfaceHeapManager::global_pmem_heap = 1;
-}
-
-SurfaceHeapManager::~SurfaceHeapManager()
-{
-}
-
-void SurfaceHeapManager::onFirstRef()
-{
- if (global_pmem_heap) {
- const char* device = "/dev/pmem";
- mPMemHeap = new PMemHeap(device, PMEM_SIZE);
- if (mPMemHeap->base() == MAP_FAILED) {
- mPMemHeap.clear();
- global_pmem_heap = 0;
- }
- }
-}
-
-sp<MemoryDealer> SurfaceHeapManager::createHeap(
- uint32_t flags,
- pid_t client_pid,
- const sp<MemoryDealer>& defaultAllocator)
-{
- sp<MemoryDealer> dealer;
-
- if (flags & ISurfaceComposer::eGPU) {
- // don't grant GPU memory if GPU is disabled
- char value[PROPERTY_VALUE_MAX];
- property_get("debug.egl.hw", value, "1");
- if (atoi(value) == 0) {
- flags &= ~ISurfaceComposer::eGPU;
- }
- }
-
- if (flags & ISurfaceComposer::eGPU) {
- // FIXME: this is msm7201A specific, where gpu surfaces may not be secure
- if (!(flags & ISurfaceComposer::eSecure)) {
- // if GPU doesn't work, we try eHardware
- flags |= ISurfaceComposer::eHardware;
- // asked for GPU memory, try that first
- dealer = mFlinger->getGPU()->request(client_pid);
- }
- }
-
- if (dealer == NULL) {
- if (defaultAllocator != NULL)
- // if a default allocator is given, use that
- dealer = defaultAllocator;
- }
-
- if (dealer == NULL) {
- // always try h/w accelerated memory first
- if (global_pmem_heap) {
- const sp<PMemHeap>& heap(mPMemHeap);
- if (dealer == NULL && heap != NULL) {
- dealer = new MemoryDealer(
- heap->createClientHeap(),
- heap->getAllocator());
- }
- }
- }
-
- if (dealer == NULL) {
- // return the ashmem allocator (software rendering)
- dealer = new MemoryDealer(mClientHeapSize, 0, "SFNativeHeap");
- }
- return dealer;
-}
-
-sp<SimpleBestFitAllocator> SurfaceHeapManager::getAllocator(int type) const
-{
- Mutex::Autolock _l(mLock);
- sp<SimpleBestFitAllocator> allocator;
-
- // this is only used for debugging
- switch (type) {
- case NATIVE_MEMORY_TYPE_PMEM:
- if (mPMemHeap != 0) {
- allocator = mPMemHeap->getAllocator();
- }
- break;
- }
- return allocator;
-}
-
-// ---------------------------------------------------------------------------
-
-PMemHeap::PMemHeap(const char* const device, size_t size, size_t reserved)
- : MemoryHeapBase(device, size)
-{
- //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID());
- if (base() != MAP_FAILED) {
- //LOGD("%s, %u bytes", device, virtualSize());
- if (reserved == 0)
- reserved = virtualSize();
- mAllocator = new SimpleBestFitAllocator(reserved);
- }
-}
-
-PMemHeap::~PMemHeap() {
- //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID());
-}
-
-sp<MemoryHeapPmem> PMemHeap::createClientHeap() {
- sp<MemoryHeapBase> parentHeap(this);
- return new MemoryHeapPmem(parentHeap);
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/surfaceflinger/VRamHeap.h b/libs/surfaceflinger/VRamHeap.h
deleted file mode 100644
index 9140167..0000000
--- a/libs/surfaceflinger/VRamHeap.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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_VRAM_HEAP_H
-#define ANDROID_VRAM_HEAP_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/MemoryDealer.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class PMemHeap;
-class MemoryHeapPmem;
-class SurfaceFlinger;
-
-// ---------------------------------------------------------------------------
-
-class SurfaceHeapManager : public RefBase
-{
-public:
- SurfaceHeapManager(const sp<SurfaceFlinger>& flinger, size_t clientHeapSize);
- virtual ~SurfaceHeapManager();
- virtual void onFirstRef();
- /* use ISurfaceComposer flags eGPU|eHArdware|eSecure */
- sp<MemoryDealer> createHeap(uint32_t flags=0, pid_t client_pid = 0,
- const sp<MemoryDealer>& defaultAllocator = 0);
-
- // used for debugging only...
- sp<SimpleBestFitAllocator> getAllocator(int type) const;
-
-private:
- sp<PMemHeap> getHeap(int type) const;
-
- sp<SurfaceFlinger> mFlinger;
- mutable Mutex mLock;
- size_t mClientHeapSize;
- sp<PMemHeap> mPMemHeap;
- static int global_pmem_heap;
-};
-
-// ---------------------------------------------------------------------------
-
-class PMemHeap : public MemoryHeapBase
-{
-public:
- PMemHeap(const char* const vram,
- size_t size=0, size_t reserved=0);
- virtual ~PMemHeap();
-
- virtual const sp<SimpleBestFitAllocator>& getAllocator() const {
- return mAllocator;
- }
- virtual sp<MemoryHeapPmem> createClientHeap();
-
-private:
- sp<SimpleBestFitAllocator> mAllocator;
-};
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-
-#endif // ANDROID_VRAM_HEAP_H
diff --git a/libs/surfaceflinger/clz.cpp b/libs/surfaceflinger/clz.cpp
deleted file mode 100644
index 2456b86..0000000
--- a/libs/surfaceflinger/clz.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.
- */
-
-#include "clz.h"
-
-namespace android {
-
-int clz_impl(int32_t x)
-{
-#if defined(__arm__) && !defined(__thumb__)
- return __builtin_clz(x);
-#else
- if (!x) return 32;
- int e = 31;
- if (x&0xFFFF0000) { e -=16; x >>=16; }
- if (x&0x0000FF00) { e -= 8; x >>= 8; }
- if (x&0x000000F0) { e -= 4; x >>= 4; }
- if (x&0x0000000C) { e -= 2; x >>= 2; }
- if (x&0x00000002) { e -= 1; }
- return e;
-#endif
-}
-
-}; // namespace android
diff --git a/libs/surfaceflinger/clz.h b/libs/surfaceflinger/clz.h
deleted file mode 100644
index 0ddf986..0000000
--- a/libs/surfaceflinger/clz.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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_SURFACE_FLINGER_CLZ_H
-
-#include <stdint.h>
-
-namespace android {
-
-int clz_impl(int32_t x);
-
-int inline clz(int32_t x)
-{
-#if defined(__arm__) && !defined(__thumb__)
- return __builtin_clz(x);
-#else
- return clz_impl(x);
-#endif
-}
-
-
-}; // namespace android
-
-#endif /* ANDROID_SURFACE_FLINGER_CLZ_H */
diff --git a/libs/surfaceflinger/tests/Android.mk b/libs/surfaceflinger/tests/Android.mk
deleted file mode 100644
index 5053e7d..0000000
--- a/libs/surfaceflinger/tests/Android.mk
+++ /dev/null
@@ -1 +0,0 @@
-include $(call all-subdir-makefiles)
diff --git a/libs/surfaceflinger/tests/overlays/Android.mk b/libs/surfaceflinger/tests/overlays/Android.mk
deleted file mode 100644
index dc47e45..0000000
--- a/libs/surfaceflinger/tests/overlays/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- overlays.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libutils \
- libui
-
-LOCAL_MODULE:= test-overlays
-
-LOCAL_MODULE_TAGS := tests
-
-include $(BUILD_EXECUTABLE)
diff --git a/libs/surfaceflinger/tests/overlays/overlays.cpp b/libs/surfaceflinger/tests/overlays/overlays.cpp
deleted file mode 100644
index f3c046f..0000000
--- a/libs/surfaceflinger/tests/overlays/overlays.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <utils/IPCThreadState.h>
-#include <utils/ProcessState.h>
-#include <utils/IServiceManager.h>
-#include <utils/Log.h>
-
-#include <ui/Surface.h>
-#include <ui/ISurface.h>
-#include <ui/Overlay.h>
-#include <ui/SurfaceComposerClient.h>
-
-using namespace android;
-
-namespace android {
-class Test {
-public:
- static const sp<ISurface>& getISurface(const sp<Surface>& s) {
- return s->getISurface();
- }
-};
-};
-
-int main(int argc, char** argv)
-{
- // set up the thread-pool
- sp<ProcessState> proc(ProcessState::self());
- ProcessState::self()->startThreadPool();
-
- // create a client to surfaceflinger
- sp<SurfaceComposerClient> client = new SurfaceComposerClient();
-
- // create pushbuffer surface
- sp<Surface> surface = client->createSurface(getpid(), 0, 320, 240,
- PIXEL_FORMAT_UNKNOWN, ISurfaceComposer::ePushBuffers);
-
- // get to the isurface
- sp<ISurface> isurface = Test::getISurface(surface);
- printf("isurface = %p\n", isurface.get());
-
- // now request an overlay
- sp<OverlayRef> ref = isurface->createOverlay(320, 240, PIXEL_FORMAT_RGB_565);
- sp<Overlay> overlay = new Overlay(ref);
-
-
- /*
- * here we can use the overlay API
- */
-
- overlay_buffer_t buffer;
- overlay->dequeueBuffer(&buffer);
- printf("buffer = %p\n", buffer);
-
- void* address = overlay->getBufferAddress(buffer);
- printf("address = %p\n", address);
-
- overlay->queueBuffer(buffer);
-
- return 0;
-}
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
deleted file mode 100644
index f944357..0000000
--- a/libs/ui/Android.mk
+++ /dev/null
@@ -1,41 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- Camera.cpp \
- CameraParameters.cpp \
- EGLDisplaySurface.cpp \
- EGLNativeWindowSurface.cpp \
- EventHub.cpp \
- EventRecurrence.cpp \
- KeyLayoutMap.cpp \
- KeyCharacterMap.cpp \
- ICamera.cpp \
- ICameraClient.cpp \
- ICameraService.cpp \
- IOverlay.cpp \
- ISurfaceComposer.cpp \
- ISurface.cpp \
- ISurfaceFlingerClient.cpp \
- LayerState.cpp \
- Overlay.cpp \
- PixelFormat.cpp \
- Point.cpp \
- Rect.cpp \
- Region.cpp \
- Surface.cpp \
- SurfaceComposerClient.cpp \
- SurfaceFlingerSynchro.cpp \
- Time.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libcorecg \
- libcutils \
- libutils \
- libpixelflinger \
- libhardware \
- libhardware_legacy
-
-LOCAL_MODULE:= libui
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/ui/Camera.cpp b/libs/ui/Camera.cpp
deleted file mode 100644
index 6c60b85..0000000
--- a/libs/ui/Camera.cpp
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
-**
-** Copyright (C) 2008, The Android Open Source Project
-** Copyright (C) 2008 HTC Inc.
-**
-** 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.
-*/
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "Camera"
-#include <utils/Log.h>
-#include <utils/IServiceManager.h>
-#include <utils/threads.h>
-#include <utils/IMemory.h>
-#include <ui/Surface.h>
-#include <ui/Camera.h>
-#include <ui/ICameraService.h>
-
-namespace android {
-
-// client singleton for camera service binder interface
-Mutex Camera::mLock;
-sp<ICameraService> Camera::mCameraService;
-sp<Camera::DeathNotifier> Camera::mDeathNotifier;
-
-// establish binder interface to camera service
-const sp<ICameraService>& Camera::getCameraService()
-{
- Mutex::Autolock _l(mLock);
- if (mCameraService.get() == 0) {
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder;
- do {
- binder = sm->getService(String16("media.camera"));
- if (binder != 0)
- break;
- LOGW("CameraService not published, waiting...");
- usleep(500000); // 0.5 s
- } while(true);
- if (mDeathNotifier == NULL) {
- mDeathNotifier = new DeathNotifier();
- }
- binder->linkToDeath(mDeathNotifier);
- mCameraService = interface_cast<ICameraService>(binder);
- }
- LOGE_IF(mCameraService==0, "no CameraService!?");
- return mCameraService;
-}
-
-// ---------------------------------------------------------------------------
-
-Camera::Camera()
-{
- init();
-}
-
-Camera::Camera(const sp<ICamera>& camera)
-{
- init();
- // connect this client to existing camera remote
- if (camera->connect(this) == NO_ERROR) {
- mStatus = NO_ERROR;
- mCamera = camera;
- camera->asBinder()->linkToDeath(this);
- }
-}
-
-void Camera::init()
-{
- mStatus = UNKNOWN_ERROR;
- mShutterCallback = 0;
- mShutterCallbackCookie = 0;
- mRawCallback = 0;
- mRawCallbackCookie = 0;
- mJpegCallback = 0;
- mJpegCallbackCookie = 0;
- mPreviewCallback = 0;
- mPreviewCallbackCookie = 0;
- mRecordingCallback = 0;
- mRecordingCallbackCookie = 0;
- mErrorCallback = 0;
- mErrorCallbackCookie = 0;
- mAutoFocusCallback = 0;
- mAutoFocusCallbackCookie = 0;
-}
-
-Camera::~Camera()
-{
- disconnect();
-}
-
-sp<Camera> Camera::connect()
-{
- LOGV("connect");
- sp<Camera> c = new Camera();
- const sp<ICameraService>& cs = getCameraService();
- if (cs != 0) {
- c->mCamera = cs->connect(c);
- }
- if (c->mCamera != 0) {
- c->mCamera->asBinder()->linkToDeath(c);
- c->mStatus = NO_ERROR;
- }
- return c;
-}
-
-void Camera::disconnect()
-{
- LOGV("disconnect");
- if (mCamera != 0) {
- mErrorCallback = 0;
- mCamera->disconnect();
- mCamera = 0;
- }
-}
-
-status_t Camera::reconnect()
-{
- LOGV("reconnect");
- sp <ICamera> c = mCamera;
- if (c == 0) return NO_INIT;
- return c->connect(this);
-}
-
-sp<ICamera> Camera::remote()
-{
- return mCamera;
-}
-
-status_t Camera::lock()
-{
- sp <ICamera> c = mCamera;
- if (c == 0) return NO_INIT;
- return c->lock();
-}
-
-status_t Camera::unlock()
-{
- sp <ICamera> c = mCamera;
- if (c == 0) return NO_INIT;
- return c->unlock();
-}
-
-// pass the buffered ISurface to the camera service
-status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
-{
- LOGV("setPreviewDisplay");
- if (surface == 0) {
- LOGE("app passed NULL surface");
- return NO_INIT;
- }
- sp <ICamera> c = mCamera;
- if (c == 0) return NO_INIT;
- return c->setPreviewDisplay(surface->getISurface());
-}
-
-status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
-{
- LOGV("setPreviewDisplay");
- if (surface == 0) {
- LOGE("app passed NULL surface");
- return NO_INIT;
- }
- sp <ICamera> c = mCamera;
- if (c == 0) return NO_INIT;
- return c->setPreviewDisplay(surface);
-}
-
-
-// start preview mode, must call setPreviewDisplay first
-status_t Camera::startPreview()
-{
- LOGV("startPreview");
- sp <ICamera> c = mCamera;
- if (c == 0) return NO_INIT;
- return c->startPreview();
-}
-
-// start recording mode, must call setPreviewDisplay first
-status_t Camera::startRecording()
-{
- LOGV("startRecording");
- sp <ICamera> c = mCamera;
- if (c == 0) return NO_INIT;
- return c->startRecording();
-}
-
-// stop preview mode
-void Camera::stopPreview()
-{
- LOGV("stopPreview");
- sp <ICamera> c = mCamera;
- if (c == 0) return;
- c->stopPreview();
-}
-
-// stop recording mode
-void Camera::stopRecording()
-{
- LOGV("stopRecording");
- sp <ICamera> c = mCamera;
- if (c == 0) return;
- c->stopRecording();
-}
-
-// release a recording frame
-void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
-{
- LOGV("releaseRecordingFrame");
- sp <ICamera> c = mCamera;
- if (c == 0) return;
- c->releaseRecordingFrame(mem);
-}
-
-// get preview state
-bool Camera::previewEnabled()
-{
- LOGV("previewEnabled");
- sp <ICamera> c = mCamera;
- if (c == 0) return false;
- return c->previewEnabled();
-}
-
-// get recording state
-bool Camera::recordingEnabled()
-{
- LOGV("recordingEnabled");
- sp <ICamera> c = mCamera;
- if (c == 0) return false;
- return c->recordingEnabled();
-}
-
-status_t Camera::autoFocus()
-{
- LOGV("autoFocus");
- sp <ICamera> c = mCamera;
- if (c == 0) return NO_INIT;
- return c->autoFocus();
-}
-
-// take a picture
-status_t Camera::takePicture()
-{
- LOGV("takePicture");
- sp <ICamera> c = mCamera;
- if (c == 0) return NO_INIT;
- return c->takePicture();
-}
-
-// set preview/capture parameters - key/value pairs
-status_t Camera::setParameters(const String8& params)
-{
- LOGV("setParameters");
- sp <ICamera> c = mCamera;
- if (c == 0) return NO_INIT;
- return c->setParameters(params);
-}
-
-// get preview/capture parameters - key/value pairs
-String8 Camera::getParameters() const
-{
- LOGV("getParameters");
- String8 params;
- sp <ICamera> c = mCamera;
- if (c != 0) params = mCamera->getParameters();
- return params;
-}
-
-void Camera::setAutoFocusCallback(autofocus_callback cb, void *cookie)
-{
- LOGV("setAutoFocusCallback");
- mAutoFocusCallback = cb;
- mAutoFocusCallbackCookie = cookie;
-}
-
-void Camera::setShutterCallback(shutter_callback cb, void *cookie)
-{
- LOGV("setShutterCallback");
- mShutterCallback = cb;
- mShutterCallbackCookie = cookie;
-}
-
-void Camera::setRawCallback(frame_callback cb, void *cookie)
-{
- LOGV("setRawCallback");
- mRawCallback = cb;
- mRawCallbackCookie = cookie;
-}
-
-void Camera::setJpegCallback(frame_callback cb, void *cookie)
-{
- LOGV("setJpegCallback");
- mJpegCallback = cb;
- mJpegCallbackCookie = cookie;
-}
-
-void Camera::setPreviewCallback(frame_callback cb, void *cookie, int flag)
-{
- LOGV("setPreviewCallback");
- mPreviewCallback = cb;
- mPreviewCallbackCookie = cookie;
- sp <ICamera> c = mCamera;
- if (c == 0) return;
- mCamera->setPreviewCallbackFlag(flag);
-}
-
-void Camera::setRecordingCallback(frame_callback cb, void *cookie)
-{
- LOGV("setRecordingCallback");
- mRecordingCallback = cb;
- mRecordingCallbackCookie = cookie;
-}
-
-void Camera::setErrorCallback(error_callback cb, void *cookie)
-{
- LOGV("setErrorCallback");
- mErrorCallback = cb;
- mErrorCallbackCookie = cookie;
-}
-
-void Camera::autoFocusCallback(bool focused)
-{
- LOGV("autoFocusCallback");
- if (mAutoFocusCallback) {
- mAutoFocusCallback(focused, mAutoFocusCallbackCookie);
- }
-}
-
-void Camera::shutterCallback()
-{
- LOGV("shutterCallback");
- if (mShutterCallback) {
- mShutterCallback(mShutterCallbackCookie);
- }
-}
-
-void Camera::rawCallback(const sp<IMemory>& picture)
-{
- LOGV("rawCallback");
- if (mRawCallback) {
- mRawCallback(picture, mRawCallbackCookie);
- }
-}
-
-// callback from camera service when image is ready
-void Camera::jpegCallback(const sp<IMemory>& picture)
-{
- LOGV("jpegCallback");
- if (mJpegCallback) {
- mJpegCallback(picture, mJpegCallbackCookie);
- }
-}
-
-// callback from camera service when preview frame is ready
-void Camera::previewCallback(const sp<IMemory>& frame)
-{
- LOGV("frameCallback");
- if (mPreviewCallback) {
- mPreviewCallback(frame, mPreviewCallbackCookie);
- }
-}
-
-// callback from camera service when a recording frame is ready
-void Camera::recordingCallback(const sp<IMemory>& frame)
-{
- LOGV("recordingCallback");
- if (mRecordingCallback) {
- mRecordingCallback(frame, mRecordingCallbackCookie);
- }
-}
-
-// callback from camera service when an error occurs in preview or takePicture
-void Camera::errorCallback(status_t error)
-{
- LOGV("errorCallback");
- if (mErrorCallback) {
- mErrorCallback(error, mErrorCallbackCookie);
- }
-}
-
-void Camera::binderDied(const wp<IBinder>& who) {
- LOGW("ICamera died");
- if (mErrorCallback) {
- mErrorCallback(DEAD_OBJECT, mErrorCallbackCookie);
- }
-}
-
-void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
- LOGV("binderDied");
- Mutex::Autolock _l(Camera::mLock);
- Camera::mCameraService.clear();
- LOGW("Camera server died!");
-}
-
-}; // namespace android
-
diff --git a/libs/ui/CameraParameters.cpp b/libs/ui/CameraParameters.cpp
deleted file mode 100644
index 6c25836..0000000
--- a/libs/ui/CameraParameters.cpp
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
-**
-** Copyright 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.
-*/
-
-#define LOG_TAG "CameraParams"
-#include <utils/Log.h>
-
-#include <string.h>
-#include <stdlib.h>
-#include <ui/CameraParameters.h>
-
-namespace android {
-
-static const char* portrait = "portrait";
-static const char* landscape = "landscape";
-
-CameraParameters::CameraParameters()
- : mMap()
-{
-}
-
-CameraParameters::~CameraParameters()
-{
-}
-
-String8 CameraParameters::flatten() const
-{
- String8 flattened("");
- size_t size = mMap.size();
-
- for (size_t i = 0; i < size; i++) {
- String8 k, v;
- k = mMap.keyAt(i);
- v = mMap.valueAt(i);
-
- flattened += k;
- flattened += "=";
- flattened += v;
- if (i != size-1)
- flattened += ";";
- }
-
- return flattened;
-}
-
-void CameraParameters::unflatten(const String8 &params)
-{
- const char *a = params.string();
- const char *b;
-
- mMap.clear();
-
- for (;;) {
- // Find the bounds of the key name.
- b = strchr(a, '=');
- if (b == 0)
- break;
-
- // Create the key string.
- String8 k(a, (size_t)(b-a));
-
- // Find the value.
- a = b+1;
- b = strchr(a, ';');
- if (b == 0) {
- // If there's no semicolon, this is the last item.
- String8 v(a);
- mMap.add(k, v);
- break;
- }
-
- String8 v(a, (size_t)(b-a));
- mMap.add(k, v);
- a = b+1;
- }
-}
-
-
-void CameraParameters::set(const char *key, const char *value)
-{
- // XXX i think i can do this with strspn()
- if (strchr(key, '=') || strchr(key, ';')) {
- //XXX LOGE("Key \"%s\"contains invalid character (= or ;)", key);
- return;
- }
-
- if (strchr(value, '=') || strchr(key, ';')) {
- //XXX LOGE("Value \"%s\"contains invalid character (= or ;)", value);
- return;
- }
-
- mMap.replaceValueFor(String8(key), String8(value));
-}
-
-void CameraParameters::set(const char *key, int value)
-{
- char str[16];
- sprintf(str, "%d", value);
- set(key, str);
-}
-
-const char *CameraParameters::get(const char *key) const
-{
- String8 v = mMap.valueFor(String8(key));
- if (v.length() == 0)
- return 0;
- return v.string();
-}
-
-int CameraParameters::getInt(const char *key) const
-{
- const char *v = get(key);
- if (v == 0)
- return -1;
- return strtol(v, 0, 0);
-}
-
-static int parse_size(const char *str, int &width, int &height)
-{
- // Find the width.
- char *end;
- int w = (int)strtol(str, &end, 10);
- // If an 'x' does not immediately follow, give up.
- if (*end != 'x')
- return -1;
-
- // Find the height, immediately after the 'x'.
- int h = (int)strtol(end+1, 0, 10);
-
- width = w;
- height = h;
-
- return 0;
-}
-
-void CameraParameters::setPreviewSize(int width, int height)
-{
- char str[32];
- sprintf(str, "%dx%d", width, height);
- set("preview-size", str);
-}
-
-void CameraParameters::getPreviewSize(int *width, int *height) const
-{
- *width = -1;
- *height = -1;
-
- // Get the current string, if it doesn't exist, leave the -1x-1
- const char *p = get("preview-size");
- if (p == 0)
- return;
-
- int w, h;
- if (parse_size(p, w, h) == 0) {
- *width = w;
- *height = h;
- }
-}
-
-void CameraParameters::setPreviewFrameRate(int fps)
-{
- set("preview-frame-rate", fps);
-}
-
-int CameraParameters::getPreviewFrameRate() const
-{
- return getInt("preview-frame-rate");
-}
-
-void CameraParameters::setPreviewFormat(const char *format)
-{
- set("preview-format", format);
-}
-
-int CameraParameters::getOrientation() const
-{
- const char* orientation = get("orientation");
- if (orientation && !strcmp(orientation, portrait))
- return CAMERA_ORIENTATION_PORTRAIT;
- return CAMERA_ORIENTATION_LANDSCAPE;
-}
-
-void CameraParameters::setOrientation(int orientation)
-{
- if (orientation == CAMERA_ORIENTATION_PORTRAIT) {
- set("preview-format", portrait);
- } else {
- set("preview-format", landscape);
- }
-}
-
-const char *CameraParameters::getPreviewFormat() const
-{
- return get("preview-format");
-}
-
-void CameraParameters::setPictureSize(int width, int height)
-{
- char str[32];
- sprintf(str, "%dx%d", width, height);
- set("picture-size", str);
-}
-
-void CameraParameters::getPictureSize(int *width, int *height) const
-{
- *width = -1;
- *height = -1;
-
- // Get the current string, if it doesn't exist, leave the -1x-1
- const char *p = get("picture-size");
- if (p == 0)
- return;
-
- int w, h;
- if (parse_size(p, w, h) == 0) {
- *width = w;
- *height = h;
- }
-}
-
-void CameraParameters::setPictureFormat(const char *format)
-{
- set("picture-format", format);
-}
-
-const char *CameraParameters::getPictureFormat() const
-{
- return get("picture-format");
-}
-
-void CameraParameters::dump() const
-{
- LOGD("dump: mMap.size = %d", mMap.size());
- for (size_t i = 0; i < mMap.size(); i++) {
- String8 k, v;
- k = mMap.keyAt(i);
- v = mMap.valueAt(i);
- LOGD("%s: %s\n", k.string(), v.string());
- }
-}
-
-status_t CameraParameters::dump(int fd, const Vector<String16>& args) const
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
- snprintf(buffer, 255, "CameraParameters::dump: mMap.size = %d\n", mMap.size());
- result.append(buffer);
- for (size_t i = 0; i < mMap.size(); i++) {
- String8 k, v;
- k = mMap.keyAt(i);
- v = mMap.valueAt(i);
- snprintf(buffer, 255, "\t%s: %s\n", k.string(), v.string());
- result.append(buffer);
- }
- write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-}; // namespace android
diff --git a/libs/ui/EGLDisplaySurface.cpp b/libs/ui/EGLDisplaySurface.cpp
deleted file mode 100644
index d06c98b..0000000
--- a/libs/ui/EGLDisplaySurface.cpp
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- **
- ** Copyright 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.
- */
-
-#define LOG_TAG "EGLDisplaySurface"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-
-#include <cutils/log.h>
-#include <cutils/atomic.h>
-#include <cutils/properties.h>
-
-#include <hardware/copybit.h>
-
-#include <ui/SurfaceComposerClient.h>
-#include <ui/DisplayInfo.h>
-#include <ui/Rect.h>
-#include <ui/Region.h>
-#include <ui/EGLDisplaySurface.h>
-
-#if HAVE_ANDROID_OS
-#include <linux/msm_mdp.h>
-#endif
-
-#include <EGL/egl.h>
-
-#include <pixelflinger/format.h>
-
-
-// ----------------------------------------------------------------------------
-
-egl_native_window_t* android_createDisplaySurface()
-{
- egl_native_window_t* s = new android::EGLDisplaySurface();
- s->memory_type = NATIVE_MEMORY_TYPE_GPU;
- return s;
-}
-
-#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
-#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
-
-// ----------------------------------------------------------------------------
-namespace android {
-// ----------------------------------------------------------------------------
-
-EGLDisplaySurface::EGLDisplaySurface()
- : EGLNativeSurface<EGLDisplaySurface>()
-{
- egl_native_window_t::version = sizeof(egl_native_window_t);
- egl_native_window_t::ident = 0;
- egl_native_window_t::incRef = &EGLDisplaySurface::hook_incRef;
- egl_native_window_t::decRef = &EGLDisplaySurface::hook_decRef;
- egl_native_window_t::swapBuffers = &EGLDisplaySurface::hook_swapBuffers;
- egl_native_window_t::connect = 0;
- egl_native_window_t::disconnect = 0;
-
- mFb[0].data = 0;
- mFb[1].data = 0;
- mBlitEngine = 0;
- egl_native_window_t::fd = mapFrameBuffer();
- if (egl_native_window_t::fd >= 0) {
-
- hw_module_t const* module;
- if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
- copybit_open(module, &mBlitEngine);
- }
-
- const float in2mm = 25.4f;
- float refreshRate = 1000000000000000LLU / (
- float( mInfo.upper_margin + mInfo.lower_margin + mInfo.yres )
- * ( mInfo.left_margin + mInfo.right_margin + mInfo.xres )
- * mInfo.pixclock);
-
- const GGLSurface& buffer = mFb[1 - mIndex];
- egl_native_window_t::width = buffer.width;
- egl_native_window_t::height = buffer.height;
- egl_native_window_t::stride = buffer.stride;
- egl_native_window_t::format = buffer.format;
- egl_native_window_t::base = intptr_t(mFb[0].data);
- egl_native_window_t::offset =
- intptr_t(buffer.data) - egl_native_window_t::base;
- egl_native_window_t::flags = 0;
- egl_native_window_t::xdpi = (mInfo.xres * in2mm) / mInfo.width;
- egl_native_window_t::ydpi = (mInfo.yres * in2mm) / mInfo.height;
- egl_native_window_t::fps = refreshRate;
- egl_native_window_t::memory_type = NATIVE_MEMORY_TYPE_FB;
- // no error, set the magic word
- egl_native_window_t::magic = 0x600913;
- }
- mSwapCount = -1;
- mPageFlipCount = 0;
-}
-
-EGLDisplaySurface::~EGLDisplaySurface()
-{
- magic = 0;
- copybit_close(mBlitEngine);
- mBlitEngine = 0;
- close(egl_native_window_t::fd);
- munmap(mFb[0].data, mSize);
- if (!(mFlags & PAGE_FLIP))
- free((void*)mFb[1].data);
-}
-
-void EGLDisplaySurface::hook_incRef(NativeWindowType window) {
- EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
- that->incStrong(that);
-}
-void EGLDisplaySurface::hook_decRef(NativeWindowType window) {
- EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
- that->decStrong(that);
-}
-uint32_t EGLDisplaySurface::hook_swapBuffers(NativeWindowType window) {
- EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
- return that->swapBuffers();
-}
-
-void EGLDisplaySurface::setSwapRectangle(int l, int t, int w, int h)
-{
- mInfo.reserved[0] = 0x54445055; // "UPDT";
- mInfo.reserved[1] = (uint16_t)l | ((uint32_t)t << 16);
- mInfo.reserved[2] = (uint16_t)(l+w) | ((uint32_t)(t+h) << 16);
-}
-
-uint32_t EGLDisplaySurface::swapBuffers()
-{
-#define SHOW_FPS 0
-#if SHOW_FPS
- nsecs_t now = systemTime();
- if (mSwapCount == -1) {
- mTime = now;
- mSwapCount = 0;
- mSleep = 0;
- } else {
- nsecs_t d = now-mTime;
- if (d >= seconds(1)) {
- double fps = (mSwapCount * double(seconds(1))) / double(d);
- LOGD("%f fps, sleep=%d / frame",
- fps, (int)ns2us(mSleep / mSwapCount));
- mSwapCount = 0;
- mTime = now;
- mSleep = 0;
- } else {
- mSwapCount++;
- }
- }
-#endif
- /* If we can't do the page_flip, just copy the back buffer to the front */
- if (!(mFlags & PAGE_FLIP)) {
- memcpy(mFb[0].data, mFb[1].data, mInfo.xres*mInfo.yres*2);
- return 0;
- }
-
- // do the actual flip
- mIndex = 1 - mIndex;
- mInfo.activate = FB_ACTIVATE_VBL;
- mInfo.yoffset = mIndex ? mInfo.yres : 0;
- if (ioctl(egl_native_window_t::fd, FBIOPUT_VSCREENINFO, &mInfo) == -1) {
- LOGE("FBIOPUT_VSCREENINFO failed");
- return 0;
- }
-
- /*
- * this is a monstrous hack: Because the h/w accelerator is not able
- * to render directly into the framebuffer, we need to copy its
- * internal framebuffer out to the fb.
- * oem[0] is used to access the fd of internal fb.
- * All this is needed only in standalone mode, in SurfaceFlinger mode
- * we control where the GPU renders.
- * We do this only if we have copybit, since this hack is needed only
- * with msm7k.
- */
- if (egl_native_window_t::memory_type == NATIVE_MEMORY_TYPE_GPU && oem[0] && mBlitEngine) {
- copybit_device_t *copybit = mBlitEngine;
- copybit_rect_t sdrect = { 0, 0,
- egl_native_window_t::width, egl_native_window_t::height };
- copybit_image_t dst = {
- egl_native_window_t::width,
- egl_native_window_t::height,
- egl_native_window_t::format,
- egl_native_window_t::offset,
- (void*)egl_native_window_t::base,
- egl_native_window_t::fd
- };
- copybit_image_t src = {
- egl_native_window_t::width,
- egl_native_window_t::height,
- egl_native_window_t::format, // XXX: use proper format
- egl_native_window_t::offset,
- (void*)egl_native_window_t::base, // XXX: use proper base
- egl_native_window_t::oem[0]
- };
- region_iterator it(Region(Rect(
- egl_native_window_t::width, egl_native_window_t::height)));
- copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
- copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
- copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
- copybit->stretch(copybit, &dst, &src, &sdrect, &sdrect, &it);
- }
-
- // update the address of the buffer to draw to next
- const GGLSurface& buffer = mFb[1 - mIndex];
- egl_native_window_t::offset =
- intptr_t(buffer.data) - egl_native_window_t::base;
-
-#if SHOW_FPS
- mSleep += systemTime()-now;
-#endif
-
- mPageFlipCount++;
-
- // We don't support screen-size changes for now
- return 0;
-}
-
-int32_t EGLDisplaySurface::getPageFlipCount() const
-{
- return mPageFlipCount;
-}
-
-void EGLDisplaySurface::copyFrontToBack(const Region& copyback)
-{
-#if HAVE_ANDROID_OS
- if (mBlitEngine) {
- copybit_image_t dst = {
- w: egl_native_window_t::stride,
- h: egl_native_window_t::height,
- format: egl_native_window_t::format,
- offset: mFb[1-mIndex].data - mFb[0].data,
- base: (void*)egl_native_window_t::base,
- fd: egl_native_window_t::fd
- };
- copybit_image_t src = {
- w: egl_native_window_t::stride,
- h: egl_native_window_t::height,
- format: egl_native_window_t::format,
- offset: mFb[mIndex].data - mFb[0].data,
- base: (void*)egl_native_window_t::base,
- fd: egl_native_window_t::fd
- };
- region_iterator it(copyback);
- mBlitEngine->blit(mBlitEngine, &dst, &src, &it);
- } else
-#endif
- {
- /* no extra copy needed since we copied back to front instead of
- * flipping */
- if (!(mFlags & PAGE_FLIP)) {
- return;
- }
-
- Region::iterator iterator(copyback);
- if (iterator) {
- Rect r;
- uint8_t* const screen_src = mFb[ mIndex].data;
- uint8_t* const screen_dst = mFb[1-mIndex].data;
- const size_t bpp = bytesPerPixel(egl_native_window_t::format);
- const size_t bpr = egl_native_window_t::stride * bpp;
- while (iterator.iterate(&r)) {
- ssize_t h = r.bottom - r.top;
- if (h) {
- size_t size = (r.right - r.left) * bpp;
- size_t o = (r.left + egl_native_window_t::stride * r.top) * bpp;
- uint8_t* s = screen_src + o;
- uint8_t* d = screen_dst + o;
- if (size == bpr) {
- size *= h;
- h = 1;
- }
- do {
- memcpy(d, s, size);
- d += bpr;
- s += bpr;
- } while (--h > 0);
- }
- }
- }
- }
-}
-
-void EGLDisplaySurface::copyFrontToImage(const copybit_image_t& dst)
-{
-#if HAVE_ANDROID_OS
- if (mBlitEngine) {
- copybit_image_t src = {
- w: egl_native_window_t::stride,
- h: egl_native_window_t::height,
- format: egl_native_window_t::format,
- offset: mFb[mIndex].data - mFb[0].data,
- base: (void*)egl_native_window_t::base,
- fd: egl_native_window_t::fd
- };
- region_iterator it(Region(Rect(
- egl_native_window_t::width, egl_native_window_t::height)));
- mBlitEngine->blit(mBlitEngine, &dst, &src, &it);
- } else
-#endif
- {
- uint8_t* const screen_src = mFb[ mIndex].data;
- const size_t bpp = bytesPerPixel(egl_native_window_t::format);
- const size_t bpr = egl_native_window_t::stride * bpp;
- memcpy((char*)dst.base + dst.offset, screen_src,
- bpr*egl_native_window_t::height);
- }
-}
-
-void EGLDisplaySurface::copyBackToImage(const copybit_image_t& dst)
-{
-#if HAVE_ANDROID_OS
- if (mBlitEngine) {
- copybit_image_t src = {
- w: egl_native_window_t::stride,
- h: egl_native_window_t::height,
- format: egl_native_window_t::format,
- offset: mFb[1-mIndex].data - mFb[0].data,
- base: (void*)egl_native_window_t::base,
- fd: egl_native_window_t::fd
- };
- region_iterator it(Region(Rect(
- egl_native_window_t::width, egl_native_window_t::height)));
- mBlitEngine->blit(mBlitEngine, &dst, &src, &it);
- } else
-#endif
- {
- uint8_t* const screen_src = mFb[1-mIndex].data;
- const size_t bpp = bytesPerPixel(egl_native_window_t::format);
- const size_t bpr = egl_native_window_t::stride * bpp;
- memcpy((char*)dst.base + dst.offset, screen_src,
- bpr*egl_native_window_t::height);
- }
-}
-
-
-status_t EGLDisplaySurface::mapFrameBuffer()
-{
- char const * const device_template[] = {
- "/dev/graphics/fb%u",
- "/dev/fb%u",
- 0 };
- int fd = -1;
- int i=0;
- char name[64];
- while ((fd==-1) && device_template[i]) {
- snprintf(name, 64, device_template[i], 0);
- fd = open(name, O_RDWR, 0);
- i++;
- }
- if (fd < 0)
- return -errno;
-
- struct fb_fix_screeninfo finfo;
- if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
- return -errno;
-
- struct fb_var_screeninfo info;
- if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
- return -errno;
-
- info.reserved[0] = 0;
- info.reserved[1] = 0;
- info.reserved[2] = 0;
- info.xoffset = 0;
- info.yoffset = 0;
- info.yres_virtual = info.yres * 2;
- info.bits_per_pixel = 16;
- /* Explicitly request 5/6/5 */
- info.red.offset = 11;
- info.red.length = 5;
- info.green.offset = 5;
- info.green.length = 6;
- info.blue.offset = 0;
- info.blue.length = 5;
- info.transp.offset = 0;
- info.transp.length = 0;
- info.activate = FB_ACTIVATE_NOW;
-
- uint32_t flags = PAGE_FLIP;
- if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) {
- info.yres_virtual = info.yres;
- flags &= ~PAGE_FLIP;
- LOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported");
- }
-
- if (info.yres_virtual < info.yres * 2) {
- info.yres_virtual = info.yres;
- flags &= ~PAGE_FLIP;
- LOGW("page flipping not supported (yres_virtual=%d, requested=%d)",
- info.yres_virtual, info.yres*2);
- }
-
- if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
- return -errno;
-
- int refreshRate = 1000000000000000LLU /
- (
- uint64_t( info.upper_margin + info.lower_margin + info.yres )
- * ( info.left_margin + info.right_margin + info.xres )
- * info.pixclock
- );
-
- if (refreshRate == 0) {
- // bleagh, bad info from the driver
- refreshRate = 60*1000; // 60 Hz
- }
- if (int(info.width) <= 0 || int(info.height) <= 0) {
- // the driver doesn't return that information
- // default to 160 dpi
- info.width = ((info.xres * 25.4f)/160.0f + 0.5f);
- info.height = ((info.yres * 25.4f)/160.0f + 0.5f);
- }
-
- float xdpi = (info.xres * 25.4f) / info.width;
- float ydpi = (info.yres * 25.4f) / info.height;
- float fps = refreshRate / 1000.0f;
-
- LOGI( "using (fd=%d)\n"
- "id = %s\n"
- "xres = %d px\n"
- "yres = %d px\n"
- "xres_virtual = %d px\n"
- "yres_virtual = %d px\n"
- "bpp = %d\n"
- "r = %2u:%u\n"
- "g = %2u:%u\n"
- "b = %2u:%u\n",
- fd,
- finfo.id,
- info.xres,
- info.yres,
- info.xres_virtual,
- info.yres_virtual,
- info.bits_per_pixel,
- info.red.offset, info.red.length,
- info.green.offset, info.green.length,
- info.blue.offset, info.blue.length
- );
-
- LOGI( "width = %d mm (%f dpi)\n"
- "height = %d mm (%f dpi)\n"
- "refresh rate = %.2f Hz\n",
- info.width, xdpi,
- info.height, ydpi,
- fps
- );
-
-
- if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
- return -errno;
-
- if (finfo.smem_len <= 0)
- return -errno;
-
- /*
- * Open and map the display.
- */
-
- void* buffer = (uint16_t*) mmap(
- 0, finfo.smem_len,
- PROT_READ | PROT_WRITE,
- MAP_SHARED,
- fd, 0);
-
- if (buffer == MAP_FAILED)
- return -errno;
-
- // at least for now, always clear the fb
- memset(buffer, 0, finfo.smem_len);
-
- uint8_t* offscreen[2];
- offscreen[0] = (uint8_t*)buffer;
- if (flags & PAGE_FLIP) {
- offscreen[1] = (uint8_t*)buffer + finfo.line_length*info.yres;
- } else {
- offscreen[1] = (uint8_t*)malloc(finfo.smem_len);
- if (offscreen[1] == 0) {
- munmap(buffer, finfo.smem_len);
- return NO_MEMORY;
- }
- }
-
- mFlags = flags;
- mInfo = info;
- mFinfo = finfo;
- mSize = finfo.smem_len;
- mIndex = 0;
- for (int i=0 ; i<2 ; i++) {
- mFb[i].version = sizeof(GGLSurface);
- mFb[i].width = info.xres;
- mFb[i].height = info.yres;
- mFb[i].stride = finfo.line_length / (info.bits_per_pixel >> 3);
- mFb[i].data = (GGLubyte*)(offscreen[i]);
- mFb[i].format = GGL_PIXEL_FORMAT_RGB_565;
- }
- return fd;
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
diff --git a/libs/ui/EGLNativeWindowSurface.cpp b/libs/ui/EGLNativeWindowSurface.cpp
deleted file mode 100644
index f1071cf..0000000
--- a/libs/ui/EGLNativeWindowSurface.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
-**
-** Copyright 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.
-*/
-
-#define LOG_TAG "EGLNativeWindowSurface"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <cutils/log.h>
-#include <cutils/atomic.h>
-
-#include <ui/SurfaceComposerClient.h>
-#include <ui/DisplayInfo.h>
-#include <ui/Rect.h>
-
-#include <EGL/egl.h>
-
-#include <pixelflinger/format.h>
-
-#include <ui/EGLNativeWindowSurface.h>
-
-// ----------------------------------------------------------------------------
-namespace android {
-// ----------------------------------------------------------------------------
-
-EGLNativeWindowSurface::EGLNativeWindowSurface(const sp<Surface>& surface)
- : EGLNativeSurface<EGLNativeWindowSurface>(),
- mSurface(surface), mConnected(false)
-{
- egl_native_window_t::magic = 0x600913;
- egl_native_window_t::version = sizeof(egl_native_window_t);
- egl_native_window_t::ident = 0;
- egl_native_window_t::incRef = &EGLNativeWindowSurface::hook_incRef;
- egl_native_window_t::decRef = &EGLNativeWindowSurface::hook_decRef;
- egl_native_window_t::swapBuffers = &EGLNativeWindowSurface::hook_swapBuffers;
- egl_native_window_t::connect = &EGLNativeWindowSurface::hook_connect;
- egl_native_window_t::disconnect = &EGLNativeWindowSurface::hook_disconnect;
-
- DisplayInfo dinfo;
- SurfaceComposerClient::getDisplayInfo(0, &dinfo);
- egl_native_window_t::xdpi = dinfo.xdpi;
- egl_native_window_t::ydpi = dinfo.ydpi;
- egl_native_window_t::fps = dinfo.fps;
- egl_native_window_t::flags= EGL_NATIVES_FLAG_DESTROY_BACKBUFFER;
-}
-
-EGLNativeWindowSurface::~EGLNativeWindowSurface()
-{
- disconnect();
- mSurface.clear();
- magic = 0;
-}
-
-void EGLNativeWindowSurface::hook_incRef(NativeWindowType window)
-{
- EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
- that->incStrong(that);
-}
-
-void EGLNativeWindowSurface::hook_decRef(NativeWindowType window)
-{
- EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
- that->decStrong(that);
-}
-
-void EGLNativeWindowSurface::hook_connect(NativeWindowType window)
-{
- EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
- that->connect();
-}
-
-void EGLNativeWindowSurface::hook_disconnect(NativeWindowType window)
-{
- EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
- that->disconnect();
-}
-
-uint32_t EGLNativeWindowSurface::hook_swapBuffers(NativeWindowType window)
-{
- EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
- return that->swapBuffers();
-}
-
-void EGLNativeWindowSurface::setSwapRectangle(int l, int t, int w, int h)
-{
- mSurface->setSwapRectangle(Rect(l, t, l+w, t+h));
-}
-
-uint32_t EGLNativeWindowSurface::swapBuffers()
-{
- const int w = egl_native_window_t::width;
- const int h = egl_native_window_t::height;
- const sp<Surface>& surface(mSurface);
- Surface::SurfaceInfo info;
- surface->unlockAndPost();
- surface->lock(&info);
- // update the address of the buffer to draw to next
- egl_native_window_t::base = intptr_t(info.base);
- egl_native_window_t::offset = intptr_t(info.bits) - intptr_t(info.base);
-
- // update size if it changed
- if (w != int(info.w) || h != int(info.h)) {
- egl_native_window_t::width = info.w;
- egl_native_window_t::height = info.h;
- egl_native_window_t::stride = info.bpr / bytesPerPixel(info.format);
- egl_native_window_t::format = info.format;
- return EGL_NATIVES_FLAG_SIZE_CHANGED;
- }
- return 0;
-}
-
-void EGLNativeWindowSurface::connect()
-{
- if (!mConnected) {
- Surface::SurfaceInfo info;
- mSurface->lock(&info);
- mSurface->setSwapRectangle(Rect(info.w, info.h));
- mConnected = true;
-
- egl_native_window_t::width = info.w;
- egl_native_window_t::height = info.h;
- egl_native_window_t::stride = info.bpr / bytesPerPixel(info.format);
- egl_native_window_t::format = info.format;
- egl_native_window_t::base = intptr_t(info.base);
- egl_native_window_t::offset = intptr_t(info.bits) - intptr_t(info.base);
- // FIXME: egl_native_window_t::memory_type used to be set from
- // mSurface, but we wanted to break this dependency. We set it to
- // GPU because the software rendered doesn't care, but the h/w
- // accelerator needs it. Eventually, this value should go away
- // completely, since memory will be managed by OpenGL.
- egl_native_window_t::memory_type = NATIVE_MEMORY_TYPE_GPU;
- egl_native_window_t::fd = 0;
- }
-}
-
-void EGLNativeWindowSurface::disconnect()
-{
- if (mConnected) {
- mSurface->unlock();
- mConnected = false;
- }
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
deleted file mode 100644
index 3b29b09..0000000
--- a/libs/ui/EventHub.cpp
+++ /dev/null
@@ -1,793 +0,0 @@
-//
-// Copyright 2005 The Android Open Source Project
-//
-// Handle events, like key input and vsync.
-//
-// The goal is to provide an optimized solution for Linux, not an
-// implementation that works well across all platforms. We expect
-// events to arrive on file descriptors, so that we can use a select()
-// select() call to sleep.
-//
-// We can't select() on anything but network sockets in Windows, so we
-// provide an alternative implementation of waitEvent for that platform.
-//
-#define LOG_TAG "EventHub"
-
-//#define LOG_NDEBUG 0
-
-#include <ui/EventHub.h>
-#include <hardware_legacy/power.h>
-
-#include <cutils/properties.h>
-#include <utils/IServiceManager.h>
-#include <utils/Log.h>
-#include <utils/Timers.h>
-#include <utils.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <memory.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "KeyLayoutMap.h"
-
-#include <string.h>
-#include <stdint.h>
-#include <dirent.h>
-#ifdef HAVE_INOTIFY
-# include <sys/inotify.h>
-#endif
-#ifdef HAVE_ANDROID_OS
-# include <sys/limits.h> /* not part of Linux */
-#endif
-#include <sys/poll.h>
-#include <sys/ioctl.h>
-
-/* this macro is used to tell if "bit" is set in "array"
- * it selects a byte from the array, and does a boolean AND
- * operation with a byte that only has the relevant bit set.
- * eg. to check for the 12th bit, we do (array[1] & 1<<4)
- */
-#define test_bit(bit, array) (array[bit/8] & (1<<(bit%8)))
-
-#define ID_MASK 0x0000ffff
-#define SEQ_MASK 0x7fff0000
-#define SEQ_SHIFT 16
-#define id_to_index(id) ((id&ID_MASK)+1)
-
-namespace android {
-
-static const char *WAKE_LOCK_ID = "KeyEvents";
-static const char *device_path = "/dev/input";
-
-/* return the larger integer */
-static inline int max(int v1, int v2)
-{
- return (v1 > v2) ? v1 : v2;
-}
-
-EventHub::device_t::device_t(int32_t _id, const char* _path)
- : id(_id), path(_path), classes(0)
- , keyBitmask(NULL), layoutMap(new KeyLayoutMap()), next(NULL) {
-}
-
-EventHub::device_t::~device_t() {
- delete [] keyBitmask;
- delete layoutMap;
-}
-
-EventHub::EventHub(void)
- : mError(NO_INIT), mHaveFirstKeyboard(false), mFirstKeyboardId(0)
- , mDevicesById(0), mNumDevicesById(0)
- , mOpeningDevices(0), mClosingDevices(0)
- , mDevices(0), mFDs(0), mFDCount(0)
-{
- acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
-#ifdef EV_SW
- memset(mSwitches, 0, sizeof(mSwitches));
-#endif
-}
-
-/*
- * Clean up.
- */
-EventHub::~EventHub(void)
-{
- release_wake_lock(WAKE_LOCK_ID);
- // we should free stuff here...
-}
-
-void EventHub::onFirstRef()
-{
- mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR;
-}
-
-status_t EventHub::errorCheck() const
-{
- return mError;
-}
-
-String8 EventHub::getDeviceName(int32_t deviceId) const
-{
- AutoMutex _l(mLock);
- device_t* device = getDevice(deviceId);
- if (device == NULL) return String8();
- return device->name;
-}
-
-uint32_t EventHub::getDeviceClasses(int32_t deviceId) const
-{
- AutoMutex _l(mLock);
- device_t* device = getDevice(deviceId);
- if (device == NULL) return 0;
- return device->classes;
-}
-
-int EventHub::getAbsoluteInfo(int32_t deviceId, int axis, int *outMinValue,
- int* outMaxValue, int* outFlat, int* outFuzz) const
-{
- AutoMutex _l(mLock);
- device_t* device = getDevice(deviceId);
- if (device == NULL) return -1;
-
- struct input_absinfo info;
-
- if(ioctl(mFDs[id_to_index(device->id)].fd, EVIOCGABS(axis), &info)) {
- LOGE("Error reading absolute controller %d for device %s fd %d\n",
- axis, device->name.string(), mFDs[id_to_index(device->id)].fd);
- return -1;
- }
- *outMinValue = info.minimum;
- *outMaxValue = info.maximum;
- *outFlat = info.flat;
- *outFuzz = info.fuzz;
- return 0;
-}
-
-int EventHub::getSwitchState(int sw) const
-{
-#ifdef EV_SW
- if (sw >= 0 && sw <= SW_MAX) {
- int32_t devid = mSwitches[sw];
- if (devid != 0) {
- return getSwitchState(devid, sw);
- }
- }
-#endif
- return -1;
-}
-
-int EventHub::getSwitchState(int32_t deviceId, int sw) const
-{
-#ifdef EV_SW
- AutoMutex _l(mLock);
- device_t* device = getDevice(deviceId);
- if (device == NULL) return -1;
-
- if (sw >= 0 && sw <= SW_MAX) {
- uint8_t sw_bitmask[(SW_MAX+1)/8];
- memset(sw_bitmask, 0, sizeof(sw_bitmask));
- if (ioctl(mFDs[id_to_index(device->id)].fd,
- EVIOCGSW(sizeof(sw_bitmask)), sw_bitmask) >= 0) {
- return test_bit(sw, sw_bitmask) ? 1 : 0;
- }
- }
-#endif
-
- return -1;
-}
-
-int EventHub::getScancodeState(int code) const
-{
- return getScancodeState(mFirstKeyboardId, code);
-}
-
-int EventHub::getScancodeState(int32_t deviceId, int code) const
-{
- AutoMutex _l(mLock);
- device_t* device = getDevice(deviceId);
- if (device == NULL) return -1;
-
- if (code >= 0 && code <= KEY_MAX) {
- uint8_t key_bitmask[(KEY_MAX+1)/8];
- memset(key_bitmask, 0, sizeof(key_bitmask));
- if (ioctl(mFDs[id_to_index(device->id)].fd,
- EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) {
- return test_bit(code, key_bitmask) ? 1 : 0;
- }
- }
-
- return -1;
-}
-
-int EventHub::getKeycodeState(int code) const
-{
- return getKeycodeState(mFirstKeyboardId, code);
-}
-
-int EventHub::getKeycodeState(int32_t deviceId, int code) const
-{
- AutoMutex _l(mLock);
- device_t* device = getDevice(deviceId);
- if (device == NULL || device->layoutMap == NULL) return -1;
-
- Vector<int32_t> scanCodes;
- device->layoutMap->findScancodes(code, &scanCodes);
-
- uint8_t key_bitmask[(KEY_MAX+1)/8];
- memset(key_bitmask, 0, sizeof(key_bitmask));
- if (ioctl(mFDs[id_to_index(device->id)].fd,
- EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) {
- #if 0
- for (size_t i=0; i<=KEY_MAX; i++) {
- LOGI("(Scan code %d: down=%d)", i, test_bit(i, key_bitmask));
- }
- #endif
- const size_t N = scanCodes.size();
- for (size_t i=0; i<N && i<=KEY_MAX; i++) {
- int32_t sc = scanCodes.itemAt(i);
- //LOGI("Code %d: down=%d", sc, test_bit(sc, key_bitmask));
- if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, key_bitmask)) {
- return 1;
- }
- }
- }
-
- return 0;
-}
-
-EventHub::device_t* EventHub::getDevice(int32_t deviceId) const
-{
- if (deviceId == 0) deviceId = mFirstKeyboardId;
- int32_t id = deviceId & ID_MASK;
- if (id >= mNumDevicesById || id < 0) return NULL;
- device_t* dev = mDevicesById[id].device;
- if (dev->id == deviceId) {
- return dev;
- }
- return NULL;
-}
-
-bool EventHub::getEvent(int32_t* outDeviceId, int32_t* outType,
- int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
- int32_t* outValue, nsecs_t* outWhen)
-{
- *outDeviceId = 0;
- *outType = 0;
- *outScancode = 0;
- *outKeycode = 0;
- *outFlags = 0;
- *outValue = 0;
- *outWhen = 0;
-
- status_t err;
-
- fd_set readfds;
- int maxFd = -1;
- int cc;
- int i;
- int res;
- int pollres;
- struct input_event iev;
-
- // Note that we only allow one caller to getEvent(), so don't need
- // to do locking here... only when adding/removing devices.
-
- while(1) {
-
- // First, report any devices that had last been added/removed.
- if (mClosingDevices != NULL) {
- device_t* device = mClosingDevices;
- LOGV("Reporting device closed: id=0x%x, name=%s\n",
- device->id, device->path.string());
- mClosingDevices = device->next;
- *outDeviceId = device->id;
- if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
- *outType = DEVICE_REMOVED;
- delete device;
- return true;
- }
- if (mOpeningDevices != NULL) {
- device_t* device = mOpeningDevices;
- LOGV("Reporting device opened: id=0x%x, name=%s\n",
- device->id, device->path.string());
- mOpeningDevices = device->next;
- *outDeviceId = device->id;
- if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
- *outType = DEVICE_ADDED;
- return true;
- }
-
- release_wake_lock(WAKE_LOCK_ID);
-
- pollres = poll(mFDs, mFDCount, -1);
-
- acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
-
- if (pollres <= 0) {
- if (errno != EINTR) {
- LOGW("select failed (errno=%d)\n", errno);
- usleep(100000);
- }
- continue;
- }
-
- //printf("poll %d, returned %d\n", mFDCount, pollres);
-
- // mFDs[0] is used for inotify, so process regular events starting at mFDs[1]
- for(i = 1; i < mFDCount; i++) {
- if(mFDs[i].revents) {
- LOGV("revents for %d = 0x%08x", i, mFDs[i].revents);
- if(mFDs[i].revents & POLLIN) {
- res = read(mFDs[i].fd, &iev, sizeof(iev));
- if (res == sizeof(iev)) {
- LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d",
- mDevices[i]->path.string(),
- (int) iev.time.tv_sec, (int) iev.time.tv_usec,
- iev.type, iev.code, iev.value);
- *outDeviceId = mDevices[i]->id;
- if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
- *outType = iev.type;
- *outScancode = iev.code;
- if (iev.type == EV_KEY) {
- err = mDevices[i]->layoutMap->map(iev.code, outKeycode, outFlags);
- LOGV("iev.code=%d outKeycode=%d outFlags=0x%08x err=%d\n",
- iev.code, *outKeycode, *outFlags, err);
- if (err != 0) {
- *outKeycode = 0;
- *outFlags = 0;
- }
- } else {
- *outKeycode = iev.code;
- }
- *outValue = iev.value;
- *outWhen = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec);
- return true;
- } else {
- if (res<0) {
- LOGW("could not get event (errno=%d)", errno);
- } else {
- LOGE("could not get event (wrong size: %d)", res);
- }
- continue;
- }
- }
- }
- }
-
- // read_notify() will modify mFDs and mFDCount, so this must be done after
- // processing all other events.
- if(mFDs[0].revents & POLLIN) {
- read_notify(mFDs[0].fd);
- }
- }
-}
-
-/*
- * Open the platform-specific input device.
- */
-bool EventHub::openPlatformInput(void)
-{
- /*
- * Open platform-specific input device(s).
- */
- int res;
-
- mFDCount = 1;
- mFDs = (pollfd *)calloc(1, sizeof(mFDs[0]));
- mDevices = (device_t **)calloc(1, sizeof(mDevices[0]));
- mFDs[0].events = POLLIN;
- mDevices[0] = NULL;
-#ifdef HAVE_INOTIFY
- mFDs[0].fd = inotify_init();
- res = inotify_add_watch(mFDs[0].fd, device_path, IN_DELETE | IN_CREATE);
- if(res < 0) {
- LOGE("could not add watch for %s, %s\n", device_path, strerror(errno));
- }
-#else
- /*
- * The code in EventHub::getEvent assumes that mFDs[0] is an inotify fd.
- * We allocate space for it and set it to something invalid.
- */
- mFDs[0].fd = -1;
-#endif
-
- res = scan_dir(device_path);
- if(res < 0) {
- LOGE("scan dir failed for %s\n", device_path);
- //open_device("/dev/input/event0");
- }
-
- return true;
-}
-
-/*
- * Inspect the known devices to determine whether physical keys exist for the given
- * framework-domain key codes.
- */
-bool EventHub::hasKeys(size_t numCodes, int32_t* keyCodes, uint8_t* outFlags) {
- for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) {
- outFlags[codeIndex] = 0;
-
- // check each available hardware device for support for this keycode
- Vector<int32_t> scanCodes;
- for (int n = 0; (n < mFDCount) && (outFlags[codeIndex] == 0); n++) {
- if (mDevices[n]) {
- status_t err = mDevices[n]->layoutMap->findScancodes(keyCodes[codeIndex], &scanCodes);
- if (!err) {
- // check the possible scan codes identified by the layout map against the
- // map of codes actually emitted by the driver
- for (size_t sc = 0; sc < scanCodes.size(); sc++) {
- if (test_bit(scanCodes[sc], mDevices[n]->keyBitmask)) {
- outFlags[codeIndex] = 1;
- break;
- }
- }
- }
- }
- }
- }
-
- return true;
-}
-
-// ----------------------------------------------------------------------------
-
-int EventHub::open_device(const char *deviceName)
-{
- int version;
- int fd;
- struct pollfd *new_mFDs;
- device_t **new_devices;
- char **new_device_names;
- char name[80];
- char location[80];
- char idstr[80];
- struct input_id id;
-
- LOGV("Opening device: %s", deviceName);
-
- AutoMutex _l(mLock);
-
- fd = open(deviceName, O_RDWR);
- if(fd < 0) {
- LOGE("could not open %s, %s\n", deviceName, strerror(errno));
- return -1;
- }
-
- if(ioctl(fd, EVIOCGVERSION, &version)) {
- LOGE("could not get driver version for %s, %s\n", deviceName, strerror(errno));
- return -1;
- }
- if(ioctl(fd, EVIOCGID, &id)) {
- LOGE("could not get driver id for %s, %s\n", deviceName, strerror(errno));
- return -1;
- }
- name[sizeof(name) - 1] = '\0';
- location[sizeof(location) - 1] = '\0';
- idstr[sizeof(idstr) - 1] = '\0';
- if(ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
- //fprintf(stderr, "could not get device name for %s, %s\n", deviceName, strerror(errno));
- name[0] = '\0';
- }
- if(ioctl(fd, EVIOCGPHYS(sizeof(location) - 1), &location) < 1) {
- //fprintf(stderr, "could not get location for %s, %s\n", deviceName, strerror(errno));
- location[0] = '\0';
- }
- if(ioctl(fd, EVIOCGUNIQ(sizeof(idstr) - 1), &idstr) < 1) {
- //fprintf(stderr, "could not get idstring for %s, %s\n", deviceName, strerror(errno));
- idstr[0] = '\0';
- }
-
- int devid = 0;
- while (devid < mNumDevicesById) {
- if (mDevicesById[devid].device == NULL) {
- break;
- }
- devid++;
- }
- if (devid >= mNumDevicesById) {
- device_ent* new_devids = (device_ent*)realloc(mDevicesById,
- sizeof(mDevicesById[0]) * (devid + 1));
- if (new_devids == NULL) {
- LOGE("out of memory");
- return -1;
- }
- mDevicesById = new_devids;
- mNumDevicesById = devid+1;
- mDevicesById[devid].device = NULL;
- mDevicesById[devid].seq = 0;
- }
-
- mDevicesById[devid].seq = (mDevicesById[devid].seq+(1<<SEQ_SHIFT))&SEQ_MASK;
- if (mDevicesById[devid].seq == 0) {
- mDevicesById[devid].seq = 1<<SEQ_SHIFT;
- }
-
- new_mFDs = (pollfd*)realloc(mFDs, sizeof(mFDs[0]) * (mFDCount + 1));
- new_devices = (device_t**)realloc(mDevices, sizeof(mDevices[0]) * (mFDCount + 1));
- if (new_mFDs == NULL || new_devices == NULL) {
- LOGE("out of memory");
- return -1;
- }
- mFDs = new_mFDs;
- mDevices = new_devices;
-
-#if 0
- LOGI("add device %d: %s\n", mFDCount, deviceName);
- LOGI(" bus: %04x\n"
- " vendor %04x\n"
- " product %04x\n"
- " version %04x\n",
- id.bustype, id.vendor, id.product, id.version);
- LOGI(" name: \"%s\"\n", name);
- LOGI(" location: \"%s\"\n"
- " id: \"%s\"\n", location, idstr);
- LOGI(" version: %d.%d.%d\n",
- version >> 16, (version >> 8) & 0xff, version & 0xff);
-#endif
-
- device_t* device = new device_t(devid|mDevicesById[devid].seq, deviceName);
- if (device == NULL) {
- LOGE("out of memory");
- return -1;
- }
-
- mFDs[mFDCount].fd = fd;
- mFDs[mFDCount].events = POLLIN;
-
- // figure out the kinds of events the device reports
- uint8_t key_bitmask[(KEY_MAX+1)/8];
- memset(key_bitmask, 0, sizeof(key_bitmask));
- LOGV("Getting keys...");
- if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >= 0) {
- //LOGI("MAP\n");
- //for (int i=0; i<((KEY_MAX+1)/8); i++) {
- // LOGI("%d: 0x%02x\n", i, key_bitmask[i]);
- //}
- for (int i=0; i<((BTN_MISC+7)/8); i++) {
- if (key_bitmask[i] != 0) {
- device->classes |= CLASS_KEYBOARD;
- // 'Q' key support = cheap test of whether this is an alpha-capable kbd
- if (test_bit(KEY_Q, key_bitmask)) {
- device->classes |= CLASS_ALPHAKEY;
- }
- break;
- }
- }
- if ((device->classes & CLASS_KEYBOARD) != 0) {
- device->keyBitmask = new uint8_t[(KEY_MAX+1)/8];
- if (device->keyBitmask != NULL) {
- memcpy(device->keyBitmask, key_bitmask, sizeof(key_bitmask));
- } else {
- delete device;
- LOGE("out of memory allocating key bitmask");
- return -1;
- }
- }
- }
- if (test_bit(BTN_MOUSE, key_bitmask)) {
- uint8_t rel_bitmask[(REL_MAX+1)/8];
- memset(rel_bitmask, 0, sizeof(rel_bitmask));
- LOGV("Getting relative controllers...");
- if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) >= 0)
- {
- if (test_bit(REL_X, rel_bitmask) && test_bit(REL_Y, rel_bitmask)) {
- device->classes |= CLASS_TRACKBALL;
- }
- }
- }
- if (test_bit(BTN_TOUCH, key_bitmask)) {
- uint8_t abs_bitmask[(ABS_MAX+1)/8];
- memset(abs_bitmask, 0, sizeof(abs_bitmask));
- LOGV("Getting absolute controllers...");
- if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) >= 0)
- {
- if (test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
- device->classes |= CLASS_TOUCHSCREEN;
- }
- }
- }
-
-#ifdef EV_SW
- // figure out the switches this device reports
- uint8_t sw_bitmask[(SW_MAX+1)/8];
- memset(sw_bitmask, 0, sizeof(sw_bitmask));
- if (ioctl(fd, EVIOCGBIT(EV_SW, sizeof(sw_bitmask)), sw_bitmask) >= 0) {
- for (int i=0; i<EV_SW; i++) {
- //LOGI("Device 0x%x sw %d: has=%d", device->id, i, test_bit(i, sw_bitmask));
- if (test_bit(i, sw_bitmask)) {
- if (mSwitches[i] == 0) {
- mSwitches[i] = device->id;
- }
- }
- }
- }
-#endif
-
- LOGI("New device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x\n",
- deviceName, name, device->id, mNumDevicesById, mFDCount, fd, device->classes);
-
- if ((device->classes&CLASS_KEYBOARD) != 0) {
- char devname[101];
- char tmpfn[101];
- char keylayoutFilename[300];
-
- // a more descriptive name
- ioctl(mFDs[mFDCount].fd, EVIOCGNAME(sizeof(devname)-1), devname);
- devname[sizeof(devname)-1] = 0;
- device->name = devname;
-
- // replace all the spaces with underscores
- strcpy(tmpfn, devname);
- for (char *p = strchr(tmpfn, ' '); p && *p; p = strchr(tmpfn, ' '))
- *p = '_';
-
- // find the .kl file we need for this device
- const char* root = getenv("ANDROID_ROOT");
- snprintf(keylayoutFilename, sizeof(keylayoutFilename),
- "%s/usr/keylayout/%s.kl", root, tmpfn);
- bool defaultKeymap = false;
- if (access(keylayoutFilename, R_OK)) {
- snprintf(keylayoutFilename, sizeof(keylayoutFilename),
- "%s/usr/keylayout/%s", root, "qwerty.kl");
- defaultKeymap = true;
- }
- device->layoutMap->load(keylayoutFilename);
-
- // tell the world about the devname (the descriptive name)
- int32_t publicID;
- if (!mHaveFirstKeyboard && !defaultKeymap) {
- publicID = 0;
- // the built-in keyboard has a well-known device ID of 0,
- // this device better not go away.
- mHaveFirstKeyboard = true;
- mFirstKeyboardId = device->id;
- } else {
- publicID = device->id;
- // ensure mFirstKeyboardId is set to -something-.
- if (mFirstKeyboardId == 0) {
- mFirstKeyboardId = device->id;
- }
- }
- char propName[100];
- sprintf(propName, "hw.keyboards.%u.devname", publicID);
- property_set(propName, devname);
-
- LOGI("New keyboard: publicID=%d device->id=%d devname='%s' propName='%s' keylayout='%s'\n",
- publicID, device->id, devname, propName, keylayoutFilename);
- }
-
- LOGV("Adding device %s %p at %d, id = %d, classes = 0x%x\n",
- deviceName, device, mFDCount, devid, device->classes);
-
- mDevicesById[devid].device = device;
- device->next = mOpeningDevices;
- mOpeningDevices = device;
- mDevices[mFDCount] = device;
-
- mFDCount++;
- return 0;
-}
-
-int EventHub::close_device(const char *deviceName)
-{
- AutoMutex _l(mLock);
-
- int i;
- for(i = 1; i < mFDCount; i++) {
- if(strcmp(mDevices[i]->path.string(), deviceName) == 0) {
- //LOGD("remove device %d: %s\n", i, deviceName);
- device_t* device = mDevices[i];
- int count = mFDCount - i - 1;
- int index = (device->id&ID_MASK);
- mDevicesById[index].device = NULL;
- memmove(mDevices + i, mDevices + i + 1, sizeof(mDevices[0]) * count);
- memmove(mFDs + i, mFDs + i + 1, sizeof(mFDs[0]) * count);
-
-#ifdef EV_SW
- for (int j=0; j<EV_SW; j++) {
- if (mSwitches[j] == device->id) {
- mSwitches[j] = 0;
- }
- }
-#endif
-
- device->next = mClosingDevices;
- mClosingDevices = device;
-
- mFDCount--;
-
- uint32_t publicID;
- if (device->id == mFirstKeyboardId) {
- LOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this",
- device->path.string(), mFirstKeyboardId);
- mFirstKeyboardId = 0;
- publicID = 0;
- } else {
- publicID = device->id;
- }
- // clear the property
- char propName[100];
- sprintf(propName, "hw.keyboards.%u.devname", publicID);
- property_set(propName, NULL);
- return 0;
- }
- }
- LOGE("remote device: %s not found\n", deviceName);
- return -1;
-}
-
-int EventHub::read_notify(int nfd)
-{
-#ifdef HAVE_INOTIFY
- int res;
- char devname[PATH_MAX];
- char *filename;
- char event_buf[512];
- int event_size;
- int event_pos = 0;
- struct inotify_event *event;
-
- res = read(nfd, event_buf, sizeof(event_buf));
- if(res < (int)sizeof(*event)) {
- if(errno == EINTR)
- return 0;
- LOGW("could not get event, %s\n", strerror(errno));
- return 1;
- }
- //printf("got %d bytes of event information\n", res);
-
- strcpy(devname, device_path);
- filename = devname + strlen(devname);
- *filename++ = '/';
-
- while(res >= (int)sizeof(*event)) {
- event = (struct inotify_event *)(event_buf + event_pos);
- //printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : "");
- if(event->len) {
- strcpy(filename, event->name);
- if(event->mask & IN_CREATE) {
- open_device(devname);
- }
- else {
- close_device(devname);
- }
- }
- event_size = sizeof(*event) + event->len;
- res -= event_size;
- event_pos += event_size;
- }
-#endif
- return 0;
-}
-
-
-int EventHub::scan_dir(const char *dirname)
-{
- char devname[PATH_MAX];
- char *filename;
- DIR *dir;
- struct dirent *de;
- dir = opendir(dirname);
- if(dir == NULL)
- return -1;
- strcpy(devname, dirname);
- filename = devname + strlen(devname);
- *filename++ = '/';
- while((de = readdir(dir))) {
- if(de->d_name[0] == '.' &&
- (de->d_name[1] == '\0' ||
- (de->d_name[1] == '.' && de->d_name[2] == '\0')))
- continue;
- strcpy(filename, de->d_name);
- open_device(devname);
- }
- closedir(dir);
- return 0;
-}
-
-}; // namespace android
diff --git a/libs/ui/EventRecurrence.cpp b/libs/ui/EventRecurrence.cpp
deleted file mode 100644
index b436b50..0000000
--- a/libs/ui/EventRecurrence.cpp
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright 2006 The Android Open Source Project
- */
-
-#include <pim/EventRecurrence.h>
-#include <utils/String8.h>
-#include <stdio.h>
-#include <limits.h>
-
-namespace android {
-
-#define FAIL_HERE() do { \
- printf("Parsing failed at line %d\n", __LINE__); \
- return UNKNOWN_ERROR; \
- } while(0)
-
-EventRecurrence::EventRecurrence()
- :freq((freq_t)0),
- until(),
- count(0),
- interval(0),
- bysecond(0),
- bysecondCount(0),
- byminute(0),
- byminuteCount(0),
- byhour(0),
- byhourCount(0),
- byday(0),
- bydayNum(0),
- bydayCount(0),
- bymonthday(0),
- bymonthdayCount(0),
- byyearday(0),
- byyeardayCount(0),
- byweekno(0),
- byweeknoCount(0),
- bymonth(0),
- bymonthCount(0),
- bysetpos(0),
- bysetposCount(0),
- wkst(0)
-{
-}
-
-EventRecurrence::~EventRecurrence()
-{
- delete[] bysecond;
- delete[] byminute;
- delete[] byhour;
- delete[] byday;
- delete[] bydayNum;
- delete[] byyearday;
- delete[] bymonthday;
- delete[] byweekno;
- delete[] bymonth;
- delete[] bysetpos;
-}
-
-enum LHS {
- NONE_LHS = 0,
- FREQ,
- UNTIL,
- COUNT,
- INTERVAL,
- BYSECOND,
- BYMINUTE,
- BYHOUR,
- BYDAY,
- BYMONTHDAY,
- BYYEARDAY,
- BYWEEKNO,
- BYMONTH,
- BYSETPOS,
- WKST
-};
-
-struct LHSProc
-{
- const char16_t* text;
- size_t textSize;
- uint32_t value;
-};
-
-const char16_t FREQ_text[] = { 'F', 'R', 'E', 'Q' };
-const char16_t UNTIL_text[] = { 'U', 'N', 'T', 'I', 'L' };
-const char16_t COUNT_text[] = { 'C', 'O', 'U', 'N', 'T' };
-const char16_t INTERVAL_text[] = { 'I', 'N', 'T', 'E', 'R', 'V', 'A', 'L'};
-const char16_t BYSECOND_text[] = { 'B', 'Y', 'S', 'E', 'C', 'O', 'N', 'D' };
-const char16_t BYMINUTE_text[] = { 'B', 'Y', 'M', 'I', 'N', 'U', 'T', 'E' };
-const char16_t BYHOUR_text[] = { 'B', 'Y', 'H', 'O', 'U', 'R' };
-const char16_t BYDAY_text[] = { 'B', 'Y', 'D', 'A', 'Y' };
-const char16_t BYMONTHDAY_text[] = { 'B','Y','M','O','N','T','H','D','A','Y' };
-const char16_t BYYEARDAY_text[] = { 'B','Y','Y','E','A','R','D','A','Y' };
-const char16_t BYWEEKNO_text[] = { 'B', 'Y', 'W', 'E', 'E', 'K', 'N', 'O' };
-const char16_t BYMONTH_text[] = { 'B', 'Y', 'M', 'O', 'N', 'T', 'H' };
-const char16_t BYSETPOS_text[] = { 'B', 'Y', 'S', 'E', 'T', 'P', 'O', 'S' };
-const char16_t WKST_text[] = { 'W', 'K', 'S', 'T' };
-
-#define SIZ(x) (sizeof(x)/sizeof(x[0]))
-
-const LHSProc LHSPROC[] = {
- { FREQ_text, SIZ(FREQ_text), FREQ },
- { UNTIL_text, SIZ(UNTIL_text), UNTIL },
- { COUNT_text, SIZ(COUNT_text), COUNT },
- { INTERVAL_text, SIZ(INTERVAL_text), INTERVAL },
- { BYSECOND_text, SIZ(BYSECOND_text), BYSECOND },
- { BYMINUTE_text, SIZ(BYMINUTE_text), BYMINUTE },
- { BYHOUR_text, SIZ(BYHOUR_text), BYHOUR },
- { BYDAY_text, SIZ(BYDAY_text), BYDAY },
- { BYMONTHDAY_text, SIZ(BYMONTHDAY_text), BYMONTHDAY },
- { BYYEARDAY_text, SIZ(BYYEARDAY_text), BYYEARDAY },
- { BYWEEKNO_text, SIZ(BYWEEKNO_text), BYWEEKNO },
- { BYMONTH_text, SIZ(BYMONTH_text), BYMONTH },
- { BYSETPOS_text, SIZ(BYSETPOS_text), BYSETPOS },
- { WKST_text, SIZ(WKST_text), WKST },
- { NULL, 0, NONE_LHS },
-};
-
-const char16_t SECONDLY_text[] = { 'S','E','C','O','N','D','L','Y' };
-const char16_t MINUTELY_text[] = { 'M','I','N','U','T','E','L','Y' };
-const char16_t HOURLY_text[] = { 'H','O','U','R','L','Y' };
-const char16_t DAILY_text[] = { 'D','A','I','L','Y' };
-const char16_t WEEKLY_text[] = { 'W','E','E','K','L','Y' };
-const char16_t MONTHLY_text[] = { 'M','O','N','T','H','L','Y' };
-const char16_t YEARLY_text[] = { 'Y','E','A','R','L','Y' };
-
-typedef LHSProc FreqProc;
-
-const FreqProc FREQPROC[] = {
- { SECONDLY_text, SIZ(SECONDLY_text), EventRecurrence::SECONDLY },
- { MINUTELY_text, SIZ(MINUTELY_text), EventRecurrence::MINUTELY },
- { HOURLY_text, SIZ(HOURLY_text), EventRecurrence::HOURLY },
- { DAILY_text, SIZ(DAILY_text), EventRecurrence::DAILY },
- { WEEKLY_text, SIZ(WEEKLY_text), EventRecurrence::WEEKLY },
- { MONTHLY_text, SIZ(MONTHLY_text), EventRecurrence::MONTHLY },
- { YEARLY_text, SIZ(YEARLY_text), EventRecurrence::YEARLY },
- { NULL, 0, NONE_LHS },
-};
-
-const char16_t SU_text[] = { 'S','U' };
-const char16_t MO_text[] = { 'M','O' };
-const char16_t TU_text[] = { 'T','U' };
-const char16_t WE_text[] = { 'W','E' };
-const char16_t TH_text[] = { 'T','H' };
-const char16_t FR_text[] = { 'F','R' };
-const char16_t SA_text[] = { 'S','A' };
-
-const FreqProc WEEKDAYPROC[] = {
- { SU_text, SIZ(SU_text), EventRecurrence::SU },
- { MO_text, SIZ(MO_text), EventRecurrence::MO },
- { TU_text, SIZ(TU_text), EventRecurrence::TU },
- { WE_text, SIZ(WE_text), EventRecurrence::WE },
- { TH_text, SIZ(TH_text), EventRecurrence::TH },
- { FR_text, SIZ(FR_text), EventRecurrence::FR },
- { SA_text, SIZ(SA_text), EventRecurrence::SA },
- { NULL, 0, NONE_LHS },
-};
-
-// returns the index into LHSPROC for the match or -1 if not found
-inline static int
-match_proc(const LHSProc* p, const char16_t* str, size_t len)
-{
- int i = 0;
- while (p->text != NULL) {
- if (p->textSize == len) {
- if (0 == memcmp(p->text, str, len*sizeof(char16_t))) {
- return i;
- }
- }
- p++;
- i++;
- }
- return -1;
-}
-
-// rangeMin and rangeMax are inclusive
-static status_t
-parse_int(const char16_t* str, size_t len, int* out,
- int rangeMin, int rangeMax, bool zeroOK)
-{
- char16_t c;
- size_t i=0;
-
- if (len == 0) {
- FAIL_HERE();
- }
- bool negative = false;
- c = str[0];
- if (c == '-' ) {
- negative = true;
- i++;
- }
- else if (c == '+') {
- i++;
- }
- int n = 0;
- for (; i<len; i++) {
- c = str[i];
- if (c < '0' || c > '9') {
- FAIL_HERE();
- }
- int prev = n;
- n *= 10;
- // the spec doesn't address how big these numbers can be,
- // so we're not going to worry about not being able to represent
- // INT_MIN, and if we're going to wrap, we'll just clamp to
- // INT_MAX instead
- if (n < prev) {
- n = INT_MAX;
- } else {
- n += c - '0';
- }
- }
- if (negative) {
- n = -n;
- }
- if (n < rangeMin || n > rangeMax) {
- FAIL_HERE();
- }
- if (!zeroOK && n == 0) {
- FAIL_HERE();
- }
- *out = n;
- return NO_ERROR;
-}
-
-static status_t
-parse_int_list(const char16_t* str, size_t len, int* countOut, int** listOut,
- int rangeMin, int rangeMax, bool zeroOK,
- status_t (*func)(const char16_t*,size_t,int*,int,int,bool)=parse_int)
-{
- status_t err;
-
- if (len == 0) {
- *countOut = 0;
- *listOut = NULL;
- return NO_ERROR;
- }
-
- // make one pass through looking for commas so we know how big to make our
- // out array.
- int count = 1;
- for (size_t i=0; i<len; i++) {
- if (str[i] == ',') {
- count++;
- }
- }
-
- int* list = new int[count];
- const char16_t* p = str;
- int commaIndex = 0;
- size_t i;
-
- for (i=0; i<len; i++) {
- if (str[i] == ',') {
- err = func(p, (str+i-p), list+commaIndex, rangeMin,
- rangeMax, zeroOK);
- if (err != NO_ERROR) {
- goto bail;
- }
- commaIndex++;
- p = str+i+1;
- }
- }
-
- err = func(p, (str+i-p), list+commaIndex, rangeMin, rangeMax, zeroOK);
- if (err != NO_ERROR) {
- goto bail;
- }
- commaIndex++;
-
- *countOut = count;
- *listOut = list;
-
- return NO_ERROR;
-
-bail:
- delete[] list;
- FAIL_HERE();
-}
-
-// the numbers here are small, so we pack them both into one value, and then
-// split it out later. it lets us reuse all the comma separated list code.
-static status_t
-parse_byday(const char16_t* s, size_t len, int* out,
- int rangeMin, int rangeMax, bool zeroOK)
-{
- status_t err;
- int n = 0;
- const char16_t* p = s;
- size_t plen = len;
-
- if (len > 0) {
- char16_t c = s[0];
- if (c == '-' || c == '+' || (c >= '0' && c <= '9')) {
- if (len > 1) {
- size_t nlen = 0;
- c = s[nlen];
- while (nlen < len
- && (c == '-' || c == '+' || (c >= '0' && c <= '9'))) {
- c = s[nlen];
- nlen++;
- }
- if (nlen > 0) {
- nlen--;
- err = parse_int(s, nlen, &n, rangeMin, rangeMax, zeroOK);
- if (err != NO_ERROR) {
- FAIL_HERE();
- }
- p += nlen;
- plen -= nlen;
- }
- }
- }
-
- int index = match_proc(WEEKDAYPROC, p, plen);
- if (index >= 0) {
- *out = (0xffff0000 & WEEKDAYPROC[index].value)
- | (0x0000ffff & n);
- return NO_ERROR;
- }
- }
- return UNKNOWN_ERROR;
-}
-
-static void
-postprocess_byday(int count, int* byday, int** bydayNum)
-{
- int* bdn = new int[count];
- *bydayNum = bdn;
- for (int i=0; i<count; i++) {
- uint32_t v = byday[i];
- int16_t num = v & 0x0000ffff;
- byday[i] = v & 0xffff0000;
- // will sign extend:
- bdn[i] = num;
- }
-}
-
-#define PARSE_INT_LIST_CHECKED(name, rangeMin, rangeMax, zeroOK) \
- if (name##Count != 0 || NO_ERROR != parse_int_list(s, slen, \
- &name##Count, &name, rangeMin, rangeMax, zeroOK)) { \
- FAIL_HERE(); \
- }
-status_t
-EventRecurrence::parse(const String16& str)
-{
- char16_t const* work = str.string();
- size_t len = str.size();
-
- int lhsIndex = NONE_LHS;
- int index;
-
- size_t start = 0;
- for (size_t i=0; i<len; i++) {
- char16_t c = work[i];
- if (c != ';' && i == len-1) {
- c = ';';
- i++;
- }
- if (c == ';' || c == '=') {
- if (i != start) {
- const char16_t* s = work+start;
- const size_t slen = i-start;
-
- String8 thestring(String16(s, slen));
-
- switch (c)
- {
- case '=':
- if (lhsIndex == NONE_LHS) {
- lhsIndex = match_proc(LHSPROC, s, slen);
- if (lhsIndex >= 0) {
- break;
- }
- }
- FAIL_HERE();
- case ';':
- {
- switch (LHSPROC[lhsIndex].value)
- {
- case FREQ:
- if (this->freq != 0) {
- FAIL_HERE();
- }
- index = match_proc(FREQPROC, s, slen);
- if (index >= 0) {
- this->freq = (freq_t)FREQPROC[index].value;
- }
- break;
- case UNTIL:
- // XXX should check that this is a valid time
- until.setTo(String16(s, slen));
- break;
- case COUNT:
- if (count != 0
- || NO_ERROR != parse_int(s, slen,
- &count, INT_MIN, INT_MAX, true)) {
- FAIL_HERE();
- }
- break;
- case INTERVAL:
- if (interval != 0
- || NO_ERROR != parse_int(s, slen,
- &interval, INT_MIN, INT_MAX, false)) {
- FAIL_HERE();
- }
- break;
- case BYSECOND:
- PARSE_INT_LIST_CHECKED(bysecond, 0, 59, true)
- break;
- case BYMINUTE:
- PARSE_INT_LIST_CHECKED(byminute, 0, 59, true)
- break;
- case BYHOUR:
- PARSE_INT_LIST_CHECKED(byhour, 0, 23, true)
- break;
- case BYDAY:
- if (bydayCount != 0 || NO_ERROR !=
- parse_int_list(s, slen, &bydayCount,
- &byday, -53, 53, false,
- parse_byday)) {
- FAIL_HERE();
- }
- postprocess_byday(bydayCount, byday, &bydayNum);
- break;
- case BYMONTHDAY:
- PARSE_INT_LIST_CHECKED(bymonthday, -31, 31,
- false)
- break;
- case BYYEARDAY:
- PARSE_INT_LIST_CHECKED(byyearday, -366, 366,
- false)
- break;
- case BYWEEKNO:
- PARSE_INT_LIST_CHECKED(byweekno, -53, 53,
- false)
- break;
- case BYMONTH:
- PARSE_INT_LIST_CHECKED(bymonth, 1, 12, false)
- break;
- case BYSETPOS:
- PARSE_INT_LIST_CHECKED(bysetpos,
- INT_MIN, INT_MAX, true)
- break;
- case WKST:
- if (this->wkst != 0) {
- FAIL_HERE();
- }
- index = match_proc(WEEKDAYPROC, s, slen);
- if (index >= 0) {
- this->wkst = (int)WEEKDAYPROC[index].value;
- }
- break;
- default:
- FAIL_HERE();
- }
- lhsIndex = NONE_LHS;
- break;
- }
- }
-
- start = i+1;
- }
- }
- }
-
- // enforce that there was a FREQ
- if (freq == 0) {
- FAIL_HERE();
- }
-
- // default wkst to MO if it wasn't specified
- if (wkst == 0) {
- wkst = MO;
- }
-
- return NO_ERROR;
-}
-
-
-}; // namespace android
-
-
diff --git a/libs/ui/ICamera.cpp b/libs/ui/ICamera.cpp
deleted file mode 100644
index ab0fef1..0000000
--- a/libs/ui/ICamera.cpp
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
-**
-** Copyright 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.
-*/
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "ICamera"
-#include <utils/Log.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/Parcel.h>
-#include <ui/ICamera.h>
-
-namespace android {
-
-enum {
- DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
- SET_PREVIEW_DISPLAY,
- SET_PREVIEW_CALLBACK_FLAG,
- START_PREVIEW,
- STOP_PREVIEW,
- AUTO_FOCUS,
- TAKE_PICTURE,
- SET_PARAMETERS,
- GET_PARAMETERS,
- CONNECT,
- LOCK,
- UNLOCK,
- PREVIEW_ENABLED,
- START_RECORDING,
- STOP_RECORDING,
- RECORDING_ENABLED,
- RELEASE_RECORDING_FRAME,
-};
-
-class BpCamera: public BpInterface<ICamera>
-{
-public:
- BpCamera(const sp<IBinder>& impl)
- : BpInterface<ICamera>(impl)
- {
- }
-
- // disconnect from camera service
- void disconnect()
- {
- LOGV("disconnect");
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- remote()->transact(DISCONNECT, data, &reply);
- }
-
- // pass the buffered ISurface to the camera service
- status_t setPreviewDisplay(const sp<ISurface>& surface)
- {
- LOGV("setPreviewDisplay");
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- data.writeStrongBinder(surface->asBinder());
- remote()->transact(SET_PREVIEW_DISPLAY, data, &reply);
- return reply.readInt32();
- }
-
- // set the preview callback flag to affect how the received frames from
- // preview are handled. See Camera.h for details.
- void setPreviewCallbackFlag(int flag)
- {
- LOGV("setPreviewCallbackFlag(%d)", flag);
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- data.writeInt32(flag);
- remote()->transact(SET_PREVIEW_CALLBACK_FLAG, data, &reply);
- }
-
- // start preview mode, must call setPreviewDisplay first
- status_t startPreview()
- {
- LOGV("startPreview");
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- remote()->transact(START_PREVIEW, data, &reply);
- return reply.readInt32();
- }
-
- // start recording mode, must call setPreviewDisplay first
- status_t startRecording()
- {
- LOGV("startRecording");
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- remote()->transact(START_RECORDING, data, &reply);
- return reply.readInt32();
- }
-
- // stop preview mode
- void stopPreview()
- {
- LOGV("stopPreview");
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- remote()->transact(STOP_PREVIEW, data, &reply);
- }
-
- // stop recording mode
- void stopRecording()
- {
- LOGV("stopRecording");
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- remote()->transact(STOP_RECORDING, data, &reply);
- }
-
- void releaseRecordingFrame(const sp<IMemory>& mem)
- {
- LOGV("releaseRecordingFrame");
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- data.writeStrongBinder(mem->asBinder());
- remote()->transact(RELEASE_RECORDING_FRAME, data, &reply);
- }
-
- // check preview state
- bool previewEnabled()
- {
- LOGV("previewEnabled");
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- remote()->transact(PREVIEW_ENABLED, data, &reply);
- return reply.readInt32();
- }
-
- // check recording state
- bool recordingEnabled()
- {
- LOGV("recordingEnabled");
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- remote()->transact(RECORDING_ENABLED, data, &reply);
- return reply.readInt32();
- }
-
- // auto focus
- status_t autoFocus()
- {
- LOGV("autoFocus");
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- remote()->transact(AUTO_FOCUS, data, &reply);
- status_t ret = reply.readInt32();
- return ret;
- }
-
- // take a picture - returns an IMemory (ref-counted mmap)
- status_t takePicture()
- {
- LOGV("takePicture");
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- remote()->transact(TAKE_PICTURE, data, &reply);
- status_t ret = reply.readInt32();
- return ret;
- }
-
- // set preview/capture parameters - key/value pairs
- status_t setParameters(const String8& params)
- {
- LOGV("setParameters");
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- data.writeString8(params);
- remote()->transact(SET_PARAMETERS, data, &reply);
- return reply.readInt32();
- }
-
- // get preview/capture parameters - key/value pairs
- String8 getParameters() const
- {
- LOGV("getParameters");
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- remote()->transact(GET_PARAMETERS, data, &reply);
- return reply.readString8();
- }
- virtual status_t connect(const sp<ICameraClient>& cameraClient)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- data.writeStrongBinder(cameraClient->asBinder());
- remote()->transact(CONNECT, data, &reply);
- return reply.readInt32();
- }
- virtual status_t lock()
- {
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- remote()->transact(LOCK, data, &reply);
- return reply.readInt32();
- }
- virtual status_t unlock()
- {
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- remote()->transact(UNLOCK, data, &reply);
- return reply.readInt32();
- }
-};
-
-IMPLEMENT_META_INTERFACE(Camera, "android.hardware.ICamera");
-
-// ----------------------------------------------------------------------
-
-#define CHECK_INTERFACE(interface, data, reply) \
- do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
- LOGW("Call incorrectly routed to " #interface); \
- return PERMISSION_DENIED; \
- } } while (0)
-
-status_t BnCamera::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case DISCONNECT: {
- LOGV("DISCONNECT");
- CHECK_INTERFACE(ICamera, data, reply);
- disconnect();
- return NO_ERROR;
- } break;
- case SET_PREVIEW_DISPLAY: {
- LOGV("SET_PREVIEW_DISPLAY");
- CHECK_INTERFACE(ICamera, data, reply);
- sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
- reply->writeInt32(setPreviewDisplay(surface));
- return NO_ERROR;
- } break;
- case SET_PREVIEW_CALLBACK_FLAG: {
- LOGV("SET_PREVIEW_CALLBACK_TYPE");
- CHECK_INTERFACE(ICamera, data, reply);
- int callback_flag = data.readInt32();
- setPreviewCallbackFlag(callback_flag);
- return NO_ERROR;
- } break;
- case START_PREVIEW: {
- LOGV("START_PREVIEW");
- CHECK_INTERFACE(ICamera, data, reply);
- reply->writeInt32(startPreview());
- return NO_ERROR;
- } break;
- case START_RECORDING: {
- LOGV("START_RECORDING");
- CHECK_INTERFACE(ICamera, data, reply);
- reply->writeInt32(startRecording());
- return NO_ERROR;
- } break;
- case STOP_PREVIEW: {
- LOGV("STOP_PREVIEW");
- CHECK_INTERFACE(ICamera, data, reply);
- stopPreview();
- return NO_ERROR;
- } break;
- case STOP_RECORDING: {
- LOGV("STOP_RECORDING");
- CHECK_INTERFACE(ICamera, data, reply);
- stopRecording();
- return NO_ERROR;
- } break;
- case RELEASE_RECORDING_FRAME: {
- LOGV("RELEASE_RECORDING_FRAME");
- CHECK_INTERFACE(ICamera, data, reply);
- sp<IMemory> mem = interface_cast<IMemory>(data.readStrongBinder());
- releaseRecordingFrame(mem);
- return NO_ERROR;
- } break;
- case PREVIEW_ENABLED: {
- LOGV("PREVIEW_ENABLED");
- CHECK_INTERFACE(ICamera, data, reply);
- reply->writeInt32(previewEnabled());
- return NO_ERROR;
- } break;
- case RECORDING_ENABLED: {
- LOGV("RECORDING_ENABLED");
- CHECK_INTERFACE(ICamera, data, reply);
- reply->writeInt32(recordingEnabled());
- return NO_ERROR;
- } break;
- case AUTO_FOCUS: {
- LOGV("AUTO_FOCUS");
- CHECK_INTERFACE(ICamera, data, reply);
- reply->writeInt32(autoFocus());
- return NO_ERROR;
- } break;
- case TAKE_PICTURE: {
- LOGV("TAKE_PICTURE");
- CHECK_INTERFACE(ICamera, data, reply);
- reply->writeInt32(takePicture());
- return NO_ERROR;
- } break;
- case SET_PARAMETERS: {
- LOGV("SET_PARAMETERS");
- CHECK_INTERFACE(ICamera, data, reply);
- String8 params(data.readString8());
- reply->writeInt32(setParameters(params));
- return NO_ERROR;
- } break;
- case GET_PARAMETERS: {
- LOGV("GET_PARAMETERS");
- CHECK_INTERFACE(ICamera, data, reply);
- reply->writeString8(getParameters());
- return NO_ERROR;
- } break;
- case CONNECT: {
- CHECK_INTERFACE(ICamera, data, reply);
- sp<ICameraClient> cameraClient = interface_cast<ICameraClient>(data.readStrongBinder());
- reply->writeInt32(connect(cameraClient));
- return NO_ERROR;
- } break;
- case LOCK: {
- CHECK_INTERFACE(ICamera, data, reply);
- reply->writeInt32(lock());
- return NO_ERROR;
- } break;
- case UNLOCK: {
- CHECK_INTERFACE(ICamera, data, reply);
- reply->writeInt32(unlock());
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
diff --git a/libs/ui/ICameraClient.cpp b/libs/ui/ICameraClient.cpp
deleted file mode 100644
index 4bec9d2..0000000
--- a/libs/ui/ICameraClient.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
-**
-** Copyright 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.
-*/
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "ICameraClient"
-#include <utils/Log.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <ui/ICameraClient.h>
-
-namespace android {
-
-enum {
- SHUTTER_CALLBACK = IBinder::FIRST_CALL_TRANSACTION,
- RAW_CALLBACK,
- JPEG_CALLBACK,
- PREVIEW_CALLBACK,
- ERROR_CALLBACK,
- AUTOFOCUS_CALLBACK,
- RECORDING_CALLBACK,
-};
-
-class BpCameraClient: public BpInterface<ICameraClient>
-{
-public:
- BpCameraClient(const sp<IBinder>& impl)
- : BpInterface<ICameraClient>(impl)
- {
- }
-
- // callback to let the app know the shutter has closed, ideal for playing the shutter sound
- void shutterCallback()
- {
- LOGV("shutterCallback");
- Parcel data, reply;
- data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
- remote()->transact(SHUTTER_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
- }
-
- // callback from camera service to app with picture data
- void rawCallback(const sp<IMemory>& picture)
- {
- LOGV("rawCallback");
- Parcel data, reply;
- data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
- data.writeStrongBinder(picture->asBinder());
- remote()->transact(RAW_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
- }
-
- // callback from camera service to app with picture data
- void jpegCallback(const sp<IMemory>& picture)
- {
- LOGV("jpegCallback");
- Parcel data, reply;
- data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
- data.writeStrongBinder(picture->asBinder());
- remote()->transact(JPEG_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
- }
-
- // callback from camera service to app with preview frame data
- void previewCallback(const sp<IMemory>& frame)
- {
- LOGV("previewCallback");
- Parcel data, reply;
- data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
- data.writeStrongBinder(frame->asBinder());
- remote()->transact(PREVIEW_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
- }
-
- // callback from camera service to app with recording frame data
- void recordingCallback(const sp<IMemory>& frame)
- {
- LOGV("recordingCallback");
- Parcel data, reply;
- data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
- data.writeStrongBinder(frame->asBinder());
- remote()->transact(RECORDING_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
- }
-
- // callback from camera service to app to report error
- void errorCallback(status_t error)
- {
- LOGV("errorCallback");
- Parcel data, reply;
- data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
- data.writeInt32(error);
- remote()->transact(ERROR_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
- }
-
- // callback from camera service to app to report autofocus completion
- void autoFocusCallback(bool focused)
- {
- LOGV("autoFocusCallback");
- Parcel data, reply;
- data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
- data.writeInt32(focused);
- remote()->transact(AUTOFOCUS_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
- }
-};
-
-IMPLEMENT_META_INTERFACE(CameraClient, "android.hardware.ICameraClient");
-
-// ----------------------------------------------------------------------
-
-#define CHECK_INTERFACE(interface, data, reply) \
- do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
- LOGW("Call incorrectly routed to " #interface); \
- return PERMISSION_DENIED; \
- } } while (0)
-
-status_t BnCameraClient::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case SHUTTER_CALLBACK: {
- LOGV("SHUTTER_CALLBACK");
- CHECK_INTERFACE(ICameraClient, data, reply);
- shutterCallback();
- return NO_ERROR;
- } break;
- case RAW_CALLBACK: {
- LOGV("RAW_CALLBACK");
- CHECK_INTERFACE(ICameraClient, data, reply);
- sp<IMemory> picture = interface_cast<IMemory>(data.readStrongBinder());
- rawCallback(picture);
- return NO_ERROR;
- } break;
- case JPEG_CALLBACK: {
- LOGV("JPEG_CALLBACK");
- CHECK_INTERFACE(ICameraClient, data, reply);
- sp<IMemory> picture = interface_cast<IMemory>(data.readStrongBinder());
- jpegCallback(picture);
- return NO_ERROR;
- } break;
- case PREVIEW_CALLBACK: {
- LOGV("PREVIEW_CALLBACK");
- CHECK_INTERFACE(ICameraClient, data, reply);
- sp<IMemory> frame = interface_cast<IMemory>(data.readStrongBinder());
- previewCallback(frame);
- return NO_ERROR;
- } break;
- case RECORDING_CALLBACK: {
- LOGV("RECORDING_CALLBACK");
- CHECK_INTERFACE(ICameraClient, data, reply);
- sp<IMemory> frame = interface_cast<IMemory>(data.readStrongBinder());
- recordingCallback(frame);
- return NO_ERROR;
- } break;
- case ERROR_CALLBACK: {
- LOGV("ERROR_CALLBACK");
- CHECK_INTERFACE(ICameraClient, data, reply);
- status_t error = data.readInt32();
- errorCallback(error);
- return NO_ERROR;
- } break;
- case AUTOFOCUS_CALLBACK: {
- LOGV("AUTOFOCUS_CALLBACK");
- CHECK_INTERFACE(ICameraClient, data, reply);
- bool focused = (bool)data.readInt32();
- autoFocusCallback(focused);
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
diff --git a/libs/ui/ICameraService.cpp b/libs/ui/ICameraService.cpp
deleted file mode 100644
index e5687fe..0000000
--- a/libs/ui/ICameraService.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
-**
-** Copyright 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.
-*/
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Parcel.h>
-#include <utils/IPCThreadState.h>
-#include <utils/IServiceManager.h>
-
-#include <ui/ICameraService.h>
-
-namespace android {
-
-class BpCameraService: public BpInterface<ICameraService>
-{
-public:
- BpCameraService(const sp<IBinder>& impl)
- : BpInterface<ICameraService>(impl)
- {
- }
-
- // connect to camera service
- virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
- data.writeStrongBinder(cameraClient->asBinder());
- remote()->transact(BnCameraService::CONNECT, data, &reply);
- return interface_cast<ICamera>(reply.readStrongBinder());
- }
-};
-
-IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService");
-
-// ----------------------------------------------------------------------
-
-#define CHECK_INTERFACE(interface, data, reply) \
- do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
- LOGW("Call incorrectly routed to " #interface); \
- return PERMISSION_DENIED; \
- } } while (0)
-
-status_t BnCameraService::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case CONNECT: {
- CHECK_INTERFACE(ICameraService, data, reply);
- sp<ICameraClient> cameraClient = interface_cast<ICameraClient>(data.readStrongBinder());
- sp<ICamera> camera = connect(cameraClient);
- reply->writeStrongBinder(camera->asBinder());
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
diff --git a/libs/ui/IOverlay.cpp b/libs/ui/IOverlay.cpp
deleted file mode 100644
index fed47c2..0000000
--- a/libs/ui/IOverlay.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Parcel.h>
-#include <utils/IInterface.h>
-
-#include <ui/IOverlay.h>
-
-namespace android {
-
-enum {
- DESTROY = IBinder::FIRST_CALL_TRANSACTION, // one-way transaction
-};
-
-class BpOverlay : public BpInterface<IOverlay>
-{
-public:
- BpOverlay(const sp<IBinder>& impl)
- : BpInterface<IOverlay>(impl)
- {
- }
-
- virtual void destroy()
- {
- Parcel data, reply;
- data.writeInterfaceToken(IOverlay::getInterfaceDescriptor());
- remote()->transact(DESTROY, data, &reply, IBinder::FLAG_ONEWAY);
- }
-};
-
-IMPLEMENT_META_INTERFACE(Overlay, "android.ui.IOverlay");
-
-// ----------------------------------------------------------------------
-
-#define CHECK_INTERFACE(interface, data, reply) \
- do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
- LOGW("Call incorrectly routed to " #interface); \
- return PERMISSION_DENIED; \
- } } while (0)
-
-status_t BnOverlay::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case DESTROY: {
- CHECK_INTERFACE(IOverlay, data, reply);
- destroy();
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-}; // namespace android
diff --git a/libs/ui/ISurface.cpp b/libs/ui/ISurface.cpp
deleted file mode 100644
index d5e9f81..0000000
--- a/libs/ui/ISurface.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * 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.
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Parcel.h>
-#include <utils/IMemory.h>
-
-#include <ui/ISurface.h>
-#include <ui/Overlay.h>
-
-
-namespace android {
-
-ISurface::BufferHeap::BufferHeap()
- : w(0), h(0), hor_stride(0), ver_stride(0), format(0),
- transform(0), flags(0)
-{
-}
-
-ISurface::BufferHeap::BufferHeap(uint32_t w, uint32_t h,
- int32_t hor_stride, int32_t ver_stride,
- PixelFormat format, const sp<IMemoryHeap>& heap)
- : w(w), h(h), hor_stride(hor_stride), ver_stride(ver_stride),
- format(format), transform(0), flags(0), heap(heap)
-{
-}
-
-ISurface::BufferHeap::BufferHeap(uint32_t w, uint32_t h,
- int32_t hor_stride, int32_t ver_stride,
- PixelFormat format, uint32_t transform, uint32_t flags,
- const sp<IMemoryHeap>& heap)
- : w(w), h(h), hor_stride(hor_stride), ver_stride(ver_stride),
- format(format), transform(transform), flags(flags), heap(heap)
-{
-}
-
-
-ISurface::BufferHeap::~BufferHeap()
-{
-}
-
-class BpSurface : public BpInterface<ISurface>
-{
-public:
- BpSurface(const sp<IBinder>& impl)
- : BpInterface<ISurface>(impl)
- {
- }
-
- virtual status_t registerBuffers(const BufferHeap& buffers)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
- data.writeInt32(buffers.w);
- data.writeInt32(buffers.h);
- data.writeInt32(buffers.hor_stride);
- data.writeInt32(buffers.ver_stride);
- data.writeInt32(buffers.format);
- data.writeInt32(buffers.transform);
- data.writeInt32(buffers.flags);
- data.writeStrongBinder(buffers.heap->asBinder());
- remote()->transact(REGISTER_BUFFERS, data, &reply);
- status_t result = reply.readInt32();
- return result;
- }
-
- virtual void postBuffer(ssize_t offset)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
- data.writeInt32(offset);
- remote()->transact(POST_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);
- }
-
- virtual void unregisterBuffers()
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
- remote()->transact(UNREGISTER_BUFFERS, data, &reply);
- }
-
- virtual sp<OverlayRef> createOverlay(
- uint32_t w, uint32_t h, int32_t format)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
- data.writeInt32(w);
- data.writeInt32(h);
- data.writeInt32(format);
- remote()->transact(CREATE_OVERLAY, data, &reply);
- return OverlayRef::readFromParcel(reply);
- }
-};
-
-IMPLEMENT_META_INTERFACE(Surface, "android.ui.ISurface");
-
-// ----------------------------------------------------------------------
-
-#define CHECK_INTERFACE(interface, data, reply) \
- do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
- LOGW("Call incorrectly routed to " #interface); \
- return PERMISSION_DENIED; \
- } } while (0)
-
-status_t BnSurface::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case REGISTER_BUFFERS: {
- CHECK_INTERFACE(ISurface, data, reply);
- BufferHeap buffer;
- buffer.w = data.readInt32();
- buffer.h = data.readInt32();
- buffer.hor_stride = data.readInt32();
- buffer.ver_stride= data.readInt32();
- buffer.format = data.readInt32();
- buffer.transform = data.readInt32();
- buffer.flags = data.readInt32();
- buffer.heap = interface_cast<IMemoryHeap>(data.readStrongBinder());
- status_t err = registerBuffers(buffer);
- reply->writeInt32(err);
- return NO_ERROR;
- } break;
- case UNREGISTER_BUFFERS: {
- CHECK_INTERFACE(ISurface, data, reply);
- unregisterBuffers();
- return NO_ERROR;
- } break;
- case POST_BUFFER: {
- CHECK_INTERFACE(ISurface, data, reply);
- ssize_t offset = data.readInt32();
- postBuffer(offset);
- return NO_ERROR;
- } break;
- case CREATE_OVERLAY: {
- CHECK_INTERFACE(ISurface, data, reply);
- int w = data.readInt32();
- int h = data.readInt32();
- int f = data.readInt32();
- sp<OverlayRef> o = createOverlay(w, h, f);
- return OverlayRef::writeToParcel(reply, o);
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-}; // namespace android
diff --git a/libs/ui/ISurfaceComposer.cpp b/libs/ui/ISurfaceComposer.cpp
deleted file mode 100644
index 0fea6f9..0000000
--- a/libs/ui/ISurfaceComposer.cpp
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * 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.
- */
-
-// tag as surfaceflinger
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Parcel.h>
-#include <utils/IMemory.h>
-#include <utils/IPCThreadState.h>
-#include <utils/IServiceManager.h>
-
-#include <ui/ISurfaceComposer.h>
-#include <ui/DisplayInfo.h>
-
-// ---------------------------------------------------------------------------
-
-#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
-#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
-{
-public:
- BpSurfaceComposer(const sp<IBinder>& impl)
- : BpInterface<ISurfaceComposer>(impl)
- {
- }
-
- virtual sp<ISurfaceFlingerClient> createConnection()
- {
- uint32_t n;
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
- return interface_cast<ISurfaceFlingerClient>(reply.readStrongBinder());
- }
-
- virtual sp<IMemory> getCblk() const
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- remote()->transact(BnSurfaceComposer::GET_CBLK, data, &reply);
- return interface_cast<IMemory>(reply.readStrongBinder());
- }
-
- virtual void openGlobalTransaction()
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- remote()->transact(BnSurfaceComposer::OPEN_GLOBAL_TRANSACTION, data, &reply);
- }
-
- virtual void closeGlobalTransaction()
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- remote()->transact(BnSurfaceComposer::CLOSE_GLOBAL_TRANSACTION, data, &reply);
- }
-
- virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeInt32(dpy);
- data.writeInt32(flags);
- remote()->transact(BnSurfaceComposer::FREEZE_DISPLAY, data, &reply);
- return reply.readInt32();
- }
-
- virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeInt32(dpy);
- data.writeInt32(flags);
- remote()->transact(BnSurfaceComposer::UNFREEZE_DISPLAY, data, &reply);
- return reply.readInt32();
- }
-
- virtual int setOrientation(DisplayID dpy, int orientation)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeInt32(dpy);
- data.writeInt32(orientation);
- remote()->transact(BnSurfaceComposer::SET_ORIENTATION, data, &reply);
- return reply.readInt32();
- }
-
- virtual void bootFinished()
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
- }
-
- virtual status_t requestGPU(
- const sp<IGPUCallback>& callback, gpu_info_t* gpu)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeStrongBinder(callback->asBinder());
- remote()->transact(BnSurfaceComposer::REQUEST_GPU, data, &reply);
- gpu->regs = interface_cast<IMemory>(reply.readStrongBinder());
- gpu->count = reply.readInt32();
-
- // FIXME: for now, we don't dynamically allocate the regions array
- size_t maxCount = sizeof(gpu->regions)/sizeof(*gpu->regions);
- if (gpu->count > maxCount)
- return BAD_VALUE;
-
- for (size_t i=0 ; i<gpu->count ; i++) {
- gpu->regions[i].region = interface_cast<IMemory>(reply.readStrongBinder());
- gpu->regions[i].reserved = reply.readInt32();
- }
- return reply.readInt32();
- }
-
- virtual status_t revokeGPU()
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- remote()->transact(BnSurfaceComposer::REVOKE_GPU, data, &reply);
- return reply.readInt32();
- }
-
- virtual void signal() const
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- remote()->transact(BnSurfaceComposer::SIGNAL, data, &reply, IBinder::FLAG_ONEWAY);
- }
-};
-
-IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
-
-// ----------------------------------------------------------------------
-
-#define CHECK_INTERFACE(interface, data, reply) \
- do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
- LOGW("Call incorrectly routed to " #interface); \
- return PERMISSION_DENIED; \
- } } while (0)
-
-status_t BnSurfaceComposer::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- status_t err = BnInterface<ISurfaceComposer>::onTransact(code, data, reply, flags);
- if (err == NO_ERROR)
- return err;
-
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
-
- switch(code) {
- case CREATE_CONNECTION: {
- sp<IBinder> b = createConnection()->asBinder();
- reply->writeStrongBinder(b);
- } break;
- case OPEN_GLOBAL_TRANSACTION: {
- openGlobalTransaction();
- } break;
- case CLOSE_GLOBAL_TRANSACTION: {
- closeGlobalTransaction();
- } break;
- case SET_ORIENTATION: {
- DisplayID dpy = data.readInt32();
- int orientation = data.readInt32();
- reply->writeInt32( setOrientation(dpy, orientation) );
- } break;
- case FREEZE_DISPLAY: {
- DisplayID dpy = data.readInt32();
- uint32_t flags = data.readInt32();
- reply->writeInt32( freezeDisplay(dpy, flags) );
- } break;
- case UNFREEZE_DISPLAY: {
- DisplayID dpy = data.readInt32();
- uint32_t flags = data.readInt32();
- reply->writeInt32( unfreezeDisplay(dpy, flags) );
- } break;
- case BOOT_FINISHED: {
- bootFinished();
- } break;
- case REVOKE_GPU: {
- reply->writeInt32( revokeGPU() );
- } break;
- case SIGNAL: {
- signal();
- } break;
- case GET_CBLK: {
- sp<IBinder> b = getCblk()->asBinder();
- reply->writeStrongBinder(b);
- } break;
- case REQUEST_GPU: {
- // TODO: this should be protected by a permission
- gpu_info_t info;
- sp<IGPUCallback> callback
- = interface_cast<IGPUCallback>(data.readStrongBinder());
- status_t res = requestGPU(callback, &info);
-
- // FIXME: for now, we don't dynamically allocate the regions array
- size_t maxCount = sizeof(info.regions)/sizeof(*info.regions);
- if (info.count > maxCount)
- return BAD_VALUE;
-
- reply->writeStrongBinder(info.regs->asBinder());
- reply->writeInt32(info.count);
- for (size_t i=0 ; i<info.count ; i++) {
- reply->writeStrongBinder(info.regions[i].region->asBinder());
- reply->writeInt32(info.regions[i].reserved);
- }
- reply->writeInt32(res);
- } break;
- default:
- return UNKNOWN_TRANSACTION;
- }
- return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-enum {
- // Note: BOOT_FINISHED must remain this value, it is called by ActivityManagerService.
- GPU_LOST = IBinder::FIRST_CALL_TRANSACTION
-};
-
-class BpGPUCallback : public BpInterface<IGPUCallback>
-{
-public:
- BpGPUCallback(const sp<IBinder>& impl)
- : BpInterface<IGPUCallback>(impl)
- {
- }
-
- virtual void gpuLost()
- {
- Parcel data, reply;
- data.writeInterfaceToken(IGPUCallback::getInterfaceDescriptor());
- remote()->transact(GPU_LOST, data, &reply, IBinder::FLAG_ONEWAY);
- }
-};
-
-IMPLEMENT_META_INTERFACE(GPUCallback, "android.ui.IGPUCallback");
-
-status_t BnGPUCallback::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case GPU_LOST: {
- CHECK_INTERFACE(IGPUCallback, data, reply);
- gpuLost();
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-};
diff --git a/libs/ui/ISurfaceFlingerClient.cpp b/libs/ui/ISurfaceFlingerClient.cpp
deleted file mode 100644
index dd6a798..0000000
--- a/libs/ui/ISurfaceFlingerClient.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * 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.
- */
-
-// tag as surfaceflinger
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Parcel.h>
-#include <utils/IMemory.h>
-#include <utils/IPCThreadState.h>
-#include <utils/IServiceManager.h>
-
-#include <ui/ISurface.h>
-#include <ui/ISurfaceFlingerClient.h>
-#include <ui/Point.h>
-#include <ui/Rect.h>
-
-#include <private/ui/LayerState.h>
-
-// ---------------------------------------------------------------------------
-
-#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
-#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-enum {
- GET_CBLK = IBinder::FIRST_CALL_TRANSACTION,
- CREATE_SURFACE,
- DESTROY_SURFACE,
- SET_STATE
-};
-
-class BpSurfaceFlingerClient : public BpInterface<ISurfaceFlingerClient>
-{
-public:
- BpSurfaceFlingerClient(const sp<IBinder>& impl)
- : BpInterface<ISurfaceFlingerClient>(impl)
- {
- }
-
- virtual void getControlBlocks(sp<IMemory>* ctl) const
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
- remote()->transact(GET_CBLK, data, &reply);
- *ctl = interface_cast<IMemory>(reply.readStrongBinder());
- }
-
- virtual sp<ISurface> createSurface( surface_data_t* params,
- int pid,
- DisplayID display,
- uint32_t w,
- uint32_t h,
- PixelFormat format,
- uint32_t flags)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
- data.writeInt32(pid);
- data.writeInt32(display);
- data.writeInt32(w);
- data.writeInt32(h);
- data.writeInt32(format);
- data.writeInt32(flags);
- remote()->transact(CREATE_SURFACE, data, &reply);
- params->readFromParcel(reply);
- return interface_cast<ISurface>(reply.readStrongBinder());
- }
-
- virtual status_t destroySurface(SurfaceID sid)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
- data.writeInt32(sid);
- remote()->transact(DESTROY_SURFACE, data, &reply);
- return reply.readInt32();
- }
-
- virtual status_t setState(int32_t count, const layer_state_t* states)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
- data.writeInt32(count);
- for (int i=0 ; i<count ; i++)
- states[i].write(data);
- remote()->transact(SET_STATE, data, &reply);
- return reply.readInt32();
- }
-};
-
-IMPLEMENT_META_INTERFACE(SurfaceFlingerClient, "android.ui.ISurfaceFlingerClient");
-
-// ----------------------------------------------------------------------
-
-#define CHECK_INTERFACE(interface, data, reply) \
- do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
- LOGW("Call incorrectly routed to " #interface); \
- return PERMISSION_DENIED; \
- } } while (0)
-
-status_t BnSurfaceFlingerClient::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- // codes that don't require permission check
-
- switch(code) {
- case GET_CBLK: {
- CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
- sp<IMemory> ctl;
- getControlBlocks(&ctl);
- reply->writeStrongBinder(ctl->asBinder());
- return NO_ERROR;
- } break;
- }
-
- // these must be checked
-
- IPCThreadState* ipc = IPCThreadState::self();
- const int pid = ipc->getCallingPid();
- const int self_pid = getpid();
- if (UNLIKELY(pid != self_pid)) {
- // we're called from a different process, do the real check
- if (!checkCallingPermission(
- String16("android.permission.ACCESS_SURFACE_FLINGER")))
- {
- const int uid = ipc->getCallingUid();
- LOGE("Permission Denial: "
- "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
- return PERMISSION_DENIED;
- }
- }
-
- switch(code) {
- case CREATE_SURFACE: {
- CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
- surface_data_t params;
- int32_t pid = data.readInt32();
- DisplayID display = data.readInt32();
- uint32_t w = data.readInt32();
- uint32_t h = data.readInt32();
- PixelFormat format = data.readInt32();
- uint32_t flags = data.readInt32();
- sp<ISurface> s = createSurface(&params, pid, display, w, h, format, flags);
- params.writeToParcel(reply);
- reply->writeStrongBinder(s->asBinder());
- return NO_ERROR;
- } break;
- case DESTROY_SURFACE: {
- CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
- reply->writeInt32( destroySurface( data.readInt32() ) );
- return NO_ERROR;
- } break;
- case SET_STATE: {
- CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
- int32_t count = data.readInt32();
- layer_state_t* states = new layer_state_t[count];
- for (int i=0 ; i<count ; i++)
- states[i].read(data);
- status_t err = setState(count, states);
- delete [] states;
- reply->writeInt32(err);
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-// ----------------------------------------------------------------------
-
-status_t ISurfaceFlingerClient::surface_data_t::readFromParcel(const Parcel& parcel)
-{
- token = parcel.readInt32();
- identity = parcel.readInt32();
- heap[0] = interface_cast<IMemoryHeap>(parcel.readStrongBinder());
- heap[1] = interface_cast<IMemoryHeap>(parcel.readStrongBinder());
- return NO_ERROR;
-}
-
-status_t ISurfaceFlingerClient::surface_data_t::writeToParcel(Parcel* parcel) const
-{
- parcel->writeInt32(token);
- parcel->writeInt32(identity);
- parcel->writeStrongBinder(heap[0]!=0 ? heap[0]->asBinder() : NULL);
- parcel->writeStrongBinder(heap[1]!=0 ? heap[1]->asBinder() : NULL);
- return NO_ERROR;
-}
-
-}; // namespace android
diff --git a/libs/ui/KeyCharacterMap.cpp b/libs/ui/KeyCharacterMap.cpp
deleted file mode 100644
index e891181..0000000
--- a/libs/ui/KeyCharacterMap.cpp
+++ /dev/null
@@ -1,263 +0,0 @@
-#define LOG_TAG "KeyCharacterMap"
-
-#include <ui/KeyCharacterMap.h>
-#include <cutils/properties.h>
-
-#include <utils/Log.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <string.h>
-
-struct Header
-{
- char magic[8];
- unsigned int endian;
- unsigned int version;
- unsigned int keycount;
- unsigned char kbdtype;
- char padding[11];
-};
-
-KeyCharacterMap::KeyCharacterMap()
-{
-}
-
-KeyCharacterMap::~KeyCharacterMap()
-{
- free(m_keys);
-}
-
-unsigned short
-KeyCharacterMap::get(int keycode, int meta)
-{
- Key* k = find_key(keycode);
- if (k != NULL) {
- return k->data[meta & META_MASK];
- }
- return 0;
-}
-
-unsigned short
-KeyCharacterMap::getNumber(int keycode)
-{
- Key* k = find_key(keycode);
- if (k != NULL) {
- return k->number;
- }
- return 0;
-}
-
-unsigned short
-KeyCharacterMap::getMatch(int keycode, const unsigned short* chars,
- int charsize, uint32_t modifiers)
-{
- Key* k = find_key(keycode);
- modifiers &= 3; // ignore the SYM key because we don't have keymap entries for it
- if (k != NULL) {
- const uint16_t* data = k->data;
- for (int j=0; j<charsize; j++) {
- uint16_t c = chars[j];
- for (int i=0; i<(META_MASK + 1); i++) {
- if ((modifiers == 0) || ((modifiers & i) != 0)) {
- if (c == data[i]) {
- return c;
- }
- }
- }
- }
- }
- return 0;
-}
-
-unsigned short
-KeyCharacterMap::getDisplayLabel(int keycode)
-{
- Key* k = find_key(keycode);
- if (k != NULL) {
- return k->display_label;
- }
- return 0;
-}
-
-bool
-KeyCharacterMap::getKeyData(int keycode, unsigned short *displayLabel,
- unsigned short *number, unsigned short* results)
-{
- Key* k = find_key(keycode);
- if (k != NULL) {
- memcpy(results, k->data, sizeof(short)*(META_MASK + 1));
- *number = k->number;
- *displayLabel = k->display_label;
- return true;
- } else {
- return false;
- }
-}
-
-bool
-KeyCharacterMap::find_char(uint16_t c, uint32_t* key, uint32_t* mods)
-{
- uint32_t N = m_keyCount;
- for (int j=0; j<(META_MASK + 1); j++) {
- Key const* keys = m_keys;
- for (uint32_t i=0; i<N; i++) {
- if (keys->data[j] == c) {
- *key = keys->keycode;
- *mods = j;
- return true;
- }
- keys++;
- }
- }
- return false;
-}
-
-bool
-KeyCharacterMap::getEvents(uint16_t* chars, size_t len,
- Vector<int32_t>* keys, Vector<uint32_t>* modifiers)
-{
- for (size_t i=0; i<len; i++) {
- uint32_t k, mods;
- if (find_char(chars[i], &k, &mods)) {
- keys->add(k);
- modifiers->add(mods);
- } else {
- return false;
- }
- }
- return true;
-}
-
-KeyCharacterMap::Key*
-KeyCharacterMap::find_key(int keycode)
-{
- Key* keys = m_keys;
- int low = 0;
- int high = m_keyCount - 1;
- int mid;
- int n;
- while (low <= high) {
- mid = (low + high) / 2;
- n = keys[mid].keycode;
- if (keycode < n) {
- high = mid - 1;
- } else if (keycode > n) {
- low = mid + 1;
- } else {
- return keys + mid;
- }
- }
- return NULL;
-}
-
-KeyCharacterMap*
-KeyCharacterMap::load(int id)
-{
- KeyCharacterMap* rv = NULL;
- char path[PATH_MAX];
- char propName[100];
- char dev[PROPERTY_VALUE_MAX];
- char tmpfn[PROPERTY_VALUE_MAX];
- int err;
- const char* root = getenv("ANDROID_ROOT");
-
- sprintf(propName, "hw.keyboards.%u.devname", id);
- err = property_get(propName, dev, "");
- if (err > 0) {
- // replace all the spaces with underscores
- strcpy(tmpfn, dev);
- for (char *p = strchr(tmpfn, ' '); p && *p; p = strchr(tmpfn, ' '))
- *p = '_';
- snprintf(path, sizeof(path), "%s/usr/keychars/%s.kcm.bin", root, tmpfn);
- //LOGD("load: dev='%s' path='%s'\n", dev, path);
- rv = try_file(path);
- if (rv != NULL) {
- return rv;
- }
- LOGW("Error loading keycharmap file '%s'. %s='%s'", path, propName, dev);
- } else {
- LOGW("No keyboard for id %d", id);
- }
-
- snprintf(path, sizeof(path), "%s/usr/keychars/qwerty.kcm.bin", root);
- rv = try_file(path);
- if (rv == NULL) {
- LOGE("Can't find any keycharmaps (also tried %s)", path);
- return NULL;
- }
- LOGW("Using default keymap: %s", path);
-
- return rv;
-}
-
-KeyCharacterMap*
-KeyCharacterMap::try_file(const char* filename)
-{
- KeyCharacterMap* rv = NULL;
- Key* keys;
- int fd;
- off_t filesize;
- Header header;
- int err;
-
- fd = open(filename, O_RDONLY);
- if (fd == -1) {
- LOGW("Can't open keycharmap file");
- return NULL;
- }
-
- filesize = lseek(fd, 0, SEEK_END);
- lseek(fd, 0, SEEK_SET);
-
- // validate the header
- if (filesize <= (off_t)sizeof(header)) {
- LOGW("Bad keycharmap - filesize=%d\n", (int)filesize);
- goto cleanup1;
- }
-
- err = read(fd, &header, sizeof(header));
- if (err == -1) {
- LOGW("Error reading keycharmap file");
- goto cleanup1;
- }
-
- if (0 != memcmp(header.magic, "keychar", 8)) {
- LOGW("Bad keycharmap magic token");
- goto cleanup1;
- }
- if (header.endian != 0x12345678) {
- LOGW("Bad keycharmap endians");
- goto cleanup1;
- }
- if ((header.version & 0xff) != 2) {
- LOGW("Only support keycharmap version 2 (got 0x%08x)", header.version);
- goto cleanup1;
- }
- if (filesize < (off_t)(sizeof(Header)+(sizeof(Key)*header.keycount))) {
- LOGW("Bad keycharmap file size\n");
- goto cleanup1;
- }
-
- // read the key data
- keys = (Key*)malloc(sizeof(Key)*header.keycount);
- err = read(fd, keys, sizeof(Key)*header.keycount);
- if (err == -1) {
- LOGW("Error reading keycharmap file");
- free(keys);
- goto cleanup1;
- }
-
- // return the object
- rv = new KeyCharacterMap;
- rv->m_keyCount = header.keycount;
- rv->m_keys = keys;
- rv->m_type = header.kbdtype;
-
-cleanup1:
- close(fd);
-
- return rv;
-}
diff --git a/libs/ui/KeyLayoutMap.cpp b/libs/ui/KeyLayoutMap.cpp
deleted file mode 100644
index 15ae54c..0000000
--- a/libs/ui/KeyLayoutMap.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-#define LOG_TAG "KeyLayoutMap"
-
-#include "KeyLayoutMap.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <utils/String8.h>
-#include <stdlib.h>
-#include <ui/KeycodeLabels.h>
-#include <utils/Log.h>
-
-namespace android {
-
-KeyLayoutMap::KeyLayoutMap()
- :m_status(NO_INIT),
- m_keys()
-{
-}
-
-KeyLayoutMap::~KeyLayoutMap()
-{
-}
-
-static String8
-next_token(char const** p, int *line)
-{
- bool begun = false;
- const char* begin = *p;
- const char* end = *p;
- while (true) {
- if (*end == '\n') {
- (*line)++;
- }
- switch (*end)
- {
- case '#':
- if (begun) {
- *p = end;
- return String8(begin, end-begin);
- } else {
- do {
- begin++;
- end++;
- } while (*begin != '\0' && *begin != '\n');
- }
- case '\0':
- case ' ':
- case '\n':
- case '\r':
- case '\t':
- if (begun || (*end == '\0')) {
- *p = end;
- return String8(begin, end-begin);
- } else {
- begin++;
- end++;
- break;
- }
- default:
- end++;
- begun = true;
- }
- }
-}
-
-static int32_t
-token_to_value(const char *literal, const KeycodeLabel *list)
-{
- while (list->literal) {
- if (0 == strcmp(literal, list->literal)) {
- return list->value;
- }
- list++;
- }
- return list->value;
-}
-
-status_t
-KeyLayoutMap::load(const char* filename)
-{
- int fd = open(filename, O_RDONLY);
- if (fd < 0) {
- LOGE("error opening file=%s err=%s\n", filename, strerror(errno));
- m_status = errno;
- return errno;
- }
-
- off_t len = lseek(fd, 0, SEEK_END);
- off_t errlen = lseek(fd, 0, SEEK_SET);
- if (len < 0 || errlen < 0) {
- close(fd);
- LOGE("error seeking file=%s err=%s\n", filename, strerror(errno));
- m_status = errno;
- return errno;
- }
-
- char* buf = (char*)malloc(len+1);
- if (read(fd, buf, len) != len) {
- LOGE("error reading file=%s err=%s\n", filename, strerror(errno));
- m_status = errno != 0 ? errno : ((int)NOT_ENOUGH_DATA);
- return errno != 0 ? errno : ((int)NOT_ENOUGH_DATA);
- }
- errno = 0;
- buf[len] = '\0';
-
- int32_t scancode = -1;
- int32_t keycode = -1;
- uint32_t flags = 0;
- uint32_t tmp;
- char* end;
- status_t err = NO_ERROR;
- int line = 1;
- char const* p = buf;
- enum { BEGIN, SCANCODE, KEYCODE, FLAG } state = BEGIN;
- while (true) {
- String8 token = next_token(&p, &line);
- if (*p == '\0') {
- break;
- }
- switch (state)
- {
- case BEGIN:
- if (token == "key") {
- state = SCANCODE;
- } else {
- LOGE("%s:%d: expected key, got '%s'\n", filename, line,
- token.string());
- err = BAD_VALUE;
- goto done;
- }
- break;
- case SCANCODE:
- scancode = strtol(token.string(), &end, 0);
- if (*end != '\0') {
- LOGE("%s:%d: expected scancode (a number), got '%s'\n",
- filename, line, token.string());
- goto done;
- }
- //LOGI("%s:%d: got scancode %d\n", filename, line, scancode );
- state = KEYCODE;
- break;
- case KEYCODE:
- keycode = token_to_value(token.string(), KEYCODES);
- //LOGI("%s:%d: got keycode %d for %s\n", filename, line, keycode, token.string() );
- if (keycode == 0) {
- LOGE("%s:%d: expected keycode, got '%s'\n",
- filename, line, token.string());
- goto done;
- }
- state = FLAG;
- break;
- case FLAG:
- if (token == "key") {
- if (scancode != -1) {
- //LOGI("got key decl scancode=%d keycode=%d"
- // " flags=0x%08x\n", scancode, keycode, flags);
- Key k = { keycode, flags };
- m_keys.add(scancode, k);
- state = SCANCODE;
- scancode = -1;
- keycode = -1;
- flags = 0;
- break;
- }
- }
- tmp = token_to_value(token.string(), FLAGS);
- //LOGI("%s:%d: got flags %x for %s\n", filename, line, tmp, token.string() );
- if (tmp == 0) {
- LOGE("%s:%d: expected flag, got '%s'\n",
- filename, line, token.string());
- goto done;
- }
- flags |= tmp;
- break;
- }
- }
- if (state == FLAG && scancode != -1 ) {
- //LOGI("got key decl scancode=%d keycode=%d"
- // " flags=0x%08x\n", scancode, keycode, flags);
- Key k = { keycode, flags };
- m_keys.add(scancode, k);
- }
-
-done:
- free(buf);
- close(fd);
-
- m_status = err;
- return err;
-}
-
-status_t
-KeyLayoutMap::map(int32_t scancode, int32_t *keycode, uint32_t *flags) const
-{
- if (m_status != NO_ERROR) {
- return m_status;
- }
-
- ssize_t index = m_keys.indexOfKey(scancode);
- if (index < 0) {
- //LOGW("couldn't map scancode=%d\n", scancode);
- return NAME_NOT_FOUND;
- }
-
- const Key& k = m_keys.valueAt(index);
-
- *keycode = k.keycode;
- *flags = k.flags;
-
- //LOGD("mapped scancode=%d to keycode=%d flags=0x%08x\n", scancode,
- // keycode, flags);
-
- return NO_ERROR;
-}
-
-status_t
-KeyLayoutMap::findScancodes(int32_t keycode, Vector<int32_t>* outScancodes) const
-{
- if (m_status != NO_ERROR) {
- return m_status;
- }
-
- const size_t N = m_keys.size();
- for (size_t i=0; i<N; i++) {
- if (m_keys.valueAt(i).keycode == keycode) {
- outScancodes->add(m_keys.keyAt(i));
- }
- }
-
- return NO_ERROR;
-}
-
-};
diff --git a/libs/ui/KeyLayoutMap.h b/libs/ui/KeyLayoutMap.h
deleted file mode 100644
index 43f84ce..0000000
--- a/libs/ui/KeyLayoutMap.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef KEYLAYOUTMAP_H
-#define KEYLAYOUTMAP_H
-
-#include <utils/KeyedVector.h>
-
-namespace android {
-
-class KeyLayoutMap
-{
-public:
- KeyLayoutMap();
- ~KeyLayoutMap();
-
- status_t load(const char* filename);
-
- status_t map(int32_t scancode, int32_t *keycode, uint32_t *flags) const;
- status_t findScancodes(int32_t keycode, Vector<int32_t>* outScancodes) const;
-
-private:
- struct Key {
- int32_t keycode;
- uint32_t flags;
- };
-
- status_t m_status;
- KeyedVector<int32_t,Key> m_keys;
-};
-
-};
-
-#endif // KEYLAYOUTMAP_H
diff --git a/libs/ui/LayerState.cpp b/libs/ui/LayerState.cpp
deleted file mode 100644
index 0b6374b..0000000
--- a/libs/ui/LayerState.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.
- */
-
-#include <utils/Errors.h>
-#include <utils/Parcel.h>
-#include <private/ui/LayerState.h>
-
-namespace android {
-
-status_t layer_state_t::write(Parcel& output) const
-{
- size_t size = sizeof(layer_state_t);
-
- //output.writeStrongBinder(surface->asBinder());
- //size -= sizeof(surface);
-
- transparentRegion.write(output);
- size -= sizeof(transparentRegion);
-
- output.write(this, size);
-
- return NO_ERROR;
-}
-
-status_t layer_state_t::read(const Parcel& input)
-{
- size_t size = sizeof(layer_state_t);
-
- //surface = interface_cast<ISurface>(input.readStrongBinder());
- //size -= sizeof(surface);
-
- transparentRegion.read(input);
- size -= sizeof(transparentRegion);
-
- input.read(this, size);
-
- return NO_ERROR;
-}
-
-}; // namespace android
diff --git a/libs/ui/MODULE_LICENSE_APACHE2 b/libs/ui/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/libs/ui/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/libs/ui/NOTICE b/libs/ui/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/libs/ui/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/libs/ui/Overlay.cpp b/libs/ui/Overlay.cpp
deleted file mode 100644
index b236edc..0000000
--- a/libs/ui/Overlay.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * 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.
- */
-
-#include <utils/IMemory.h>
-#include <utils/Parcel.h>
-#include <utils/Errors.h>
-#include <utils/MemoryHeapBase.h>
-
-#include <ui/IOverlay.h>
-#include <ui/Overlay.h>
-
-#include <hardware/overlay.h>
-
-namespace android {
-
-Overlay::Overlay(const sp<OverlayRef>& overlayRef)
- : mOverlayRef(overlayRef), mOverlayData(0), mStatus(NO_INIT)
-{
- mOverlayData = NULL;
- hw_module_t const* module;
- if (overlayRef != 0) {
- if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {
- if (overlay_data_open(module, &mOverlayData) == NO_ERROR) {
- mStatus = mOverlayData->initialize(mOverlayData,
- overlayRef->mOverlayHandle);
- }
- }
- }
-}
-
-Overlay::~Overlay() {
- if (mOverlayData) {
- overlay_data_close(mOverlayData);
- }
-}
-
-status_t Overlay::dequeueBuffer(overlay_buffer_t* buffer)
-{
- if (mStatus != NO_ERROR) return mStatus;
- return mOverlayData->dequeueBuffer(mOverlayData, buffer);
-}
-
-status_t Overlay::queueBuffer(overlay_buffer_t buffer)
-{
- if (mStatus != NO_ERROR) return mStatus;
- return mOverlayData->queueBuffer(mOverlayData, buffer);
-}
-
-int32_t Overlay::getBufferCount() const
-{
- if (mStatus != NO_ERROR) return mStatus;
- return mOverlayData->getBufferCount(mOverlayData);
-}
-
-void* Overlay::getBufferAddress(overlay_buffer_t buffer)
-{
- if (mStatus != NO_ERROR) return NULL;
- return mOverlayData->getBufferAddress(mOverlayData, buffer);
-}
-
-void Overlay::destroy() {
- if (mStatus != NO_ERROR) return;
- mOverlayRef->mOverlayChannel->destroy();
-}
-
-status_t Overlay::getStatus() const {
- return mStatus;
-}
-
-overlay_handle_t Overlay::getHandleRef() const {
- if (mStatus != NO_ERROR) return NULL;
- return mOverlayRef->mOverlayHandle;
-}
-
-uint32_t Overlay::getWidth() const {
- if (mStatus != NO_ERROR) return 0;
- return mOverlayRef->mWidth;
-}
-
-uint32_t Overlay::getHeight() const {
- if (mStatus != NO_ERROR) return 0;
- return mOverlayRef->mHeight;
-}
-
-int32_t Overlay::getFormat() const {
- if (mStatus != NO_ERROR) return -1;
- return mOverlayRef->mFormat;
-}
-
-int32_t Overlay::getWidthStride() const {
- if (mStatus != NO_ERROR) return 0;
- return mOverlayRef->mWidthStride;
-}
-
-int32_t Overlay::getHeightStride() const {
- if (mStatus != NO_ERROR) return 0;
- return mOverlayRef->mHeightStride;
-}
-// ----------------------------------------------------------------------------
-
-OverlayRef::OverlayRef()
- : mOverlayHandle(0),
- mWidth(0), mHeight(0), mFormat(0), mWidthStride(0), mHeightStride(0),
- mOwnHandle(true)
-{
-}
-
-OverlayRef::OverlayRef(overlay_handle_t handle, const sp<IOverlay>& channel,
- uint32_t w, uint32_t h, int32_t f, uint32_t ws, uint32_t hs)
- : mOverlayHandle(handle), mOverlayChannel(channel),
- mWidth(w), mHeight(h), mFormat(f), mWidthStride(ws), mHeightStride(hs),
- mOwnHandle(false)
-{
-}
-
-OverlayRef::~OverlayRef()
-{
- if (mOwnHandle) {
- /* FIXME: handles should be promoted to "real" API and be handled by
- * the framework */
- for (int i=0 ; i<mOverlayHandle->numFds ; i++) {
- close(mOverlayHandle->data[i]);
- }
- free((void*)mOverlayHandle);
- }
-}
-
-sp<OverlayRef> OverlayRef::readFromParcel(const Parcel& data) {
- sp<OverlayRef> result;
- sp<IOverlay> overlay = IOverlay::asInterface(data.readStrongBinder());
- if (overlay != NULL) {
- uint32_t w = data.readInt32();
- uint32_t h = data.readInt32();
- uint32_t f = data.readInt32();
- uint32_t ws = data.readInt32();
- uint32_t hs = data.readInt32();
- native_handle* handle = data.readNativeHandle(NULL, NULL);
-
- result = new OverlayRef();
- result->mOverlayHandle = handle;
- result->mOverlayChannel = overlay;
- result->mWidth = w;
- result->mHeight = h;
- result->mFormat = f;
- result->mWidthStride = ws;
- result->mHeightStride = hs;
- }
- return result;
-}
-
-status_t OverlayRef::writeToParcel(Parcel* reply, const sp<OverlayRef>& o) {
- if (o != NULL) {
- reply->writeStrongBinder(o->mOverlayChannel->asBinder());
- reply->writeInt32(o->mWidth);
- reply->writeInt32(o->mHeight);
- reply->writeInt32(o->mFormat);
- reply->writeInt32(o->mWidthStride);
- reply->writeInt32(o->mHeightStride);
- reply->writeNativeHandle(*(o->mOverlayHandle));
- } else {
- reply->writeStrongBinder(NULL);
- }
- return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp
deleted file mode 100644
index b65ed97..0000000
--- a/libs/ui/PixelFormat.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.
- */
-
-#include <ui/PixelFormat.h>
-#include <pixelflinger/format.h>
-
-namespace android {
-
-size_t PixelFormatInfo::getScanlineSize(unsigned int width) const
-{
- size_t size;
- if ((components >= 6) && (components <= 8)) {
- // YCbCr formats are differents.
- size = (width * bitsPerPixel)>>3;
- } else {
- size = width * bytesPerPixel;
- }
- return size;
-}
-
-ssize_t bytesPerPixel(PixelFormat format)
-{
- PixelFormatInfo info;
- status_t err = getPixelFormatInfo(format, &info);
- return (err < 0) ? err : info.bytesPerPixel;
-}
-
-ssize_t bitsPerPixel(PixelFormat format)
-{
- PixelFormatInfo info;
- status_t err = getPixelFormatInfo(format, &info);
- return (err < 0) ? err : info.bitsPerPixel;
-}
-
-status_t getPixelFormatInfo(PixelFormat format, PixelFormatInfo* info)
-{
- if (format < 0)
- return BAD_VALUE;
-
- if (info->version != sizeof(PixelFormatInfo))
- return INVALID_OPERATION;
-
- size_t numEntries;
- const GGLFormat *i = gglGetPixelFormatTable(&numEntries) + format;
- bool valid = uint32_t(format) < numEntries;
- if (!valid) {
- return BAD_INDEX;
- }
-
- #define COMPONENT(name) \
- case GGL_##name: info->components = PixelFormatInfo::name; break;
-
- switch (i->components) {
- COMPONENT(ALPHA)
- COMPONENT(RGB)
- COMPONENT(RGBA)
- COMPONENT(LUMINANCE)
- COMPONENT(LUMINANCE_ALPHA)
- COMPONENT(Y_CB_CR_SP)
- COMPONENT(Y_CB_CR_P)
- COMPONENT(Y_CB_CR_I)
- default:
- return BAD_INDEX;
- }
-
- #undef COMPONENT
-
- info->format = format;
- info->bytesPerPixel = i->size;
- info->bitsPerPixel = i->bitsPerPixel;
- info->h_alpha = i->ah;
- info->l_alpha = i->al;
- info->h_red = i->rh;
- info->l_red = i->rl;
- info->h_green = i->gh;
- info->l_green = i->gl;
- info->h_blue = i->bh;
- info->l_blue = i->bl;
-
- return NO_ERROR;
-}
-
-}; // namespace android
-
diff --git a/libs/ui/Point.cpp b/libs/ui/Point.cpp
deleted file mode 100644
index 438d49f..0000000
--- a/libs/ui/Point.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Point.cpp
- * Android
- *
- * Created on 11/16/2006.
- * Copyright 2005 The Android Open Source Project
- *
- */
-
-#include <ui/Point.h>
-
diff --git a/libs/ui/Rect.cpp b/libs/ui/Rect.cpp
deleted file mode 100644
index 99e68bb..0000000
--- a/libs/ui/Rect.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Rect.cpp
- * Android
- *
- * Created on 10/14/05.
- * Copyright 2005 The Android Open Source Project
- *
- */
-
-#include <ui/Rect.h>
-
-namespace android {
-
-inline int min(int a, int b) {
- return (a<b) ? a : b;
-}
-
-inline int max(int a, int b) {
- return (a>b) ? a : b;
-}
-
-void Rect::makeInvalid() {
- left = 0;
- top = 0;
- right = -1;
- bottom = -1;
-}
-
-bool Rect::operator < (const Rect& rhs) const
-{
- if (top<rhs.top) {
- return true;
- } else if (top == rhs.top) {
- if (left < rhs.left) {
- return true;
- } else if (left == rhs.left) {
- if (bottom<rhs.bottom) {
- return true;
- } else if (bottom == rhs.bottom) {
- if (right<rhs.right) {
- return true;
- }
- }
- }
- }
- return false;
-}
-
-Rect& Rect::offsetTo(int x, int y)
-{
- right -= left - x;
- bottom -= top - y;
- left = x;
- top = y;
- return *this;
-}
-
-Rect& Rect::offsetBy(int x, int y)
-{
- left += x;
- top += y;
- right+= x;
- bottom+=y;
- return *this;
-}
-
-Rect Rect::operator + (const Point& rhs) const
-{
- return Rect(left+rhs.x, top+rhs.y, right+rhs.x, bottom+rhs.y);
-}
-
-Rect Rect::operator - (const Point& rhs) const
-{
- return Rect(left-rhs.x, top-rhs.y, right-rhs.x, bottom-rhs.y);
-}
-
-bool Rect::intersect(const Rect& with, Rect* result) const
-{
- result->left = max(left, with.left);
- result->top = max(top, with.top);
- result->right = min(right, with.right);
- result->bottom = min(bottom, with.bottom);
- return !(result->isEmpty());
-}
-
-}; // namespace android
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
deleted file mode 100644
index 26e694a..0000000
--- a/libs/ui/Region.cpp
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "Region"
-
-#include <stdio.h>
-#include <utils/Atomic.h>
-#include <utils/Debug.h>
-#include <utils/String8.h>
-#include <ui/Region.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-Region::Region()
-{
-}
-
-Region::Region(const Region& rhs)
- : mRegion(rhs.mRegion)
-{
-}
-
-Region::Region(const SkRegion& rhs)
- : mRegion(rhs)
-{
-}
-
-Region::~Region()
-{
-}
-
-Region::Region(const Rect& rhs)
-{
- set(rhs);
-}
-
-Region::Region(const Parcel& parcel)
-{
- read(parcel);
-}
-
-Region::Region(const void* buffer)
-{
- read(buffer);
-}
-
-Region& Region::operator = (const Region& rhs)
-{
- mRegion = rhs.mRegion;
- return *this;
-}
-
-const SkRegion& Region::toSkRegion() const
-{
- return mRegion;
-}
-
-Rect Region::bounds() const
-{
- const SkIRect& b(mRegion.getBounds());
- return Rect(b.fLeft, b.fTop, b.fRight, b.fBottom);
-}
-
-void Region::clear()
-{
- mRegion.setEmpty();
-}
-
-void Region::set(const Rect& r)
-{
- SkIRect ir;
- ir.set(r.left, r.top, r.right, r.bottom);
- mRegion.setRect(ir);
-}
-
-// ----------------------------------------------------------------------------
-
-Region& Region::orSelf(const Rect& r)
-{
- SkIRect ir;
- ir.set(r.left, r.top, r.right, r.bottom);
- mRegion.op(ir, SkRegion::kUnion_Op);
- return *this;
-}
-
-Region& Region::andSelf(const Rect& r)
-{
- SkIRect ir;
- ir.set(r.left, r.top, r.right, r.bottom);
- mRegion.op(ir, SkRegion::kIntersect_Op);
- return *this;
-}
-
-// ----------------------------------------------------------------------------
-
-Region& Region::orSelf(const Region& rhs) {
- mRegion.op(rhs.mRegion, SkRegion::kUnion_Op);
- return *this;
-}
-
-Region& Region::andSelf(const Region& rhs) {
- mRegion.op(rhs.mRegion, SkRegion::kIntersect_Op);
- return *this;
-}
-
-Region& Region::subtractSelf(const Region& rhs) {
- mRegion.op(rhs.mRegion, SkRegion::kDifference_Op);
- return *this;
-}
-
-Region& Region::translateSelf(int x, int y) {
- if (x|y) mRegion.translate(x, y);
- return *this;
-}
-
-Region Region::merge(const Region& rhs) const {
- Region result;
- result.mRegion.op(mRegion, rhs.mRegion, SkRegion::kUnion_Op);
- return result;
-}
-
-Region Region::intersect(const Region& rhs) const {
- Region result;
- result.mRegion.op(mRegion, rhs.mRegion, SkRegion::kIntersect_Op);
- return result;
-}
-
-Region Region::subtract(const Region& rhs) const {
- Region result;
- result.mRegion.op(mRegion, rhs.mRegion, SkRegion::kDifference_Op);
- return result;
-}
-
-Region Region::translate(int x, int y) const {
- Region result;
- mRegion.translate(x, y, &result.mRegion);
- return result;
-}
-
-// ----------------------------------------------------------------------------
-
-Region& Region::orSelf(const Region& rhs, int dx, int dy) {
- SkRegion r(rhs.mRegion);
- r.translate(dx, dy);
- mRegion.op(r, SkRegion::kUnion_Op);
- return *this;
-}
-
-Region& Region::andSelf(const Region& rhs, int dx, int dy) {
- SkRegion r(rhs.mRegion);
- r.translate(dx, dy);
- mRegion.op(r, SkRegion::kIntersect_Op);
- return *this;
-}
-
-Region& Region::subtractSelf(const Region& rhs, int dx, int dy) {
- SkRegion r(rhs.mRegion);
- r.translate(dx, dy);
- mRegion.op(r, SkRegion::kDifference_Op);
- return *this;
-}
-
-Region Region::merge(const Region& rhs, int dx, int dy) const {
- Region result;
- SkRegion r(rhs.mRegion);
- r.translate(dx, dy);
- result.mRegion.op(mRegion, r, SkRegion::kUnion_Op);
- return result;
-}
-
-Region Region::intersect(const Region& rhs, int dx, int dy) const {
- Region result;
- SkRegion r(rhs.mRegion);
- r.translate(dx, dy);
- result.mRegion.op(mRegion, r, SkRegion::kIntersect_Op);
- return result;
-}
-
-Region Region::subtract(const Region& rhs, int dx, int dy) const {
- Region result;
- SkRegion r(rhs.mRegion);
- r.translate(dx, dy);
- result.mRegion.op(mRegion, r, SkRegion::kDifference_Op);
- return result;
-}
-
-// ----------------------------------------------------------------------------
-
-Region::iterator::iterator(const Region& r)
- : mIt(r.mRegion)
-{
-}
-
-int Region::iterator::iterate(Rect* rect)
-{
- if (mIt.done())
- return 0;
- const SkIRect& r(mIt.rect());
- rect->left = r.fLeft;
- rect->top = r.fTop;
- rect->right = r.fRight;
- rect->bottom= r.fBottom;
- mIt.next();
- return 1;
-}
-
-// ----------------------------------------------------------------------------
-
-// we write a 4byte size ahead of the actual region, so we know how much we'll need for reading
-
-status_t Region::write(Parcel& parcel) const
-{
- int32_t size = mRegion.flatten(NULL);
- parcel.writeInt32(size);
- mRegion.flatten(parcel.writeInplace(size));
- return NO_ERROR;
-}
-
-status_t Region::read(const Parcel& parcel)
-{
- size_t size = parcel.readInt32();
- mRegion.unflatten(parcel.readInplace(size));
- return NO_ERROR;
-}
-
-ssize_t Region::write(void* buffer, size_t size) const
-{
- size_t sizeNeeded = mRegion.flatten(NULL);
- if (sizeNeeded > size) return NO_MEMORY;
- return mRegion.flatten(buffer);
-}
-
-ssize_t Region::read(const void* buffer)
-{
- return mRegion.unflatten(buffer);
-}
-
-ssize_t Region::writeEmpty(void* buffer, size_t size)
-{
- if (size < 4) return NO_MEMORY;
- // this needs to stay in sync with SkRegion
- *static_cast<int32_t*>(buffer) = -1;
- return 4;
-}
-
-bool Region::isEmpty(void* buffer)
-{
- // this needs to stay in sync with SkRegion
- return *static_cast<int32_t*>(buffer) == -1;
-}
-
-size_t Region::rects(Vector<Rect>& rectList) const
-{
- rectList.clear();
- if (!isEmpty()) {
- SkRegion::Iterator iterator(mRegion);
- while( !iterator.done() ) {
- const SkIRect& ir(iterator.rect());
- rectList.push(Rect(ir.fLeft, ir.fTop, ir.fRight, ir.fBottom));
- iterator.next();
- }
- }
- return rectList.size();
-}
-
-void Region::dump(String8& out, const char* what, uint32_t flags) const
-{
- (void)flags;
- Vector<Rect> r;
- rects(r);
-
- size_t SIZE = 256;
- char buffer[SIZE];
-
- snprintf(buffer, SIZE, " Region %s (this=%p, count=%d)\n", what, this, r.size());
- out.append(buffer);
- for (size_t i=0 ; i<r.size() ; i++) {
- snprintf(buffer, SIZE, " [%3d, %3d, %3d, %3d]\n",
- r[i].left, r[i].top,r[i].right,r[i].bottom);
- out.append(buffer);
- }
-}
-
-void Region::dump(const char* what, uint32_t flags) const
-{
- (void)flags;
- Vector<Rect> r;
- rects(r);
- LOGD(" Region %s (this=%p, count=%d)\n", what, this, r.size());
- for (size_t i=0 ; i<r.size() ; i++) {
- LOGD(" [%3d, %3d, %3d, %3d]\n",
- r[i].left, r[i].top,r[i].right,r[i].bottom);
- }
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp
deleted file mode 100644
index 4ea9ae2..0000000
--- a/libs/ui/Surface.cpp
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "Surface"
-
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <utils/Atomic.h>
-#include <utils/Errors.h>
-#include <utils/threads.h>
-#include <utils/IPCThreadState.h>
-#include <utils/IMemory.h>
-#include <utils/Log.h>
-
-#include <ui/ISurface.h>
-#include <ui/Surface.h>
-#include <ui/SurfaceComposerClient.h>
-#include <ui/Rect.h>
-
-#include <private/ui/SharedState.h>
-#include <private/ui/LayerState.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-Surface::Surface(const sp<SurfaceComposerClient>& client,
- const sp<ISurface>& surface,
- const ISurfaceFlingerClient::surface_data_t& data,
- uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
- bool owner)
- : mClient(client), mSurface(surface),
- mToken(data.token), mIdentity(data.identity),
- mFormat(format), mFlags(flags), mOwner(owner)
-{
- mSwapRectangle.makeInvalid();
- mSurfaceHeapBase[0] = 0;
- mSurfaceHeapBase[1] = 0;
- mHeap[0] = data.heap[0];
- mHeap[1] = data.heap[1];
-}
-
-Surface::Surface(Surface const* rhs)
- : mOwner(false)
-{
- mToken = rhs->mToken;
- mIdentity= rhs->mIdentity;
- mClient = rhs->mClient;
- mSurface = rhs->mSurface;
- mHeap[0] = rhs->mHeap[0];
- mHeap[1] = rhs->mHeap[1];
- mFormat = rhs->mFormat;
- mFlags = rhs->mFlags;
- mSurfaceHeapBase[0] = rhs->mSurfaceHeapBase[0];
- mSurfaceHeapBase[1] = rhs->mSurfaceHeapBase[1];
- mSwapRectangle.makeInvalid();
-}
-
-Surface::~Surface()
-{
- if (mOwner && mToken>=0 && mClient!=0) {
- mClient->destroySurface(mToken);
- }
- mClient.clear();
- mSurface.clear();
- mHeap[0].clear();
- mHeap[1].clear();
- IPCThreadState::self()->flushCommands();
-}
-
-sp<Surface> Surface::dup() const
-{
- Surface const * r = this;
- if (this && mOwner) {
- // the only reason we need to do this is because of Java's garbage
- // collector: because we're creating a copy of the Surface
- // instead of a reference, we can garantee that when our last
- // reference goes away, the real surface will be deleted.
- // Without this hack (the code is correct too), we'd have to
- // wait for a GC for the surface to go away.
- r = new Surface(this);
- }
- return const_cast<Surface*>(r);
-}
-
-status_t Surface::nextBuffer(SurfaceInfo* info) {
- return mClient->nextBuffer(this, info);
-}
-
-status_t Surface::lock(SurfaceInfo* info, bool blocking) {
- return Surface::lock(info, NULL, blocking);
-}
-
-status_t Surface::lock(SurfaceInfo* info, Region* dirty, bool blocking) {
- if (heapBase(0) == 0) return INVALID_OPERATION;
- if (heapBase(1) == 0) return INVALID_OPERATION;
- return mClient->lockSurface(this, info, dirty, blocking);
-}
-
-status_t Surface::unlockAndPost() {
- if (heapBase(0) == 0) return INVALID_OPERATION;
- if (heapBase(1) == 0) return INVALID_OPERATION;
- return mClient->unlockAndPostSurface(this);
-}
-
-status_t Surface::unlock() {
- if (heapBase(0) == 0) return INVALID_OPERATION;
- if (heapBase(1) == 0) return INVALID_OPERATION;
- return mClient->unlockSurface(this);
-}
-
-status_t Surface::setLayer(int32_t layer) {
- return mClient->setLayer(this, layer);
-}
-status_t Surface::setPosition(int32_t x, int32_t y) {
- return mClient->setPosition(this, x, y);
-}
-status_t Surface::setSize(uint32_t w, uint32_t h) {
- return mClient->setSize(this, w, h);
-}
-status_t Surface::hide() {
- return mClient->hide(this);
-}
-status_t Surface::show(int32_t layer) {
- return mClient->show(this, layer);
-}
-status_t Surface::freeze() {
- return mClient->freeze(this);
-}
-status_t Surface::unfreeze() {
- return mClient->unfreeze(this);
-}
-status_t Surface::setFlags(uint32_t flags, uint32_t mask) {
- return mClient->setFlags(this, flags, mask);
-}
-status_t Surface::setTransparentRegionHint(const Region& transparent) {
- return mClient->setTransparentRegionHint(this, transparent);
-}
-status_t Surface::setAlpha(float alpha) {
- return mClient->setAlpha(this, alpha);
-}
-status_t Surface::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
- return mClient->setMatrix(this, dsdx, dtdx, dsdy, dtdy);
-}
-status_t Surface::setFreezeTint(uint32_t tint) {
- return mClient->setFreezeTint(this, tint);
-}
-
-Region Surface::dirtyRegion() const {
- return mDirtyRegion;
-}
-void Surface::setDirtyRegion(const Region& region) const {
- mDirtyRegion = region;
-}
-const Rect& Surface::swapRectangle() const {
- return mSwapRectangle;
-}
-void Surface::setSwapRectangle(const Rect& r) {
- mSwapRectangle = r;
-}
-
-sp<Surface> Surface::readFromParcel(Parcel* parcel)
-{
- sp<SurfaceComposerClient> client;
- ISurfaceFlingerClient::surface_data_t data;
- sp<IBinder> clientBinder= parcel->readStrongBinder();
- sp<ISurface> surface = interface_cast<ISurface>(parcel->readStrongBinder());
- data.heap[0] = interface_cast<IMemoryHeap>(parcel->readStrongBinder());
- data.heap[1] = interface_cast<IMemoryHeap>(parcel->readStrongBinder());
- data.token = parcel->readInt32();
- data.identity = parcel->readInt32();
- PixelFormat format = parcel->readInt32();
- uint32_t flags = parcel->readInt32();
-
- if (clientBinder != NULL)
- client = SurfaceComposerClient::clientForConnection(clientBinder);
-
- return new Surface(client, surface, data, 0, 0, format, flags, false);
-}
-
-status_t Surface::writeToParcel(const sp<Surface>& surface, Parcel* parcel)
-{
- uint32_t flags=0;
- uint32_t format=0;
- SurfaceID token = -1;
- uint32_t identity = 0;
- sp<SurfaceComposerClient> client;
- sp<ISurface> sur;
- sp<IMemoryHeap> heap[2];
- if (surface->isValid()) {
- token = surface->mToken;
- identity = surface->mIdentity;
- client = surface->mClient;
- sur = surface->mSurface;
- heap[0] = surface->mHeap[0];
- heap[1] = surface->mHeap[1];
- format = surface->mFormat;
- flags = surface->mFlags;
- }
- parcel->writeStrongBinder(client!=0 ? client->connection() : NULL);
- parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
- parcel->writeStrongBinder(heap[0]!=0 ? heap[0]->asBinder() : NULL);
- parcel->writeStrongBinder(heap[1]!=0 ? heap[1]->asBinder() : NULL);
- parcel->writeInt32(token);
- parcel->writeInt32(identity);
- parcel->writeInt32(format);
- parcel->writeInt32(flags);
- return NO_ERROR;
-}
-
-bool Surface::isSameSurface(const sp<Surface>& lhs, const sp<Surface>& rhs)
-{
- if (lhs == 0 || rhs == 0)
- return false;
- return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
-}
-
-void* Surface::heapBase(int i) const
-{
- void* heapBase = mSurfaceHeapBase[i];
- // map lazily so it doesn't get mapped in clients that don't need it
- if (heapBase == 0) {
- const sp<IMemoryHeap>& heap(mHeap[i]);
- if (heap != 0) {
- heapBase = static_cast<uint8_t*>(heap->base());
- if (heapBase == MAP_FAILED) {
- heapBase = NULL;
- LOGE("Couldn't map Surface's heap (binder=%p, heap=%p)",
- heap->asBinder().get(), heap.get());
- }
- mSurfaceHeapBase[i] = heapBase;
- }
- }
- return heapBase;
-}
-
-}; // namespace android
-
diff --git a/libs/ui/SurfaceComposerClient.cpp b/libs/ui/SurfaceComposerClient.cpp
deleted file mode 100644
index 9354a7a..0000000
--- a/libs/ui/SurfaceComposerClient.cpp
+++ /dev/null
@@ -1,1026 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "SurfaceComposerClient"
-
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <cutils/memory.h>
-
-#include <utils/Atomic.h>
-#include <utils/Errors.h>
-#include <utils/threads.h>
-#include <utils/KeyedVector.h>
-#include <utils/IPCThreadState.h>
-#include <utils/IServiceManager.h>
-#include <utils/IMemory.h>
-#include <utils/Log.h>
-
-#include <ui/ISurfaceComposer.h>
-#include <ui/ISurfaceFlingerClient.h>
-#include <ui/ISurface.h>
-#include <ui/SurfaceComposerClient.h>
-#include <ui/DisplayInfo.h>
-#include <ui/Rect.h>
-#include <ui/Point.h>
-
-#include <private/ui/SharedState.h>
-#include <private/ui/LayerState.h>
-#include <private/ui/SurfaceFlingerSynchro.h>
-
-#include <pixelflinger/pixelflinger.h>
-
-#include <utils/BpBinder.h>
-
-#define VERBOSE(...) ((void)0)
-//#define VERBOSE LOGD
-
-#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
-#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-// Must not be holding SurfaceComposerClient::mLock when acquiring gLock here.
-static Mutex gLock;
-static sp<ISurfaceComposer> gSurfaceManager;
-static DefaultKeyedVector< sp<IBinder>, sp<SurfaceComposerClient> > gActiveConnections;
-static SortedVector<sp<SurfaceComposerClient> > gOpenTransactions;
-static sp<IMemory> gServerCblkMemory;
-static volatile surface_flinger_cblk_t* gServerCblk;
-
-const sp<ISurfaceComposer>& _get_surface_manager()
-{
- if (gSurfaceManager != 0) {
- return gSurfaceManager;
- }
-
- sp<IBinder> binder;
- sp<IServiceManager> sm = defaultServiceManager();
- do {
- binder = sm->getService(String16("SurfaceFlinger"));
- if (binder == 0) {
- LOGW("SurfaceFlinger not published, waiting...");
- usleep(500000); // 0.5 s
- }
- } while(binder == 0);
- sp<ISurfaceComposer> sc(interface_cast<ISurfaceComposer>(binder));
-
- Mutex::Autolock _l(gLock);
- if (gSurfaceManager == 0) {
- gSurfaceManager = sc;
- }
- return gSurfaceManager;
-}
-
-static volatile surface_flinger_cblk_t const * get_cblk()
-{
- if (gServerCblk == 0) {
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
- Mutex::Autolock _l(gLock);
- if (gServerCblk == 0) {
- gServerCblkMemory = sm->getCblk();
- LOGE_IF(gServerCblkMemory==0, "Can't get server control block");
- gServerCblk = (surface_flinger_cblk_t *)gServerCblkMemory->pointer();
- LOGE_IF(gServerCblk==0, "Can't get server control block address");
- }
- }
- return gServerCblk;
-}
-
-// ---------------------------------------------------------------------------
-
-static void copyBlt(const GGLSurface& dst,
- const GGLSurface& src, const Region& reg)
-{
- Region::iterator iterator(reg);
- if (iterator) {
- // NOTE: dst and src must be the same format
- Rect r;
- const size_t bpp = bytesPerPixel(src.format);
- const size_t dbpr = dst.stride * bpp;
- const size_t sbpr = src.stride * bpp;
- while (iterator.iterate(&r)) {
- ssize_t h = r.bottom - r.top;
- if (h) {
- size_t size = (r.right - r.left) * bpp;
- uint8_t* s = src.data + (r.left + src.stride * r.top) * bpp;
- uint8_t* d = dst.data + (r.left + dst.stride * r.top) * bpp;
- if (dbpr==sbpr && size==sbpr) {
- size *= h;
- h = 1;
- }
- do {
- memcpy(d, s, size);
- d += dbpr;
- s += sbpr;
- } while (--h > 0);
- }
- }
- }
-}
-
-// ---------------------------------------------------------------------------
-
-surface_flinger_cblk_t::surface_flinger_cblk_t()
-{
-}
-
-// ---------------------------------------------------------------------------
-
-per_client_cblk_t::per_client_cblk_t()
-{
-}
-
-// these functions are used by the clients
-inline status_t per_client_cblk_t::validate(size_t i) const {
- if (uint32_t(i) >= NUM_LAYERS_MAX)
- return BAD_INDEX;
- if (layers[i].swapState & eInvalidSurface)
- return NO_MEMORY;
- return NO_ERROR;
-}
-
-int32_t per_client_cblk_t::lock_layer(size_t i, uint32_t flags)
-{
- int32_t index;
- uint32_t state;
- int timeout = 0;
- status_t result;
- layer_cblk_t * const layer = layers + i;
- const bool blocking = flags & BLOCKING;
- const bool inspect = flags & INSPECT;
-
- do {
- state = layer->swapState;
-
- if (UNLIKELY((state&(eFlipRequested|eNextFlipPending)) == eNextFlipPending)) {
- LOGE("eNextFlipPending set but eFlipRequested not set, "
- "layer=%d (lcblk=%p), state=%08x",
- int(i), layer, int(state));
- return INVALID_OPERATION;
- }
-
- if (UNLIKELY(state&eLocked)) {
- LOGE("eLocked set when entering lock_layer(), "
- "layer=%d (lcblk=%p), state=%08x",
- int(i), layer, int(state));
- return WOULD_BLOCK;
- }
-
-
- if (state & (eFlipRequested | eNextFlipPending | eResizeRequested
- | eInvalidSurface))
- {
- int32_t resizeIndex;
- Mutex::Autolock _l(lock);
- // might block for a very short amount of time
- // will never cause the server to block (trylock())
-
- goto start_loop_here;
-
- // We block the client if:
- // eNextFlipPending: we've used both buffers already, so we need to
- // wait for one to become availlable.
- // eResizeRequested: the buffer we're going to acquire is being
- // resized. Block until it is done.
- // eFlipRequested && eBusy: the buffer we're going to acquire is
- // currently in use by the server.
- // eInvalidSurface: this is a special case, we don't block in this
- // case, we just return an error.
-
- while((state & (eNextFlipPending|eInvalidSurface)) ||
- (state & ((resizeIndex) ? eResizeBuffer1 : eResizeBuffer0)) ||
- ((state & (eFlipRequested|eBusy)) == (eFlipRequested|eBusy)) )
- {
- if (state & eInvalidSurface)
- return NO_MEMORY;
-
- if (!blocking)
- return WOULD_BLOCK;
-
- timeout = 0;
- result = cv.waitRelative(lock, seconds(1));
- if (__builtin_expect(result!=NO_ERROR, false)) {
- const int newState = layer->swapState;
- LOGW( "lock_layer timed out (is the CPU pegged?) "
- "layer=%d, lcblk=%p, state=%08x (was %08x)",
- int(i), layer, newState, int(state));
- timeout = newState != int(state);
- }
-
- start_loop_here:
- state = layer->swapState;
- resizeIndex = (state&eIndex) ^ ((state&eFlipRequested)>>1);
- }
-
- LOGW_IF(timeout,
- "lock_layer() timed out but didn't appear to need "
- "to be locked and we recovered "
- "(layer=%d, lcblk=%p, state=%08x)",
- int(i), layer, int(state));
- }
-
- // eFlipRequested is not set and cannot be set by another thread: it's
- // safe to use the first buffer without synchronization.
-
- // Choose the index depending on eFlipRequested.
- // When it's set, choose the 'other' buffer.
- index = (state&eIndex) ^ ((state&eFlipRequested)>>1);
-
- // make sure this buffer is valid
- if (layer->surface[index].bits_offset < 0) {
- return status_t(layer->surface[index].bits_offset);
- }
-
- if (inspect) {
- // we just want to inspect this layer. don't lock it.
- goto done;
- }
-
- // last thing before we're done, we need to atomically lock the state
- } while (android_atomic_cmpxchg(state, state|eLocked, &(layer->swapState)));
-
- VERBOSE("locked layer=%d (lcblk=%p), buffer=%d, state=0x%08x",
- int(i), layer, int(index), int(state));
-
- // store the index of the locked buffer (for client use only)
- layer->flags &= ~eBufferIndex;
- layer->flags |= ((index << eBufferIndexShift) & eBufferIndex);
-
-done:
- return index;
-}
-
-uint32_t per_client_cblk_t::unlock_layer_and_post(size_t i)
-{
- // atomically set eFlipRequested and clear eLocked and optionnaly
- // set eNextFlipPending if eFlipRequested was already set
-
- layer_cblk_t * const layer = layers + i;
- int32_t oldvalue, newvalue;
- do {
- oldvalue = layer->swapState;
- // get current value
-
- newvalue = oldvalue & ~eLocked;
- // clear eLocked
-
- newvalue |= eFlipRequested;
- // set eFlipRequested
-
- if (oldvalue & eFlipRequested)
- newvalue |= eNextFlipPending;
- // if eFlipRequested was alread set, set eNextFlipPending
-
- } while (android_atomic_cmpxchg(oldvalue, newvalue, &(layer->swapState)));
-
- VERBOSE("request pageflip for layer=%d, buffer=%d, state=0x%08x",
- int(i), int((layer->flags & eBufferIndex) >> eBufferIndexShift),
- int(newvalue));
-
- // from this point, the server can kick in at anytime and use the first
- // buffer, so we cannot use it anymore, and we must use the 'other'
- // buffer instead (or wait if it is not availlable yet, see lock_layer).
-
- return newvalue;
-}
-
-void per_client_cblk_t::unlock_layer(size_t i)
-{
- layer_cblk_t * const layer = layers + i;
- android_atomic_and(~eLocked, &layer->swapState);
-}
-
-// ---------------------------------------------------------------------------
-
-static inline int compare_type( const layer_state_t& lhs,
- const layer_state_t& rhs) {
- if (lhs.surface < rhs.surface) return -1;
- if (lhs.surface > rhs.surface) return 1;
- return 0;
-}
-
-SurfaceComposerClient::SurfaceComposerClient()
-{
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
- if (sm == 0) {
- _init(0, 0);
- return;
- }
-
- _init(sm, sm->createConnection());
-
- if (mClient != 0) {
- Mutex::Autolock _l(gLock);
- VERBOSE("Adding client %p to map", this);
- gActiveConnections.add(mClient->asBinder(), this);
- }
-}
-
-SurfaceComposerClient::SurfaceComposerClient(
- const sp<ISurfaceComposer>& sm, const sp<IBinder>& conn)
-{
- _init(sm, interface_cast<ISurfaceFlingerClient>(conn));
-}
-
-void SurfaceComposerClient::_init(
- const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn)
-{
- VERBOSE("Creating client %p, conn %p", this, conn.get());
-
- mSignalServer = 0;
- mPrebuiltLayerState = 0;
- mTransactionOpen = 0;
- mStatus = NO_ERROR;
- mControl = 0;
-
- mClient = conn;
- if (mClient == 0) {
- mStatus = NO_INIT;
- return;
- }
-
- mClient->getControlBlocks(&mControlMemory);
- mSignalServer = new SurfaceFlingerSynchro(sm);
- mControl = static_cast<per_client_cblk_t *>(mControlMemory->pointer());
-}
-
-SurfaceComposerClient::~SurfaceComposerClient()
-{
- VERBOSE("Destroying client %p, conn %p", this, mClient.get());
- dispose();
-}
-
-status_t SurfaceComposerClient::initCheck() const
-{
- return mStatus;
-}
-
-status_t SurfaceComposerClient::validateSurface(
- per_client_cblk_t const* cblk, Surface const * surface)
-{
- SurfaceID index = surface->ID();
- if (cblk == 0) {
- LOGE("cblk is null (surface id=%d, identity=%u)",
- index, surface->getIdentity());
- return NO_INIT;
- }
-
- status_t err = cblk->validate(index);
- if (err != NO_ERROR) {
- LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
- index, surface->getIdentity(), err, strerror(-err));
- return err;
- }
-
- if (surface->getIdentity() != uint32_t(cblk->layers[index].identity)) {
- LOGE("using an invalid surface id=%d, identity=%u should be %d",
- index, surface->getIdentity(), cblk->layers[index].identity);
- return NO_INIT;
- }
-
- return NO_ERROR;
-}
-
-sp<IBinder> SurfaceComposerClient::connection() const
-{
- return (mClient != 0) ? mClient->asBinder() : 0;
-}
-
-sp<SurfaceComposerClient>
-SurfaceComposerClient::clientForConnection(const sp<IBinder>& conn)
-{
- sp<SurfaceComposerClient> client;
-
- { // scope for lock
- Mutex::Autolock _l(gLock);
- client = gActiveConnections.valueFor(conn);
- }
-
- if (client == 0) {
- // Need to make a new client.
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
- client = new SurfaceComposerClient(sm, conn);
- if (client != 0 && client->initCheck() == NO_ERROR) {
- Mutex::Autolock _l(gLock);
- gActiveConnections.add(conn, client);
- //LOGD("we have %d connections", gActiveConnections.size());
- } else {
- client.clear();
- }
- }
-
- return client;
-}
-
-void SurfaceComposerClient::dispose()
-{
- // this can be called more than once.
-
- sp<IMemory> controlMemory;
- sp<ISurfaceFlingerClient> client;
- sp<IMemoryHeap> surfaceHeap;
-
- {
- Mutex::Autolock _lg(gLock);
- Mutex::Autolock _lm(mLock);
-
- delete mSignalServer;
- mSignalServer = 0;
-
- if (mClient != 0) {
- client = mClient;
- mClient.clear();
-
- ssize_t i = gActiveConnections.indexOfKey(client->asBinder());
- if (i >= 0 && gActiveConnections.valueAt(i) == this) {
- VERBOSE("Removing client %p from map at %d", this, int(i));
- gActiveConnections.removeItemsAt(i);
- }
- }
-
- delete mPrebuiltLayerState;
- mPrebuiltLayerState = 0;
- controlMemory = mControlMemory;
- surfaceHeap = mSurfaceHeap;
- mControlMemory.clear();
- mSurfaceHeap.clear();
- mControl = 0;
- mStatus = NO_INIT;
- }
-}
-
-status_t SurfaceComposerClient::getDisplayInfo(
- DisplayID dpy, DisplayInfo* info)
-{
- if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
- return BAD_VALUE;
-
- volatile surface_flinger_cblk_t const * cblk = get_cblk();
- volatile display_cblk_t const * dcblk = cblk->displays + dpy;
-
- info->w = dcblk->w;
- info->h = dcblk->h;
- info->orientation = dcblk->orientation;
- info->xdpi = dcblk->xdpi;
- info->ydpi = dcblk->ydpi;
- info->fps = dcblk->fps;
- info->density = dcblk->density;
- return getPixelFormatInfo(dcblk->format, &(info->pixelFormatInfo));
-}
-
-ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)
-{
- if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
- return BAD_VALUE;
- volatile surface_flinger_cblk_t const * cblk = get_cblk();
- volatile display_cblk_t const * dcblk = cblk->displays + dpy;
- return dcblk->w;
-}
-
-ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)
-{
- if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
- return BAD_VALUE;
- volatile surface_flinger_cblk_t const * cblk = get_cblk();
- volatile display_cblk_t const * dcblk = cblk->displays + dpy;
- return dcblk->h;
-}
-
-ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)
-{
- if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
- return BAD_VALUE;
- volatile surface_flinger_cblk_t const * cblk = get_cblk();
- volatile display_cblk_t const * dcblk = cblk->displays + dpy;
- return dcblk->orientation;
-}
-
-ssize_t SurfaceComposerClient::getNumberOfDisplays()
-{
- volatile surface_flinger_cblk_t const * cblk = get_cblk();
- uint32_t connected = cblk->connected;
- int n = 0;
- while (connected) {
- if (connected&1) n++;
- connected >>= 1;
- }
- return n;
-}
-
-sp<Surface> SurfaceComposerClient::createSurface(
- int pid,
- DisplayID display,
- uint32_t w,
- uint32_t h,
- PixelFormat format,
- uint32_t flags)
-{
- sp<Surface> result;
- if (mStatus == NO_ERROR) {
- ISurfaceFlingerClient::surface_data_t data;
- sp<ISurface> surface = mClient->createSurface(&data, pid,
- display, w, h, format, flags);
- if (surface != 0) {
- if (uint32_t(data.token) < NUM_LAYERS_MAX) {
- result = new Surface(this, surface, data, w, h, format, flags);
- }
- }
- }
- return result;
-}
-
-status_t SurfaceComposerClient::destroySurface(SurfaceID sid)
-{
- if (mStatus != NO_ERROR)
- return mStatus;
-
- // it's okay to destroy a surface while a transaction is open,
- // (transactions really are a client-side concept)
- // however, this indicates probably a misuse of the API or a bug
- // in the client code.
- LOGW_IF(mTransactionOpen,
- "Destroying surface while a transaction is open. "
- "Client %p: destroying surface %d, mTransactionOpen=%d",
- this, sid, mTransactionOpen);
-
- status_t err = mClient->destroySurface(sid);
- return err;
-}
-
-status_t SurfaceComposerClient::nextBuffer(Surface* surface,
- Surface::SurfaceInfo* info)
-{
- SurfaceID index = surface->ID();
- per_client_cblk_t* const cblk = mControl;
- status_t err = validateSurface(cblk, surface);
- if (err != NO_ERROR)
- return err;
-
- int32_t backIdx = surface->mBackbufferIndex;
- layer_cblk_t* const lcblk = &(cblk->layers[index]);
- const surface_info_t* const front = lcblk->surface + (1-backIdx);
- info->w = front->w;
- info->h = front->h;
- info->format = front->format;
- info->base = surface->heapBase(1-backIdx);
- info->bits = reinterpret_cast<void*>(intptr_t(info->base) + front->bits_offset);
- info->bpr = front->bpr;
-
- return 0;
-}
-
-status_t SurfaceComposerClient::lockSurface(
- Surface* surface,
- Surface::SurfaceInfo* other,
- Region* dirty,
- bool blocking)
-{
- Mutex::Autolock _l(surface->getLock());
-
- SurfaceID index = surface->ID();
- per_client_cblk_t* const cblk = mControl;
- status_t err = validateSurface(cblk, surface);
- if (err != NO_ERROR)
- return err;
-
- int32_t backIdx = cblk->lock_layer(size_t(index),
- per_client_cblk_t::BLOCKING);
- if (backIdx >= 0) {
- surface->mBackbufferIndex = backIdx;
- layer_cblk_t* const lcblk = &(cblk->layers[index]);
- const surface_info_t* const back = lcblk->surface + backIdx;
- const surface_info_t* const front = lcblk->surface + (1-backIdx);
- other->w = back->w;
- other->h = back->h;
- other->format = back->format;
- other->base = surface->heapBase(backIdx);
- other->bits = reinterpret_cast<void*>(intptr_t(other->base) + back->bits_offset);
- other->bpr = back->bpr;
-
- const Rect bounds(other->w, other->h);
- Region newDirtyRegion;
-
- if (back->flags & surface_info_t::eBufferDirty) {
- /* it is safe to write *back here, because we're guaranteed
- * SurfaceFlinger is not touching it (since it just granted
- * access to us) */
- const_cast<surface_info_t*>(back)->flags &=
- ~surface_info_t::eBufferDirty;
-
- // content is meaningless in this case and the whole surface
- // needs to be redrawn.
-
- newDirtyRegion.set(bounds);
- if (dirty) {
- *dirty = newDirtyRegion;
- }
-
- //if (bytesPerPixel(other->format) == 4) {
- // android_memset32(
- // (uint32_t*)other->bits, 0xFF00FF00, other->h * other->bpr);
- //} else {
- // android_memset16( // fill with green
- // (uint16_t*)other->bits, 0x7E0, other->h * other->bpr);
- //}
- }
- else
- {
- if (dirty) {
- dirty->andSelf(Region(bounds));
- newDirtyRegion = *dirty;
- } else {
- newDirtyRegion.set(bounds);
- }
-
- Region copyback;
- if (!(lcblk->flags & eNoCopyBack)) {
- const Region previousDirtyRegion(surface->dirtyRegion());
- copyback = previousDirtyRegion.subtract(newDirtyRegion);
- }
-
- if (!copyback.isEmpty()) {
- // copy front to back
- GGLSurface cb;
- cb.version = sizeof(GGLSurface);
- cb.width = back->w;
- cb.height = back->h;
- cb.stride = back->stride;
- cb.data = (GGLubyte*)surface->heapBase(backIdx);
- cb.data += back->bits_offset;
- cb.format = back->format;
-
- GGLSurface t;
- t.version = sizeof(GGLSurface);
- t.width = front->w;
- t.height = front->h;
- t.stride = front->stride;
- t.data = (GGLubyte*)surface->heapBase(1-backIdx);
- t.data += front->bits_offset;
- t.format = front->format;
-
- //const Region copyback(lcblk->region + 1-backIdx);
- copyBlt(cb, t, copyback);
- }
- }
-
- // update dirty region
- surface->setDirtyRegion(newDirtyRegion);
- }
- return (backIdx < 0) ? status_t(backIdx) : status_t(NO_ERROR);
-}
-
-void SurfaceComposerClient::_signal_server()
-{
- mSignalServer->signal();
-}
-
-void SurfaceComposerClient::_send_dirty_region(
- layer_cblk_t* lcblk, const Region& dirty)
-{
- const int32_t index = (lcblk->flags & eBufferIndex) >> eBufferIndexShift;
- flat_region_t* flat_region = lcblk->region + index;
- status_t err = dirty.write(flat_region, sizeof(flat_region_t));
- if (err < NO_ERROR) {
- // region doesn't fit, use the bounds
- const Region reg(dirty.bounds());
- reg.write(flat_region, sizeof(flat_region_t));
- }
-}
-
-status_t SurfaceComposerClient::unlockAndPostSurface(Surface* surface)
-{
- Mutex::Autolock _l(surface->getLock());
-
- SurfaceID index = surface->ID();
- per_client_cblk_t* const cblk = mControl;
- status_t err = validateSurface(cblk, surface);
- if (err != NO_ERROR)
- return err;
-
- Region dirty(surface->dirtyRegion());
- const Rect& swapRect(surface->swapRectangle());
- if (swapRect.isValid()) {
- dirty.set(swapRect);
- }
-
- // transmit the dirty region
- layer_cblk_t* const lcblk = &(cblk->layers[index]);
- _send_dirty_region(lcblk, dirty);
- uint32_t newstate = cblk->unlock_layer_and_post(size_t(index));
- if (!(newstate & eNextFlipPending))
- _signal_server();
- return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::unlockSurface(Surface* surface)
-{
- Mutex::Autolock _l(surface->getLock());
-
- SurfaceID index = surface->ID();
- per_client_cblk_t* const cblk = mControl;
- status_t err = validateSurface(cblk, surface);
- if (err != NO_ERROR)
- return err;
-
- layer_cblk_t* const lcblk = &(cblk->layers[index]);
- cblk->unlock_layer(size_t(index));
- return NO_ERROR;
-}
-
-void SurfaceComposerClient::openGlobalTransaction()
-{
- Mutex::Autolock _l(gLock);
-
- if (gOpenTransactions.size()) {
- LOGE("openGlobalTransaction() called more than once. skipping.");
- return;
- }
-
- const size_t N = gActiveConnections.size();
- VERBOSE("openGlobalTransaction (%ld clients)", N);
- for (size_t i=0; i<N; i++) {
- sp<SurfaceComposerClient> client(gActiveConnections.valueAt(i));
- if (gOpenTransactions.indexOf(client) < 0) {
- if (client->openTransaction() == NO_ERROR) {
- if (gOpenTransactions.add(client) < 0) {
- // Ooops!
- LOGE( "Unable to add a SurfaceComposerClient "
- "to the global transaction set (out of memory?)");
- client->closeTransaction();
- // let it go, it'll fail later when the user
- // tries to do something with the transaction
- }
- } else {
- LOGE("openTransaction on client %p failed", client.get());
- // let it go, it'll fail later when the user
- // tries to do something with the transaction
- }
- }
- }
-}
-
-void SurfaceComposerClient::closeGlobalTransaction()
-{
- gLock.lock();
- SortedVector< sp<SurfaceComposerClient> > clients(gOpenTransactions);
- gOpenTransactions.clear();
- gLock.unlock();
-
- const size_t N = clients.size();
- VERBOSE("closeGlobalTransaction (%ld clients)", N);
- if (N == 1) {
- clients[0]->closeTransaction();
- } else {
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
- sm->openGlobalTransaction();
- for (size_t i=0; i<N; i++) {
- clients[i]->closeTransaction();
- }
- sm->closeGlobalTransaction();
- }
-}
-
-status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
-{
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
- return sm->freezeDisplay(dpy, flags);
-}
-
-status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
-{
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
- return sm->unfreezeDisplay(dpy, flags);
-}
-
-int SurfaceComposerClient::setOrientation(DisplayID dpy, int orientation)
-{
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
- return sm->setOrientation(dpy, orientation);
-}
-
-status_t SurfaceComposerClient::openTransaction()
-{
- if (mStatus != NO_ERROR)
- return mStatus;
- Mutex::Autolock _l(mLock);
- VERBOSE( "openTransaction (client %p, mTransactionOpen=%d)",
- this, mTransactionOpen);
- mTransactionOpen++;
- if (mPrebuiltLayerState == 0) {
- mPrebuiltLayerState = new layer_state_t;
- }
- return NO_ERROR;
-}
-
-
-status_t SurfaceComposerClient::closeTransaction()
-{
- if (mStatus != NO_ERROR)
- return mStatus;
-
- Mutex::Autolock _l(mLock);
-
- VERBOSE( "closeTransaction (client %p, mTransactionOpen=%d)",
- this, mTransactionOpen);
-
- if (mTransactionOpen <= 0) {
- LOGE( "closeTransaction (client %p, mTransactionOpen=%d) "
- "called more times than openTransaction()",
- this, mTransactionOpen);
- return INVALID_OPERATION;
- }
-
- if (mTransactionOpen >= 2) {
- mTransactionOpen--;
- return NO_ERROR;
- }
-
- mTransactionOpen = 0;
- const ssize_t count = mStates.size();
- if (count) {
- mClient->setState(count, mStates.array());
- mStates.clear();
- }
- return NO_ERROR;
-}
-
-layer_state_t* SurfaceComposerClient::_get_state_l(const sp<Surface>& surface)
-{
- SurfaceID index = surface->ID();
- per_client_cblk_t* const cblk = mControl;
- status_t err = validateSurface(cblk, surface.get());
- if (err != NO_ERROR)
- return 0;
-
- // API usage error, do nothing.
- if (mTransactionOpen<=0) {
- LOGE("Not in transaction (client=%p, SurfaceID=%d, mTransactionOpen=%d",
- this, int(index), mTransactionOpen);
- return 0;
- }
-
- // use mPrebuiltLayerState just to find out if we already have it
- layer_state_t& dummy = *mPrebuiltLayerState;
- dummy.surface = index;
- ssize_t i = mStates.indexOf(dummy);
- if (i < 0) {
- // we don't have it, add an initialized layer_state to our list
- i = mStates.add(dummy);
- }
- return mStates.editArray() + i;
-}
-
-layer_state_t* SurfaceComposerClient::_lockLayerState(const sp<Surface>& surface)
-{
- layer_state_t* s;
- mLock.lock();
- s = _get_state_l(surface);
- if (!s) mLock.unlock();
- return s;
-}
-
-void SurfaceComposerClient::_unlockLayerState()
-{
- mLock.unlock();
-}
-
-status_t SurfaceComposerClient::setPosition(Surface* surface, int32_t x, int32_t y)
-{
- layer_state_t* s = _lockLayerState(surface);
- if (!s) return BAD_INDEX;
- s->what |= ISurfaceComposer::ePositionChanged;
- s->x = x;
- s->y = y;
- _unlockLayerState();
- return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::setSize(Surface* surface, uint32_t w, uint32_t h)
-{
- layer_state_t* s = _lockLayerState(surface);
- if (!s) return BAD_INDEX;
- s->what |= ISurfaceComposer::eSizeChanged;
- s->w = w;
- s->h = h;
- _unlockLayerState();
- return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::setLayer(Surface* surface, int32_t z)
-{
- layer_state_t* s = _lockLayerState(surface);
- if (!s) return BAD_INDEX;
- s->what |= ISurfaceComposer::eLayerChanged;
- s->z = z;
- _unlockLayerState();
- return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::hide(Surface* surface)
-{
- return setFlags(surface, ISurfaceComposer::eLayerHidden,
- ISurfaceComposer::eLayerHidden);
-}
-
-status_t SurfaceComposerClient::show(Surface* surface, int32_t)
-{
- return setFlags(surface, 0, ISurfaceComposer::eLayerHidden);
-}
-
-status_t SurfaceComposerClient::freeze(Surface* surface)
-{
- return setFlags(surface, ISurfaceComposer::eLayerFrozen,
- ISurfaceComposer::eLayerFrozen);
-}
-
-status_t SurfaceComposerClient::unfreeze(Surface* surface)
-{
- return setFlags(surface, 0, ISurfaceComposer::eLayerFrozen);
-}
-
-status_t SurfaceComposerClient::setFlags(Surface* surface,
- uint32_t flags, uint32_t mask)
-{
- layer_state_t* s = _lockLayerState(surface);
- if (!s) return BAD_INDEX;
- s->what |= ISurfaceComposer::eVisibilityChanged;
- s->flags &= ~mask;
- s->flags |= (flags & mask);
- s->mask |= mask;
- _unlockLayerState();
- return NO_ERROR;
-}
-
-
-status_t SurfaceComposerClient::setTransparentRegionHint(
- Surface* surface, const Region& transparentRegion)
-{
- layer_state_t* s = _lockLayerState(surface);
- if (!s) return BAD_INDEX;
- s->what |= ISurfaceComposer::eTransparentRegionChanged;
- s->transparentRegion = transparentRegion;
- _unlockLayerState();
- return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::setAlpha(Surface* surface, float alpha)
-{
- layer_state_t* s = _lockLayerState(surface);
- if (!s) return BAD_INDEX;
- s->what |= ISurfaceComposer::eAlphaChanged;
- s->alpha = alpha;
- _unlockLayerState();
- return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::setMatrix(
- Surface* surface,
- float dsdx, float dtdx,
- float dsdy, float dtdy )
-{
- layer_state_t* s = _lockLayerState(surface);
- if (!s) return BAD_INDEX;
- s->what |= ISurfaceComposer::eMatrixChanged;
- layer_state_t::matrix22_t matrix;
- matrix.dsdx = dsdx;
- matrix.dtdx = dtdx;
- matrix.dsdy = dsdy;
- matrix.dtdy = dtdy;
- s->matrix = matrix;
- _unlockLayerState();
- return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::setFreezeTint(Surface* surface, uint32_t tint)
-{
- layer_state_t* s = _lockLayerState(surface);
- if (!s) return BAD_INDEX;
- s->what |= ISurfaceComposer::eFreezeTintChanged;
- s->tint = tint;
- _unlockLayerState();
- return NO_ERROR;
-}
-
-}; // namespace android
-
diff --git a/libs/ui/SurfaceFlingerSynchro.cpp b/libs/ui/SurfaceFlingerSynchro.cpp
deleted file mode 100644
index 5cd9755..0000000
--- a/libs/ui/SurfaceFlingerSynchro.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "SurfaceFlingerSynchro"
-
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <utils/IPCThreadState.h>
-#include <utils/Log.h>
-
-#include <private/ui/SurfaceFlingerSynchro.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-SurfaceFlingerSynchro::Barrier::Barrier()
- : state(CLOSED) {
-}
-
-SurfaceFlingerSynchro::Barrier::~Barrier() {
-}
-
-void SurfaceFlingerSynchro::Barrier::open() {
- asm volatile ("":::"memory");
- Mutex::Autolock _l(lock);
- state = OPENED;
- cv.broadcast();
-}
-
-void SurfaceFlingerSynchro::Barrier::close() {
- Mutex::Autolock _l(lock);
- state = CLOSED;
-}
-
-void SurfaceFlingerSynchro::Barrier::waitAndClose()
-{
- Mutex::Autolock _l(lock);
- while (state == CLOSED) {
- // we're about to wait, flush the binder command buffer
- IPCThreadState::self()->flushCommands();
- cv.wait(lock);
- }
- state = CLOSED;
-}
-
-status_t SurfaceFlingerSynchro::Barrier::waitAndClose(nsecs_t timeout)
-{
- Mutex::Autolock _l(lock);
- while (state == CLOSED) {
- // we're about to wait, flush the binder command buffer
- IPCThreadState::self()->flushCommands();
- int err = cv.waitRelative(lock, timeout);
- if (err != 0)
- return err;
- }
- state = CLOSED;
- return NO_ERROR;
-}
-
-// ---------------------------------------------------------------------------
-
-SurfaceFlingerSynchro::SurfaceFlingerSynchro(const sp<ISurfaceComposer>& flinger)
- : mSurfaceComposer(flinger)
-{
-}
-
-SurfaceFlingerSynchro::SurfaceFlingerSynchro()
-{
-}
-
-SurfaceFlingerSynchro::~SurfaceFlingerSynchro()
-{
-}
-
-status_t SurfaceFlingerSynchro::signal()
-{
- mSurfaceComposer->signal();
- return NO_ERROR;
-}
-
-status_t SurfaceFlingerSynchro::wait()
-{
- mBarrier.waitAndClose();
- return NO_ERROR;
-}
-
-status_t SurfaceFlingerSynchro::wait(nsecs_t timeout)
-{
- if (timeout == 0)
- return SurfaceFlingerSynchro::wait();
- return mBarrier.waitAndClose(timeout);
-}
-
-void SurfaceFlingerSynchro::open()
-{
- mBarrier.open();
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
diff --git a/libs/ui/Time.cpp b/libs/ui/Time.cpp
deleted file mode 100644
index b553913..0000000
--- a/libs/ui/Time.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-#include <utils/TimeUtils.h>
-#include <stdio.h>
-#include <cutils/tztime.h>
-
-namespace android {
-
-static void
-dump(const Time& t)
-{
- #ifdef HAVE_TM_GMTOFF
- long tm_gmtoff = t.t.tm_gmtoff;
- #else
- long tm_gmtoff = 0;
- #endif
- printf("%04d-%02d-%02d %02d:%02d:%02d (%d,%ld,%d,%d)\n",
- t.t.tm_year+1900, t.t.tm_mon+1, t.t.tm_mday,
- t.t.tm_hour, t.t.tm_min, t.t.tm_sec,
- t.t.tm_isdst, tm_gmtoff, t.t.tm_wday, t.t.tm_yday);
-}
-
-Time::Time()
-{
- t.tm_sec = 0;
- t.tm_min = 0;
- t.tm_hour = 0;
- t.tm_mday = 0;
- t.tm_mon = 0;
- t.tm_year = 0;
- t.tm_wday = 0;
- t.tm_yday = 0;
- t.tm_isdst = -1; // we don't know, so let the C library determine
- #ifdef HAVE_TM_GMTOFF
- t.tm_gmtoff = 0;
- #endif
-}
-
-
-#define COMPARE_FIELD(field) do { \
- int diff = a.t.field - b.t.field; \
- if (diff != 0) return diff; \
- } while(0)
-
-int
-Time::compare(Time& a, Time& b)
-{
- if (0 == strcmp(a.timezone, b.timezone)) {
- // if the timezones are the same, we can easily compare the two
- // times. Otherwise, convert to milliseconds and compare that.
- // This requires that object be normalized.
- COMPARE_FIELD(tm_year);
- COMPARE_FIELD(tm_mon);
- COMPARE_FIELD(tm_mday);
- COMPARE_FIELD(tm_hour);
- COMPARE_FIELD(tm_min);
- COMPARE_FIELD(tm_sec);
- return 0;
- } else {
- int64_t am = a.toMillis(false /* use isDst */);
- int64_t bm = b.toMillis(false /* use isDst */);
- int64_t diff = am-bm;
- return (diff < 0) ? -1 : ((diff > 0) ? 1 : 0);
- }
-}
-
-static const int DAYS_PER_MONTH[] = {
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
- };
-
-static inline int days_this_month(int year, int month)
-{
- int n = DAYS_PER_MONTH[month];
- if (n != 28) {
- return n;
- } else {
- int y = year;
- return ((y%4)==0&&((y%100)!=0||(y%400)==0)) ? 29 : 28;
- }
-}
-
-void
-Time::switchTimezone(const char* timezone)
-{
- time_t seconds = mktime_tz(&(this->t), this->timezone);
- localtime_tz(&seconds, &(this->t), timezone);
-}
-
-String8
-Time::format(const char *format, const struct strftime_locale *locale) const
-{
- char buf[257];
- int n = strftime_tz(buf, 257, format, &(this->t), locale);
- if (n > 0) {
- return String8(buf);
- } else {
- return String8();
- }
-}
-
-static inline short
-tochar(int n)
-{
- return (n >= 0 && n <= 9) ? ('0'+n) : ' ';
-}
-
-static inline short
-next_char(int *m, int k)
-{
- int n = *m / k;
- *m = *m % k;
- return tochar(n);
-}
-
-void
-Time::format2445(short* buf, bool hasTime) const
-{
- int n;
-
- n = t.tm_year+1900;
- buf[0] = next_char(&n, 1000);
- buf[1] = next_char(&n, 100);
- buf[2] = next_char(&n, 10);
- buf[3] = tochar(n);
-
- n = t.tm_mon+1;
- buf[4] = next_char(&n, 10);
- buf[5] = tochar(n);
-
- n = t.tm_mday;
- buf[6] = next_char(&n, 10);
- buf[7] = tochar(n);
-
- if (hasTime) {
- buf[8] = 'T';
-
- n = t.tm_hour;
- buf[9] = next_char(&n, 10);
- buf[10] = tochar(n);
-
- n = t.tm_min;
- buf[11] = next_char(&n, 10);
- buf[12] = tochar(n);
-
- n = t.tm_sec;
- buf[13] = next_char(&n, 10);
- buf[14] = tochar(n);
- bool inUtc = strcmp("UTC", timezone) == 0;
- if (inUtc) {
- buf[15] = 'Z';
- }
- }
-}
-
-String8
-Time::toString() const
-{
- String8 str;
- char* s = str.lockBuffer(150);
- #ifdef HAVE_TM_GMTOFF
- long tm_gmtoff = t.tm_gmtoff;
- #else
- long tm_gmtoff = 0;
- #endif
- sprintf(s, "%04d%02d%02dT%02d%02d%02d%s(%d,%d,%ld,%d,%d)",
- t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min,
- t.tm_sec, timezone, t.tm_wday, t.tm_yday, tm_gmtoff, t.tm_isdst,
- (int)(((Time*)this)->toMillis(false /* use isDst */)/1000));
- str.unlockBuffer();
- return str;
-}
-
-void
-Time::setToNow()
-{
- time_t seconds;
- time(&seconds);
- localtime_tz(&seconds, &(this->t), this->timezone);
-}
-
-int64_t
-Time::toMillis(bool ignoreDst)
-{
- if (ignoreDst) {
- this->t.tm_isdst = -1;
- }
- int64_t r = mktime_tz(&(this->t), this->timezone);
- if (r == -1)
- return -1;
- return r * 1000;
-}
-
-void
-Time::set(int64_t millis)
-{
- time_t seconds = millis / 1000;
- localtime_tz(&seconds, &(this->t), this->timezone);
-}
-
-}; // namespace android
-
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
deleted file mode 100644
index cdb8ca2..0000000
--- a/libs/utils/Android.mk
+++ /dev/null
@@ -1,156 +0,0 @@
-# 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-# libutils is a little unique: It's built twice, once for the host
-# and once for the device.
-
-commonSources:= \
- Asset.cpp \
- AssetDir.cpp \
- AssetManager.cpp \
- BufferedTextOutput.cpp \
- CallStack.cpp \
- Debug.cpp \
- FileMap.cpp \
- RefBase.cpp \
- ResourceTypes.cpp \
- SharedBuffer.cpp \
- Static.cpp \
- StopWatch.cpp \
- String8.cpp \
- String16.cpp \
- SystemClock.cpp \
- TextOutput.cpp \
- Threads.cpp \
- TimerProbe.cpp \
- Timers.cpp \
- VectorImpl.cpp \
- ZipFileCRO.cpp \
- ZipFileRO.cpp \
- ZipUtils.cpp \
- misc.cpp \
- ported.cpp \
- LogSocket.cpp
-
-#
-# The cpp files listed here do not belong in the device
-# build. Consult with the swetland before even thinking about
-# putting them in commonSources.
-#
-# They're used by the simulator runtime and by host-side tools like
-# aapt and the simulator front-end.
-#
-hostSources:= \
- InetAddress.cpp \
- Pipe.cpp \
- Socket.cpp \
- ZipEntry.cpp \
- ZipFile.cpp
-
-# For the host
-# =====================================================
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= $(commonSources) $(hostSources)
-
-ifeq ($(HOST_OS),linux)
-# Use the futex based mutex and condition variable
-# implementation from android-arm because it's shared mem safe
- LOCAL_SRC_FILES += \
- futex_synchro.c \
- executablepath_linux.cpp
-endif
-ifeq ($(HOST_OS),darwin)
- LOCAL_SRC_FILES += \
- executablepath_darwin.cpp
-endif
-
-LOCAL_MODULE:= libutils
-
-LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS)
-LOCAL_C_INCLUDES += external/zlib
-
-ifeq ($(HOST_OS),windows)
-ifeq ($(strip $(USE_CYGWIN),),)
-# Under MinGW, ctype.h doesn't need multi-byte support
-LOCAL_CFLAGS += -DMB_CUR_MAX=1
-endif
-endif
-
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-
-
-# For the device
-# =====================================================
-include $(CLEAR_VARS)
-
-
-# we have the common sources, plus some device-specific stuff
-LOCAL_SRC_FILES:= \
- $(commonSources) \
- Binder.cpp \
- BpBinder.cpp \
- IInterface.cpp \
- IMemory.cpp \
- IPCThreadState.cpp \
- MemoryDealer.cpp \
- MemoryBase.cpp \
- MemoryHeapBase.cpp \
- MemoryHeapPmem.cpp \
- Parcel.cpp \
- ProcessState.cpp \
- IPermissionController.cpp \
- IServiceManager.cpp \
- Unicode.cpp
-
-ifeq ($(TARGET_SIMULATOR),true)
-LOCAL_SRC_FILES += $(hostSources)
-endif
-
-ifeq ($(TARGET_OS),linux)
-# Use the futex based mutex and condition variable
-# implementation from android-arm because it's shared mem safe
-LOCAL_SRC_FILES += futex_synchro.c
-LOCAL_LDLIBS += -lrt -ldl
-endif
-
-LOCAL_C_INCLUDES += \
- external/zlib \
- external/icu4c/common
-LOCAL_LDLIBS += -lpthread
-
-LOCAL_SHARED_LIBRARIES := \
- libz \
- liblog \
- libcutils
-
-ifneq ($(TARGET_SIMULATOR),true)
-ifeq ($(TARGET_OS)-$(TARGET_ARCH),linux-x86)
-# This is needed on x86 to bring in dl_iterate_phdr for CallStack.cpp
-LOCAL_SHARED_LIBRARIES += \
- libdl
-endif # linux-x86
-endif # sim
-
-LOCAL_MODULE:= libutils
-
-#LOCAL_CFLAGS+=
-#LOCAL_LDFLAGS:=
-
-include $(BUILD_SHARED_LIBRARY)
-
diff --git a/libs/utils/Asset.cpp b/libs/utils/Asset.cpp
deleted file mode 100644
index 91203dd..0000000
--- a/libs/utils/Asset.cpp
+++ /dev/null
@@ -1,813 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Provide access to a read-only asset.
-//
-
-#define LOG_TAG "asset"
-//#define NDEBUG 0
-
-#include <utils/Asset.h>
-#include <utils/Atomic.h>
-#include <utils/FileMap.h>
-#include <utils/ZipUtils.h>
-#include <utils/ZipFileRO.h>
-#include <utils/Log.h>
-
-#include <string.h>
-#include <memory.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <assert.h>
-
-using namespace android;
-
-#ifndef O_BINARY
-# define O_BINARY 0
-#endif
-
-static volatile int32_t gCount = 0;
-
-int32_t Asset::getGlobalCount()
-{
- return gCount;
-}
-
-Asset::Asset(void)
- : mAccessMode(ACCESS_UNKNOWN)
-{
- int count = android_atomic_inc(&gCount)+1;
- //LOGI("Creating Asset %p #%d\n", this, count);
-}
-
-Asset::~Asset(void)
-{
- int count = android_atomic_dec(&gCount);
- //LOGI("Destroying Asset in %p #%d\n", this, count);
-}
-
-/*
- * Create a new Asset from a file on disk. There is a fair chance that
- * the file doesn't actually exist.
- *
- * We can use "mode" to decide how we want to go about it.
- */
-/*static*/ Asset* Asset::createFromFile(const char* fileName, AccessMode mode)
-{
- _FileAsset* pAsset;
- status_t result;
- off_t length;
- int fd;
-
- fd = open(fileName, O_RDONLY | O_BINARY);
- if (fd < 0)
- return NULL;
-
- /*
- * Under Linux, the lseek fails if we actually opened a directory. To
- * be correct we should test the file type explicitly, but since we
- * always open things read-only it doesn't really matter, so there's
- * no value in incurring the extra overhead of an fstat() call.
- */
- length = lseek(fd, 0, SEEK_END);
- if (length < 0) {
- ::close(fd);
- return NULL;
- }
- (void) lseek(fd, 0, SEEK_SET);
-
- pAsset = new _FileAsset;
- result = pAsset->openChunk(fileName, fd, 0, length);
- if (result != NO_ERROR) {
- delete pAsset;
- return NULL;
- }
-
- pAsset->mAccessMode = mode;
- return pAsset;
-}
-
-
-/*
- * Create a new Asset from a compressed file on disk. There is a fair chance
- * that the file doesn't actually exist.
- *
- * We currently support gzip files. We might want to handle .bz2 someday.
- */
-/*static*/ Asset* Asset::createFromCompressedFile(const char* fileName,
- AccessMode mode)
-{
- _CompressedAsset* pAsset;
- status_t result;
- off_t fileLen;
- bool scanResult;
- long offset;
- int method;
- long uncompressedLen, compressedLen;
- int fd;
-
- fd = open(fileName, O_RDONLY | O_BINARY);
- if (fd < 0)
- return NULL;
-
- fileLen = lseek(fd, 0, SEEK_END);
- if (fileLen < 0) {
- ::close(fd);
- return NULL;
- }
- (void) lseek(fd, 0, SEEK_SET);
-
- /* want buffered I/O for the file scan; must dup so fclose() is safe */
- FILE* fp = fdopen(dup(fd), "rb");
- if (fp == NULL) {
- ::close(fd);
- return NULL;
- }
-
- unsigned long crc32;
- scanResult = ZipUtils::examineGzip(fp, &method, &uncompressedLen,
- &compressedLen, &crc32);
- offset = ftell(fp);
- fclose(fp);
- if (!scanResult) {
- LOGD("File '%s' is not in gzip format\n", fileName);
- ::close(fd);
- return NULL;
- }
-
- pAsset = new _CompressedAsset;
- result = pAsset->openChunk(fd, offset, method, uncompressedLen,
- compressedLen);
- if (result != NO_ERROR) {
- delete pAsset;
- return NULL;
- }
-
- pAsset->mAccessMode = mode;
- return pAsset;
-}
-
-
-#if 0
-/*
- * Create a new Asset from part of an open file.
- */
-/*static*/ Asset* Asset::createFromFileSegment(int fd, off_t offset,
- size_t length, AccessMode mode)
-{
- _FileAsset* pAsset;
- status_t result;
-
- pAsset = new _FileAsset;
- result = pAsset->openChunk(NULL, fd, offset, length);
- if (result != NO_ERROR)
- return NULL;
-
- pAsset->mAccessMode = mode;
- return pAsset;
-}
-
-/*
- * Create a new Asset from compressed data in an open file.
- */
-/*static*/ Asset* Asset::createFromCompressedData(int fd, off_t offset,
- int compressionMethod, size_t uncompressedLen, size_t compressedLen,
- AccessMode mode)
-{
- _CompressedAsset* pAsset;
- status_t result;
-
- pAsset = new _CompressedAsset;
- result = pAsset->openChunk(fd, offset, compressionMethod,
- uncompressedLen, compressedLen);
- if (result != NO_ERROR)
- return NULL;
-
- pAsset->mAccessMode = mode;
- return pAsset;
-}
-#endif
-
-/*
- * Create a new Asset from a memory mapping.
- */
-/*static*/ Asset* Asset::createFromUncompressedMap(FileMap* dataMap,
- AccessMode mode)
-{
- _FileAsset* pAsset;
- status_t result;
-
- pAsset = new _FileAsset;
- result = pAsset->openChunk(dataMap);
- if (result != NO_ERROR)
- return NULL;
-
- pAsset->mAccessMode = mode;
- return pAsset;
-}
-
-/*
- * Create a new Asset from compressed data in a memory mapping.
- */
-/*static*/ Asset* Asset::createFromCompressedMap(FileMap* dataMap,
- int method, size_t uncompressedLen, AccessMode mode)
-{
- _CompressedAsset* pAsset;
- status_t result;
-
- pAsset = new _CompressedAsset;
- result = pAsset->openChunk(dataMap, method, uncompressedLen);
- if (result != NO_ERROR)
- return NULL;
-
- pAsset->mAccessMode = mode;
- return pAsset;
-}
-
-
-/*
- * Do generic seek() housekeeping. Pass in the offset/whence values from
- * the seek request, along with the current chunk offset and the chunk
- * length.
- *
- * Returns the new chunk offset, or -1 if the seek is illegal.
- */
-off_t Asset::handleSeek(off_t offset, int whence, off_t curPosn, off_t maxPosn)
-{
- off_t newOffset;
-
- switch (whence) {
- case SEEK_SET:
- newOffset = offset;
- break;
- case SEEK_CUR:
- newOffset = curPosn + offset;
- break;
- case SEEK_END:
- newOffset = maxPosn + offset;
- break;
- default:
- LOGW("unexpected whence %d\n", whence);
- // this was happening due to an off_t size mismatch
- assert(false);
- return (off_t) -1;
- }
-
- if (newOffset < 0 || newOffset > maxPosn) {
- LOGW("seek out of range: want %ld, end=%ld\n",
- (long) newOffset, (long) maxPosn);
- return (off_t) -1;
- }
-
- return newOffset;
-}
-
-
-/*
- * ===========================================================================
- * _FileAsset
- * ===========================================================================
- */
-
-/*
- * Constructor.
- */
-_FileAsset::_FileAsset(void)
- : mStart(0), mLength(0), mOffset(0), mFp(NULL), mFileName(NULL), mMap(NULL), mBuf(NULL)
-{
-}
-
-/*
- * Destructor. Release resources.
- */
-_FileAsset::~_FileAsset(void)
-{
- close();
-}
-
-/*
- * Operate on a chunk of an uncompressed file.
- *
- * Zero-length chunks are allowed.
- */
-status_t _FileAsset::openChunk(const char* fileName, int fd, off_t offset, size_t length)
-{
- assert(mFp == NULL); // no reopen
- assert(mMap == NULL);
- assert(fd >= 0);
- assert(offset >= 0);
-
- /*
- * Seek to end to get file length.
- */
- off_t fileLength;
- fileLength = lseek(fd, 0, SEEK_END);
- if (fileLength == (off_t) -1) {
- // probably a bad file descriptor
- LOGD("failed lseek (errno=%d)\n", errno);
- return UNKNOWN_ERROR;
- }
-
- if ((off_t) (offset + length) > fileLength) {
- LOGD("start (%ld) + len (%ld) > end (%ld)\n",
- (long) offset, (long) length, (long) fileLength);
- return BAD_INDEX;
- }
-
- /* after fdopen, the fd will be closed on fclose() */
- mFp = fdopen(fd, "rb");
- if (mFp == NULL)
- return UNKNOWN_ERROR;
-
- mStart = offset;
- mLength = length;
- assert(mOffset == 0);
-
- /* seek the FILE* to the start of chunk */
- if (fseek(mFp, mStart, SEEK_SET) != 0) {
- assert(false);
- }
-
- mFileName = fileName != NULL ? strdup(fileName) : NULL;
-
- return NO_ERROR;
-}
-
-/*
- * Create the chunk from the map.
- */
-status_t _FileAsset::openChunk(FileMap* dataMap)
-{
- assert(mFp == NULL); // no reopen
- assert(mMap == NULL);
- assert(dataMap != NULL);
-
- mMap = dataMap;
- mStart = -1; // not used
- mLength = dataMap->getDataLength();
- assert(mOffset == 0);
-
- return NO_ERROR;
-}
-
-/*
- * Read a chunk of data.
- */
-ssize_t _FileAsset::read(void* buf, size_t count)
-{
- size_t maxLen;
- size_t actual;
-
- assert(mOffset >= 0 && mOffset <= mLength);
-
- if (getAccessMode() == ACCESS_BUFFER) {
- /*
- * On first access, read or map the entire file. The caller has
- * requested buffer access, either because they're going to be
- * using the buffer or because what they're doing has appropriate
- * performance needs and access patterns.
- */
- if (mBuf == NULL)
- getBuffer(false);
- }
-
- /* adjust count if we're near EOF */
- maxLen = mLength - mOffset;
- if (count > maxLen)
- count = maxLen;
-
- if (!count)
- return 0;
-
- if (mMap != NULL) {
- /* copy from mapped area */
- //printf("map read\n");
- memcpy(buf, (char*)mMap->getDataPtr() + mOffset, count);
- actual = count;
- } else if (mBuf != NULL) {
- /* copy from buffer */
- //printf("buf read\n");
- memcpy(buf, (char*)mBuf + mOffset, count);
- actual = count;
- } else {
- /* read from the file */
- //printf("file read\n");
- if (ftell(mFp) != mStart + mOffset) {
- LOGE("Hosed: %ld != %ld+%ld\n",
- ftell(mFp), (long) mStart, (long) mOffset);
- assert(false);
- }
-
- /*
- * This returns 0 on error or eof. We need to use ferror() or feof()
- * to tell the difference, but we don't currently have those on the
- * device. However, we know how much data is *supposed* to be in the
- * file, so if we don't read the full amount we know something is
- * hosed.
- */
- actual = fread(buf, 1, count, mFp);
- if (actual == 0) // something failed -- I/O error?
- return -1;
-
- assert(actual == count);
- }
-
- mOffset += actual;
- return actual;
-}
-
-/*
- * Seek to a new position.
- */
-off_t _FileAsset::seek(off_t offset, int whence)
-{
- off_t newPosn;
- long actualOffset;
-
- // compute new position within chunk
- newPosn = handleSeek(offset, whence, mOffset, mLength);
- if (newPosn == (off_t) -1)
- return newPosn;
-
- actualOffset = (long) (mStart + newPosn);
-
- if (mFp != NULL) {
- if (fseek(mFp, (long) actualOffset, SEEK_SET) != 0)
- return (off_t) -1;
- }
-
- mOffset = actualOffset - mStart;
- return mOffset;
-}
-
-/*
- * Close the asset.
- */
-void _FileAsset::close(void)
-{
- if (mMap != NULL) {
- mMap->release();
- mMap = NULL;
- }
- if (mBuf != NULL) {
- delete[] mBuf;
- mBuf = NULL;
- }
-
- if (mFileName != NULL) {
- free(mFileName);
- mFileName = NULL;
- }
-
- if (mFp != NULL) {
- // can only be NULL when called from destructor
- // (otherwise we would never return this object)
- fclose(mFp);
- mFp = NULL;
- }
-}
-
-/*
- * Return a read-only pointer to a buffer.
- *
- * We can either read the whole thing in or map the relevant piece of
- * the source file. Ideally a map would be established at a higher
- * level and we'd be using a different object, but we didn't, so we
- * deal with it here.
- */
-const void* _FileAsset::getBuffer(bool wordAligned)
-{
- /* subsequent requests just use what we did previously */
- if (mBuf != NULL)
- return mBuf;
- if (mMap != NULL) {
- if (!wordAligned) {
- return mMap->getDataPtr();
- }
- return ensureAlignment(mMap);
- }
-
- assert(mFp != NULL);
-
- if (mLength < kReadVsMapThreshold) {
- unsigned char* buf;
- long allocLen;
-
- /* zero-length files are allowed; not sure about zero-len allocs */
- /* (works fine with gcc + x86linux) */
- allocLen = mLength;
- if (mLength == 0)
- allocLen = 1;
-
- buf = new unsigned char[allocLen];
- if (buf == NULL) {
- LOGE("alloc of %ld bytes failed\n", (long) allocLen);
- return NULL;
- }
-
- LOGV("Asset %p allocating buffer size %d (smaller than threshold)", this, (int)allocLen);
- if (mLength > 0) {
- long oldPosn = ftell(mFp);
- fseek(mFp, mStart, SEEK_SET);
- if (fread(buf, 1, mLength, mFp) != (size_t) mLength) {
- LOGE("failed reading %ld bytes\n", (long) mLength);
- delete[] buf;
- return NULL;
- }
- fseek(mFp, oldPosn, SEEK_SET);
- }
-
- LOGV(" getBuffer: loaded into buffer\n");
-
- mBuf = buf;
- return mBuf;
- } else {
- FileMap* map;
-
- map = new FileMap;
- if (!map->create(NULL, fileno(mFp), mStart, mLength, true)) {
- map->release();
- return NULL;
- }
-
- LOGV(" getBuffer: mapped\n");
-
- mMap = map;
- if (!wordAligned) {
- return mMap->getDataPtr();
- }
- return ensureAlignment(mMap);
- }
-}
-
-int _FileAsset::openFileDescriptor(off_t* outStart, off_t* outLength) const
-{
- if (mMap != NULL) {
- const char* fname = mMap->getFileName();
- if (fname == NULL) {
- fname = mFileName;
- }
- if (fname == NULL) {
- return -1;
- }
- *outStart = mMap->getDataOffset();
- *outLength = mMap->getDataLength();
- return open(fname, O_RDONLY | O_BINARY);
- }
- if (mFileName == NULL) {
- return -1;
- }
- *outStart = mStart;
- *outLength = mLength;
- return open(mFileName, O_RDONLY | O_BINARY);
-}
-
-const void* _FileAsset::ensureAlignment(FileMap* map)
-{
- void* data = map->getDataPtr();
- if ((((size_t)data)&0x3) == 0) {
- // We can return this directly if it is aligned on a word
- // boundary.
- return data;
- }
- // If not aligned on a word boundary, then we need to copy it into
- // our own buffer.
- LOGV("Copying FileAsset %p to buffer size %d to make it aligned.", this, (int)mLength);
- unsigned char* buf = new unsigned char[mLength];
- if (buf == NULL) {
- LOGE("alloc of %ld bytes failed\n", (long) mLength);
- return NULL;
- }
- memcpy(buf, data, mLength);
- mBuf = buf;
- return buf;
-}
-
-/*
- * ===========================================================================
- * _CompressedAsset
- * ===========================================================================
- */
-
-/*
- * Constructor.
- */
-_CompressedAsset::_CompressedAsset(void)
- : mStart(0), mCompressedLen(0), mUncompressedLen(0), mOffset(0),
- mMap(NULL), mFd(-1), mBuf(NULL)
-{
-}
-
-/*
- * Destructor. Release resources.
- */
-_CompressedAsset::~_CompressedAsset(void)
-{
- close();
-}
-
-/*
- * Open a chunk of compressed data inside a file.
- *
- * This currently just sets up some values and returns. On the first
- * read, we expand the entire file into a buffer and return data from it.
- */
-status_t _CompressedAsset::openChunk(int fd, off_t offset,
- int compressionMethod, size_t uncompressedLen, size_t compressedLen)
-{
- assert(mFd < 0); // no re-open
- assert(mMap == NULL);
- assert(fd >= 0);
- assert(offset >= 0);
- assert(compressedLen > 0);
-
- if (compressionMethod != ZipFileRO::kCompressDeflated) {
- assert(false);
- return UNKNOWN_ERROR;
- }
-
- mStart = offset;
- mCompressedLen = compressedLen;
- mUncompressedLen = uncompressedLen;
- assert(mOffset == 0);
- mFd = fd;
- assert(mBuf == NULL);
-
- return NO_ERROR;
-}
-
-/*
- * Open a chunk of compressed data in a mapped region.
- *
- * Nothing is expanded until the first read call.
- */
-status_t _CompressedAsset::openChunk(FileMap* dataMap, int compressionMethod,
- size_t uncompressedLen)
-{
- assert(mFd < 0); // no re-open
- assert(mMap == NULL);
- assert(dataMap != NULL);
-
- if (compressionMethod != ZipFileRO::kCompressDeflated) {
- assert(false);
- return UNKNOWN_ERROR;
- }
-
- mMap = dataMap;
- mStart = -1; // not used
- mCompressedLen = dataMap->getDataLength();
- mUncompressedLen = uncompressedLen;
- assert(mOffset == 0);
-
- return NO_ERROR;
-}
-
-/*
- * Read data from a chunk of compressed data.
- *
- * [For now, that's just copying data out of a buffer.]
- */
-ssize_t _CompressedAsset::read(void* buf, size_t count)
-{
- size_t maxLen;
- size_t actual;
-
- assert(mOffset >= 0 && mOffset <= mUncompressedLen);
-
- // TODO: if mAccessMode == ACCESS_STREAMING, use zlib more cleverly
-
- if (mBuf == NULL) {
- if (getBuffer(false) == NULL)
- return -1;
- }
- assert(mBuf != NULL);
-
- /* adjust count if we're near EOF */
- maxLen = mUncompressedLen - mOffset;
- if (count > maxLen)
- count = maxLen;
-
- if (!count)
- return 0;
-
- /* copy from buffer */
- //printf("comp buf read\n");
- memcpy(buf, (char*)mBuf + mOffset, count);
- actual = count;
-
- mOffset += actual;
- return actual;
-}
-
-/*
- * Handle a seek request.
- *
- * If we're working in a streaming mode, this is going to be fairly
- * expensive, because it requires plowing through a bunch of compressed
- * data.
- */
-off_t _CompressedAsset::seek(off_t offset, int whence)
-{
- off_t newPosn;
-
- // compute new position within chunk
- newPosn = handleSeek(offset, whence, mOffset, mUncompressedLen);
- if (newPosn == (off_t) -1)
- return newPosn;
-
- mOffset = newPosn;
- return mOffset;
-}
-
-/*
- * Close the asset.
- */
-void _CompressedAsset::close(void)
-{
- if (mMap != NULL) {
- mMap->release();
- mMap = NULL;
- }
- if (mBuf != NULL) {
- delete[] mBuf;
- mBuf = NULL;
- }
-
- if (mFd > 0) {
- ::close(mFd);
- mFd = -1;
- }
-}
-
-/*
- * Get a pointer to a read-only buffer of data.
- *
- * The first time this is called, we expand the compressed data into a
- * buffer.
- */
-const void* _CompressedAsset::getBuffer(bool wordAligned)
-{
- unsigned char* buf = NULL;
-
- if (mBuf != NULL)
- return mBuf;
-
- if (mUncompressedLen > UNCOMPRESS_DATA_MAX) {
- LOGD("Data exceeds UNCOMPRESS_DATA_MAX (%ld vs %d)\n",
- (long) mUncompressedLen, UNCOMPRESS_DATA_MAX);
- goto bail;
- }
-
- /*
- * Allocate a buffer and read the file into it.
- */
- buf = new unsigned char[mUncompressedLen];
- if (buf == NULL) {
- LOGW("alloc %ld bytes failed\n", (long) mUncompressedLen);
- goto bail;
- }
-
- if (mMap != NULL) {
- if (!ZipFileRO::inflateBuffer(buf, mMap->getDataPtr(),
- mUncompressedLen, mCompressedLen))
- goto bail;
- } else {
- assert(mFd >= 0);
-
- /*
- * Seek to the start of the compressed data.
- */
- if (lseek(mFd, mStart, SEEK_SET) != mStart)
- goto bail;
-
- /*
- * Expand the data into it.
- */
- if (!ZipUtils::inflateToBuffer(mFd, buf, mUncompressedLen,
- mCompressedLen))
- goto bail;
- }
-
- /* success! */
- mBuf = buf;
- buf = NULL;
-
-bail:
- delete[] buf;
- return mBuf;
-}
-
diff --git a/libs/utils/AssetDir.cpp b/libs/utils/AssetDir.cpp
deleted file mode 100644
index c5f664e..0000000
--- a/libs/utils/AssetDir.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Provide access to a virtual directory in "asset space". Most of the
-// implementation is in the header file or in friend functions in
-// AssetManager.
-//
-#include <utils/AssetDir.h>
-
-using namespace android;
-
-
-/*
- * Find a matching entry in a vector of FileInfo. Because it's sorted, we
- * can use a binary search.
- *
- * Assumes the vector is sorted in ascending order.
- */
-/*static*/ int AssetDir::FileInfo::findEntry(const SortedVector<FileInfo>* pVector,
- const String8& fileName)
-{
- FileInfo tmpInfo;
-
- tmpInfo.setFileName(fileName);
- return pVector->indexOf(tmpInfo);
-
-#if 0 // don't need this after all (uses 1/2 compares of SortedVector though)
- int lo, hi, cur;
-
- lo = 0;
- hi = pVector->size() -1;
- while (lo <= hi) {
- int cmp;
-
- cur = (hi + lo) / 2;
- cmp = strcmp(pVector->itemAt(cur).getFileName(), fileName);
- if (cmp == 0) {
- /* match, bail */
- return cur;
- } else if (cmp < 0) {
- /* too low */
- lo = cur + 1;
- } else {
- /* too high */
- hi = cur -1;
- }
- }
-
- return -1;
-#endif
-}
-
diff --git a/libs/utils/AssetManager.cpp b/libs/utils/AssetManager.cpp
deleted file mode 100644
index 447b801..0000000
--- a/libs/utils/AssetManager.cpp
+++ /dev/null
@@ -1,1637 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Provide access to read-only assets.
-//
-
-#define LOG_TAG "asset"
-//#define LOG_NDEBUG 0
-
-#include <utils/AssetManager.h>
-#include <utils/AssetDir.h>
-#include <utils/Asset.h>
-#include <utils/Atomic.h>
-#include <utils/String8.h>
-#include <utils/ResourceTypes.h>
-#include <utils/String8.h>
-#include <utils/ZipFileRO.h>
-#include <utils/Log.h>
-#include <utils/Timers.h>
-#include <utils/threads.h>
-
-#include <dirent.h>
-#include <errno.h>
-#include <assert.h>
-
-using namespace android;
-
-/*
- * Names for default app, locale, and vendor. We might want to change
- * these to be an actual locale, e.g. always use en-US as the default.
- */
-static const char* kDefaultLocale = "default";
-static const char* kDefaultVendor = "default";
-static const char* kAssetsRoot = "assets";
-static const char* kAppZipName = NULL; //"classes.jar";
-static const char* kSystemAssets = "framework/framework-res.apk";
-
-static const char* kExcludeExtension = ".EXCLUDE";
-
-static Asset* const kExcludedAsset = (Asset*) 0xd000000d;
-
-static volatile int32_t gCount = 0;
-
-
-/*
- * ===========================================================================
- * AssetManager
- * ===========================================================================
- */
-
-int32_t AssetManager::getGlobalCount()
-{
- return gCount;
-}
-
-AssetManager::AssetManager(CacheMode cacheMode)
- : mLocale(NULL), mVendor(NULL),
- mResources(NULL), mConfig(new ResTable_config),
- mCacheMode(cacheMode), mCacheValid(false)
-{
- int count = android_atomic_inc(&gCount)+1;
- //LOGI("Creating AssetManager %p #%d\n", this, count);
- memset(mConfig, 0, sizeof(ResTable_config));
-}
-
-AssetManager::~AssetManager(void)
-{
- int count = android_atomic_dec(&gCount);
- //LOGI("Destroying AssetManager in %p #%d\n", this, count);
-
- delete mConfig;
- delete mResources;
-
- // don't have a String class yet, so make sure we clean up
- delete[] mLocale;
- delete[] mVendor;
-}
-
-bool AssetManager::addAssetPath(const String8& path, void** cookie)
-{
- AutoMutex _l(mLock);
-
- asset_path ap;
-
- String8 realPath(path);
- if (kAppZipName) {
- realPath.appendPath(kAppZipName);
- }
- ap.type = ::getFileType(realPath.string());
- if (ap.type == kFileTypeRegular) {
- ap.path = realPath;
- } else {
- ap.path = path;
- ap.type = ::getFileType(path.string());
- if (ap.type != kFileTypeDirectory && ap.type != kFileTypeRegular) {
- LOGW("Asset path %s is neither a directory nor file (type=%d).",
- path.string(), (int)ap.type);
- return false;
- }
- }
-
- // Skip if we have it already.
- for (size_t i=0; i<mAssetPaths.size(); i++) {
- if (mAssetPaths[i].path == ap.path) {
- if (cookie) {
- *cookie = (void*)(i+1);
- }
- return true;
- }
- }
-
- LOGV("In %p Asset %s path: %s", this,
- ap.type == kFileTypeDirectory ? "dir" : "zip", ap.path.string());
-
- mAssetPaths.add(ap);
-
- // new paths are always added at the end
- if (cookie) {
- *cookie = (void*)mAssetPaths.size();
- }
-
- return true;
-}
-
-bool AssetManager::addDefaultAssets()
-{
- const char* root = getenv("ANDROID_ROOT");
- LOG_ALWAYS_FATAL_IF(root == NULL, "ANDROID_ROOT not set");
-
- String8 path(root);
- path.appendPath(kSystemAssets);
-
- return addAssetPath(path, NULL);
-}
-
-void* AssetManager::nextAssetPath(void* cookie) const
-{
- AutoMutex _l(mLock);
- size_t next = ((size_t)cookie)+1;
- return next > mAssetPaths.size() ? NULL : (void*)next;
-}
-
-String8 AssetManager::getAssetPath(void* cookie) const
-{
- AutoMutex _l(mLock);
- const size_t which = ((size_t)cookie)-1;
- if (which < mAssetPaths.size()) {
- return mAssetPaths[which].path;
- }
- return String8();
-}
-
-/*
- * Set the current locale. Use NULL to indicate no locale.
- *
- * Close and reopen Zip archives as appropriate, and reset cached
- * information in the locale-specific sections of the tree.
- */
-void AssetManager::setLocale(const char* locale)
-{
- AutoMutex _l(mLock);
- setLocaleLocked(locale);
-}
-
-void AssetManager::setLocaleLocked(const char* locale)
-{
- if (mLocale != NULL) {
- /* previously set, purge cached data */
- purgeFileNameCacheLocked();
- //mZipSet.purgeLocale();
- delete[] mLocale;
- }
- mLocale = strdupNew(locale);
-
- updateResourceParamsLocked();
-}
-
-/*
- * Set the current vendor. Use NULL to indicate no vendor.
- *
- * Close and reopen Zip archives as appropriate, and reset cached
- * information in the vendor-specific sections of the tree.
- */
-void AssetManager::setVendor(const char* vendor)
-{
- AutoMutex _l(mLock);
-
- if (mVendor != NULL) {
- /* previously set, purge cached data */
- purgeFileNameCacheLocked();
- //mZipSet.purgeVendor();
- delete[] mVendor;
- }
- mVendor = strdupNew(vendor);
-}
-
-void AssetManager::setConfiguration(const ResTable_config& config, const char* locale)
-{
- AutoMutex _l(mLock);
- *mConfig = config;
- if (locale) {
- setLocaleLocked(locale);
- } else if (config.language[0] != 0) {
- char spec[9];
- spec[0] = config.language[0];
- spec[1] = config.language[1];
- if (config.country[0] != 0) {
- spec[2] = '_';
- spec[3] = config.country[0];
- spec[4] = config.country[1];
- spec[5] = 0;
- } else {
- spec[3] = 0;
- }
- setLocaleLocked(spec);
- } else {
- updateResourceParamsLocked();
- }
-}
-
-/*
- * Open an asset.
- *
- * The data could be;
- * - In a file on disk (assetBase + fileName).
- * - In a compressed file on disk (assetBase + fileName.gz).
- * - In a Zip archive, uncompressed or compressed.
- *
- * It can be in a number of different directories and Zip archives.
- * The search order is:
- * - [appname]
- * - locale + vendor
- * - "default" + vendor
- * - locale + "default"
- * - "default + "default"
- * - "common"
- * - (same as above)
- *
- * To find a particular file, we have to try up to eight paths with
- * all three forms of data.
- *
- * We should probably reject requests for "illegal" filenames, e.g. those
- * with illegal characters or "../" backward relative paths.
- */
-Asset* AssetManager::open(const char* fileName, AccessMode mode)
-{
- AutoMutex _l(mLock);
-
- LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
-
-
- if (mCacheMode != CACHE_OFF && !mCacheValid)
- loadFileNameCacheLocked();
-
- String8 assetName(kAssetsRoot);
- assetName.appendPath(fileName);
-
- /*
- * For each top-level asset path, search for the asset.
- */
-
- size_t i = mAssetPaths.size();
- while (i > 0) {
- i--;
- LOGV("Looking for asset '%s' in '%s'\n",
- assetName.string(), mAssetPaths.itemAt(i).path.string());
- Asset* pAsset = openNonAssetInPathLocked(assetName.string(), mode, mAssetPaths.itemAt(i));
- if (pAsset != NULL) {
- return pAsset != kExcludedAsset ? pAsset : NULL;
- }
- }
-
- return NULL;
-}
-
-/*
- * Open a non-asset file as if it were an asset.
- *
- * The "fileName" is the partial path starting from the application
- * name.
- */
-Asset* AssetManager::openNonAsset(const char* fileName, AccessMode mode)
-{
- AutoMutex _l(mLock);
-
- LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
-
-
- if (mCacheMode != CACHE_OFF && !mCacheValid)
- loadFileNameCacheLocked();
-
- /*
- * For each top-level asset path, search for the asset.
- */
-
- size_t i = mAssetPaths.size();
- while (i > 0) {
- i--;
- LOGV("Looking for non-asset '%s' in '%s'\n", fileName, mAssetPaths.itemAt(i).path.string());
- Asset* pAsset = openNonAssetInPathLocked(
- fileName, mode, mAssetPaths.itemAt(i));
- if (pAsset != NULL) {
- return pAsset != kExcludedAsset ? pAsset : NULL;
- }
- }
-
- return NULL;
-}
-
-Asset* AssetManager::openNonAsset(void* cookie, const char* fileName, AccessMode mode)
-{
- const size_t which = ((size_t)cookie)-1;
-
- AutoMutex _l(mLock);
-
- LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
-
-
- if (mCacheMode != CACHE_OFF && !mCacheValid)
- loadFileNameCacheLocked();
-
- if (which < mAssetPaths.size()) {
- LOGV("Looking for non-asset '%s' in '%s'\n", fileName,
- mAssetPaths.itemAt(which).path.string());
- Asset* pAsset = openNonAssetInPathLocked(
- fileName, mode, mAssetPaths.itemAt(which));
- if (pAsset != NULL) {
- return pAsset != kExcludedAsset ? pAsset : NULL;
- }
- }
-
- return NULL;
-}
-
-/*
- * Get the type of a file in the asset namespace.
- *
- * This currently only works for regular files. All others (including
- * directories) will return kFileTypeNonexistent.
- */
-FileType AssetManager::getFileType(const char* fileName)
-{
- Asset* pAsset = NULL;
-
- /*
- * Open the asset. This is less efficient than simply finding the
- * file, but it's not too bad (we don't uncompress or mmap data until
- * the first read() call).
- */
- pAsset = open(fileName, Asset::ACCESS_STREAMING);
- delete pAsset;
-
- if (pAsset == NULL)
- return kFileTypeNonexistent;
- else
- return kFileTypeRegular;
-}
-
-const ResTable* AssetManager::getResTable(bool required) const
-{
- ResTable* rt = mResources;
- if (rt) {
- return rt;
- }
-
- // Iterate through all asset packages, collecting resources from each.
-
- AutoMutex _l(mLock);
-
- if (mResources != NULL) {
- return mResources;
- }
-
- if (required) {
- LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
- }
-
- if (mCacheMode != CACHE_OFF && !mCacheValid)
- const_cast<AssetManager*>(this)->loadFileNameCacheLocked();
-
- const size_t N = mAssetPaths.size();
- for (size_t i=0; i<N; i++) {
- Asset* ass = NULL;
- bool shared = true;
- const asset_path& ap = mAssetPaths.itemAt(i);
- LOGV("Looking for resource asset in '%s'\n", ap.path.string());
- if (ap.type != kFileTypeDirectory) {
- ass = const_cast<AssetManager*>(this)->
- mZipSet.getZipResourceTable(ap.path);
- if (ass == NULL) {
- LOGV("loading resource table %s\n", ap.path.string());
- ass = const_cast<AssetManager*>(this)->
- openNonAssetInPathLocked("resources.arsc",
- Asset::ACCESS_BUFFER,
- ap);
- if (ass != NULL && ass != kExcludedAsset) {
- ass = const_cast<AssetManager*>(this)->
- mZipSet.setZipResourceTable(ap.path, ass);
- }
- }
- } else {
- LOGV("loading resource table %s\n", ap.path.string());
- Asset* ass = const_cast<AssetManager*>(this)->
- openNonAssetInPathLocked("resources.arsc",
- Asset::ACCESS_BUFFER,
- ap);
- shared = false;
- }
- if (ass != NULL && ass != kExcludedAsset) {
- if (rt == NULL) {
- mResources = rt = new ResTable();
- updateResourceParamsLocked();
- }
- LOGV("Installing resource asset %p in to table %p\n", ass, mResources);
- rt->add(ass, (void*)(i+1), !shared);
-
- if (!shared) {
- delete ass;
- }
- }
- }
-
- if (required && !rt) LOGW("Unable to find resources file resources.arsc");
- if (!rt) {
- mResources = rt = new ResTable();
- }
- return rt;
-}
-
-void AssetManager::updateResourceParamsLocked() const
-{
- ResTable* res = mResources;
- if (!res) {
- return;
- }
-
- size_t llen = mLocale ? strlen(mLocale) : 0;
- mConfig->language[0] = 0;
- mConfig->language[1] = 0;
- mConfig->country[0] = 0;
- mConfig->country[1] = 0;
- if (llen >= 2) {
- mConfig->language[0] = mLocale[0];
- mConfig->language[1] = mLocale[1];
- }
- if (llen >= 5) {
- mConfig->country[0] = mLocale[3];
- mConfig->country[1] = mLocale[4];
- }
- mConfig->size = sizeof(*mConfig);
-
- res->setParameters(mConfig);
-}
-
-const ResTable& AssetManager::getResources(bool required) const
-{
- const ResTable* rt = getResTable(required);
- return *rt;
-}
-
-bool AssetManager::isUpToDate()
-{
- AutoMutex _l(mLock);
- return mZipSet.isUpToDate();
-}
-
-void AssetManager::getLocales(Vector<String8>* locales) const
-{
- ResTable* res = mResources;
- if (res != NULL) {
- res->getLocales(locales);
- }
-}
-
-/*
- * Open a non-asset file as if it were an asset, searching for it in the
- * specified app.
- *
- * Pass in a NULL values for "appName" if the common app directory should
- * be used.
- */
-Asset* AssetManager::openNonAssetInPathLocked(const char* fileName, AccessMode mode,
- const asset_path& ap)
-{
- Asset* pAsset = NULL;
-
- /* look at the filesystem on disk */
- if (ap.type == kFileTypeDirectory) {
- String8 path(ap.path);
- path.appendPath(fileName);
-
- pAsset = openAssetFromFileLocked(path, mode);
-
- if (pAsset == NULL) {
- /* try again, this time with ".gz" */
- path.append(".gz");
- pAsset = openAssetFromFileLocked(path, mode);
- }
-
- if (pAsset != NULL) {
- //printf("FOUND NA '%s' on disk\n", fileName);
- pAsset->setAssetSource(path);
- }
-
- /* look inside the zip file */
- } else {
- String8 path(fileName);
-
- /* check the appropriate Zip file */
- ZipFileRO* pZip;
- ZipEntryRO entry;
-
- pZip = getZipFileLocked(ap);
- if (pZip != NULL) {
- //printf("GOT zip, checking NA '%s'\n", (const char*) path);
- entry = pZip->findEntryByName(path.string());
- if (entry != NULL) {
- //printf("FOUND NA in Zip file for %s\n", appName ? appName : kAppCommon);
- pAsset = openAssetFromZipLocked(pZip, entry, mode, path);
- }
- }
-
- if (pAsset != NULL) {
- /* create a "source" name, for debug/display */
- pAsset->setAssetSource(
- createZipSourceNameLocked(ZipSet::getPathName(ap.path.string()), String8(""),
- String8(fileName)));
- }
- }
-
- return pAsset;
-}
-
-/*
- * Open an asset, searching for it in the directory hierarchy for the
- * specified app.
- *
- * Pass in a NULL values for "appName" if the common app directory should
- * be used.
- */
-Asset* AssetManager::openInPathLocked(const char* fileName, AccessMode mode,
- const asset_path& ap)
-{
- Asset* pAsset = NULL;
-
- /*
- * Try various combinations of locale and vendor.
- */
- if (mLocale != NULL && mVendor != NULL)
- pAsset = openInLocaleVendorLocked(fileName, mode, ap, mLocale, mVendor);
- if (pAsset == NULL && mVendor != NULL)
- pAsset = openInLocaleVendorLocked(fileName, mode, ap, NULL, mVendor);
- if (pAsset == NULL && mLocale != NULL)
- pAsset = openInLocaleVendorLocked(fileName, mode, ap, mLocale, NULL);
- if (pAsset == NULL)
- pAsset = openInLocaleVendorLocked(fileName, mode, ap, NULL, NULL);
-
- return pAsset;
-}
-
-/*
- * Open an asset, searching for it in the directory hierarchy for the
- * specified locale and vendor.
- *
- * We also search in "app.jar".
- *
- * Pass in NULL values for "appName", "locale", and "vendor" if the
- * defaults should be used.
- */
-Asset* AssetManager::openInLocaleVendorLocked(const char* fileName, AccessMode mode,
- const asset_path& ap, const char* locale, const char* vendor)
-{
- Asset* pAsset = NULL;
-
- if (ap.type == kFileTypeDirectory) {
- if (mCacheMode == CACHE_OFF) {
- /* look at the filesystem on disk */
- String8 path(createPathNameLocked(ap, locale, vendor));
- path.appendPath(fileName);
-
- String8 excludeName(path);
- excludeName.append(kExcludeExtension);
- if (::getFileType(excludeName.string()) != kFileTypeNonexistent) {
- /* say no more */
- //printf("+++ excluding '%s'\n", (const char*) excludeName);
- return kExcludedAsset;
- }
-
- pAsset = openAssetFromFileLocked(path, mode);
-
- if (pAsset == NULL) {
- /* try again, this time with ".gz" */
- path.append(".gz");
- pAsset = openAssetFromFileLocked(path, mode);
- }
-
- if (pAsset != NULL)
- pAsset->setAssetSource(path);
- } else {
- /* find in cache */
- String8 path(createPathNameLocked(ap, locale, vendor));
- path.appendPath(fileName);
-
- AssetDir::FileInfo tmpInfo;
- bool found = false;
-
- String8 excludeName(path);
- excludeName.append(kExcludeExtension);
-
- if (mCache.indexOf(excludeName) != NAME_NOT_FOUND) {
- /* go no farther */
- //printf("+++ Excluding '%s'\n", (const char*) excludeName);
- return kExcludedAsset;
- }
-
- /*
- * File compression extensions (".gz") don't get stored in the
- * name cache, so we have to try both here.
- */
- if (mCache.indexOf(path) != NAME_NOT_FOUND) {
- found = true;
- pAsset = openAssetFromFileLocked(path, mode);
- if (pAsset == NULL) {
- /* try again, this time with ".gz" */
- path.append(".gz");
- pAsset = openAssetFromFileLocked(path, mode);
- }
- }
-
- if (pAsset != NULL)
- pAsset->setAssetSource(path);
-
- /*
- * Don't continue the search into the Zip files. Our cached info
- * said it was a file on disk; to be consistent with openDir()
- * we want to return the loose asset. If the cached file gets
- * removed, we fail.
- *
- * The alternative is to update our cache when files get deleted,
- * or make some sort of "best effort" promise, but for now I'm
- * taking the hard line.
- */
- if (found) {
- if (pAsset == NULL)
- LOGD("Expected file not found: '%s'\n", path.string());
- return pAsset;
- }
- }
- }
-
- /*
- * Either it wasn't found on disk or on the cached view of the disk.
- * Dig through the currently-opened set of Zip files. If caching
- * is disabled, the Zip file may get reopened.
- */
- if (pAsset == NULL && ap.type == kFileTypeRegular) {
- String8 path;
-
- path.appendPath((locale != NULL) ? locale : kDefaultLocale);
- path.appendPath((vendor != NULL) ? vendor : kDefaultVendor);
- path.appendPath(fileName);
-
- /* check the appropriate Zip file */
- ZipFileRO* pZip;
- ZipEntryRO entry;
-
- pZip = getZipFileLocked(ap);
- if (pZip != NULL) {
- //printf("GOT zip, checking '%s'\n", (const char*) path);
- entry = pZip->findEntryByName(path.string());
- if (entry != NULL) {
- //printf("FOUND in Zip file for %s/%s-%s\n",
- // appName, locale, vendor);
- pAsset = openAssetFromZipLocked(pZip, entry, mode, path);
- }
- }
-
- if (pAsset != NULL) {
- /* create a "source" name, for debug/display */
- pAsset->setAssetSource(createZipSourceNameLocked(ZipSet::getPathName(ap.path.string()),
- String8(""), String8(fileName)));
- }
- }
-
- return pAsset;
-}
-
-/*
- * Create a "source name" for a file from a Zip archive.
- */
-String8 AssetManager::createZipSourceNameLocked(const String8& zipFileName,
- const String8& dirName, const String8& fileName)
-{
- String8 sourceName("zip:");
- sourceName.append(zipFileName);
- sourceName.append(":");
- if (dirName.length() > 0) {
- sourceName.appendPath(dirName);
- }
- sourceName.appendPath(fileName);
- return sourceName;
-}
-
-/*
- * Create a path to a loose asset (asset-base/app/locale/vendor).
- */
-String8 AssetManager::createPathNameLocked(const asset_path& ap, const char* locale,
- const char* vendor)
-{
- String8 path(ap.path);
- path.appendPath((locale != NULL) ? locale : kDefaultLocale);
- path.appendPath((vendor != NULL) ? vendor : kDefaultVendor);
- return path;
-}
-
-/*
- * Create a path to a loose asset (asset-base/app/rootDir).
- */
-String8 AssetManager::createPathNameLocked(const asset_path& ap, const char* rootDir)
-{
- String8 path(ap.path);
- if (rootDir != NULL) path.appendPath(rootDir);
- return path;
-}
-
-/*
- * Return a pointer to one of our open Zip archives. Returns NULL if no
- * matching Zip file exists.
- *
- * Right now we have 2 possible Zip files (1 each in app/"common").
- *
- * If caching is set to CACHE_OFF, to get the expected behavior we
- * need to reopen the Zip file on every request. That would be silly
- * and expensive, so instead we just check the file modification date.
- *
- * Pass in NULL values for "appName", "locale", and "vendor" if the
- * generics should be used.
- */
-ZipFileRO* AssetManager::getZipFileLocked(const asset_path& ap)
-{
- LOGV("getZipFileLocked() in %p\n", this);
-
- return mZipSet.getZip(ap.path);
-}
-
-/*
- * Try to open an asset from a file on disk.
- *
- * If the file is compressed with gzip, we seek to the start of the
- * deflated data and pass that in (just like we would for a Zip archive).
- *
- * For uncompressed data, we may already have an mmap()ed version sitting
- * around. If so, we want to hand that to the Asset instead.
- *
- * This returns NULL if the file doesn't exist, couldn't be opened, or
- * claims to be a ".gz" but isn't.
- */
-Asset* AssetManager::openAssetFromFileLocked(const String8& pathName,
- AccessMode mode)
-{
- Asset* pAsset = NULL;
-
- if (strcasecmp(pathName.getPathExtension().string(), ".gz") == 0) {
- //printf("TRYING '%s'\n", (const char*) pathName);
- pAsset = Asset::createFromCompressedFile(pathName.string(), mode);
- } else {
- //printf("TRYING '%s'\n", (const char*) pathName);
- pAsset = Asset::createFromFile(pathName.string(), mode);
- }
-
- return pAsset;
-}
-
-/*
- * Given an entry in a Zip archive, create a new Asset object.
- *
- * If the entry is uncompressed, we may want to create or share a
- * slice of shared memory.
- */
-Asset* AssetManager::openAssetFromZipLocked(const ZipFileRO* pZipFile,
- const ZipEntryRO entry, AccessMode mode, const String8& entryName)
-{
- Asset* pAsset = NULL;
-
- // TODO: look for previously-created shared memory slice?
- int method;
- long uncompressedLen;
-
- //printf("USING Zip '%s'\n", pEntry->getFileName());
-
- //pZipFile->getEntryInfo(entry, &method, &uncompressedLen, &compressedLen,
- // &offset);
- if (!pZipFile->getEntryInfo(entry, &method, &uncompressedLen, NULL, NULL,
- NULL, NULL))
- {
- LOGW("getEntryInfo failed\n");
- return NULL;
- }
-
- FileMap* dataMap = pZipFile->createEntryFileMap(entry);
- if (dataMap == NULL) {
- LOGW("create map from entry failed\n");
- return NULL;
- }
-
- if (method == ZipFileRO::kCompressStored) {
- pAsset = Asset::createFromUncompressedMap(dataMap, mode);
- LOGV("Opened uncompressed entry %s in zip %s mode %d: %p", entryName.string(),
- dataMap->getFileName(), mode, pAsset);
- } else {
- pAsset = Asset::createFromCompressedMap(dataMap, method,
- uncompressedLen, mode);
- LOGV("Opened compressed entry %s in zip %s mode %d: %p", entryName.string(),
- dataMap->getFileName(), mode, pAsset);
- }
- if (pAsset == NULL) {
- /* unexpected */
- LOGW("create from segment failed\n");
- }
-
- return pAsset;
-}
-
-
-
-/*
- * Open a directory in the asset namespace.
- *
- * An "asset directory" is simply the combination of all files in all
- * locations, with ".gz" stripped for loose files. With app, locale, and
- * vendor defined, we have 8 directories and 2 Zip archives to scan.
- *
- * Pass in "" for the root dir.
- */
-AssetDir* AssetManager::openDir(const char* dirName)
-{
- AutoMutex _l(mLock);
-
- AssetDir* pDir = NULL;
- SortedVector<AssetDir::FileInfo>* pMergedInfo = NULL;
-
- LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
- assert(dirName != NULL);
-
- //printf("+++ openDir(%s) in '%s'\n", dirName, (const char*) mAssetBase);
-
- if (mCacheMode != CACHE_OFF && !mCacheValid)
- loadFileNameCacheLocked();
-
- pDir = new AssetDir;
-
- /*
- * Scan the various directories, merging what we find into a single
- * vector. We want to scan them in reverse priority order so that
- * the ".EXCLUDE" processing works correctly. Also, if we decide we
- * want to remember where the file is coming from, we'll get the right
- * version.
- *
- * We start with Zip archives, then do loose files.
- */
- pMergedInfo = new SortedVector<AssetDir::FileInfo>;
-
- size_t i = mAssetPaths.size();
- while (i > 0) {
- i--;
- const asset_path& ap = mAssetPaths.itemAt(i);
- if (ap.type == kFileTypeRegular) {
- LOGV("Adding directory %s from zip %s", dirName, ap.path.string());
- scanAndMergeZipLocked(pMergedInfo, ap, kAssetsRoot, dirName);
- } else {
- LOGV("Adding directory %s from dir %s", dirName, ap.path.string());
- scanAndMergeDirLocked(pMergedInfo, ap, kAssetsRoot, dirName);
- }
- }
-
-#if 0
- printf("FILE LIST:\n");
- for (i = 0; i < (size_t) pMergedInfo->size(); i++) {
- printf(" %d: (%d) '%s'\n", i,
- pMergedInfo->itemAt(i).getFileType(),
- (const char*) pMergedInfo->itemAt(i).getFileName());
- }
-#endif
-
- pDir->setFileList(pMergedInfo);
- return pDir;
-}
-
-/*
- * Scan the contents of the specified directory and merge them into the
- * "pMergedInfo" vector, removing previous entries if we find "exclude"
- * directives.
- *
- * Returns "false" if we found nothing to contribute.
- */
-bool AssetManager::scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
- const asset_path& ap, const char* rootDir, const char* dirName)
-{
- SortedVector<AssetDir::FileInfo>* pContents;
- String8 path;
-
- assert(pMergedInfo != NULL);
-
- //printf("scanAndMergeDir: %s %s %s %s\n", appName, locale, vendor,dirName);
-
- if (mCacheValid) {
- int i, start, count;
-
- pContents = new SortedVector<AssetDir::FileInfo>;
-
- /*
- * Get the basic partial path and find it in the cache. That's
- * the start point for the search.
- */
- path = createPathNameLocked(ap, rootDir);
- if (dirName[0] != '\0')
- path.appendPath(dirName);
-
- start = mCache.indexOf(path);
- if (start == NAME_NOT_FOUND) {
- //printf("+++ not found in cache: dir '%s'\n", (const char*) path);
- delete pContents;
- return false;
- }
-
- /*
- * The match string looks like "common/default/default/foo/bar/".
- * The '/' on the end ensures that we don't match on the directory
- * itself or on ".../foo/barfy/".
- */
- path.append("/");
-
- count = mCache.size();
-
- /*
- * Pick out the stuff in the current dir by examining the pathname.
- * It needs to match the partial pathname prefix, and not have a '/'
- * (fssep) anywhere after the prefix.
- */
- for (i = start+1; i < count; i++) {
- if (mCache[i].getFileName().length() > path.length() &&
- strncmp(mCache[i].getFileName().string(), path.string(), path.length()) == 0)
- {
- const char* name = mCache[i].getFileName().string();
- // XXX THIS IS BROKEN! Looks like we need to store the full
- // path prefix separately from the file path.
- if (strchr(name + path.length(), '/') == NULL) {
- /* grab it, reducing path to just the filename component */
- AssetDir::FileInfo tmp = mCache[i];
- tmp.setFileName(tmp.getFileName().getPathLeaf());
- pContents->add(tmp);
- }
- } else {
- /* no longer in the dir or its subdirs */
- break;
- }
-
- }
- } else {
- path = createPathNameLocked(ap, rootDir);
- if (dirName[0] != '\0')
- path.appendPath(dirName);
- pContents = scanDirLocked(path);
- if (pContents == NULL)
- return false;
- }
-
- // if we wanted to do an incremental cache fill, we would do it here
-
- /*
- * Process "exclude" directives. If we find a filename that ends with
- * ".EXCLUDE", we look for a matching entry in the "merged" set, and
- * remove it if we find it. We also delete the "exclude" entry.
- */
- int i, count, exclExtLen;
-
- count = pContents->size();
- exclExtLen = strlen(kExcludeExtension);
- for (i = 0; i < count; i++) {
- const char* name;
- int nameLen;
-
- name = pContents->itemAt(i).getFileName().string();
- nameLen = strlen(name);
- if (nameLen > exclExtLen &&
- strcmp(name + (nameLen - exclExtLen), kExcludeExtension) == 0)
- {
- String8 match(name, nameLen - exclExtLen);
- int matchIdx;
-
- matchIdx = AssetDir::FileInfo::findEntry(pMergedInfo, match);
- if (matchIdx > 0) {
- LOGV("Excluding '%s' [%s]\n",
- pMergedInfo->itemAt(matchIdx).getFileName().string(),
- pMergedInfo->itemAt(matchIdx).getSourceName().string());
- pMergedInfo->removeAt(matchIdx);
- } else {
- //printf("+++ no match on '%s'\n", (const char*) match);
- }
-
- LOGD("HEY: size=%d removing %d\n", (int)pContents->size(), i);
- pContents->removeAt(i);
- i--; // adjust "for" loop
- count--; // and loop limit
- }
- }
-
- mergeInfoLocked(pMergedInfo, pContents);
-
- delete pContents;
-
- return true;
-}
-
-/*
- * Scan the contents of the specified directory, and stuff what we find
- * into a newly-allocated vector.
- *
- * Files ending in ".gz" will have their extensions removed.
- *
- * We should probably think about skipping files with "illegal" names,
- * e.g. illegal characters (/\:) or excessive length.
- *
- * Returns NULL if the specified directory doesn't exist.
- */
-SortedVector<AssetDir::FileInfo>* AssetManager::scanDirLocked(const String8& path)
-{
- SortedVector<AssetDir::FileInfo>* pContents = NULL;
- DIR* dir;
- struct dirent* entry;
- FileType fileType;
-
- LOGV("Scanning dir '%s'\n", path.string());
-
- dir = opendir(path.string());
- if (dir == NULL)
- return NULL;
-
- pContents = new SortedVector<AssetDir::FileInfo>;
-
- while (1) {
- entry = readdir(dir);
- if (entry == NULL)
- break;
-
- if (strcmp(entry->d_name, ".") == 0 ||
- strcmp(entry->d_name, "..") == 0)
- continue;
-
-#ifdef _DIRENT_HAVE_D_TYPE
- if (entry->d_type == DT_REG)
- fileType = kFileTypeRegular;
- else if (entry->d_type == DT_DIR)
- fileType = kFileTypeDirectory;
- else
- fileType = kFileTypeUnknown;
-#else
- // stat the file
- fileType = ::getFileType(path.appendPathCopy(entry->d_name).string());
-#endif
-
- if (fileType != kFileTypeRegular && fileType != kFileTypeDirectory)
- continue;
-
- AssetDir::FileInfo info;
- info.set(String8(entry->d_name), fileType);
- if (strcasecmp(info.getFileName().getPathExtension().string(), ".gz") == 0)
- info.setFileName(info.getFileName().getBasePath());
- info.setSourceName(path.appendPathCopy(info.getFileName()));
- pContents->add(info);
- }
-
- closedir(dir);
- return pContents;
-}
-
-/*
- * Scan the contents out of the specified Zip archive, and merge what we
- * find into "pMergedInfo". If the Zip archive in question doesn't exist,
- * we return immediately.
- *
- * Returns "false" if we found nothing to contribute.
- */
-bool AssetManager::scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
- const asset_path& ap, const char* rootDir, const char* baseDirName)
-{
- ZipFileRO* pZip;
- Vector<String8> dirs;
- AssetDir::FileInfo info;
- SortedVector<AssetDir::FileInfo> contents;
- String8 sourceName, zipName, dirName;
-
- pZip = mZipSet.getZip(ap.path);
- if (pZip == NULL) {
- LOGW("Failure opening zip %s\n", ap.path.string());
- return false;
- }
-
- zipName = ZipSet::getPathName(ap.path.string());
-
- /* convert "sounds" to "rootDir/sounds" */
- if (rootDir != NULL) dirName = rootDir;
- dirName.appendPath(baseDirName);
-
- /*
- * Scan through the list of files, looking for a match. The files in
- * the Zip table of contents are not in sorted order, so we have to
- * process the entire list. We're looking for a string that begins
- * with the characters in "dirName", is followed by a '/', and has no
- * subsequent '/' in the stuff that follows.
- *
- * What makes this especially fun is that directories are not stored
- * explicitly in Zip archives, so we have to infer them from context.
- * When we see "sounds/foo.wav" we have to leave a note to ourselves
- * to insert a directory called "sounds" into the list. We store
- * these in temporary vector so that we only return each one once.
- *
- * Name comparisons are case-sensitive to match UNIX filesystem
- * semantics.
- */
- int dirNameLen = dirName.length();
- for (int i = 0; i < pZip->getNumEntries(); i++) {
- ZipEntryRO entry;
- char nameBuf[256];
-
- entry = pZip->findEntryByIndex(i);
- if (pZip->getEntryFileName(entry, nameBuf, sizeof(nameBuf)) != 0) {
- // TODO: fix this if we expect to have long names
- LOGE("ARGH: name too long?\n");
- continue;
- }
- if (dirNameLen == 0 ||
- (strncmp(nameBuf, dirName.string(), dirNameLen) == 0 &&
- nameBuf[dirNameLen] == '/'))
- {
- const char* cp;
- const char* nextSlash;
-
- cp = nameBuf + dirNameLen;
- if (dirNameLen != 0)
- cp++; // advance past the '/'
-
- nextSlash = strchr(cp, '/');
-//xxx this may break if there are bare directory entries
- if (nextSlash == NULL) {
- /* this is a file in the requested directory */
-
- info.set(String8(nameBuf).getPathLeaf(), kFileTypeRegular);
-
- info.setSourceName(
- createZipSourceNameLocked(zipName, dirName, info.getFileName()));
-
- contents.add(info);
- //printf("FOUND: file '%s'\n", (const char*) info.mFileName);
- } else {
- /* this is a subdir; add it if we don't already have it*/
- String8 subdirName(cp, nextSlash - cp);
- size_t j;
- size_t N = dirs.size();
-
- for (j = 0; j < N; j++) {
- if (subdirName == dirs[j]) {
- break;
- }
- }
- if (j == N) {
- dirs.add(subdirName);
- }
-
- //printf("FOUND: dir '%s'\n", (const char*) subdirName);
- }
- }
- }
-
- /*
- * Add the set of unique directories.
- */
- for (int i = 0; i < (int) dirs.size(); i++) {
- info.set(dirs[i], kFileTypeDirectory);
- info.setSourceName(
- createZipSourceNameLocked(zipName, dirName, info.getFileName()));
- contents.add(info);
- }
-
- mergeInfoLocked(pMergedInfo, &contents);
-
- return true;
-}
-
-
-/*
- * Merge two vectors of FileInfo.
- *
- * The merged contents will be stuffed into *pMergedInfo.
- *
- * If an entry for a file exists in both "pMergedInfo" and "pContents",
- * we use the newer "pContents" entry.
- */
-void AssetManager::mergeInfoLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
- const SortedVector<AssetDir::FileInfo>* pContents)
-{
- /*
- * Merge what we found in this directory with what we found in
- * other places.
- *
- * Two basic approaches:
- * (1) Create a new array that holds the unique values of the two
- * arrays.
- * (2) Take the elements from pContents and shove them into pMergedInfo.
- *
- * Because these are vectors of complex objects, moving elements around
- * inside the vector requires constructing new objects and allocating
- * storage for members. With approach #1, we're always adding to the
- * end, whereas with #2 we could be inserting multiple elements at the
- * front of the vector. Approach #1 requires a full copy of the
- * contents of pMergedInfo, but approach #2 requires the same copy for
- * every insertion at the front of pMergedInfo.
- *
- * (We should probably use a SortedVector interface that allows us to
- * just stuff items in, trusting us to maintain the sort order.)
- */
- SortedVector<AssetDir::FileInfo>* pNewSorted;
- int mergeMax, contMax;
- int mergeIdx, contIdx;
-
- pNewSorted = new SortedVector<AssetDir::FileInfo>;
- mergeMax = pMergedInfo->size();
- contMax = pContents->size();
- mergeIdx = contIdx = 0;
-
- while (mergeIdx < mergeMax || contIdx < contMax) {
- if (mergeIdx == mergeMax) {
- /* hit end of "merge" list, copy rest of "contents" */
- pNewSorted->add(pContents->itemAt(contIdx));
- contIdx++;
- } else if (contIdx == contMax) {
- /* hit end of "cont" list, copy rest of "merge" */
- pNewSorted->add(pMergedInfo->itemAt(mergeIdx));
- mergeIdx++;
- } else if (pMergedInfo->itemAt(mergeIdx) == pContents->itemAt(contIdx))
- {
- /* items are identical, add newer and advance both indices */
- pNewSorted->add(pContents->itemAt(contIdx));
- mergeIdx++;
- contIdx++;
- } else if (pMergedInfo->itemAt(mergeIdx) < pContents->itemAt(contIdx))
- {
- /* "merge" is lower, add that one */
- pNewSorted->add(pMergedInfo->itemAt(mergeIdx));
- mergeIdx++;
- } else {
- /* "cont" is lower, add that one */
- assert(pContents->itemAt(contIdx) < pMergedInfo->itemAt(mergeIdx));
- pNewSorted->add(pContents->itemAt(contIdx));
- contIdx++;
- }
- }
-
- /*
- * Overwrite the "merged" list with the new stuff.
- */
- *pMergedInfo = *pNewSorted;
- delete pNewSorted;
-
-#if 0 // for Vector, rather than SortedVector
- int i, j;
- for (i = pContents->size() -1; i >= 0; i--) {
- bool add = true;
-
- for (j = pMergedInfo->size() -1; j >= 0; j--) {
- /* case-sensitive comparisons, to behave like UNIX fs */
- if (strcmp(pContents->itemAt(i).mFileName,
- pMergedInfo->itemAt(j).mFileName) == 0)
- {
- /* match, don't add this entry */
- add = false;
- break;
- }
- }
-
- if (add)
- pMergedInfo->add(pContents->itemAt(i));
- }
-#endif
-}
-
-
-/*
- * Load all files into the file name cache. We want to do this across
- * all combinations of { appname, locale, vendor }, performing a recursive
- * directory traversal.
- *
- * This is not the most efficient data structure. Also, gathering the
- * information as we needed it (file-by-file or directory-by-directory)
- * would be faster. However, on the actual device, 99% of the files will
- * live in Zip archives, so this list will be very small. The trouble
- * is that we have to check the "loose" files first, so it's important
- * that we don't beat the filesystem silly looking for files that aren't
- * there.
- *
- * Note on thread safety: this is the only function that causes updates
- * to mCache, and anybody who tries to use it will call here if !mCacheValid,
- * so we need to employ a mutex here.
- */
-void AssetManager::loadFileNameCacheLocked(void)
-{
- assert(!mCacheValid);
- assert(mCache.size() == 0);
-
-#ifdef DO_TIMINGS // need to link against -lrt for this now
- DurationTimer timer;
- timer.start();
-#endif
-
- fncScanLocked(&mCache, "");
-
-#ifdef DO_TIMINGS
- timer.stop();
- LOGD("Cache scan took %.3fms\n",
- timer.durationUsecs() / 1000.0);
-#endif
-
-#if 0
- int i;
- printf("CACHED FILE LIST (%d entries):\n", mCache.size());
- for (i = 0; i < (int) mCache.size(); i++) {
- printf(" %d: (%d) '%s'\n", i,
- mCache.itemAt(i).getFileType(),
- (const char*) mCache.itemAt(i).getFileName());
- }
-#endif
-
- mCacheValid = true;
-}
-
-/*
- * Scan up to 8 versions of the specified directory.
- */
-void AssetManager::fncScanLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
- const char* dirName)
-{
- size_t i = mAssetPaths.size();
- while (i > 0) {
- i--;
- const asset_path& ap = mAssetPaths.itemAt(i);
- fncScanAndMergeDirLocked(pMergedInfo, ap, NULL, NULL, dirName);
- if (mLocale != NULL)
- fncScanAndMergeDirLocked(pMergedInfo, ap, mLocale, NULL, dirName);
- if (mVendor != NULL)
- fncScanAndMergeDirLocked(pMergedInfo, ap, NULL, mVendor, dirName);
- if (mLocale != NULL && mVendor != NULL)
- fncScanAndMergeDirLocked(pMergedInfo, ap, mLocale, mVendor, dirName);
- }
-}
-
-/*
- * Recursively scan this directory and all subdirs.
- *
- * This is similar to scanAndMergeDir, but we don't remove the .EXCLUDE
- * files, and we prepend the extended partial path to the filenames.
- */
-bool AssetManager::fncScanAndMergeDirLocked(
- SortedVector<AssetDir::FileInfo>* pMergedInfo,
- const asset_path& ap, const char* locale, const char* vendor,
- const char* dirName)
-{
- SortedVector<AssetDir::FileInfo>* pContents;
- String8 partialPath;
- String8 fullPath;
-
- // XXX This is broken -- the filename cache needs to hold the base
- // asset path separately from its filename.
-
- partialPath = createPathNameLocked(ap, locale, vendor);
- if (dirName[0] != '\0') {
- partialPath.appendPath(dirName);
- }
-
- fullPath = partialPath;
- pContents = scanDirLocked(fullPath);
- if (pContents == NULL) {
- return false; // directory did not exist
- }
-
- /*
- * Scan all subdirectories of the current dir, merging what we find
- * into "pMergedInfo".
- */
- for (int i = 0; i < (int) pContents->size(); i++) {
- if (pContents->itemAt(i).getFileType() == kFileTypeDirectory) {
- String8 subdir(dirName);
- subdir.appendPath(pContents->itemAt(i).getFileName());
-
- fncScanAndMergeDirLocked(pMergedInfo, ap, locale, vendor, subdir.string());
- }
- }
-
- /*
- * To be consistent, we want entries for the root directory. If
- * we're the root, add one now.
- */
- if (dirName[0] == '\0') {
- AssetDir::FileInfo tmpInfo;
-
- tmpInfo.set(String8(""), kFileTypeDirectory);
- tmpInfo.setSourceName(createPathNameLocked(ap, locale, vendor));
- pContents->add(tmpInfo);
- }
-
- /*
- * We want to prepend the extended partial path to every entry in
- * "pContents". It's the same value for each entry, so this will
- * not change the sorting order of the vector contents.
- */
- for (int i = 0; i < (int) pContents->size(); i++) {
- const AssetDir::FileInfo& info = pContents->itemAt(i);
- pContents->editItemAt(i).setFileName(partialPath.appendPathCopy(info.getFileName()));
- }
-
- mergeInfoLocked(pMergedInfo, pContents);
- return true;
-}
-
-/*
- * Trash the cache.
- */
-void AssetManager::purgeFileNameCacheLocked(void)
-{
- mCacheValid = false;
- mCache.clear();
-}
-
-/*
- * ===========================================================================
- * AssetManager::SharedZip
- * ===========================================================================
- */
-
-
-Mutex AssetManager::SharedZip::gLock;
-DefaultKeyedVector<String8, wp<AssetManager::SharedZip> > AssetManager::SharedZip::gOpen;
-
-AssetManager::SharedZip::SharedZip(const String8& path, time_t modWhen)
- : mPath(path), mZipFile(NULL), mModWhen(modWhen), mResourceTableAsset(NULL)
-{
- //LOGI("Creating SharedZip %p %s\n", this, (const char*)mPath);
- mZipFile = new ZipFileRO;
- LOGV("+++ opening zip '%s'\n", mPath.string());
- if (mZipFile->open(mPath.string()) != NO_ERROR) {
- LOGD("failed to open Zip archive '%s'\n", mPath.string());
- delete mZipFile;
- mZipFile = NULL;
- }
-}
-
-sp<AssetManager::SharedZip> AssetManager::SharedZip::get(const String8& path)
-{
- AutoMutex _l(gLock);
- time_t modWhen = getFileModDate(path);
- sp<SharedZip> zip = gOpen.valueFor(path).promote();
- if (zip != NULL && zip->mModWhen == modWhen) {
- return zip;
- }
- zip = new SharedZip(path, modWhen);
- gOpen.add(path, zip);
- return zip;
-
-}
-
-ZipFileRO* AssetManager::SharedZip::getZip()
-{
- return mZipFile;
-}
-
-Asset* AssetManager::SharedZip::getResourceTableAsset()
-{
- LOGV("Getting from SharedZip %p resource asset %p\n", this, mResourceTableAsset);
- return mResourceTableAsset;
-}
-
-Asset* AssetManager::SharedZip::setResourceTableAsset(Asset* asset)
-{
- {
- AutoMutex _l(gLock);
- if (mResourceTableAsset == NULL) {
- mResourceTableAsset = asset;
- // This is not thread safe the first time it is called, so
- // do it here with the global lock held.
- asset->getBuffer(true);
- return asset;
- }
- }
- delete asset;
- return mResourceTableAsset;
-}
-
-bool AssetManager::SharedZip::isUpToDate()
-{
- time_t modWhen = getFileModDate(mPath.string());
- return mModWhen == modWhen;
-}
-
-AssetManager::SharedZip::~SharedZip()
-{
- //LOGI("Destroying SharedZip %p %s\n", this, (const char*)mPath);
- if (mResourceTableAsset != NULL) {
- delete mResourceTableAsset;
- }
- if (mZipFile != NULL) {
- delete mZipFile;
- LOGV("Closed '%s'\n", mPath.string());
- }
-}
-
-/*
- * ===========================================================================
- * AssetManager::ZipSet
- * ===========================================================================
- */
-
-/*
- * Constructor.
- */
-AssetManager::ZipSet::ZipSet(void)
-{
-}
-
-/*
- * Destructor. Close any open archives.
- */
-AssetManager::ZipSet::~ZipSet(void)
-{
- size_t N = mZipFile.size();
- for (size_t i = 0; i < N; i++)
- closeZip(i);
-}
-
-/*
- * Close a Zip file and reset the entry.
- */
-void AssetManager::ZipSet::closeZip(int idx)
-{
- mZipFile.editItemAt(idx) = NULL;
-}
-
-
-/*
- * Retrieve the appropriate Zip file from the set.
- */
-ZipFileRO* AssetManager::ZipSet::getZip(const String8& path)
-{
- int idx = getIndex(path);
- sp<SharedZip> zip = mZipFile[idx];
- if (zip == NULL) {
- zip = SharedZip::get(path);
- mZipFile.editItemAt(idx) = zip;
- }
- return zip->getZip();
-}
-
-Asset* AssetManager::ZipSet::getZipResourceTable(const String8& path)
-{
- int idx = getIndex(path);
- sp<SharedZip> zip = mZipFile[idx];
- if (zip == NULL) {
- zip = SharedZip::get(path);
- mZipFile.editItemAt(idx) = zip;
- }
- return zip->getResourceTableAsset();
-}
-
-Asset* AssetManager::ZipSet::setZipResourceTable(const String8& path,
- Asset* asset)
-{
- int idx = getIndex(path);
- sp<SharedZip> zip = mZipFile[idx];
- // doesn't make sense to call before previously accessing.
- return zip->setResourceTableAsset(asset);
-}
-
-/*
- * Generate the partial pathname for the specified archive. The caller
- * gets to prepend the asset root directory.
- *
- * Returns something like "common/en-US-noogle.jar".
- */
-/*static*/ String8 AssetManager::ZipSet::getPathName(const char* zipPath)
-{
- return String8(zipPath);
-}
-
-bool AssetManager::ZipSet::isUpToDate()
-{
- const size_t N = mZipFile.size();
- for (size_t i=0; i<N; i++) {
- if (mZipFile[i] != NULL && !mZipFile[i]->isUpToDate()) {
- return false;
- }
- }
- return true;
-}
-
-/*
- * Compute the zip file's index.
- *
- * "appName", "locale", and "vendor" should be set to NULL to indicate the
- * default directory.
- */
-int AssetManager::ZipSet::getIndex(const String8& zip) const
-{
- const size_t N = mZipPath.size();
- for (size_t i=0; i<N; i++) {
- if (mZipPath[i] == zip) {
- return i;
- }
- }
-
- mZipPath.add(zip);
- mZipFile.add(NULL);
-
- return mZipPath.size()-1;
-}
-
diff --git a/libs/utils/Binder.cpp b/libs/utils/Binder.cpp
deleted file mode 100644
index 37e4685..0000000
--- a/libs/utils/Binder.cpp
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * 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.
- */
-
-#include <utils/Binder.h>
-
-#include <utils/Atomic.h>
-#include <utils/BpBinder.h>
-#include <utils/IInterface.h>
-#include <utils/Parcel.h>
-
-#include <stdio.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-sp<IInterface> IBinder::queryLocalInterface(const String16& descriptor)
-{
- return NULL;
-}
-
-BBinder* IBinder::localBinder()
-{
- return NULL;
-}
-
-BpBinder* IBinder::remoteBinder()
-{
- return NULL;
-}
-
-bool IBinder::checkSubclass(const void* /*subclassID*/) const
-{
- return false;
-}
-
-// ---------------------------------------------------------------------------
-
-class BBinder::Extras
-{
-public:
- Mutex mLock;
- BpBinder::ObjectManager mObjects;
-};
-
-// ---------------------------------------------------------------------------
-
-BBinder::BBinder()
- : mExtras(NULL)
-{
-}
-
-bool BBinder::isBinderAlive() const
-{
- return true;
-}
-
-status_t BBinder::pingBinder()
-{
- return NO_ERROR;
-}
-
-String16 BBinder::getInterfaceDescriptor() const
-{
- LOGW("reached BBinder::getInterfaceDescriptor (this=%p)", this);
- return String16();
-}
-
-status_t BBinder::transact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- data.setDataPosition(0);
-
- status_t err = NO_ERROR;
- switch (code) {
- case PING_TRANSACTION:
- reply->writeInt32(pingBinder());
- break;
- default:
- err = onTransact(code, data, reply, flags);
- break;
- }
-
- if (reply != NULL) {
- reply->setDataPosition(0);
- }
-
- return err;
-}
-
-status_t BBinder::linkToDeath(
- const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
-{
- return INVALID_OPERATION;
-}
-
-status_t BBinder::unlinkToDeath(
- const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
- wp<DeathRecipient>* outRecipient)
-{
- return INVALID_OPERATION;
-}
-
-status_t BBinder::dump(int fd, const Vector<String16>& args)
-{
- return NO_ERROR;
-}
-
-void BBinder::attachObject(
- const void* objectID, void* object, void* cleanupCookie,
- object_cleanup_func func)
-{
- Extras* e = mExtras;
-
- if (!e) {
- e = new Extras;
- if (android_atomic_cmpxchg(0, reinterpret_cast<int32_t>(e),
- reinterpret_cast<volatile int32_t*>(&mExtras)) != 0) {
- delete e;
- e = mExtras;
- }
- if (e == 0) return; // out of memory
- }
-
- AutoMutex _l(e->mLock);
- e->mObjects.attach(objectID, object, cleanupCookie, func);
-}
-
-void* BBinder::findObject(const void* objectID) const
-{
- Extras* e = mExtras;
- if (!e) return NULL;
-
- AutoMutex _l(e->mLock);
- return e->mObjects.find(objectID);
-}
-
-void BBinder::detachObject(const void* objectID)
-{
- Extras* e = mExtras;
- if (!e) return;
-
- AutoMutex _l(e->mLock);
- e->mObjects.detach(objectID);
-}
-
-BBinder* BBinder::localBinder()
-{
- return this;
-}
-
-BBinder::~BBinder()
-{
- if (mExtras) delete mExtras;
-}
-
-
-status_t BBinder::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch (code) {
- case INTERFACE_TRANSACTION:
- reply->writeString16(getInterfaceDescriptor());
- return NO_ERROR;
-
- case DUMP_TRANSACTION: {
- int fd = data.readFileDescriptor();
- int argc = data.readInt32();
- Vector<String16> args;
- for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
- args.add(data.readString16());
- }
- return dump(fd, args);
- }
- default:
- return UNKNOWN_TRANSACTION;
- }
-}
-
-// ---------------------------------------------------------------------------
-
-enum {
- // This is used to transfer ownership of the remote binder from
- // the BpRefBase object holding it (when it is constructed), to the
- // owner of the BpRefBase object when it first acquires that BpRefBase.
- kRemoteAcquired = 0x00000001
-};
-
-BpRefBase::BpRefBase(const sp<IBinder>& o)
- : mRemote(o.get()), mRefs(NULL), mState(0)
-{
- extendObjectLifetime(OBJECT_LIFETIME_WEAK);
-
- if (mRemote) {
- mRemote->incStrong(this); // Removed on first IncStrong().
- mRefs = mRemote->createWeak(this); // Held for our entire lifetime.
- }
-}
-
-BpRefBase::~BpRefBase()
-{
- if (mRemote) {
- if (!(mState&kRemoteAcquired)) {
- mRemote->decStrong(this);
- }
- mRefs->decWeak(this);
- }
-}
-
-void BpRefBase::onFirstRef()
-{
- android_atomic_or(kRemoteAcquired, &mState);
-}
-
-void BpRefBase::onLastStrongRef(const void* id)
-{
- if (mRemote) {
- mRemote->decStrong(this);
- }
-}
-
-bool BpRefBase::onIncStrongAttempted(uint32_t flags, const void* id)
-{
- return mRemote ? mRefs->attemptIncStrong(this) : false;
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/utils/BpBinder.cpp b/libs/utils/BpBinder.cpp
deleted file mode 100644
index 69ab195..0000000
--- a/libs/utils/BpBinder.cpp
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "BpBinder"
-//#define LOG_NDEBUG 0
-
-#include <utils/BpBinder.h>
-
-#include <utils/IPCThreadState.h>
-#include <utils/Log.h>
-
-#include <stdio.h>
-
-//#undef LOGV
-//#define LOGV(...) fprintf(stderr, __VA_ARGS__)
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-BpBinder::ObjectManager::ObjectManager()
-{
-}
-
-BpBinder::ObjectManager::~ObjectManager()
-{
- kill();
-}
-
-void BpBinder::ObjectManager::attach(
- const void* objectID, void* object, void* cleanupCookie,
- IBinder::object_cleanup_func func)
-{
- entry_t e;
- e.object = object;
- e.cleanupCookie = cleanupCookie;
- e.func = func;
-
- if (mObjects.indexOfKey(objectID) >= 0) {
- LOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use",
- objectID, this, object);
- return;
- }
-
- mObjects.add(objectID, e);
-}
-
-void* BpBinder::ObjectManager::find(const void* objectID) const
-{
- const ssize_t i = mObjects.indexOfKey(objectID);
- if (i < 0) return NULL;
- return mObjects.valueAt(i).object;
-}
-
-void BpBinder::ObjectManager::detach(const void* objectID)
-{
- mObjects.removeItem(objectID);
-}
-
-void BpBinder::ObjectManager::kill()
-{
- const size_t N = mObjects.size();
- LOGV("Killing %d objects in manager %p", N, this);
- for (size_t i=0; i<N; i++) {
- const entry_t& e = mObjects.valueAt(i);
- if (e.func != NULL) {
- e.func(mObjects.keyAt(i), e.object, e.cleanupCookie);
- }
- }
-
- mObjects.clear();
-}
-
-// ---------------------------------------------------------------------------
-
-BpBinder::BpBinder(int32_t handle)
- : mHandle(handle)
- , mAlive(1)
- , mObitsSent(0)
- , mObituaries(NULL)
-{
- LOGV("Creating BpBinder %p handle %d\n", this, mHandle);
-
- extendObjectLifetime(OBJECT_LIFETIME_WEAK);
- IPCThreadState::self()->incWeakHandle(handle);
-}
-
-String16 BpBinder::getInterfaceDescriptor() const
-{
- String16 res;
- Parcel send, reply;
- status_t err = const_cast<BpBinder*>(this)->transact(
- INTERFACE_TRANSACTION, send, &reply);
- if (err == NO_ERROR) {
- res = reply.readString16();
- }
- return res;
-}
-
-bool BpBinder::isBinderAlive() const
-{
- return mAlive != 0;
-}
-
-status_t BpBinder::pingBinder()
-{
- Parcel send;
- Parcel reply;
- status_t err = transact(PING_TRANSACTION, send, &reply);
- if (err != NO_ERROR) return err;
- if (reply.dataSize() < sizeof(status_t)) return NOT_ENOUGH_DATA;
- return (status_t)reply.readInt32();
-}
-
-status_t BpBinder::dump(int fd, const Vector<String16>& args)
-{
- Parcel send;
- Parcel reply;
- send.writeFileDescriptor(fd);
- const size_t numArgs = args.size();
- send.writeInt32(numArgs);
- for (size_t i = 0; i < numArgs; i++) {
- send.writeString16(args[i]);
- }
- status_t err = transact(DUMP_TRANSACTION, send, &reply);
- return err;
-}
-
-status_t BpBinder::transact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- // Once a binder has died, it will never come back to life.
- if (mAlive) {
- status_t status = IPCThreadState::self()->transact(
- mHandle, code, data, reply, flags);
- if (status == DEAD_OBJECT) mAlive = 0;
- return status;
- }
-
- return DEAD_OBJECT;
-}
-
-status_t BpBinder::linkToDeath(
- const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
-{
- Obituary ob;
- ob.recipient = recipient;
- ob.cookie = cookie;
- ob.flags = flags;
-
- LOG_ALWAYS_FATAL_IF(recipient == NULL,
- "linkToDeath(): recipient must be non-NULL");
-
- {
- AutoMutex _l(mLock);
-
- if (!mObitsSent) {
- if (!mObituaries) {
- mObituaries = new Vector<Obituary>;
- if (!mObituaries) {
- return NO_MEMORY;
- }
- LOGV("Requesting death notification: %p handle %d\n", this, mHandle);
- getWeakRefs()->incWeak(this);
- IPCThreadState* self = IPCThreadState::self();
- self->requestDeathNotification(mHandle, this);
- self->flushCommands();
- }
- ssize_t res = mObituaries->add(ob);
- return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
- }
- }
-
- return DEAD_OBJECT;
-}
-
-status_t BpBinder::unlinkToDeath(
- const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
- wp<DeathRecipient>* outRecipient)
-{
- AutoMutex _l(mLock);
-
- if (mObitsSent) {
- return DEAD_OBJECT;
- }
-
- const size_t N = mObituaries ? mObituaries->size() : 0;
- for (size_t i=0; i<N; i++) {
- const Obituary& obit = mObituaries->itemAt(i);
- if ((obit.recipient == recipient
- || (recipient == NULL && obit.cookie == cookie))
- && obit.flags == flags) {
- const uint32_t allFlags = obit.flags|flags;
- if (outRecipient != NULL) {
- *outRecipient = mObituaries->itemAt(i).recipient;
- }
- mObituaries->removeAt(i);
- if (mObituaries->size() == 0) {
- LOGV("Clearing death notification: %p handle %d\n", this, mHandle);
- IPCThreadState* self = IPCThreadState::self();
- self->clearDeathNotification(mHandle, this);
- self->flushCommands();
- delete mObituaries;
- mObituaries = NULL;
- }
- return NO_ERROR;
- }
- }
-
- return NAME_NOT_FOUND;
-}
-
-void BpBinder::sendObituary()
-{
- LOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
- this, mHandle, mObitsSent ? "true" : "false");
-
- mAlive = 0;
- if (mObitsSent) return;
-
- mLock.lock();
- Vector<Obituary>* obits = mObituaries;
- if(obits != NULL) {
- LOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
- IPCThreadState* self = IPCThreadState::self();
- self->clearDeathNotification(mHandle, this);
- self->flushCommands();
- mObituaries = NULL;
- }
- mObitsSent = 1;
- mLock.unlock();
-
- LOGV("Reporting death of proxy %p for %d recipients\n",
- this, obits ? obits->size() : 0);
-
- if (obits != NULL) {
- const size_t N = obits->size();
- for (size_t i=0; i<N; i++) {
- reportOneDeath(obits->itemAt(i));
- }
-
- delete obits;
- }
-}
-
-void BpBinder::reportOneDeath(const Obituary& obit)
-{
- sp<DeathRecipient> recipient = obit.recipient.promote();
- LOGV("Reporting death to recipient: %p\n", recipient.get());
- if (recipient == NULL) return;
-
- recipient->binderDied(this);
-}
-
-
-void BpBinder::attachObject(
- const void* objectID, void* object, void* cleanupCookie,
- object_cleanup_func func)
-{
- AutoMutex _l(mLock);
- LOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
- mObjects.attach(objectID, object, cleanupCookie, func);
-}
-
-void* BpBinder::findObject(const void* objectID) const
-{
- AutoMutex _l(mLock);
- return mObjects.find(objectID);
-}
-
-void BpBinder::detachObject(const void* objectID)
-{
- AutoMutex _l(mLock);
- mObjects.detach(objectID);
-}
-
-BpBinder* BpBinder::remoteBinder()
-{
- return this;
-}
-
-BpBinder::~BpBinder()
-{
- LOGV("Destroying BpBinder %p handle %d\n", this, mHandle);
-
- IPCThreadState* ipc = IPCThreadState::self();
-
- mLock.lock();
- Vector<Obituary>* obits = mObituaries;
- if(obits != NULL) {
- if (ipc) ipc->clearDeathNotification(mHandle, this);
- mObituaries = NULL;
- }
- mLock.unlock();
-
- if (obits != NULL) {
- // XXX Should we tell any remaining DeathRecipient
- // objects that the last strong ref has gone away, so they
- // are no longer linked?
- delete obits;
- }
-
- if (ipc) {
- ipc->expungeHandle(mHandle, this);
- ipc->decWeakHandle(mHandle);
- }
-}
-
-void BpBinder::onFirstRef()
-{
- LOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle);
- IPCThreadState* ipc = IPCThreadState::self();
- if (ipc) ipc->incStrongHandle(mHandle);
-}
-
-void BpBinder::onLastStrongRef(const void* id)
-{
- LOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle);
- IF_LOGV() {
- printRefs();
- }
- IPCThreadState* ipc = IPCThreadState::self();
- if (ipc) ipc->decStrongHandle(mHandle);
-}
-
-bool BpBinder::onIncStrongAttempted(uint32_t flags, const void* id)
-{
- LOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle);
- IPCThreadState* ipc = IPCThreadState::self();
- return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/utils/BufferedTextOutput.cpp b/libs/utils/BufferedTextOutput.cpp
deleted file mode 100644
index 989662e..0000000
--- a/libs/utils/BufferedTextOutput.cpp
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * 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.
- */
-
-#include <utils/BufferedTextOutput.h>
-
-#include <utils/Atomic.h>
-#include <utils/Debug.h>
-#include <utils/Log.h>
-#include <utils/RefBase.h>
-#include <utils/Vector.h>
-#include <cutils/threads.h>
-
-#include <private/utils/Static.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-struct BufferedTextOutput::BufferState : public RefBase
-{
- BufferState(int32_t _seq)
- : seq(_seq)
- , buffer(NULL)
- , bufferPos(0)
- , bufferSize(0)
- , atFront(true)
- , indent(0)
- , bundle(0) {
- }
- ~BufferState() {
- free(buffer);
- }
-
- status_t append(const char* txt, size_t len) {
- if ((len+bufferPos) > bufferSize) {
- void* b = realloc(buffer, ((len+bufferPos)*3)/2);
- if (!b) return NO_MEMORY;
- buffer = (char*)b;
- }
- memcpy(buffer+bufferPos, txt, len);
- bufferPos += len;
- return NO_ERROR;
- }
-
- void restart() {
- bufferPos = 0;
- atFront = true;
- if (bufferSize > 256) {
- void* b = realloc(buffer, 256);
- if (b) {
- buffer = (char*)b;
- bufferSize = 256;
- }
- }
- }
-
- const int32_t seq;
- char* buffer;
- size_t bufferPos;
- size_t bufferSize;
- bool atFront;
- int32_t indent;
- int32_t bundle;
-};
-
-struct BufferedTextOutput::ThreadState
-{
- Vector<sp<BufferedTextOutput::BufferState> > states;
-};
-
-static mutex_t gMutex;
-
-static thread_store_t tls;
-
-BufferedTextOutput::ThreadState* BufferedTextOutput::getThreadState()
-{
- ThreadState* ts = (ThreadState*) thread_store_get( &tls );
- if (ts) return ts;
- ts = new ThreadState;
- thread_store_set( &tls, ts, threadDestructor );
- return ts;
-}
-
-void BufferedTextOutput::threadDestructor(void *st)
-{
- delete ((ThreadState*)st);
-}
-
-static volatile int32_t gSequence = 0;
-
-static volatile int32_t gFreeBufferIndex = -1;
-
-static int32_t allocBufferIndex()
-{
- int32_t res = -1;
-
- mutex_lock(&gMutex);
-
- if (gFreeBufferIndex >= 0) {
- res = gFreeBufferIndex;
- gFreeBufferIndex = gTextBuffers[res];
- gTextBuffers.editItemAt(res) = -1;
-
- } else {
- res = gTextBuffers.size();
- gTextBuffers.add(-1);
- }
-
- mutex_unlock(&gMutex);
-
- return res;
-}
-
-static void freeBufferIndex(int32_t idx)
-{
- mutex_lock(&gMutex);
- gTextBuffers.editItemAt(idx) = gFreeBufferIndex;
- gFreeBufferIndex = idx;
- mutex_unlock(&gMutex);
-}
-
-// ---------------------------------------------------------------------------
-
-BufferedTextOutput::BufferedTextOutput(uint32_t flags)
- : mFlags(flags)
- , mSeq(android_atomic_inc(&gSequence))
- , mIndex(allocBufferIndex())
-{
- mGlobalState = new BufferState(mSeq);
- if (mGlobalState) mGlobalState->incStrong(this);
-}
-
-BufferedTextOutput::~BufferedTextOutput()
-{
- if (mGlobalState) mGlobalState->decStrong(this);
- freeBufferIndex(mIndex);
-}
-
-status_t BufferedTextOutput::print(const char* txt, size_t len)
-{
- //printf("BufferedTextOutput: printing %d\n", len);
-
- AutoMutex _l(mLock);
- BufferState* b = getBuffer();
-
- const char* const end = txt+len;
-
- status_t err;
-
- while (txt < end) {
- // Find the next line.
- const char* first = txt;
- while (txt < end && *txt != '\n') txt++;
-
- // Include this and all following empty lines.
- while (txt < end && *txt == '\n') txt++;
-
- // Special cases for first data on a line.
- if (b->atFront) {
- if (b->indent > 0) {
- // If this is the start of a line, add the indent.
- const char* prefix = stringForIndent(b->indent);
- err = b->append(prefix, strlen(prefix));
- if (err != NO_ERROR) return err;
-
- } else if (*(txt-1) == '\n' && !b->bundle) {
- // Fast path: if we are not indenting or bundling, and
- // have been given one or more complete lines, just write
- // them out without going through the buffer.
-
- // Slurp up all of the lines.
- const char* lastLine = txt+1;
- while (txt < end) {
- if (*txt++ == '\n') lastLine = txt;
- }
- struct iovec vec;
- vec.iov_base = (void*)first;
- vec.iov_len = lastLine-first;
- //printf("Writing %d bytes of data!\n", vec.iov_len);
- writeLines(vec, 1);
- txt = lastLine;
- continue;
- }
- }
-
- // Append the new text to the buffer.
- err = b->append(first, txt-first);
- if (err != NO_ERROR) return err;
- b->atFront = *(txt-1) == '\n';
-
- // If we have finished a line and are not bundling, write
- // it out.
- //printf("Buffer is now %d bytes\n", b->bufferPos);
- if (b->atFront && !b->bundle) {
- struct iovec vec;
- vec.iov_base = b->buffer;
- vec.iov_len = b->bufferPos;
- //printf("Writing %d bytes of data!\n", vec.iov_len);
- writeLines(vec, 1);
- b->restart();
- }
- }
-
- return NO_ERROR;
-}
-
-void BufferedTextOutput::moveIndent(int delta)
-{
- AutoMutex _l(mLock);
- BufferState* b = getBuffer();
- b->indent += delta;
- if (b->indent < 0) b->indent = 0;
-}
-
-void BufferedTextOutput::pushBundle()
-{
- AutoMutex _l(mLock);
- BufferState* b = getBuffer();
- b->bundle++;
-}
-
-void BufferedTextOutput::popBundle()
-{
- AutoMutex _l(mLock);
- BufferState* b = getBuffer();
- b->bundle--;
- LOG_FATAL_IF(b->bundle < 0,
- "TextOutput::popBundle() called more times than pushBundle()");
- if (b->bundle < 0) b->bundle = 0;
-
- if (b->bundle == 0) {
- // Last bundle, write out data if it is complete. If it is not
- // complete, don't write until the last line is done... this may
- // or may not be the write thing to do, but it's the easiest.
- if (b->bufferPos > 0 && b->atFront) {
- struct iovec vec;
- vec.iov_base = b->buffer;
- vec.iov_len = b->bufferPos;
- writeLines(vec, 1);
- b->restart();
- }
- }
-}
-
-BufferedTextOutput::BufferState* BufferedTextOutput::getBuffer() const
-{
- if ((mFlags&MULTITHREADED) != 0) {
- ThreadState* ts = getThreadState();
- if (ts) {
- while (ts->states.size() <= (size_t)mIndex) ts->states.add(NULL);
- BufferState* bs = ts->states[mIndex].get();
- if (bs != NULL && bs->seq == mSeq) return bs;
-
- ts->states.editItemAt(mIndex) = new BufferState(mIndex);
- bs = ts->states[mIndex].get();
- if (bs != NULL) return bs;
- }
- }
-
- return mGlobalState;
-}
-
-}; // namespace android
diff --git a/libs/utils/CallStack.cpp b/libs/utils/CallStack.cpp
deleted file mode 100644
index 26fb22a..0000000
--- a/libs/utils/CallStack.cpp
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "CallStack"
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#if HAVE_DLADDR
-#include <dlfcn.h>
-#endif
-
-#if HAVE_CXXABI
-#include <cxxabi.h>
-#endif
-
-#include <unwind.h>
-
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <utils/CallStack.h>
-#include <utils/threads.h>
-
-
-/*****************************************************************************/
-namespace android {
-
-
-typedef struct {
- size_t count;
- size_t ignore;
- const void** addrs;
-} stack_crawl_state_t;
-
-static
-_Unwind_Reason_Code trace_function(_Unwind_Context *context, void *arg)
-{
- stack_crawl_state_t* state = (stack_crawl_state_t*)arg;
- if (state->count) {
- void* ip = (void*)_Unwind_GetIP(context);
- if (ip) {
- if (state->ignore) {
- state->ignore--;
- } else {
- state->addrs[0] = ip;
- state->addrs++;
- state->count--;
- }
- }
- }
- return _URC_NO_REASON;
-}
-
-static
-int backtrace(const void** addrs, size_t ignore, size_t size)
-{
- stack_crawl_state_t state;
- state.count = size;
- state.ignore = ignore;
- state.addrs = addrs;
- _Unwind_Backtrace(trace_function, (void*)&state);
- return size - state.count;
-}
-
-/*****************************************************************************/
-
-static
-const char *lookup_symbol(const void* addr, void **offset, char* name, size_t bufSize)
-{
-#if HAVE_DLADDR
- Dl_info info;
- if (dladdr(addr, &info)) {
- *offset = info.dli_saddr;
- return info.dli_sname;
- }
-#endif
- return NULL;
-}
-
-static
-int32_t linux_gcc_demangler(const char *mangled_name, char *unmangled_name, size_t buffersize)
-{
- size_t out_len = 0;
-#if HAVE_CXXABI
- int status = 0;
- char *demangled = abi::__cxa_demangle(mangled_name, 0, &out_len, &status);
- if (status == 0) {
- // OK
- if (out_len < buffersize) memcpy(unmangled_name, demangled, out_len);
- else out_len = 0;
- free(demangled);
- } else {
- out_len = 0;
- }
-#endif
- return out_len;
-}
-
-/*****************************************************************************/
-
-class MapInfo {
- struct mapinfo {
- struct mapinfo *next;
- uint64_t start;
- uint64_t end;
- char name[];
- };
-
- const char *map_to_name(uint64_t pc, const char* def) {
- mapinfo* mi = getMapInfoList();
- while(mi) {
- if ((pc >= mi->start) && (pc < mi->end))
- return mi->name;
- mi = mi->next;
- }
- return def;
- }
-
- mapinfo *parse_maps_line(char *line) {
- mapinfo *mi;
- int len = strlen(line);
- if (len < 1) return 0;
- line[--len] = 0;
- if (len < 50) return 0;
- if (line[20] != 'x') return 0;
- mi = (mapinfo*)malloc(sizeof(mapinfo) + (len - 47));
- if (mi == 0) return 0;
- mi->start = strtoull(line, 0, 16);
- mi->end = strtoull(line + 9, 0, 16);
- mi->next = 0;
- strcpy(mi->name, line + 49);
- return mi;
- }
-
- mapinfo* getMapInfoList() {
- Mutex::Autolock _l(mLock);
- if (milist == 0) {
- char data[1024];
- FILE *fp;
- sprintf(data, "/proc/%d/maps", getpid());
- fp = fopen(data, "r");
- if (fp) {
- while(fgets(data, 1024, fp)) {
- mapinfo *mi = parse_maps_line(data);
- if(mi) {
- mi->next = milist;
- milist = mi;
- }
- }
- fclose(fp);
- }
- }
- return milist;
- }
- mapinfo* milist;
- Mutex mLock;
- static MapInfo sMapInfo;
-
-public:
- MapInfo()
- : milist(0) {
- }
-
- ~MapInfo() {
- while (milist) {
- mapinfo *next = milist->next;
- free(milist);
- milist = next;
- }
- }
-
- static const char *mapAddressToName(const void* pc, const char* def) {
- return sMapInfo.map_to_name((uint64_t)pc, def);
- }
-
-};
-
-/*****************************************************************************/
-
-MapInfo MapInfo::sMapInfo;
-
-/*****************************************************************************/
-
-CallStack::CallStack()
- : mCount(0)
-{
-}
-
-CallStack::CallStack(const CallStack& rhs)
- : mCount(rhs.mCount)
-{
- if (mCount) {
- memcpy(mStack, rhs.mStack, mCount*sizeof(void*));
- }
-}
-
-CallStack::~CallStack()
-{
-}
-
-CallStack& CallStack::operator = (const CallStack& rhs)
-{
- mCount = rhs.mCount;
- if (mCount) {
- memcpy(mStack, rhs.mStack, mCount*sizeof(void*));
- }
- return *this;
-}
-
-bool CallStack::operator == (const CallStack& rhs) const {
- if (mCount != rhs.mCount)
- return false;
- return !mCount || (memcmp(mStack, rhs.mStack, mCount*sizeof(void*)) == 0);
-}
-
-bool CallStack::operator != (const CallStack& rhs) const {
- return !operator == (rhs);
-}
-
-bool CallStack::operator < (const CallStack& rhs) const {
- if (mCount != rhs.mCount)
- return mCount < rhs.mCount;
- return memcmp(mStack, rhs.mStack, mCount*sizeof(void*)) < 0;
-}
-
-bool CallStack::operator >= (const CallStack& rhs) const {
- return !operator < (rhs);
-}
-
-bool CallStack::operator > (const CallStack& rhs) const {
- if (mCount != rhs.mCount)
- return mCount > rhs.mCount;
- return memcmp(mStack, rhs.mStack, mCount*sizeof(void*)) > 0;
-}
-
-bool CallStack::operator <= (const CallStack& rhs) const {
- return !operator > (rhs);
-}
-
-const void* CallStack::operator [] (int index) const {
- if (index >= int(mCount))
- return 0;
- return mStack[index];
-}
-
-
-void CallStack::clear()
-{
- mCount = 0;
-}
-
-void CallStack::update(int32_t ignoreDepth, int32_t maxDepth)
-{
- if (maxDepth > MAX_DEPTH)
- maxDepth = MAX_DEPTH;
- mCount = backtrace(mStack, ignoreDepth, maxDepth);
-}
-
-// Return the stack frame name on the designated level
-String8 CallStack::toStringSingleLevel(const char* prefix, int32_t level) const
-{
- String8 res;
- char namebuf[1024];
- char tmp[256];
- char tmp1[32];
- char tmp2[32];
- void *offs;
-
- const void* ip = mStack[level];
- if (!ip) return res;
-
- if (prefix) res.append(prefix);
- snprintf(tmp1, 32, "#%02d ", level);
- res.append(tmp1);
-
- const char* name = lookup_symbol(ip, &offs, namebuf, sizeof(namebuf));
- if (name) {
- if (linux_gcc_demangler(name, tmp, 256) != 0)
- name = tmp;
- snprintf(tmp1, 32, "0x%p: <", ip);
- snprintf(tmp2, 32, ">+0x%p", offs);
- res.append(tmp1);
- res.append(name);
- res.append(tmp2);
- } else {
- name = MapInfo::mapAddressToName(ip, "<unknown>");
- snprintf(tmp, 256, "pc %p %s", ip, name);
- res.append(tmp);
- }
- res.append("\n");
-
- return res;
-}
-
-// Dump a stack trace to the log
-void CallStack::dump(const char* prefix) const
-{
- /*
- * Sending a single long log may be truncated since the stack levels can
- * get very deep. So we request function names of each frame individually.
- */
- for (int i=0; i<int(mCount); i++) {
- LOGD("%s", toStringSingleLevel(prefix, i).string());
- }
-}
-
-// Return a string (possibly very long) containing the complete stack trace
-String8 CallStack::toString(const char* prefix) const
-{
- String8 res;
-
- for (int i=0; i<int(mCount); i++) {
- res.append(toStringSingleLevel(prefix, i).string());
- }
-
- return res;
-}
-
-/*****************************************************************************/
-
-}; // namespace android
diff --git a/libs/utils/Debug.cpp b/libs/utils/Debug.cpp
deleted file mode 100644
index f7988ec..0000000
--- a/libs/utils/Debug.cpp
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * 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.
- */
-
-#include <utils/Debug.h>
-
-#include <utils/misc.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------
-
-static const char indentStr[] =
-" "
-" ";
-
-const char* stringForIndent(int32_t indentLevel)
-{
- ssize_t off = sizeof(indentStr)-1-(indentLevel*2);
- return indentStr + (off < 0 ? 0 : off);
-}
-
-// ---------------------------------------------------------------------
-
-static void defaultPrintFunc(void* cookie, const char* txt)
-{
- printf("%s", txt);
-}
-
-// ---------------------------------------------------------------------
-
-static inline int isident(int c)
-{
- return isalnum(c) || c == '_';
-}
-
-static inline bool isasciitype(char c)
-{
- if( c >= ' ' && c < 127 && c != '\'' && c != '\\' ) return true;
- return false;
-}
-
-static inline char makehexdigit(uint32_t val)
-{
- return "0123456789abcdef"[val&0xF];
-}
-
-static char* appendhexnum(uint32_t val, char* out)
-{
- for( int32_t i=28; i>=0; i-=4 ) {
- *out++ = makehexdigit( val>>i );
- }
- *out = 0;
- return out;
-}
-
-static inline char makeupperhexdigit(uint32_t val)
-{
- return "0123456789ABCDEF"[val&0xF];
-}
-
-static char* appendupperhexnum(uint32_t val, char* out)
-{
- for( int32_t i=28; i>=0; i-=4 ) {
- *out++ = makeupperhexdigit( val>>i );
- }
- *out = 0;
- return out;
-}
-
-static char* appendcharornum(char c, char* out, bool skipzero = true)
-{
- if (skipzero && c == 0) return out;
-
- if (isasciitype(c)) {
- *out++ = c;
- return out;
- }
-
- *out++ = '\\';
- *out++ = 'x';
- *out++ = makehexdigit(c>>4);
- *out++ = makehexdigit(c);
- return out;
-}
-
-static char* typetostring(uint32_t type, char* out,
- bool fullContext = true,
- bool strict = false)
-{
- char* pos = out;
- char c[4];
- c[0] = (char)((type>>24)&0xFF);
- c[1] = (char)((type>>16)&0xFF);
- c[2] = (char)((type>>8)&0xFF);
- c[3] = (char)(type&0xFF);
- bool valid;
- if( !strict ) {
- // now even less strict!
- // valid = isasciitype(c[3]);
- valid = true;
- int32_t i = 0;
- bool zero = true;
- while (valid && i<3) {
- if (c[i] == 0) {
- if (!zero) valid = false;
- } else {
- zero = false;
- //if (!isasciitype(c[i])) valid = false;
- }
- i++;
- }
- // if all zeros, not a valid type code.
- if (zero) valid = false;
- } else {
- valid = isident(c[3]) ? true : false;
- int32_t i = 0;
- bool zero = true;
- while (valid && i<3) {
- if (c[i] == 0) {
- if (!zero) valid = false;
- } else {
- zero = false;
- if (!isident(c[i])) valid = false;
- }
- i++;
- }
- }
- if( valid && (!fullContext || c[0] != '0' || c[1] != 'x') ) {
- if( fullContext ) *pos++ = '\'';
- pos = appendcharornum(c[0], pos);
- pos = appendcharornum(c[1], pos);
- pos = appendcharornum(c[2], pos);
- pos = appendcharornum(c[3], pos);
- if( fullContext ) *pos++ = '\'';
- *pos = 0;
- return pos;
- }
-
- if( fullContext ) {
- *pos++ = '0';
- *pos++ = 'x';
- }
- return appendhexnum(type, pos);
-}
-
-void printTypeCode(uint32_t typeCode, debugPrintFunc func, void* cookie)
-{
- char buffer[32];
- char* end = typetostring(typeCode, buffer);
- *end = 0;
- func ? (*func)(cookie, buffer) : defaultPrintFunc(cookie, buffer);
-}
-
-void printHexData(int32_t indent, const void *buf, size_t length,
- size_t bytesPerLine, int32_t singleLineBytesCutoff,
- size_t alignment, bool cStyle,
- debugPrintFunc func, void* cookie)
-{
- if (alignment == 0) {
- if (bytesPerLine >= 16) alignment = 4;
- else if (bytesPerLine >= 8) alignment = 2;
- else alignment = 1;
- }
- if (func == NULL) func = defaultPrintFunc;
-
- size_t offset;
-
- unsigned char *pos = (unsigned char *)buf;
-
- if (pos == NULL) {
- if (singleLineBytesCutoff < 0) func(cookie, "\n");
- func(cookie, "(NULL)");
- return;
- }
-
- if (length == 0) {
- if (singleLineBytesCutoff < 0) func(cookie, "\n");
- func(cookie, "(empty)");
- return;
- }
-
- if ((int32_t)length < 0) {
- if (singleLineBytesCutoff < 0) func(cookie, "\n");
- char buf[64];
- sprintf(buf, "(bad length: %d)", length);
- func(cookie, buf);
- return;
- }
-
- char buffer[256];
- static const size_t maxBytesPerLine = (sizeof(buffer)-1-11-4)/(3+1);
-
- if (bytesPerLine > maxBytesPerLine) bytesPerLine = maxBytesPerLine;
-
- const bool oneLine = (int32_t)length <= singleLineBytesCutoff;
- bool newLine = false;
- if (cStyle) {
- indent++;
- func(cookie, "{\n");
- newLine = true;
- } else if (!oneLine) {
- func(cookie, "\n");
- newLine = true;
- }
-
- for (offset = 0; ; offset += bytesPerLine, pos += bytesPerLine) {
- long remain = length;
-
- char* c = buffer;
- if (!oneLine && !cStyle) {
- sprintf(c, "0x%08x: ", (int)offset);
- c += 12;
- }
-
- size_t index;
- size_t word;
-
- for (word = 0; word < bytesPerLine; ) {
-
-#ifdef HAVE_LITTLE_ENDIAN
- const size_t startIndex = word+(alignment-(alignment?1:0));
- const ssize_t dir = -1;
-#else
- const size_t startIndex = word;
- const ssize_t dir = 1;
-#endif
-
- for (index = 0; index < alignment || (alignment == 0 && index < bytesPerLine); index++) {
-
- if (!cStyle) {
- if (index == 0 && word > 0 && alignment > 0) {
- *c++ = ' ';
- }
-
- if (remain-- > 0) {
- const unsigned char val = *(pos+startIndex+(index*dir));
- *c++ = makehexdigit(val>>4);
- *c++ = makehexdigit(val);
- } else if (!oneLine) {
- *c++ = ' ';
- *c++ = ' ';
- }
- } else {
- if (remain > 0) {
- if (index == 0 && word > 0) {
- *c++ = ',';
- *c++ = ' ';
- }
- if (index == 0) {
- *c++ = '0';
- *c++ = 'x';
- }
- const unsigned char val = *(pos+startIndex+(index*dir));
- *c++ = makehexdigit(val>>4);
- *c++ = makehexdigit(val);
- remain--;
- }
- }
- }
-
- word += index;
- }
-
- if (!cStyle) {
- remain = length;
- *c++ = ' ';
- *c++ = '\'';
- for (index = 0; index < bytesPerLine; index++) {
-
- if (remain-- > 0) {
- const unsigned char val = pos[index];
- *c++ = (val >= ' ' && val < 127) ? val : '.';
- } else if (!oneLine) {
- *c++ = ' ';
- }
- }
-
- *c++ = '\'';
- if (length > bytesPerLine) *c++ = '\n';
- } else {
- if (remain > 0) *c++ = ',';
- *c++ = '\n';
- }
-
- if (newLine && indent) func(cookie, stringForIndent(indent));
- *c = 0;
- func(cookie, buffer);
- newLine = true;
-
- if (length <= bytesPerLine) break;
- length -= bytesPerLine;
- }
-
- if (cStyle) {
- if (indent > 0) func(cookie, stringForIndent(indent-1));
- func(cookie, "};");
- }
-}
-
-}; // namespace android
-
diff --git a/libs/utils/FileMap.cpp b/libs/utils/FileMap.cpp
deleted file mode 100644
index e1ba9b2..0000000
--- a/libs/utils/FileMap.cpp
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Shared file mapping class.
-//
-
-#define LOG_TAG "filemap"
-
-#include <utils/FileMap.h>
-#include <utils/Log.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#ifdef HAVE_POSIX_FILEMAP
-#include <sys/mman.h>
-#endif
-
-#include <string.h>
-#include <memory.h>
-#include <errno.h>
-#include <assert.h>
-
-using namespace android;
-
-/*static*/ long FileMap::mPageSize = -1;
-
-
-/*
- * Constructor. Create an empty object.
- */
-FileMap::FileMap(void)
- : mRefCount(1), mFileName(NULL), mBasePtr(NULL), mBaseLength(0),
- mDataPtr(NULL), mDataLength(0)
-{
-}
-
-/*
- * Destructor.
- */
-FileMap::~FileMap(void)
-{
- assert(mRefCount == 0);
-
- //printf("+++ removing FileMap %p %u\n", mDataPtr, mDataLength);
-
- mRefCount = -100; // help catch double-free
- if (mFileName != NULL) {
- free(mFileName);
- }
-#ifdef HAVE_POSIX_FILEMAP
- if (munmap(mBasePtr, mBaseLength) != 0) {
- LOGD("munmap(%p, %d) failed\n", mBasePtr, (int) mBaseLength);
- }
-#endif
-#ifdef HAVE_WIN32_FILEMAP
- if ( UnmapViewOfFile(mBasePtr) == 0) {
- LOGD("UnmapViewOfFile(%p) failed, error = %ld\n", mBasePtr,
- GetLastError() );
- }
- CloseHandle(mFileMapping);
- CloseHandle(mFileHandle);
-#endif
-}
-
-
-/*
- * 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 FileMap::create(const char* origFileName, int fd, off_t offset, size_t length, bool readOnly)
-{
-#ifdef HAVE_WIN32_FILEMAP
- int adjust;
- off_t adjOffset;
- size_t adjLength;
-
- if (mPageSize == -1) {
- SYSTEM_INFO si;
-
- GetSystemInfo( &si );
- mPageSize = si.dwAllocationGranularity;
- }
-
- DWORD protect = readOnly ? PAGE_READONLY : PAGE_READWRITE;
-
- mFileHandle = (HANDLE) _get_osfhandle(fd);
- mFileMapping = CreateFileMapping( mFileHandle, NULL, protect, 0, 0, NULL);
- if (mFileMapping == NULL) {
- LOGE("CreateFileMapping(%p, %lx) failed with error %ld\n",
- mFileHandle, protect, GetLastError() );
- return false;
- }
-
- adjust = offset % mPageSize;
- adjOffset = offset - adjust;
- adjLength = length + adjust;
-
- mBasePtr = MapViewOfFile( mFileMapping,
- readOnly ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS,
- 0,
- (DWORD)(adjOffset),
- adjLength );
- if (mBasePtr == NULL) {
- LOGE("MapViewOfFile(%ld, %ld) failed with error %ld\n",
- adjOffset, adjLength, GetLastError() );
- CloseHandle(mFileMapping);
- mFileMapping = INVALID_HANDLE_VALUE;
- return false;
- }
-#endif
-#ifdef HAVE_POSIX_FILEMAP
- int prot, flags, adjust;
- off_t adjOffset;
- size_t adjLength;
-
- void* ptr;
-
- assert(mRefCount == 1);
- assert(fd >= 0);
- assert(offset >= 0);
- assert(length > 0);
-
- /* init on first use */
- if (mPageSize == -1) {
-#if NOT_USING_KLIBC
- mPageSize = sysconf(_SC_PAGESIZE);
- if (mPageSize == -1) {
- LOGE("could not get _SC_PAGESIZE\n");
- return false;
- }
-#else
- /* this holds for Linux, Darwin, Cygwin, and doesn't pain the ARM */
- mPageSize = 4096;
-#endif
- }
-
- adjust = offset % mPageSize;
-try_again:
- adjOffset = offset - adjust;
- adjLength = length + adjust;
-
- flags = MAP_SHARED;
- prot = PROT_READ;
- if (!readOnly)
- prot |= PROT_WRITE;
-
- ptr = mmap(NULL, adjLength, prot, flags, fd, adjOffset);
- if (ptr == MAP_FAILED) {
- // Cygwin does not seem to like file mapping files from an offset.
- // So if we fail, try again with offset zero
- if (adjOffset > 0) {
- adjust = offset;
- goto try_again;
- }
-
- LOGE("mmap(%ld,%ld) failed: %s\n",
- (long) adjOffset, (long) adjLength, strerror(errno));
- return false;
- }
- mBasePtr = ptr;
-#endif /* HAVE_POSIX_FILEMAP */
-
- mFileName = origFileName != NULL ? strdup(origFileName) : NULL;
- mBaseLength = adjLength;
- mDataOffset = offset;
- mDataPtr = (char*) mBasePtr + adjust;
- mDataLength = length;
-
- assert(mBasePtr != NULL);
-
- LOGV("MAP: base %p/%d data %p/%d\n",
- mBasePtr, (int) mBaseLength, mDataPtr, (int) mDataLength);
-
- return true;
-}
-
-/*
- * Provide guidance to the system.
- */
-int FileMap::advise(MapAdvice advice)
-{
-#if HAVE_MADVISE
- int cc, sysAdvice;
-
- switch (advice) {
- case NORMAL: sysAdvice = MADV_NORMAL; break;
- case RANDOM: sysAdvice = MADV_RANDOM; break;
- case SEQUENTIAL: sysAdvice = MADV_SEQUENTIAL; break;
- case WILLNEED: sysAdvice = MADV_WILLNEED; break;
- case DONTNEED: sysAdvice = MADV_DONTNEED; break;
- default:
- assert(false);
- return -1;
- }
-
- cc = madvise(mBasePtr, mBaseLength, sysAdvice);
- if (cc != 0)
- LOGW("madvise(%d) failed: %s\n", sysAdvice, strerror(errno));
- return cc;
-#else
- return -1;
-#endif // HAVE_MADVISE
-}
diff --git a/libs/utils/IDataConnection.cpp b/libs/utils/IDataConnection.cpp
deleted file mode 100644
index c6d49aa..0000000
--- a/libs/utils/IDataConnection.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.
- */
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Parcel.h>
-
-#include <utils/IDataConnection.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-enum
-{
- CONNECT_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
- DISCONNECT_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 1
-};
-
-class BpDataConnection : public BpInterface<IDataConnection>
-{
-public:
- BpDataConnection::BpDataConnection(const sp<IBinder>& impl)
- : BpInterface<IDataConnection>(impl)
- {
- }
-
- virtual void connect()
- {
- Parcel data, reply;
- data.writeInterfaceToken(IDataConnection::descriptor());
- remote()->transact(CONNECT_TRANSACTION, data, &reply);
- }
-
- virtual void disconnect()
- {
- Parcel data, reply;
- remote()->transact(DISCONNECT_TRANSACTION, data, &reply);
- }
-};
-
-IMPLEMENT_META_INTERFACE(DataConnection, "android.utils.IDataConnection");
-
-#define CHECK_INTERFACE(interface, data, reply) \
- do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
- LOGW("Call incorrectly routed to " #interface); \
- return PERMISSION_DENIED; \
- } } while (0)
-
-status_t BnDataConnection::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code)
- {
- case CONNECT_TRANSACTION:
- {
- CHECK_INTERFACE(IDataConnection, data, reply);
- connect();
- return NO_ERROR;
- }
-
- case DISCONNECT_TRANSACTION:
- {
- CHECK_INTERFACE(IDataConnection, data, reply);
- disconnect();
- return NO_ERROR;
- }
-
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/utils/IInterface.cpp b/libs/utils/IInterface.cpp
deleted file mode 100644
index 6ea8178..0000000
--- a/libs/utils/IInterface.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.
- */
-
-#include <utils/IInterface.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-sp<IBinder> IInterface::asBinder()
-{
- return this ? onAsBinder() : NULL;
-}
-
-sp<const IBinder> IInterface::asBinder() const
-{
- return this ? const_cast<IInterface*>(this)->onAsBinder() : NULL;
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/utils/IMemory.cpp b/libs/utils/IMemory.cpp
deleted file mode 100644
index 429bc2b..0000000
--- a/libs/utils/IMemory.cpp
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "IMemory"
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <sys/types.h>
-#include <sys/mman.h>
-
-#include <utils/IMemory.h>
-#include <utils/KeyedVector.h>
-#include <utils/threads.h>
-#include <utils/Atomic.h>
-#include <utils/Parcel.h>
-#include <utils/CallStack.h>
-
-#define VERBOSE 0
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-class HeapCache : public IBinder::DeathRecipient
-{
-public:
- HeapCache();
- virtual ~HeapCache();
-
- virtual void binderDied(const wp<IBinder>& who);
-
- sp<IMemoryHeap> find_heap(const sp<IBinder>& binder);
- void pin_heap(const sp<IBinder>& binder);
- void free_heap(const sp<IBinder>& binder);
- sp<IMemoryHeap> get_heap(const sp<IBinder>& binder);
- void dump_heaps();
-
-private:
- // For IMemory.cpp
- struct heap_info_t {
- sp<IMemoryHeap> heap;
- int32_t count;
- };
-
- void free_heap(const wp<IBinder>& binder);
-
- Mutex mHeapCacheLock;
- KeyedVector< wp<IBinder>, heap_info_t > mHeapCache;
-};
-
-static sp<HeapCache> gHeapCache = new HeapCache();
-
-/******************************************************************************/
-
-enum {
- HEAP_ID = IBinder::FIRST_CALL_TRANSACTION
-};
-
-class BpMemoryHeap : public BpInterface<IMemoryHeap>
-{
-public:
- BpMemoryHeap(const sp<IBinder>& impl);
- virtual ~BpMemoryHeap();
-
- virtual int getHeapID() const;
- virtual void* getBase() const;
- virtual size_t getSize() const;
- virtual uint32_t getFlags() const;
-
-private:
- friend class IMemory;
- friend class HeapCache;
-
- // for debugging in this module
- static inline sp<IMemoryHeap> find_heap(const sp<IBinder>& binder) {
- return gHeapCache->find_heap(binder);
- }
- static inline void free_heap(const sp<IBinder>& binder) {
- gHeapCache->free_heap(binder);
- }
- static inline sp<IMemoryHeap> get_heap(const sp<IBinder>& binder) {
- return gHeapCache->get_heap(binder);
- }
- static inline void dump_heaps() {
- gHeapCache->dump_heaps();
- }
- void inline pin_heap() const {
- gHeapCache->pin_heap(const_cast<BpMemoryHeap*>(this)->asBinder());
- }
-
- void assertMapped() const;
- void assertReallyMapped() const;
- void pinHeap() const;
-
- mutable volatile int32_t mHeapId;
- mutable void* mBase;
- mutable size_t mSize;
- mutable uint32_t mFlags;
- mutable bool mRealHeap;
- mutable Mutex mLock;
-};
-
-// ----------------------------------------------------------------------------
-
-enum {
- GET_MEMORY = IBinder::FIRST_CALL_TRANSACTION
-};
-
-class BpMemory : public BpInterface<IMemory>
-{
-public:
- BpMemory(const sp<IBinder>& impl);
- virtual ~BpMemory();
- virtual sp<IMemoryHeap> getMemory(ssize_t* offset=0, size_t* size=0) const;
-
-private:
- mutable sp<IMemoryHeap> mHeap;
- mutable ssize_t mOffset;
- mutable size_t mSize;
-};
-
-/******************************************************************************/
-
-void* IMemory::fastPointer(const sp<IBinder>& binder, ssize_t offset) const
-{
- sp<IMemoryHeap> realHeap = BpMemoryHeap::get_heap(binder);
- void* const base = realHeap->base();
- if (base == MAP_FAILED)
- return 0;
- return static_cast<char*>(base) + offset;
-}
-
-void* IMemory::pointer() const {
- ssize_t offset;
- sp<IMemoryHeap> heap = getMemory(&offset);
- void* const base = heap!=0 ? heap->base() : MAP_FAILED;
- if (base == MAP_FAILED)
- return 0;
- return static_cast<char*>(base) + offset;
-}
-
-size_t IMemory::size() const {
- size_t size;
- getMemory(NULL, &size);
- return size;
-}
-
-ssize_t IMemory::offset() const {
- ssize_t offset;
- getMemory(&offset);
- return offset;
-}
-
-/******************************************************************************/
-
-BpMemory::BpMemory(const sp<IBinder>& impl)
- : BpInterface<IMemory>(impl), mOffset(0), mSize(0)
-{
-}
-
-BpMemory::~BpMemory()
-{
-}
-
-sp<IMemoryHeap> BpMemory::getMemory(ssize_t* offset, size_t* size) const
-{
- if (mHeap == 0) {
- Parcel data, reply;
- data.writeInterfaceToken(IMemory::getInterfaceDescriptor());
- if (remote()->transact(GET_MEMORY, data, &reply) == NO_ERROR) {
- sp<IBinder> heap = reply.readStrongBinder();
- ssize_t o = reply.readInt32();
- size_t s = reply.readInt32();
- if (heap != 0) {
- mHeap = interface_cast<IMemoryHeap>(heap);
- if (mHeap != 0) {
- mOffset = o;
- mSize = s;
- }
- }
- }
- }
- if (offset) *offset = mOffset;
- if (size) *size = mSize;
- return mHeap;
-}
-
-// ---------------------------------------------------------------------------
-
-IMPLEMENT_META_INTERFACE(Memory, "android.utils.IMemory");
-
-#define CHECK_INTERFACE(interface, data, reply) \
- do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
- LOGW("Call incorrectly routed to " #interface); \
- return PERMISSION_DENIED; \
- } } while (0)
-
-status_t BnMemory::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case GET_MEMORY: {
- CHECK_INTERFACE(IMemory, data, reply);
- ssize_t offset;
- size_t size;
- reply->writeStrongBinder( getMemory(&offset, &size)->asBinder() );
- reply->writeInt32(offset);
- reply->writeInt32(size);
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-
-/******************************************************************************/
-
-BpMemoryHeap::BpMemoryHeap(const sp<IBinder>& impl)
- : BpInterface<IMemoryHeap>(impl),
- mHeapId(-1), mBase(MAP_FAILED), mSize(0), mFlags(0), mRealHeap(false)
-{
-}
-
-BpMemoryHeap::~BpMemoryHeap() {
- if (mHeapId != -1) {
- close(mHeapId);
- if (mRealHeap) {
- // by construction we're the last one
- if (mBase != MAP_FAILED) {
- sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder();
-
- if (VERBOSE) {
- LOGD("UNMAPPING binder=%p, heap=%p, size=%d, fd=%d",
- binder.get(), this, mSize, mHeapId);
- CallStack stack;
- stack.update();
- stack.dump("callstack");
- }
-
- munmap(mBase, mSize);
- }
- } else {
- // remove from list only if it was mapped before
- sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder();
- free_heap(binder);
- }
- }
-}
-
-void BpMemoryHeap::assertMapped() const
-{
- if (mHeapId == -1) {
- sp<IBinder> binder(const_cast<BpMemoryHeap*>(this)->asBinder());
- sp<BpMemoryHeap> heap(static_cast<BpMemoryHeap*>(find_heap(binder).get()));
- heap->assertReallyMapped();
- if (heap->mBase != MAP_FAILED) {
- Mutex::Autolock _l(mLock);
- if (mHeapId == -1) {
- mBase = heap->mBase;
- mSize = heap->mSize;
- android_atomic_write( dup( heap->mHeapId ), &mHeapId );
- }
- } else {
- // something went wrong
- free_heap(binder);
- }
- }
-}
-
-void BpMemoryHeap::assertReallyMapped() const
-{
- if (mHeapId == -1) {
-
- // remote call without mLock held, worse case scenario, we end up
- // calling transact() from multiple threads, but that's not a problem,
- // only mmap below must be in the critical section.
-
- Parcel data, reply;
- data.writeInterfaceToken(IMemoryHeap::getInterfaceDescriptor());
- status_t err = remote()->transact(HEAP_ID, data, &reply);
- int parcel_fd = reply.readFileDescriptor();
- ssize_t size = reply.readInt32();
- uint32_t flags = reply.readInt32();
-
- LOGE_IF(err, "binder=%p transaction failed fd=%d, size=%d, err=%d (%s)",
- asBinder().get(), parcel_fd, size, err, strerror(-err));
-
- int fd = dup( parcel_fd );
- LOGE_IF(fd==-1, "cannot dup fd=%d, size=%d, err=%d (%s)",
- parcel_fd, size, err, strerror(errno));
-
- int access = PROT_READ;
- if (!(flags & READ_ONLY)) {
- access |= PROT_WRITE;
- }
-
- Mutex::Autolock _l(mLock);
- if (mHeapId == -1) {
- mRealHeap = true;
- mBase = mmap(0, size, access, MAP_SHARED, fd, 0);
- if (mBase == MAP_FAILED) {
- LOGE("cannot map BpMemoryHeap (binder=%p), size=%d, fd=%d (%s)",
- asBinder().get(), size, fd, strerror(errno));
- close(fd);
- } else {
- if (flags & MAP_ONCE) {
- //LOGD("pinning heap (binder=%p, size=%d, fd=%d",
- // asBinder().get(), size, fd);
- pin_heap();
- }
- mSize = size;
- mFlags = flags;
- android_atomic_write(fd, &mHeapId);
- }
- }
- }
-}
-
-int BpMemoryHeap::getHeapID() const {
- assertMapped();
- return mHeapId;
-}
-
-void* BpMemoryHeap::getBase() const {
- assertMapped();
- return mBase;
-}
-
-size_t BpMemoryHeap::getSize() const {
- assertMapped();
- return mSize;
-}
-
-uint32_t BpMemoryHeap::getFlags() const {
- assertMapped();
- return mFlags;
-}
-
-// ---------------------------------------------------------------------------
-
-IMPLEMENT_META_INTERFACE(MemoryHeap, "android.utils.IMemoryHeap");
-
-status_t BnMemoryHeap::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case HEAP_ID: {
- CHECK_INTERFACE(IMemoryHeap, data, reply);
- reply->writeFileDescriptor(getHeapID());
- reply->writeInt32(getSize());
- reply->writeInt32(getFlags());
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-/*****************************************************************************/
-
-HeapCache::HeapCache()
- : DeathRecipient()
-{
-}
-
-HeapCache::~HeapCache()
-{
-}
-
-void HeapCache::binderDied(const wp<IBinder>& binder)
-{
- //LOGD("binderDied binder=%p", binder.unsafe_get());
- free_heap(binder);
-}
-
-sp<IMemoryHeap> HeapCache::find_heap(const sp<IBinder>& binder)
-{
- Mutex::Autolock _l(mHeapCacheLock);
- ssize_t i = mHeapCache.indexOfKey(binder);
- if (i>=0) {
- heap_info_t& info = mHeapCache.editValueAt(i);
- LOGD_IF(VERBOSE,
- "found binder=%p, heap=%p, size=%d, fd=%d, count=%d",
- binder.get(), info.heap.get(),
- static_cast<BpMemoryHeap*>(info.heap.get())->mSize,
- static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId,
- info.count);
- android_atomic_inc(&info.count);
- return info.heap;
- } else {
- heap_info_t info;
- info.heap = interface_cast<IMemoryHeap>(binder);
- info.count = 1;
- //LOGD("adding binder=%p, heap=%p, count=%d",
- // binder.get(), info.heap.get(), info.count);
- mHeapCache.add(binder, info);
- return info.heap;
- }
-}
-
-void HeapCache::pin_heap(const sp<IBinder>& binder)
-{
- Mutex::Autolock _l(mHeapCacheLock);
- ssize_t i = mHeapCache.indexOfKey(binder);
- if (i>=0) {
- heap_info_t& info(mHeapCache.editValueAt(i));
- android_atomic_inc(&info.count);
- binder->linkToDeath(this);
- } else {
- LOGE("pin_heap binder=%p not found!!!", binder.get());
- }
-}
-
-void HeapCache::free_heap(const sp<IBinder>& binder) {
- free_heap( wp<IBinder>(binder) );
-}
-
-void HeapCache::free_heap(const wp<IBinder>& binder)
-{
- sp<IMemoryHeap> rel;
- {
- Mutex::Autolock _l(mHeapCacheLock);
- ssize_t i = mHeapCache.indexOfKey(binder);
- if (i>=0) {
- heap_info_t& info(mHeapCache.editValueAt(i));
- int32_t c = android_atomic_dec(&info.count);
- if (c == 1) {
- LOGD_IF(VERBOSE,
- "removing binder=%p, heap=%p, size=%d, fd=%d, count=%d",
- binder.unsafe_get(), info.heap.get(),
- static_cast<BpMemoryHeap*>(info.heap.get())->mSize,
- static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId,
- info.count);
- rel = mHeapCache.valueAt(i).heap;
- mHeapCache.removeItemsAt(i);
- }
- } else {
- LOGE("free_heap binder=%p not found!!!", binder.unsafe_get());
- }
- }
-}
-
-sp<IMemoryHeap> HeapCache::get_heap(const sp<IBinder>& binder)
-{
- sp<IMemoryHeap> realHeap;
- Mutex::Autolock _l(mHeapCacheLock);
- ssize_t i = mHeapCache.indexOfKey(binder);
- if (i>=0) realHeap = mHeapCache.valueAt(i).heap;
- else realHeap = interface_cast<IMemoryHeap>(binder);
- return realHeap;
-}
-
-void HeapCache::dump_heaps()
-{
- Mutex::Autolock _l(mHeapCacheLock);
- int c = mHeapCache.size();
- for (int i=0 ; i<c ; i++) {
- const heap_info_t& info = mHeapCache.valueAt(i);
- BpMemoryHeap const* h(static_cast<BpMemoryHeap const *>(info.heap.get()));
- LOGD("hey=%p, heap=%p, count=%d, (fd=%d, base=%p, size=%d)",
- mHeapCache.keyAt(i).unsafe_get(),
- info.heap.get(), info.count,
- h->mHeapId, h->mBase, h->mSize);
- }
-}
-
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/utils/IPCThreadState.cpp b/libs/utils/IPCThreadState.cpp
deleted file mode 100644
index 04ae142..0000000
--- a/libs/utils/IPCThreadState.cpp
+++ /dev/null
@@ -1,1030 +0,0 @@
-/*
- * 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.
- */
-
-#include <utils/IPCThreadState.h>
-
-#include <utils/Binder.h>
-#include <utils/BpBinder.h>
-#include <utils/Debug.h>
-#include <utils/Log.h>
-#include <utils/TextOutput.h>
-#include <utils/threads.h>
-
-#include <private/utils/binder_module.h>
-#include <private/utils/Static.h>
-
-#include <sys/ioctl.h>
-#include <signal.h>
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#ifdef HAVE_PTHREADS
-#include <pthread.h>
-#include <sched.h>
-#include <sys/resource.h>
-#endif
-#ifdef HAVE_WIN32_THREADS
-#include <windows.h>
-#endif
-
-
-#if LOG_NDEBUG
-
-#define IF_LOG_TRANSACTIONS() if (false)
-#define IF_LOG_COMMANDS() if (false)
-#define LOG_REMOTEREFS(...)
-#define IF_LOG_REMOTEREFS() if (false)
-#define LOG_THREADPOOL(...)
-#define LOG_ONEWAY(...)
-
-#else
-
-#define IF_LOG_TRANSACTIONS() IF_LOG(LOG_VERBOSE, "transact")
-#define IF_LOG_COMMANDS() IF_LOG(LOG_VERBOSE, "ipc")
-#define LOG_REMOTEREFS(...) LOG(LOG_DEBUG, "remoterefs", __VA_ARGS__)
-#define IF_LOG_REMOTEREFS() IF_LOG(LOG_DEBUG, "remoterefs")
-#define LOG_THREADPOOL(...) LOG(LOG_DEBUG, "threadpool", __VA_ARGS__)
-#define LOG_ONEWAY(...) LOG(LOG_DEBUG, "ipc", __VA_ARGS__)
-
-#endif
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-static const char* getReturnString(size_t idx);
-static const char* getCommandString(size_t idx);
-static const void* printReturnCommand(TextOutput& out, const void* _cmd);
-static const void* printCommand(TextOutput& out, const void* _cmd);
-
-// This will result in a missing symbol failure if the IF_LOG_COMMANDS()
-// conditionals don't get stripped... but that is probably what we want.
-#if !LOG_NDEBUG
-static const char *kReturnStrings[] = {
-#if 1 /* TODO: error update strings */
- "unknown",
-#else
- "BR_OK",
- "BR_TIMEOUT",
- "BR_WAKEUP",
- "BR_TRANSACTION",
- "BR_REPLY",
- "BR_ACQUIRE_RESULT",
- "BR_DEAD_REPLY",
- "BR_TRANSACTION_COMPLETE",
- "BR_INCREFS",
- "BR_ACQUIRE",
- "BR_RELEASE",
- "BR_DECREFS",
- "BR_ATTEMPT_ACQUIRE",
- "BR_EVENT_OCCURRED",
- "BR_NOOP",
- "BR_SPAWN_LOOPER",
- "BR_FINISHED",
- "BR_DEAD_BINDER",
- "BR_CLEAR_DEATH_NOTIFICATION_DONE"
-#endif
-};
-
-static const char *kCommandStrings[] = {
-#if 1 /* TODO: error update strings */
- "unknown",
-#else
- "BC_NOOP",
- "BC_TRANSACTION",
- "BC_REPLY",
- "BC_ACQUIRE_RESULT",
- "BC_FREE_BUFFER",
- "BC_TRANSACTION_COMPLETE",
- "BC_INCREFS",
- "BC_ACQUIRE",
- "BC_RELEASE",
- "BC_DECREFS",
- "BC_INCREFS_DONE",
- "BC_ACQUIRE_DONE",
- "BC_ATTEMPT_ACQUIRE",
- "BC_RETRIEVE_ROOT_OBJECT",
- "BC_SET_THREAD_ENTRY",
- "BC_REGISTER_LOOPER",
- "BC_ENTER_LOOPER",
- "BC_EXIT_LOOPER",
- "BC_SYNC",
- "BC_STOP_PROCESS",
- "BC_STOP_SELF",
- "BC_REQUEST_DEATH_NOTIFICATION",
- "BC_CLEAR_DEATH_NOTIFICATION",
- "BC_DEAD_BINDER_DONE"
-#endif
-};
-
-static const char* getReturnString(size_t idx)
-{
- if (idx < sizeof(kReturnStrings) / sizeof(kReturnStrings[0]))
- return kReturnStrings[idx];
- else
- return "unknown";
-}
-
-static const char* getCommandString(size_t idx)
-{
- if (idx < sizeof(kCommandStrings) / sizeof(kCommandStrings[0]))
- return kCommandStrings[idx];
- else
- return "unknown";
-}
-
-static const void* printBinderTransactionData(TextOutput& out, const void* data)
-{
- const binder_transaction_data* btd =
- (const binder_transaction_data*)data;
- out << "target=" << btd->target.ptr << " (cookie " << btd->cookie << ")" << endl
- << "code=" << TypeCode(btd->code) << ", flags=" << (void*)btd->flags << endl
- << "data=" << btd->data.ptr.buffer << " (" << (void*)btd->data_size
- << " bytes)" << endl
- << "offsets=" << btd->data.ptr.offsets << " (" << (void*)btd->offsets_size
- << " bytes)" << endl;
- return btd+1;
-}
-
-static const void* printReturnCommand(TextOutput& out, const void* _cmd)
-{
- static const int32_t N = sizeof(kReturnStrings)/sizeof(kReturnStrings[0]);
-
- const int32_t* cmd = (const int32_t*)_cmd;
- int32_t code = *cmd++;
- if (code == BR_ERROR) {
- out << "BR_ERROR: " << (void*)(*cmd++) << endl;
- return cmd;
- } else if (code < 0 || code >= N) {
- out << "Unknown reply: " << code << endl;
- return cmd;
- }
-
- out << kReturnStrings[code];
- switch (code) {
- case BR_TRANSACTION:
- case BR_REPLY: {
- out << ": " << indent;
- cmd = (const int32_t *)printBinderTransactionData(out, cmd);
- out << dedent;
- } break;
-
- case BR_ACQUIRE_RESULT: {
- const int32_t res = *cmd++;
- out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
- } break;
-
- case BR_INCREFS:
- case BR_ACQUIRE:
- case BR_RELEASE:
- case BR_DECREFS: {
- const int32_t b = *cmd++;
- const int32_t c = *cmd++;
- out << ": target=" << (void*)b << " (cookie " << (void*)c << ")";
- } break;
-
- case BR_ATTEMPT_ACQUIRE: {
- const int32_t p = *cmd++;
- const int32_t b = *cmd++;
- const int32_t c = *cmd++;
- out << ": target=" << (void*)b << " (cookie " << (void*)c
- << "), pri=" << p;
- } break;
-
- case BR_DEAD_BINDER:
- case BR_CLEAR_DEATH_NOTIFICATION_DONE: {
- const int32_t c = *cmd++;
- out << ": death cookie " << (void*)c;
- } break;
- }
-
- out << endl;
- return cmd;
-}
-
-static const void* printCommand(TextOutput& out, const void* _cmd)
-{
- static const int32_t N = sizeof(kCommandStrings)/sizeof(kCommandStrings[0]);
-
- const int32_t* cmd = (const int32_t*)_cmd;
- int32_t code = *cmd++;
- if (code < 0 || code >= N) {
- out << "Unknown command: " << code << endl;
- return cmd;
- }
-
- out << kCommandStrings[code];
- switch (code) {
- case BC_TRANSACTION:
- case BC_REPLY: {
- out << ": " << indent;
- cmd = (const int32_t *)printBinderTransactionData(out, cmd);
- out << dedent;
- } break;
-
- case BC_ACQUIRE_RESULT: {
- const int32_t res = *cmd++;
- out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
- } break;
-
- case BC_FREE_BUFFER: {
- const int32_t buf = *cmd++;
- out << ": buffer=" << (void*)buf;
- } break;
-
- case BC_INCREFS:
- case BC_ACQUIRE:
- case BC_RELEASE:
- case BC_DECREFS: {
- const int32_t d = *cmd++;
- out << ": descriptor=" << (void*)d;
- } break;
-
- case BC_INCREFS_DONE:
- case BC_ACQUIRE_DONE: {
- const int32_t b = *cmd++;
- const int32_t c = *cmd++;
- out << ": target=" << (void*)b << " (cookie " << (void*)c << ")";
- } break;
-
- case BC_ATTEMPT_ACQUIRE: {
- const int32_t p = *cmd++;
- const int32_t d = *cmd++;
- out << ": decriptor=" << (void*)d << ", pri=" << p;
- } break;
-
- case BC_REQUEST_DEATH_NOTIFICATION:
- case BC_CLEAR_DEATH_NOTIFICATION: {
- const int32_t h = *cmd++;
- const int32_t c = *cmd++;
- out << ": handle=" << h << " (death cookie " << (void*)c << ")";
- } break;
-
- case BC_DEAD_BINDER_DONE: {
- const int32_t c = *cmd++;
- out << ": death cookie " << (void*)c;
- } break;
- }
-
- out << endl;
- return cmd;
-}
-#endif
-
-static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER;
-static bool gHaveTLS = false;
-static pthread_key_t gTLS = 0;
-static bool gShutdown = false;
-
-IPCThreadState* IPCThreadState::self()
-{
- if (gHaveTLS) {
-restart:
- const pthread_key_t k = gTLS;
- IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
- if (st) return st;
- return new IPCThreadState;
- }
-
- if (gShutdown) return NULL;
-
- pthread_mutex_lock(&gTLSMutex);
- if (!gHaveTLS) {
- if (pthread_key_create(&gTLS, threadDestructor) != 0) {
- pthread_mutex_unlock(&gTLSMutex);
- return NULL;
- }
- gHaveTLS = true;
- }
- pthread_mutex_unlock(&gTLSMutex);
- goto restart;
-}
-
-void IPCThreadState::shutdown()
-{
- gShutdown = true;
-
- if (gHaveTLS) {
- // XXX Need to wait for all thread pool threads to exit!
- IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS);
- if (st) {
- delete st;
- pthread_setspecific(gTLS, NULL);
- }
- gHaveTLS = false;
- }
-}
-
-sp<ProcessState> IPCThreadState::process()
-{
- return mProcess;
-}
-
-status_t IPCThreadState::clearLastError()
-{
- const status_t err = mLastError;
- mLastError = NO_ERROR;
- return err;
-}
-
-int IPCThreadState::getCallingPid()
-{
- return mCallingPid;
-}
-
-int IPCThreadState::getCallingUid()
-{
- return mCallingUid;
-}
-
-int64_t IPCThreadState::clearCallingIdentity()
-{
- int64_t token = ((int64_t)mCallingUid<<32) | mCallingPid;
- clearCaller();
- return token;
-}
-
-void IPCThreadState::restoreCallingIdentity(int64_t token)
-{
- mCallingUid = (int)(token>>32);
- mCallingPid = (int)token;
-}
-
-void IPCThreadState::clearCaller()
-{
- if (mProcess->supportsProcesses()) {
- mCallingPid = getpid();
- mCallingUid = getuid();
- } else {
- mCallingPid = -1;
- mCallingUid = -1;
- }
-}
-
-void IPCThreadState::flushCommands()
-{
- if (mProcess->mDriverFD <= 0)
- return;
- talkWithDriver(false);
-}
-
-void IPCThreadState::joinThreadPool(bool isMain)
-{
- LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
-
- mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
-
- status_t result;
- do {
- int32_t cmd;
-
- // When we've cleared the incoming command queue, process any pending derefs
- if (mIn.dataPosition() >= mIn.dataSize()) {
- size_t numPending = mPendingWeakDerefs.size();
- if (numPending > 0) {
- for (size_t i = 0; i < numPending; i++) {
- RefBase::weakref_type* refs = mPendingWeakDerefs[i];
- refs->decWeak(mProcess.get());
- }
- mPendingWeakDerefs.clear();
- }
-
- numPending = mPendingStrongDerefs.size();
- if (numPending > 0) {
- for (size_t i = 0; i < numPending; i++) {
- BBinder* obj = mPendingStrongDerefs[i];
- obj->decStrong(mProcess.get());
- }
- mPendingStrongDerefs.clear();
- }
- }
-
- // now get the next command to be processed, waiting if necessary
- result = talkWithDriver();
- if (result >= NO_ERROR) {
- size_t IN = mIn.dataAvail();
- if (IN < sizeof(int32_t)) continue;
- cmd = mIn.readInt32();
- IF_LOG_COMMANDS() {
- alog << "Processing top-level Command: "
- << getReturnString(cmd) << endl;
- }
- result = executeCommand(cmd);
- }
-
- // Let this thread exit the thread pool if it is no longer
- // needed and it is not the main process thread.
- if(result == TIMED_OUT && !isMain) {
- break;
- }
- } while (result != -ECONNREFUSED && result != -EBADF);
-
- LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%p\n",
- (void*)pthread_self(), getpid(), (void*)result);
-
- mOut.writeInt32(BC_EXIT_LOOPER);
- talkWithDriver(false);
-}
-
-void IPCThreadState::stopProcess(bool immediate)
-{
- //LOGI("**** STOPPING PROCESS");
- flushCommands();
- int fd = mProcess->mDriverFD;
- mProcess->mDriverFD = -1;
- close(fd);
- //kill(getpid(), SIGKILL);
-}
-
-status_t IPCThreadState::transact(int32_t handle,
- uint32_t code, const Parcel& data,
- Parcel* reply, uint32_t flags)
-{
- status_t err = data.errorCheck();
-
- flags |= TF_ACCEPT_FDS;
-
- IF_LOG_TRANSACTIONS() {
- TextOutput::Bundle _b(alog);
- alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "
- << handle << " / code " << TypeCode(code) << ": "
- << indent << data << dedent << endl;
- }
-
- if (err == NO_ERROR) {
- LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
- (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
- err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
- }
-
- if (err != NO_ERROR) {
- if (reply) reply->setError(err);
- return (mLastError = err);
- }
-
- if ((flags & TF_ONE_WAY) == 0) {
- if (reply) {
- err = waitForResponse(reply);
- } else {
- Parcel fakeReply;
- err = waitForResponse(&fakeReply);
- }
-
- IF_LOG_TRANSACTIONS() {
- TextOutput::Bundle _b(alog);
- alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "
- << handle << ": ";
- if (reply) alog << indent << *reply << dedent << endl;
- else alog << "(none requested)" << endl;
- }
- } else {
- err = waitForResponse(NULL, NULL);
- }
-
- return err;
-}
-
-void IPCThreadState::incStrongHandle(int32_t handle)
-{
- LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)\n", handle);
- mOut.writeInt32(BC_ACQUIRE);
- mOut.writeInt32(handle);
-}
-
-void IPCThreadState::decStrongHandle(int32_t handle)
-{
- LOG_REMOTEREFS("IPCThreadState::decStrongHandle(%d)\n", handle);
- mOut.writeInt32(BC_RELEASE);
- mOut.writeInt32(handle);
-}
-
-void IPCThreadState::incWeakHandle(int32_t handle)
-{
- LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle);
- mOut.writeInt32(BC_INCREFS);
- mOut.writeInt32(handle);
-}
-
-void IPCThreadState::decWeakHandle(int32_t handle)
-{
- LOG_REMOTEREFS("IPCThreadState::decWeakHandle(%d)\n", handle);
- mOut.writeInt32(BC_DECREFS);
- mOut.writeInt32(handle);
-}
-
-status_t IPCThreadState::attemptIncStrongHandle(int32_t handle)
-{
- mOut.writeInt32(BC_ATTEMPT_ACQUIRE);
- mOut.writeInt32(0); // xxx was thread priority
- mOut.writeInt32(handle);
- status_t result = UNKNOWN_ERROR;
-
- waitForResponse(NULL, &result);
-
-#if LOG_REFCOUNTS
- printf("IPCThreadState::attemptIncStrongHandle(%ld) = %s\n",
- handle, result == NO_ERROR ? "SUCCESS" : "FAILURE");
-#endif
-
- return result;
-}
-
-void IPCThreadState::expungeHandle(int32_t handle, IBinder* binder)
-{
-#if LOG_REFCOUNTS
- printf("IPCThreadState::expungeHandle(%ld)\n", handle);
-#endif
- self()->mProcess->expungeHandle(handle, binder);
-}
-
-status_t IPCThreadState::requestDeathNotification(int32_t handle, BpBinder* proxy)
-{
- mOut.writeInt32(BC_REQUEST_DEATH_NOTIFICATION);
- mOut.writeInt32((int32_t)handle);
- mOut.writeInt32((int32_t)proxy);
- return NO_ERROR;
-}
-
-status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy)
-{
- mOut.writeInt32(BC_CLEAR_DEATH_NOTIFICATION);
- mOut.writeInt32((int32_t)handle);
- mOut.writeInt32((int32_t)proxy);
- return NO_ERROR;
-}
-
-IPCThreadState::IPCThreadState()
- : mProcess(ProcessState::self())
-{
- pthread_setspecific(gTLS, this);
- clearCaller();
- mIn.setDataCapacity(256);
- mOut.setDataCapacity(256);
-}
-
-IPCThreadState::~IPCThreadState()
-{
-}
-
-status_t IPCThreadState::sendReply(const Parcel& reply, uint32_t flags)
-{
- status_t err;
- status_t statusBuffer;
- err = writeTransactionData(BC_REPLY, flags, -1, 0, reply, &statusBuffer);
- if (err < NO_ERROR) return err;
-
- return waitForResponse(NULL, NULL);
-}
-
-status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
-{
- int32_t cmd;
- int32_t err;
-
- while (1) {
- if ((err=talkWithDriver()) < NO_ERROR) break;
- err = mIn.errorCheck();
- if (err < NO_ERROR) break;
- if (mIn.dataAvail() == 0) continue;
-
- cmd = mIn.readInt32();
-
- IF_LOG_COMMANDS() {
- alog << "Processing waitForResponse Command: "
- << getReturnString(cmd) << endl;
- }
-
- switch (cmd) {
- case BR_TRANSACTION_COMPLETE:
- if (!reply && !acquireResult) goto finish;
- break;
-
- case BR_DEAD_REPLY:
- err = DEAD_OBJECT;
- goto finish;
-
- case BR_FAILED_REPLY:
- err = FAILED_TRANSACTION;
- goto finish;
-
- case BR_ACQUIRE_RESULT:
- {
- LOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
- const int32_t result = mIn.readInt32();
- if (!acquireResult) continue;
- *acquireResult = result ? NO_ERROR : INVALID_OPERATION;
- }
- goto finish;
-
- case BR_REPLY:
- {
- binder_transaction_data tr;
- err = mIn.read(&tr, sizeof(tr));
- LOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
- if (err != NO_ERROR) goto finish;
-
- if (reply) {
- if ((tr.flags & TF_STATUS_CODE) == 0) {
- reply->ipcSetDataReference(
- reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
- tr.data_size,
- reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
- tr.offsets_size/sizeof(size_t),
- freeBuffer, this);
- } else {
- err = *static_cast<const status_t*>(tr.data.ptr.buffer);
- freeBuffer(NULL,
- reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
- tr.data_size,
- reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
- tr.offsets_size/sizeof(size_t), this);
- }
- } else {
- freeBuffer(NULL,
- reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
- tr.data_size,
- reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
- tr.offsets_size/sizeof(size_t), this);
- continue;
- }
- }
- goto finish;
-
- default:
- err = executeCommand(cmd);
- if (err != NO_ERROR) goto finish;
- break;
- }
- }
-
-finish:
- if (err != NO_ERROR) {
- if (acquireResult) *acquireResult = err;
- if (reply) reply->setError(err);
- mLastError = err;
- }
-
- return err;
-}
-
-status_t IPCThreadState::talkWithDriver(bool doReceive)
-{
- LOG_ASSERT(mProcess->mDriverFD >= 0, "Binder driver is not opened");
-
- binder_write_read bwr;
-
- // Is the read buffer empty?
- const bool needRead = mIn.dataPosition() >= mIn.dataSize();
-
- // We don't want to write anything if we are still reading
- // from data left in the input buffer and the caller
- // has requested to read the next data.
- const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
-
- bwr.write_size = outAvail;
- bwr.write_buffer = (long unsigned int)mOut.data();
-
- // This is what we'll read.
- if (doReceive && needRead) {
- bwr.read_size = mIn.dataCapacity();
- bwr.read_buffer = (long unsigned int)mIn.data();
- } else {
- bwr.read_size = 0;
- }
-
- IF_LOG_COMMANDS() {
- TextOutput::Bundle _b(alog);
- if (outAvail != 0) {
- alog << "Sending commands to driver: " << indent;
- const void* cmds = (const void*)bwr.write_buffer;
- const void* end = ((const uint8_t*)cmds)+bwr.write_size;
- alog << HexDump(cmds, bwr.write_size) << endl;
- while (cmds < end) cmds = printCommand(alog, cmds);
- alog << dedent;
- }
- alog << "Size of receive buffer: " << bwr.read_size
- << ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
- }
-
- // Return immediately if there is nothing to do.
- if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
-
- bwr.write_consumed = 0;
- bwr.read_consumed = 0;
- status_t err;
- do {
- IF_LOG_COMMANDS() {
- alog << "About to read/write, write size = " << mOut.dataSize() << endl;
- }
-#if defined(HAVE_ANDROID_OS)
- if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
- err = NO_ERROR;
- else
- err = -errno;
-#else
- err = INVALID_OPERATION;
-#endif
- IF_LOG_COMMANDS() {
- alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
- }
- } while (err == -EINTR);
-
- IF_LOG_COMMANDS() {
- alog << "Our err: " << (void*)err << ", write consumed: "
- << bwr.write_consumed << " (of " << mOut.dataSize()
- << "), read consumed: " << bwr.read_consumed << endl;
- }
-
- if (err >= NO_ERROR) {
- if (bwr.write_consumed > 0) {
- if (bwr.write_consumed < (ssize_t)mOut.dataSize())
- mOut.remove(0, bwr.write_consumed);
- else
- mOut.setDataSize(0);
- }
- if (bwr.read_consumed > 0) {
- mIn.setDataSize(bwr.read_consumed);
- mIn.setDataPosition(0);
- }
- IF_LOG_COMMANDS() {
- TextOutput::Bundle _b(alog);
- alog << "Remaining data size: " << mOut.dataSize() << endl;
- alog << "Received commands from driver: " << indent;
- const void* cmds = mIn.data();
- const void* end = mIn.data() + mIn.dataSize();
- alog << HexDump(cmds, mIn.dataSize()) << endl;
- while (cmds < end) cmds = printReturnCommand(alog, cmds);
- alog << dedent;
- }
- return NO_ERROR;
- }
-
- return err;
-}
-
-status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
- int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
-{
- binder_transaction_data tr;
-
- tr.target.handle = handle;
- tr.code = code;
- tr.flags = binderFlags;
-
- const status_t err = data.errorCheck();
- if (err == NO_ERROR) {
- tr.data_size = data.ipcDataSize();
- tr.data.ptr.buffer = data.ipcData();
- tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t);
- tr.data.ptr.offsets = data.ipcObjects();
- } else if (statusBuffer) {
- tr.flags |= TF_STATUS_CODE;
- *statusBuffer = err;
- tr.data_size = sizeof(status_t);
- tr.data.ptr.buffer = statusBuffer;
- tr.offsets_size = 0;
- tr.data.ptr.offsets = NULL;
- } else {
- return (mLastError = err);
- }
-
- mOut.writeInt32(cmd);
- mOut.write(&tr, sizeof(tr));
-
- return NO_ERROR;
-}
-
-sp<BBinder> the_context_object;
-
-void setTheContextObject(sp<BBinder> obj)
-{
- the_context_object = obj;
-}
-
-status_t IPCThreadState::executeCommand(int32_t cmd)
-{
- BBinder* obj;
- RefBase::weakref_type* refs;
- status_t result = NO_ERROR;
-
- switch (cmd) {
- case BR_ERROR:
- result = mIn.readInt32();
- break;
-
- case BR_OK:
- break;
-
- case BR_ACQUIRE:
- refs = (RefBase::weakref_type*)mIn.readInt32();
- obj = (BBinder*)mIn.readInt32();
- LOG_ASSERT(refs->refBase() == obj,
- "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
- refs, obj, refs->refBase());
- obj->incStrong(mProcess.get());
- IF_LOG_REMOTEREFS() {
- LOG_REMOTEREFS("BR_ACQUIRE from driver on %p", obj);
- obj->printRefs();
- }
- mOut.writeInt32(BC_ACQUIRE_DONE);
- mOut.writeInt32((int32_t)refs);
- mOut.writeInt32((int32_t)obj);
- break;
-
- case BR_RELEASE:
- refs = (RefBase::weakref_type*)mIn.readInt32();
- obj = (BBinder*)mIn.readInt32();
- LOG_ASSERT(refs->refBase() == obj,
- "BR_RELEASE: object %p does not match cookie %p (expected %p)",
- refs, obj, refs->refBase());
- IF_LOG_REMOTEREFS() {
- LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);
- obj->printRefs();
- }
- mPendingStrongDerefs.push(obj);
- break;
-
- case BR_INCREFS:
- refs = (RefBase::weakref_type*)mIn.readInt32();
- obj = (BBinder*)mIn.readInt32();
- refs->incWeak(mProcess.get());
- mOut.writeInt32(BC_INCREFS_DONE);
- mOut.writeInt32((int32_t)refs);
- mOut.writeInt32((int32_t)obj);
- break;
-
- case BR_DECREFS:
- refs = (RefBase::weakref_type*)mIn.readInt32();
- obj = (BBinder*)mIn.readInt32();
- // NOTE: This assertion is not valid, because the object may no
- // longer exist (thus the (BBinder*)cast above resulting in a different
- // memory address).
- //LOG_ASSERT(refs->refBase() == obj,
- // "BR_DECREFS: object %p does not match cookie %p (expected %p)",
- // refs, obj, refs->refBase());
- mPendingWeakDerefs.push(refs);
- break;
-
- case BR_ATTEMPT_ACQUIRE:
- refs = (RefBase::weakref_type*)mIn.readInt32();
- obj = (BBinder*)mIn.readInt32();
-
- {
- const bool success = refs->attemptIncStrong(mProcess.get());
- LOG_ASSERT(success && refs->refBase() == obj,
- "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
- refs, obj, refs->refBase());
-
- mOut.writeInt32(BC_ACQUIRE_RESULT);
- mOut.writeInt32((int32_t)success);
- }
- break;
-
- case BR_TRANSACTION:
- {
- binder_transaction_data tr;
- result = mIn.read(&tr, sizeof(tr));
- LOG_ASSERT(result == NO_ERROR,
- "Not enough command data for brTRANSACTION");
- if (result != NO_ERROR) break;
-
- Parcel buffer;
- buffer.ipcSetDataReference(
- reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
- tr.data_size,
- reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
- tr.offsets_size/sizeof(size_t), freeBuffer, this);
-
- const pid_t origPid = mCallingPid;
- const uid_t origUid = mCallingUid;
-
- mCallingPid = tr.sender_pid;
- mCallingUid = tr.sender_euid;
-
- //LOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
-
- Parcel reply;
- IF_LOG_TRANSACTIONS() {
- TextOutput::Bundle _b(alog);
- alog << "BR_TRANSACTION thr " << (void*)pthread_self()
- << " / obj " << tr.target.ptr << " / code "
- << TypeCode(tr.code) << ": " << indent << buffer
- << dedent << endl
- << "Data addr = "
- << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
- << ", offsets addr="
- << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
- }
- if (tr.target.ptr) {
- sp<BBinder> b((BBinder*)tr.cookie);
- const status_t error = b->transact(tr.code, buffer, &reply, 0);
- if (error < NO_ERROR) reply.setError(error);
-
- } else {
- const status_t error = the_context_object->transact(tr.code, buffer, &reply, 0);
- if (error < NO_ERROR) reply.setError(error);
- }
-
- //LOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
- // mCallingPid, origPid, origUid);
-
- if ((tr.flags & TF_ONE_WAY) == 0) {
- LOG_ONEWAY("Sending reply to %d!", mCallingPid);
- sendReply(reply, 0);
- } else {
- LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
- }
-
- mCallingPid = origPid;
- mCallingUid = origUid;
-
- IF_LOG_TRANSACTIONS() {
- TextOutput::Bundle _b(alog);
- alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
- << tr.target.ptr << ": " << indent << reply << dedent << endl;
- }
-
- }
- break;
-
- case BR_DEAD_BINDER:
- {
- BpBinder *proxy = (BpBinder*)mIn.readInt32();
- proxy->sendObituary();
- mOut.writeInt32(BC_DEAD_BINDER_DONE);
- mOut.writeInt32((int32_t)proxy);
- } break;
-
- case BR_CLEAR_DEATH_NOTIFICATION_DONE:
- {
- BpBinder *proxy = (BpBinder*)mIn.readInt32();
- proxy->getWeakRefs()->decWeak(proxy);
- } break;
-
- case BR_FINISHED:
- result = TIMED_OUT;
- break;
-
- case BR_NOOP:
- break;
-
- case BR_SPAWN_LOOPER:
- mProcess->spawnPooledThread(false);
- break;
-
- default:
- printf("*** BAD COMMAND %d received from Binder driver\n", cmd);
- result = UNKNOWN_ERROR;
- break;
- }
-
- if (result != NO_ERROR) {
- mLastError = result;
- }
-
- return result;
-}
-
-void IPCThreadState::threadDestructor(void *st)
-{
- IPCThreadState* const self = static_cast<IPCThreadState*>(st);
- if (self) {
- self->flushCommands();
-#if defined(HAVE_ANDROID_OS)
- ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0);
-#endif
- delete self;
- }
-}
-
-
-void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data, size_t dataSize,
- const size_t* objects, size_t objectsSize,
- void* cookie)
-{
- //LOGI("Freeing parcel %p", &parcel);
- IF_LOG_COMMANDS() {
- alog << "Writing BC_FREE_BUFFER for " << data << endl;
- }
- LOG_ASSERT(data != NULL, "Called with NULL data");
- if (parcel != NULL) parcel->closeFileDescriptors();
- IPCThreadState* state = self();
- state->mOut.writeInt32(BC_FREE_BUFFER);
- state->mOut.writeInt32((int32_t)data);
-}
-
-}; // namespace android
diff --git a/libs/utils/IPermissionController.cpp b/libs/utils/IPermissionController.cpp
deleted file mode 100644
index f01d38f..0000000
--- a/libs/utils/IPermissionController.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "PermissionController"
-
-#include <utils/IPermissionController.h>
-
-#include <utils/Debug.h>
-#include <utils/Log.h>
-#include <utils/Parcel.h>
-#include <utils/String8.h>
-
-#include <private/utils/Static.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------
-
-class BpPermissionController : public BpInterface<IPermissionController>
-{
-public:
- BpPermissionController(const sp<IBinder>& impl)
- : BpInterface<IPermissionController>(impl)
- {
- }
-
- virtual bool checkPermission(const String16& permission, int32_t pid, int32_t uid)
- {
- Parcel data, reply;
- data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
- data.writeString16(permission);
- data.writeInt32(pid);
- data.writeInt32(uid);
- remote()->transact(CHECK_PERMISSION_TRANSACTION, data, &reply);
- // fail on exception
- if (reply.readInt32() != 0) return 0;
- return reply.readInt32() != 0;
- }
-};
-
-IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController");
-
-// ----------------------------------------------------------------------
-
-#define CHECK_INTERFACE(interface, data, reply) \
- do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
- LOGW("Call incorrectly routed to " #interface); \
- return PERMISSION_DENIED; \
- } } while (0)
-
-status_t BnPermissionController::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- //printf("PermissionController received: "); data.print();
- switch(code) {
- case CHECK_PERMISSION_TRANSACTION: {
- CHECK_INTERFACE(IPermissionController, data, reply);
- String16 permission = data.readString16();
- int32_t pid = data.readInt32();
- int32_t uid = data.readInt32();
- bool res = checkPermission(permission, pid, uid);
- // write exception
- reply->writeInt32(0);
- reply->writeInt32(res ? 1 : 0);
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-}; // namespace android
-
diff --git a/libs/utils/IServiceManager.cpp b/libs/utils/IServiceManager.cpp
deleted file mode 100644
index 9beeadd..0000000
--- a/libs/utils/IServiceManager.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "ServiceManager"
-
-#include <utils/IServiceManager.h>
-
-#include <utils/Debug.h>
-#include <utils/IPCThreadState.h>
-#include <utils/Log.h>
-#include <utils/Parcel.h>
-#include <utils/String8.h>
-#include <utils/SystemClock.h>
-
-#include <private/utils/Static.h>
-
-#include <unistd.h>
-
-namespace android {
-
-sp<IServiceManager> defaultServiceManager()
-{
- if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
-
- {
- AutoMutex _l(gDefaultServiceManagerLock);
- if (gDefaultServiceManager == NULL) {
- gDefaultServiceManager = interface_cast<IServiceManager>(
- ProcessState::self()->getContextObject(NULL));
- }
- }
-
- return gDefaultServiceManager;
-}
-
-bool checkCallingPermission(const String16& permission)
-{
- return checkCallingPermission(permission, NULL, NULL);
-}
-
-static String16 _permission("permission");
-
-bool checkCallingPermission(const String16& permission, int32_t* outPid, int32_t* outUid)
-{
- IPCThreadState* ipcState = IPCThreadState::self();
- int32_t pid = ipcState->getCallingPid();
- int32_t uid = ipcState->getCallingUid();
- if (outPid) *outPid = pid;
- if (outUid) *outUid= uid;
-
- sp<IPermissionController> pc;
- gDefaultServiceManagerLock.lock();
- pc = gPermissionController;
- gDefaultServiceManagerLock.unlock();
-
- int64_t startTime = 0;
-
- while (true) {
- if (pc != NULL) {
- bool res = pc->checkPermission(permission, pid, uid);
- if (res) {
- if (startTime != 0) {
- LOGI("Check passed after %d seconds for %s from uid=%d pid=%d",
- (int)((uptimeMillis()-startTime)/1000),
- String8(permission).string(), uid, pid);
- }
- return res;
- }
-
- // Is this a permission failure, or did the controller go away?
- if (pc->asBinder()->isBinderAlive()) {
- LOGW("Permission failure: %s from uid=%d pid=%d",
- String8(permission).string(), uid, pid);
- return false;
- }
-
- // Object is dead!
- gDefaultServiceManagerLock.lock();
- if (gPermissionController == pc) {
- gPermissionController = NULL;
- }
- gDefaultServiceManagerLock.unlock();
- }
-
- // Need to retrieve the permission controller.
- sp<IBinder> binder = defaultServiceManager()->checkService(_permission);
- if (binder == NULL) {
- // Wait for the permission controller to come back...
- if (startTime == 0) {
- startTime = uptimeMillis();
- LOGI("Waiting to check permission %s from uid=%d pid=%d",
- String8(permission).string(), uid, pid);
- }
- sleep(1);
- } else {
- pc = interface_cast<IPermissionController>(binder);
- // Install the new permission controller, and try again.
- gDefaultServiceManagerLock.lock();
- gPermissionController = pc;
- gDefaultServiceManagerLock.unlock();
- }
- }
-}
-
-// ----------------------------------------------------------------------
-
-class BpServiceManager : public BpInterface<IServiceManager>
-{
-public:
- BpServiceManager(const sp<IBinder>& impl)
- : BpInterface<IServiceManager>(impl)
- {
- }
-
- virtual sp<IBinder> getService(const String16& name) const
- {
- unsigned n;
- for (n = 0; n < 5; n++){
- sp<IBinder> svc = checkService(name);
- if (svc != NULL) return svc;
- LOGI("Waiting for sevice %s...\n", String8(name).string());
- sleep(1);
- }
- return NULL;
- }
-
- virtual sp<IBinder> checkService( const String16& name) const
- {
- Parcel data, reply;
- data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
- data.writeString16(name);
- remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
- return reply.readStrongBinder();
- }
-
- virtual status_t addService(const String16& name, const sp<IBinder>& service)
- {
- Parcel data, reply;
- data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
- data.writeString16(name);
- data.writeStrongBinder(service);
- status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
- return err == NO_ERROR ? reply.readInt32() : err;
- }
-
- virtual Vector<String16> listServices()
- {
- Vector<String16> res;
- int n = 0;
-
- for (;;) {
- Parcel data, reply;
- data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
- data.writeInt32(n++);
- status_t err = remote()->transact(LIST_SERVICES_TRANSACTION, data, &reply);
- if (err != NO_ERROR)
- break;
- res.add(reply.readString16());
- }
- return res;
- }
-};
-
-IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
-
-// ----------------------------------------------------------------------
-
-#define CHECK_INTERFACE(interface, data, reply) \
- do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
- LOGW("Call incorrectly routed to " #interface); \
- return PERMISSION_DENIED; \
- } } while (0)
-
-status_t BnServiceManager::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- //printf("ServiceManager received: "); data.print();
- switch(code) {
- case GET_SERVICE_TRANSACTION: {
- CHECK_INTERFACE(IServiceManager, data, reply);
- String16 which = data.readString16();
- sp<IBinder> b = const_cast<BnServiceManager*>(this)->getService(which);
- reply->writeStrongBinder(b);
- return NO_ERROR;
- } break;
- case CHECK_SERVICE_TRANSACTION: {
- CHECK_INTERFACE(IServiceManager, data, reply);
- String16 which = data.readString16();
- sp<IBinder> b = const_cast<BnServiceManager*>(this)->checkService(which);
- reply->writeStrongBinder(b);
- return NO_ERROR;
- } break;
- case ADD_SERVICE_TRANSACTION: {
- CHECK_INTERFACE(IServiceManager, data, reply);
- String16 which = data.readString16();
- sp<IBinder> b = data.readStrongBinder();
- status_t err = addService(which, b);
- reply->writeInt32(err);
- return NO_ERROR;
- } break;
- case LIST_SERVICES_TRANSACTION: {
- CHECK_INTERFACE(IServiceManager, data, reply);
- Vector<String16> list = listServices();
- const size_t N = list.size();
- reply->writeInt32(N);
- for (size_t i=0; i<N; i++) {
- reply->writeString16(list[i]);
- }
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-}; // namespace android
-
diff --git a/libs/utils/InetAddress.cpp b/libs/utils/InetAddress.cpp
deleted file mode 100644
index 39a0a68..0000000
--- a/libs/utils/InetAddress.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Internet address class.
-//
-#ifdef HAVE_WINSOCK
-# include <winsock2.h>
-#else
-# include <sys/types.h>
-# include <sys/socket.h>
-# include <netinet/in.h>
-//# include <arpa/inet.h>
-# include <netdb.h>
-#endif
-
-#include <utils/inet_address.h>
-#include <utils/threads.h>
-#include <utils/Log.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-using namespace android;
-
-
-/*
- * ===========================================================================
- * InetAddress
- * ===========================================================================
- */
-
-// lock for the next couple of functions; could tuck into InetAddress
-static Mutex* gGHBNLock;
-
-/*
- * Lock/unlock access to the hostent struct returned by gethostbyname().
- */
-static inline void lock_gethostbyname(void)
-{
- if (gGHBNLock == NULL)
- gGHBNLock = new Mutex;
- gGHBNLock->lock();
-}
-static inline void unlock_gethostbyname(void)
-{
- assert(gGHBNLock != NULL);
- gGHBNLock->unlock();
-}
-
-
-/*
- * Constructor -- just init members. This is private so that callers
- * are required to use getByName().
- */
-InetAddress::InetAddress(void)
- : mAddress(NULL), mLength(-1), mName(NULL)
-{
-}
-
-/*
- * Destructor -- free address storage.
- */
-InetAddress::~InetAddress(void)
-{
- delete[] (char*) mAddress;
- delete[] mName;
-}
-
-/*
- * Copy constructor.
- */
-InetAddress::InetAddress(const InetAddress& orig)
-{
- *this = orig; // use assignment code
-}
-
-/*
- * Assignment operator.
- */
-InetAddress& InetAddress::operator=(const InetAddress& addr)
-{
- // handle self-assignment
- if (this == &addr)
- return *this;
- // copy mLength and mAddress
- mLength = addr.mLength;
- if (mLength > 0) {
- mAddress = new char[mLength];
- memcpy(mAddress, addr.mAddress, mLength);
- LOG(LOG_DEBUG, "socket",
- "HEY: copied %d bytes in assignment operator\n", mLength);
- } else {
- mAddress = NULL;
- }
- // copy mName
- mName = new char[strlen(addr.mName)+1];
- strcpy(mName, addr.mName);
-
- return *this;
-}
-
-/*
- * Create a new object from a name or a dotted-number IP notation.
- *
- * Returns NULL on failure.
- */
-InetAddress*
-InetAddress::getByName(const char* host)
-{
- InetAddress* newAddr = NULL;
- struct sockaddr_in addr;
- struct hostent* he;
- DurationTimer hostTimer, lockTimer;
-
- // gethostbyname() isn't reentrant, so we need to lock things until
- // we can copy the data out.
- lockTimer.start();
- lock_gethostbyname();
- hostTimer.start();
-
- he = gethostbyname(host);
- if (he == NULL) {
- LOG(LOG_WARN, "socket", "WARNING: cannot resolve host %s\n", host);
- unlock_gethostbyname();
- return NULL;
- }
-
- memcpy(&addr.sin_addr, he->h_addr, he->h_length);
- addr.sin_family = he->h_addrtype;
- addr.sin_port = 0;
-
- // got it, unlock us
- hostTimer.stop();
- he = NULL;
- unlock_gethostbyname();
-
- lockTimer.stop();
- if ((long) lockTimer.durationUsecs() > 100000) {
- long lockTime = (long) lockTimer.durationUsecs();
- long hostTime = (long) hostTimer.durationUsecs();
- LOG(LOG_DEBUG, "socket",
- "Lookup of %s took %.3fs (gethostbyname=%.3fs lock=%.3fs)\n",
- host, lockTime / 1000000.0, hostTime / 1000000.0,
- (lockTime - hostTime) / 1000000.0);
- }
-
- // Alloc storage and copy it over.
- newAddr = new InetAddress();
- if (newAddr == NULL)
- return NULL;
-
- newAddr->mLength = sizeof(struct sockaddr_in);
- newAddr->mAddress = new char[sizeof(struct sockaddr_in)];
- if (newAddr->mAddress == NULL) {
- delete newAddr;
- return NULL;
- }
- memcpy(newAddr->mAddress, &addr, newAddr->mLength);
-
- // Keep this for debug messages.
- newAddr->mName = new char[strlen(host)+1];
- if (newAddr->mName == NULL) {
- delete newAddr;
- return NULL;
- }
- strcpy(newAddr->mName, host);
-
- return newAddr;
-}
-
-
-/*
- * ===========================================================================
- * InetSocketAddress
- * ===========================================================================
- */
-
-/*
- * Create an address with the host wildcard (INADDR_ANY).
- */
-bool InetSocketAddress::create(int port)
-{
- assert(mAddress == NULL);
-
- mAddress = InetAddress::getByName("0.0.0.0");
- if (mAddress == NULL)
- return false;
- mPort = port;
- return true;
-}
-
-/*
- * Create address with host and port specified.
- */
-bool InetSocketAddress::create(const InetAddress* addr, int port)
-{
- assert(mAddress == NULL);
-
- mAddress = new InetAddress(*addr); // make a copy
- if (mAddress == NULL)
- return false;
- mPort = port;
- return true;
-}
-
-/*
- * Create address with host and port specified.
- */
-bool InetSocketAddress::create(const char* host, int port)
-{
- assert(mAddress == NULL);
-
- mAddress = InetAddress::getByName(host);
- if (mAddress == NULL)
- return false;
- mPort = port;
- return true;
-}
-
diff --git a/libs/utils/LogSocket.cpp b/libs/utils/LogSocket.cpp
deleted file mode 100644
index 55c1b99..0000000
--- a/libs/utils/LogSocket.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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 HAVE_WINSOCK
-//#define SOCKETLOG
-#endif
-
-#ifdef SOCKETLOG
-
-#define LOG_TAG "SOCKETLOG"
-
-#include <string.h>
-#include <cutils/log.h>
-#include "utils/LogSocket.h"
-#include "utils/logger.h"
-#include "cutils/hashmap.h"
-
-// defined in //device/data/etc/event-log-tags
-#define SOCKET_CLOSE_LOG 51000
-
-static Hashmap* statsMap = NULL;
-
-#define LOG_LIST_NUMBER 5
-
-typedef struct SocketStats {
- int fd;
- unsigned int send;
- unsigned int recv;
- unsigned int ip;
- unsigned short port;
- short reason;
-}SocketStats;
-
-SocketStats *get_socket_stats(int fd) {
- if (statsMap == NULL) {
- statsMap = hashmapCreate(8, &hashmapIntHash, &hashmapIntEquals);
- }
-
- SocketStats *s = (SocketStats*) hashmapGet(statsMap, &fd);
- if (s == NULL) {
- // LOGD("create SocketStats for fd %d", fd);
- s = (SocketStats*) malloc(sizeof(SocketStats));
- memset(s, 0, sizeof(SocketStats));
- s->fd = fd;
- hashmapPut(statsMap, &s->fd, s);
- }
- return s;
-}
-
-void log_socket_connect(int fd, unsigned int ip, unsigned short port) {
- // LOGD("log_socket_connect for fd %d ip %d port%d", fd, ip, port);
- SocketStats *s = get_socket_stats(fd);
- s->ip = ip;
- s->port = port;
-}
-
-void add_send_stats(int fd, int send) {
- if (send <=0) {
- LOGE("add_send_stats send %d", send);
- return;
- }
- SocketStats *s = get_socket_stats(fd);
- s->send += send;
- // LOGD("add_send_stats for fd %d ip %d port%d", fd, s->ip, s->port);
-}
-
-void add_recv_stats(int fd, int recv) {
- if (recv <=0) {
- LOGE("add_recv_stats recv %d", recv);
- return;
- }
- SocketStats *s = get_socket_stats(fd);
- s->recv += recv;
- // LOGD("add_recv_stats for fd %d ip %d port%d", fd, s->ip, s->port);
-}
-
-char* put_int(char* buf, int value) {
- *buf = EVENT_TYPE_INT;
- buf++;
- memcpy(buf, &value, sizeof(int));
- return buf + sizeof(int);
-}
-
-void log_socket_close(int fd, short reason) {
- if (statsMap) {
- SocketStats *s = (SocketStats*) hashmapGet(statsMap, &fd);
- if (s != NULL) {
- if (s->send != 0 || s->recv != 0) {
- s->reason = reason;
- // 5 int + list type need 2 bytes
- char buf[LOG_LIST_NUMBER * 5 + 2];
- buf[0] = EVENT_TYPE_LIST;
- buf[1] = LOG_LIST_NUMBER;
- char* writePos = buf + 2;
- writePos = put_int(writePos, s->send);
- writePos = put_int(writePos, s->recv);
- writePos = put_int(writePos, s->ip);
- writePos = put_int(writePos, s->port);
- writePos = put_int(writePos, s->reason);
-
- android_bWriteLog(SOCKET_CLOSE_LOG, buf, sizeof(buf));
- // LOGD("send %d recv %d reason %d", s->send, s->recv, s->reason);
- }
- hashmapRemove(statsMap, &s->fd);
- free(s);
- }
- }
-}
-
-#else
-void add_send_stats(int fd, int send) {}
-void add_recv_stats(int fd, int recv) {}
-void log_socket_close(int fd, short reason) {}
-void log_socket_connect(int fd, unsigned int ip, unsigned short port) {}
-#endif
diff --git a/libs/utils/MODULE_LICENSE_APACHE2 b/libs/utils/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/libs/utils/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/libs/utils/MemoryBase.cpp b/libs/utils/MemoryBase.cpp
deleted file mode 100644
index f25e11c..0000000
--- a/libs/utils/MemoryBase.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.
- */
-
-
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <utils/MemoryBase.h>
-
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-MemoryBase::MemoryBase(const sp<IMemoryHeap>& heap,
- ssize_t offset, size_t size)
- : mSize(size), mOffset(offset), mHeap(heap)
-{
-}
-
-sp<IMemoryHeap> MemoryBase::getMemory(ssize_t* offset, size_t* size) const
-{
- if (offset) *offset = mOffset;
- if (size) *size = mSize;
- return mHeap;
-}
-
-MemoryBase::~MemoryBase()
-{
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/utils/MemoryDealer.cpp b/libs/utils/MemoryDealer.cpp
deleted file mode 100644
index cf8201b..0000000
--- a/libs/utils/MemoryDealer.cpp
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "MemoryDealer"
-
-#include <utils/MemoryDealer.h>
-
-#include <utils/Log.h>
-#include <utils/IPCThreadState.h>
-#include <utils/SortedVector.h>
-#include <utils/String8.h>
-#include <utils/MemoryBase.h>
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/file.h>
-
-namespace android {
-
-
-// ----------------------------------------------------------------------------
-
-class SimpleMemory : public MemoryBase {
-public:
- SimpleMemory(const sp<IMemoryHeap>& heap, ssize_t offset, size_t size);
- virtual ~SimpleMemory();
-};
-
-
-// ----------------------------------------------------------------------------
-
-MemoryDealer::Allocation::Allocation(
- const sp<MemoryDealer>& dealer, ssize_t offset, size_t size,
- const sp<IMemory>& memory)
- : mDealer(dealer), mOffset(offset), mSize(size), mMemory(memory)
-{
-}
-
-MemoryDealer::Allocation::~Allocation()
-{
- if (mSize) {
- /* NOTE: it's VERY important to not free allocations of size 0 because
- * they're special as they don't have any record in the allocator
- * and could alias some real allocation (their offset is zero). */
- mDealer->deallocate(mOffset);
- }
-}
-
-sp<IMemoryHeap> MemoryDealer::Allocation::getMemory(
- ssize_t* offset, size_t* size) const
-{
- return mMemory->getMemory(offset, size);
-}
-
-// ----------------------------------------------------------------------------
-
-MemoryDealer::MemoryDealer(size_t size, uint32_t flags, const char* name)
- : mHeap(new SharedHeap(size, flags, name)),
- mAllocator(new SimpleBestFitAllocator(size))
-{
-}
-
-MemoryDealer::MemoryDealer(const sp<HeapInterface>& heap)
- : mHeap(heap),
- mAllocator(new SimpleBestFitAllocator(heap->virtualSize()))
-{
-}
-
-MemoryDealer::MemoryDealer( const sp<HeapInterface>& heap,
- const sp<AllocatorInterface>& allocator)
- : mHeap(heap), mAllocator(allocator)
-{
-}
-
-MemoryDealer::~MemoryDealer()
-{
-}
-
-sp<IMemory> MemoryDealer::allocate(size_t size, uint32_t flags)
-{
- sp<IMemory> memory;
- const ssize_t offset = allocator()->allocate(size, flags);
- if (offset >= 0) {
- sp<IMemory> new_memory = heap()->mapMemory(offset, size);
- if (new_memory != 0) {
- memory = new Allocation(this, offset, size, new_memory);
- } else {
- LOGE("couldn't map [%8x, %d]", offset, size);
- if (size) {
- /* NOTE: it's VERY important to not free allocations of size 0
- * because they're special as they don't have any record in the
- * allocator and could alias some real allocation
- * (their offset is zero). */
- allocator()->deallocate(offset);
- }
- }
- }
- return memory;
-}
-
-void MemoryDealer::deallocate(size_t offset)
-{
- allocator()->deallocate(offset);
-}
-
-void MemoryDealer::dump(const char* what, uint32_t flags) const
-{
- allocator()->dump(what, flags);
-}
-
-const sp<HeapInterface>& MemoryDealer::heap() const {
- return mHeap;
-}
-
-const sp<AllocatorInterface>& MemoryDealer::allocator() const {
- return mAllocator;
-}
-
-// ----------------------------------------------------------------------------
-
-// align all the memory blocks on a cache-line boundary
-const int SimpleBestFitAllocator::kMemoryAlign = 32;
-
-SimpleBestFitAllocator::SimpleBestFitAllocator(size_t size)
-{
- size_t pagesize = getpagesize();
- mHeapSize = ((size + pagesize-1) & ~(pagesize-1));
-
- chunk_t* node = new chunk_t(0, mHeapSize / kMemoryAlign);
- mList.insertHead(node);
-}
-
-SimpleBestFitAllocator::~SimpleBestFitAllocator()
-{
- while(!mList.isEmpty()) {
- delete mList.remove(mList.head());
- }
-}
-
-size_t SimpleBestFitAllocator::size() const
-{
- return mHeapSize;
-}
-
-size_t SimpleBestFitAllocator::allocate(size_t size, uint32_t flags)
-{
- Mutex::Autolock _l(mLock);
- ssize_t offset = alloc(size, flags);
- return offset;
-}
-
-status_t SimpleBestFitAllocator::deallocate(size_t offset)
-{
- Mutex::Autolock _l(mLock);
- chunk_t const * const freed = dealloc(offset);
- if (freed) {
- return NO_ERROR;
- }
- return NAME_NOT_FOUND;
-}
-
-ssize_t SimpleBestFitAllocator::alloc(size_t size, uint32_t flags)
-{
- if (size == 0) {
- return 0;
- }
- size = (size + kMemoryAlign-1) / kMemoryAlign;
- chunk_t* free_chunk = 0;
- chunk_t* cur = mList.head();
-
- size_t pagesize = getpagesize();
- while (cur) {
- int extra = 0;
- if (flags & PAGE_ALIGNED)
- extra = ( -cur->start & ((pagesize/kMemoryAlign)-1) ) ;
-
- // best fit
- if (cur->free && (cur->size >= (size+extra))) {
- if ((!free_chunk) || (cur->size < free_chunk->size)) {
- free_chunk = cur;
- }
- if (cur->size == size) {
- break;
- }
- }
- cur = cur->next;
- }
-
- if (free_chunk) {
- const size_t free_size = free_chunk->size;
- free_chunk->free = 0;
- free_chunk->size = size;
- if (free_size > size) {
- int extra = 0;
- if (flags & PAGE_ALIGNED)
- extra = ( -free_chunk->start & ((pagesize/kMemoryAlign)-1) ) ;
- if (extra) {
- chunk_t* split = new chunk_t(free_chunk->start, extra);
- free_chunk->start += extra;
- mList.insertBefore(free_chunk, split);
- }
-
- LOGE_IF((flags&PAGE_ALIGNED) &&
- ((free_chunk->start*kMemoryAlign)&(pagesize-1)),
- "PAGE_ALIGNED requested, but page is not aligned!!!");
-
- const ssize_t tail_free = free_size - (size+extra);
- if (tail_free > 0) {
- chunk_t* split = new chunk_t(
- free_chunk->start + free_chunk->size, tail_free);
- mList.insertAfter(free_chunk, split);
- }
- }
- return (free_chunk->start)*kMemoryAlign;
- }
- return NO_MEMORY;
-}
-
-SimpleBestFitAllocator::chunk_t* SimpleBestFitAllocator::dealloc(size_t start)
-{
- start = start / kMemoryAlign;
- chunk_t* cur = mList.head();
- while (cur) {
- if (cur->start == start) {
- LOG_FATAL_IF(cur->free,
- "block at offset 0x%08lX of size 0x%08lX already freed",
- cur->start*kMemoryAlign, cur->size*kMemoryAlign);
-
- // merge freed blocks together
- chunk_t* freed = cur;
- cur->free = 1;
- do {
- chunk_t* const p = cur->prev;
- chunk_t* const n = cur->next;
- if (p && (p->free || !cur->size)) {
- freed = p;
- p->size += cur->size;
- mList.remove(cur);
- delete cur;
- }
- cur = n;
- } while (cur && cur->free);
-
- #ifndef NDEBUG
- if (!freed->free) {
- dump_l("dealloc (!freed->free)");
- }
- #endif
- LOG_FATAL_IF(!freed->free,
- "freed block at offset 0x%08lX of size 0x%08lX is not free!",
- freed->start * kMemoryAlign, freed->size * kMemoryAlign);
-
- return freed;
- }
- cur = cur->next;
- }
- return 0;
-}
-
-void SimpleBestFitAllocator::dump(const char* what, uint32_t flags) const
-{
- Mutex::Autolock _l(mLock);
- dump_l(what, flags);
-}
-
-void SimpleBestFitAllocator::dump_l(const char* what, uint32_t flags) const
-{
- String8 result;
- dump_l(result, what, flags);
- LOGD("%s", result.string());
-}
-
-void SimpleBestFitAllocator::dump(String8& result,
- const char* what, uint32_t flags) const
-{
- Mutex::Autolock _l(mLock);
- dump_l(result, what, flags);
-}
-
-void SimpleBestFitAllocator::dump_l(String8& result,
- const char* what, uint32_t flags) const
-{
- size_t size = 0;
- int32_t i = 0;
- chunk_t const* cur = mList.head();
-
- const size_t SIZE = 256;
- char buffer[SIZE];
- snprintf(buffer, SIZE, " %s (%p, size=%u)\n",
- what, this, (unsigned int)mHeapSize);
-
- result.append(buffer);
-
- while (cur) {
- const char* errs[] = {"", "| link bogus NP",
- "| link bogus PN", "| link bogus NP+PN" };
- int np = ((cur->next) && cur->next->prev != cur) ? 1 : 0;
- int pn = ((cur->prev) && cur->prev->next != cur) ? 2 : 0;
-
- snprintf(buffer, SIZE, " %3u: %08x | 0x%08X | 0x%08X | %s %s\n",
- i, int(cur), int(cur->start*kMemoryAlign),
- int(cur->size*kMemoryAlign),
- int(cur->free) ? "F" : "A",
- errs[np|pn]);
-
- result.append(buffer);
-
- if (!cur->free)
- size += cur->size*kMemoryAlign;
-
- i++;
- cur = cur->next;
- }
- snprintf(buffer, SIZE, " size allocated: %u (%u KB)\n", int(size), int(size/1024));
- result.append(buffer);
-}
-
-// ----------------------------------------------------------------------------
-
-
-SharedHeap::SharedHeap(size_t size, uint32_t flags, char const * name)
- : MemoryHeapBase(size, flags, name)
-{
-}
-
-SharedHeap::~SharedHeap()
-{
-}
-
-sp<IMemory> SharedHeap::mapMemory(size_t offset, size_t size)
-{
- return new SimpleMemory(this, offset, size);
-}
-
-
-SimpleMemory::SimpleMemory(const sp<IMemoryHeap>& heap,
- ssize_t offset, size_t size)
- : MemoryBase(heap, offset, size)
-{
-#ifndef NDEBUG
- void* const start_ptr = (void*)(intptr_t(heap->base()) + offset);
- memset(start_ptr, 0xda, size);
-#endif
-}
-
-SimpleMemory::~SimpleMemory()
-{
- size_t freedOffset = getOffset();
- size_t freedSize = getSize();
-
- // keep the size to unmap in excess
- size_t pagesize = getpagesize();
- size_t start = freedOffset;
- size_t end = start + freedSize;
- start &= ~(pagesize-1);
- end = (end + pagesize-1) & ~(pagesize-1);
-
- // give back to the kernel the pages we don't need
- size_t free_start = freedOffset;
- size_t free_end = free_start + freedSize;
- if (start < free_start)
- start = free_start;
- if (end > free_end)
- end = free_end;
- start = (start + pagesize-1) & ~(pagesize-1);
- end &= ~(pagesize-1);
-
- if (start < end) {
- void* const start_ptr = (void*)(intptr_t(getHeap()->base()) + start);
- size_t size = end-start;
-
-#ifndef NDEBUG
- memset(start_ptr, 0xdf, size);
-#endif
-
- // MADV_REMOVE is not defined on Dapper based Goobuntu
-#ifdef MADV_REMOVE
- if (size) {
- int err = madvise(start_ptr, size, MADV_REMOVE);
- LOGW_IF(err, "madvise(%p, %u, MADV_REMOVE) returned %s",
- start_ptr, size, err<0 ? strerror(errno) : "Ok");
- }
-#endif
- }
-}
-
-}; // namespace android
diff --git a/libs/utils/MemoryHeapBase.cpp b/libs/utils/MemoryHeapBase.cpp
deleted file mode 100644
index 8251728..0000000
--- a/libs/utils/MemoryHeapBase.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "MemoryHeapBase"
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-
-#include <cutils/log.h>
-#include <cutils/ashmem.h>
-#include <cutils/atomic.h>
-
-#include <utils/MemoryHeapBase.h>
-
-#if HAVE_ANDROID_OS
-#include <linux/android_pmem.h>
-#endif
-
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-MemoryHeapBase::MemoryHeapBase()
- : mFD(-1), mSize(0), mBase(MAP_FAILED),
- mDevice(NULL), mNeedUnmap(false)
-{
-}
-
-MemoryHeapBase::MemoryHeapBase(size_t size, uint32_t flags, char const * name)
- : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
- mDevice(0), mNeedUnmap(false)
-{
- const size_t pagesize = getpagesize();
- size = ((size + pagesize-1) & ~(pagesize-1));
- int fd = ashmem_create_region(name == NULL ? "MemoryHeapBase" : name, size);
- LOGE_IF(fd<0, "error creating ashmem region: %s", strerror(errno));
- if (fd >= 0) {
- if (mapfd(fd, size) == NO_ERROR) {
- if (flags & READ_ONLY) {
- ashmem_set_prot_region(fd, PROT_READ);
- }
- }
- }
-}
-
-MemoryHeapBase::MemoryHeapBase(const char* device, size_t size, uint32_t flags)
- : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
- mDevice(0), mNeedUnmap(false)
-{
- int fd = open(device, O_RDWR);
- LOGE_IF(fd<0, "error opening %s: %s", device, strerror(errno));
- if (fd >= 0) {
- const size_t pagesize = getpagesize();
- size = ((size + pagesize-1) & ~(pagesize-1));
- if (mapfd(fd, size) == NO_ERROR) {
- mDevice = device;
- }
- }
-}
-
-MemoryHeapBase::MemoryHeapBase(int fd, size_t size, uint32_t flags)
- : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
- mDevice(0), mNeedUnmap(false)
-{
- const size_t pagesize = getpagesize();
- size = ((size + pagesize-1) & ~(pagesize-1));
- mapfd(dup(fd), size);
-}
-
-status_t MemoryHeapBase::init(int fd, void *base, int size, int flags, const char* device)
-{
- if (mFD != -1) {
- return INVALID_OPERATION;
- }
- mFD = fd;
- mBase = base;
- mSize = size;
- mFlags = flags;
- mDevice = device;
- return NO_ERROR;
-}
-
-status_t MemoryHeapBase::mapfd(int fd, size_t size)
-{
- if (size == 0) {
- // try to figure out the size automatically
-#if HAVE_ANDROID_OS
- // first try the PMEM ioctl
- pmem_region reg;
- int err = ioctl(fd, PMEM_GET_TOTAL_SIZE, &reg);
- if (err == 0)
- size = reg.len;
-#endif
- if (size == 0) { // try fstat
- struct stat sb;
- if (fstat(fd, &sb) == 0)
- size = sb.st_size;
- }
- // if it didn't work, let mmap() fail.
- }
-
- if ((mFlags & DONT_MAP_LOCALLY) == 0) {
- void* base = (uint8_t*)mmap(0, size,
- PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- if (base == MAP_FAILED) {
- LOGE("mmap(fd=%d, size=%u) failed (%s)",
- fd, uint32_t(size), strerror(errno));
- close(fd);
- return -errno;
- }
- //LOGD("mmap(fd=%d, base=%p, size=%lu)", fd, base, size);
- mBase = base;
- mNeedUnmap = true;
- } else {
- mBase = 0; // not MAP_FAILED
- mNeedUnmap = false;
- }
- mFD = fd;
- mSize = size;
- return NO_ERROR;
-}
-
-MemoryHeapBase::~MemoryHeapBase()
-{
- dispose();
-}
-
-void MemoryHeapBase::dispose()
-{
- int fd = android_atomic_or(-1, &mFD);
- if (fd >= 0) {
- if (mNeedUnmap) {
- //LOGD("munmap(fd=%d, base=%p, size=%lu)", fd, mBase, mSize);
- munmap(mBase, mSize);
- }
- mBase = 0;
- mSize = 0;
- close(fd);
- }
-}
-
-int MemoryHeapBase::getHeapID() const {
- return mFD;
-}
-
-void* MemoryHeapBase::getBase() const {
- return mBase;
-}
-
-size_t MemoryHeapBase::getSize() const {
- return mSize;
-}
-
-uint32_t MemoryHeapBase::getFlags() const {
- return mFlags;
-}
-
-const char* MemoryHeapBase::getDevice() const {
- return mDevice;
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/utils/MemoryHeapPmem.cpp b/libs/utils/MemoryHeapPmem.cpp
deleted file mode 100644
index eba2b30..0000000
--- a/libs/utils/MemoryHeapPmem.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "MemoryHeapPmem"
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-
-#include <cutils/log.h>
-
-#include <utils/MemoryHeapPmem.h>
-#include <utils/MemoryHeapBase.h>
-
-#if HAVE_ANDROID_OS
-#include <linux/android_pmem.h>
-#endif
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-MemoryHeapPmem::MemoryPmem::MemoryPmem(const sp<MemoryHeapPmem>& heap)
- : BnMemory(), mClientHeap(heap)
-{
-}
-
-MemoryHeapPmem::MemoryPmem::~MemoryPmem() {
- if (mClientHeap != NULL) {
- mClientHeap->remove(this);
- }
-}
-
-// ---------------------------------------------------------------------------
-
-class SubRegionMemory : public MemoryHeapPmem::MemoryPmem {
-public:
- SubRegionMemory(const sp<MemoryHeapPmem>& heap, ssize_t offset, size_t size);
- virtual ~SubRegionMemory();
- virtual sp<IMemoryHeap> getMemory(ssize_t* offset, size_t* size) const;
-private:
- friend class MemoryHeapPmem;
- void revoke();
- size_t mSize;
- ssize_t mOffset;
-};
-
-SubRegionMemory::SubRegionMemory(const sp<MemoryHeapPmem>& heap,
- ssize_t offset, size_t size)
- : MemoryHeapPmem::MemoryPmem(heap), mSize(size), mOffset(offset)
-{
-#ifndef NDEBUG
- void* const start_ptr = (void*)(intptr_t(getHeap()->base()) + offset);
- memset(start_ptr, 0xda, size);
-#endif
-
-#if HAVE_ANDROID_OS
- if (size > 0) {
- const size_t pagesize = getpagesize();
- size = (size + pagesize-1) & ~(pagesize-1);
- int our_fd = heap->heapID();
- struct pmem_region sub = { offset, size };
- int err = ioctl(our_fd, PMEM_MAP, &sub);
- LOGE_IF(err<0, "PMEM_MAP failed (%s), "
- "mFD=%d, sub.offset=%lu, sub.size=%lu",
- strerror(errno), our_fd, sub.offset, sub.len);
-}
-#endif
-}
-
-sp<IMemoryHeap> SubRegionMemory::getMemory(ssize_t* offset, size_t* size) const
-{
- if (offset) *offset = mOffset;
- if (size) *size = mSize;
- return getHeap();
-}
-
-SubRegionMemory::~SubRegionMemory()
-{
- revoke();
-}
-
-
-void SubRegionMemory::revoke()
-{
- // NOTE: revoke() doesn't need to be protected by a lock because it
- // can only be called from MemoryHeapPmem::revoke(), which means
- // that we can't be in ~SubRegionMemory(), or in ~SubRegionMemory(),
- // which means MemoryHeapPmem::revoke() wouldn't have been able to
- // promote() it.
-
-#if HAVE_ANDROID_OS
- if (mSize != NULL) {
- const sp<MemoryHeapPmem>& heap(getHeap());
- int our_fd = heap->heapID();
- struct pmem_region sub;
- sub.offset = mOffset;
- sub.len = mSize;
- int err = ioctl(our_fd, PMEM_UNMAP, &sub);
- LOGE_IF(err<0, "PMEM_UNMAP failed (%s), "
- "mFD=%d, sub.offset=%lu, sub.size=%lu",
- strerror(errno), our_fd, sub.offset, sub.len);
- mSize = 0;
- }
-#endif
-}
-
-// ---------------------------------------------------------------------------
-
-MemoryHeapPmem::MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap,
- uint32_t flags)
- : HeapInterface(), MemoryHeapBase()
-{
- char const * const device = pmemHeap->getDevice();
-#if HAVE_ANDROID_OS
- if (device) {
- int fd = open(device, O_RDWR);
- LOGE_IF(fd<0, "couldn't open %s (%s)", device, strerror(errno));
- if (fd >= 0) {
- int err = ioctl(fd, PMEM_CONNECT, pmemHeap->heapID());
- if (err < 0) {
- LOGE("PMEM_CONNECT failed (%s), mFD=%d, sub-fd=%d",
- strerror(errno), fd, pmemHeap->heapID());
- close(fd);
- } else {
- // everything went well...
- mParentHeap = pmemHeap;
- MemoryHeapBase::init(fd,
- pmemHeap->getBase(),
- pmemHeap->getSize(),
- pmemHeap->getFlags() | flags,
- device);
- }
- }
- }
-#else
- mParentHeap = pmemHeap;
- MemoryHeapBase::init(
- dup(pmemHeap->heapID()),
- pmemHeap->getBase(),
- pmemHeap->getSize(),
- pmemHeap->getFlags() | flags,
- device);
-#endif
-}
-
-MemoryHeapPmem::~MemoryHeapPmem()
-{
-}
-
-sp<IMemory> MemoryHeapPmem::mapMemory(size_t offset, size_t size)
-{
- sp<MemoryPmem> memory = createMemory(offset, size);
- if (memory != 0) {
- Mutex::Autolock _l(mLock);
- mAllocations.add(memory);
- }
- return memory;
-}
-
-sp<MemoryHeapPmem::MemoryPmem> MemoryHeapPmem::createMemory(
- size_t offset, size_t size)
-{
- sp<SubRegionMemory> memory;
- if (heapID() > 0)
- memory = new SubRegionMemory(this, offset, size);
- return memory;
-}
-
-status_t MemoryHeapPmem::slap()
-{
-#if HAVE_ANDROID_OS
- size_t size = getSize();
- const size_t pagesize = getpagesize();
- size = (size + pagesize-1) & ~(pagesize-1);
- int our_fd = getHeapID();
- struct pmem_region sub = { 0, size };
- int err = ioctl(our_fd, PMEM_MAP, &sub);
- LOGE_IF(err<0, "PMEM_MAP failed (%s), "
- "mFD=%d, sub.offset=%lu, sub.size=%lu",
- strerror(errno), our_fd, sub.offset, sub.len);
- return -errno;
-#else
- return NO_ERROR;
-#endif
-}
-
-status_t MemoryHeapPmem::unslap()
-{
-#if HAVE_ANDROID_OS
- size_t size = getSize();
- const size_t pagesize = getpagesize();
- size = (size + pagesize-1) & ~(pagesize-1);
- int our_fd = getHeapID();
- struct pmem_region sub = { 0, size };
- int err = ioctl(our_fd, PMEM_UNMAP, &sub);
- LOGE_IF(err<0, "PMEM_UNMAP failed (%s), "
- "mFD=%d, sub.offset=%lu, sub.size=%lu",
- strerror(errno), our_fd, sub.offset, sub.len);
- return -errno;
-#else
- return NO_ERROR;
-#endif
-}
-
-void MemoryHeapPmem::revoke()
-{
- SortedVector< wp<MemoryPmem> > allocations;
-
- { // scope for lock
- Mutex::Autolock _l(mLock);
- allocations = mAllocations;
- }
-
- ssize_t count = allocations.size();
- for (ssize_t i=0 ; i<count ; i++) {
- sp<MemoryPmem> memory(allocations[i].promote());
- if (memory != 0)
- memory->revoke();
- }
-}
-
-void MemoryHeapPmem::remove(const wp<MemoryPmem>& memory)
-{
- Mutex::Autolock _l(mLock);
- mAllocations.remove(memory);
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/utils/NOTICE b/libs/utils/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/libs/utils/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/libs/utils/Parcel.cpp b/libs/utils/Parcel.cpp
deleted file mode 100644
index 0f4b647..0000000
--- a/libs/utils/Parcel.cpp
+++ /dev/null
@@ -1,1377 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "Parcel"
-//#define LOG_NDEBUG 0
-
-#include <utils/Parcel.h>
-
-#include <utils/Binder.h>
-#include <utils/BpBinder.h>
-#include <utils/Debug.h>
-#include <utils/ProcessState.h>
-#include <utils/Log.h>
-#include <utils/String8.h>
-#include <utils/String16.h>
-#include <utils/TextOutput.h>
-#include <utils/misc.h>
-
-#include <private/utils/binder_module.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#ifndef INT32_MAX
-#define INT32_MAX ((int32_t)(2147483647))
-#endif
-
-#define LOG_REFS(...)
-//#define LOG_REFS(...) LOG(LOG_DEBUG, "Parcel", __VA_ARGS__)
-
-// ---------------------------------------------------------------------------
-
-#define PAD_SIZE(s) (((s)+3)&~3)
-
-// XXX This can be made public if we want to provide
-// support for typed data.
-struct small_flat_data
-{
- uint32_t type;
- uint32_t data;
-};
-
-namespace android {
-
-void acquire_object(const sp<ProcessState>& proc,
- const flat_binder_object& obj, const void* who)
-{
- switch (obj.type) {
- case BINDER_TYPE_BINDER:
- if (obj.binder) {
- LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
- static_cast<IBinder*>(obj.cookie)->incStrong(who);
- }
- return;
- case BINDER_TYPE_WEAK_BINDER:
- if (obj.binder)
- static_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who);
- return;
- case BINDER_TYPE_HANDLE: {
- const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
- if (b != NULL) {
- LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
- b->incStrong(who);
- }
- return;
- }
- case BINDER_TYPE_WEAK_HANDLE: {
- const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
- if (b != NULL) b.get_refs()->incWeak(who);
- return;
- }
- case BINDER_TYPE_FD: {
- // intentionally blank -- nothing to do to acquire this, but we do
- // recognize it as a legitimate object type.
- return;
- }
- }
-
- LOGD("Invalid object type 0x%08lx", obj.type);
-}
-
-void release_object(const sp<ProcessState>& proc,
- const flat_binder_object& obj, const void* who)
-{
- switch (obj.type) {
- case BINDER_TYPE_BINDER:
- if (obj.binder) {
- LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
- static_cast<IBinder*>(obj.cookie)->decStrong(who);
- }
- return;
- case BINDER_TYPE_WEAK_BINDER:
- if (obj.binder)
- static_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who);
- return;
- case BINDER_TYPE_HANDLE: {
- const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
- if (b != NULL) {
- LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
- b->decStrong(who);
- }
- return;
- }
- case BINDER_TYPE_WEAK_HANDLE: {
- const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
- if (b != NULL) b.get_refs()->decWeak(who);
- return;
- }
- case BINDER_TYPE_FD: {
- if (obj.cookie != (void*)0) close(obj.handle);
- return;
- }
- }
-
- LOGE("Invalid object type 0x%08lx", obj.type);
-}
-
-inline static status_t finish_flatten_binder(
- const sp<IBinder>& binder, const flat_binder_object& flat, Parcel* out)
-{
- return out->writeObject(flat, false);
-}
-
-status_t flatten_binder(const sp<ProcessState>& proc,
- const sp<IBinder>& binder, Parcel* out)
-{
- flat_binder_object obj;
-
- obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
- if (binder != NULL) {
- IBinder *local = binder->localBinder();
- if (!local) {
- BpBinder *proxy = binder->remoteBinder();
- if (proxy == NULL) {
- LOGE("null proxy");
- }
- const int32_t handle = proxy ? proxy->handle() : 0;
- obj.type = BINDER_TYPE_HANDLE;
- obj.handle = handle;
- obj.cookie = NULL;
- } else {
- obj.type = BINDER_TYPE_BINDER;
- obj.binder = local->getWeakRefs();
- obj.cookie = local;
- }
- } else {
- obj.type = BINDER_TYPE_BINDER;
- obj.binder = NULL;
- obj.cookie = NULL;
- }
-
- return finish_flatten_binder(binder, obj, out);
-}
-
-status_t flatten_binder(const sp<ProcessState>& proc,
- const wp<IBinder>& binder, Parcel* out)
-{
- flat_binder_object obj;
-
- obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
- if (binder != NULL) {
- sp<IBinder> real = binder.promote();
- if (real != NULL) {
- IBinder *local = real->localBinder();
- if (!local) {
- BpBinder *proxy = real->remoteBinder();
- if (proxy == NULL) {
- LOGE("null proxy");
- }
- const int32_t handle = proxy ? proxy->handle() : 0;
- obj.type = BINDER_TYPE_WEAK_HANDLE;
- obj.handle = handle;
- obj.cookie = NULL;
- } else {
- obj.type = BINDER_TYPE_WEAK_BINDER;
- obj.binder = binder.get_refs();
- obj.cookie = binder.unsafe_get();
- }
- return finish_flatten_binder(real, obj, out);
- }
-
- // XXX How to deal? In order to flatten the given binder,
- // we need to probe it for information, which requires a primary
- // reference... but we don't have one.
- //
- // The OpenBinder implementation uses a dynamic_cast<> here,
- // but we can't do that with the different reference counting
- // implementation we are using.
- LOGE("Unable to unflatten Binder weak reference!");
- obj.type = BINDER_TYPE_BINDER;
- obj.binder = NULL;
- obj.cookie = NULL;
- return finish_flatten_binder(NULL, obj, out);
-
- } else {
- obj.type = BINDER_TYPE_BINDER;
- obj.binder = NULL;
- obj.cookie = NULL;
- return finish_flatten_binder(NULL, obj, out);
- }
-}
-
-inline static status_t finish_unflatten_binder(
- BpBinder* proxy, const flat_binder_object& flat, const Parcel& in)
-{
- return NO_ERROR;
-}
-
-status_t unflatten_binder(const sp<ProcessState>& proc,
- const Parcel& in, sp<IBinder>* out)
-{
- const flat_binder_object* flat = in.readObject(false);
-
- if (flat) {
- switch (flat->type) {
- case BINDER_TYPE_BINDER:
- *out = static_cast<IBinder*>(flat->cookie);
- return finish_unflatten_binder(NULL, *flat, in);
- case BINDER_TYPE_HANDLE:
- *out = proc->getStrongProxyForHandle(flat->handle);
- return finish_unflatten_binder(
- static_cast<BpBinder*>(out->get()), *flat, in);
- }
- }
- return BAD_TYPE;
-}
-
-status_t unflatten_binder(const sp<ProcessState>& proc,
- const Parcel& in, wp<IBinder>* out)
-{
- const flat_binder_object* flat = in.readObject(false);
-
- if (flat) {
- switch (flat->type) {
- case BINDER_TYPE_BINDER:
- *out = static_cast<IBinder*>(flat->cookie);
- return finish_unflatten_binder(NULL, *flat, in);
- case BINDER_TYPE_WEAK_BINDER:
- if (flat->binder != NULL) {
- out->set_object_and_refs(
- static_cast<IBinder*>(flat->cookie),
- static_cast<RefBase::weakref_type*>(flat->binder));
- } else {
- *out = NULL;
- }
- return finish_unflatten_binder(NULL, *flat, in);
- case BINDER_TYPE_HANDLE:
- case BINDER_TYPE_WEAK_HANDLE:
- *out = proc->getWeakProxyForHandle(flat->handle);
- return finish_unflatten_binder(
- static_cast<BpBinder*>(out->unsafe_get()), *flat, in);
- }
- }
- return BAD_TYPE;
-}
-
-// ---------------------------------------------------------------------------
-
-Parcel::Parcel()
-{
- initState();
-}
-
-Parcel::~Parcel()
-{
- freeDataNoInit();
-}
-
-const uint8_t* Parcel::data() const
-{
- return mData;
-}
-
-size_t Parcel::dataSize() const
-{
- return (mDataSize > mDataPos ? mDataSize : mDataPos);
-}
-
-size_t Parcel::dataAvail() const
-{
- // TODO: decide what to do about the possibility that this can
- // report an available-data size that exceeds a Java int's max
- // positive value, causing havoc. Fortunately this will only
- // happen if someone constructs a Parcel containing more than two
- // gigabytes of data, which on typical phone hardware is simply
- // not possible.
- return dataSize() - dataPosition();
-}
-
-size_t Parcel::dataPosition() const
-{
- return mDataPos;
-}
-
-size_t Parcel::dataCapacity() const
-{
- return mDataCapacity;
-}
-
-status_t Parcel::setDataSize(size_t size)
-{
- status_t err;
- err = continueWrite(size);
- if (err == NO_ERROR) {
- mDataSize = size;
- LOGV("setDataSize Setting data size of %p to %d\n", this, mDataSize);
- }
- return err;
-}
-
-void Parcel::setDataPosition(size_t pos) const
-{
- mDataPos = pos;
- mNextObjectHint = 0;
-}
-
-status_t Parcel::setDataCapacity(size_t size)
-{
- if (size > mDataSize) return continueWrite(size);
- return NO_ERROR;
-}
-
-status_t Parcel::setData(const uint8_t* buffer, size_t len)
-{
- status_t err = restartWrite(len);
- if (err == NO_ERROR) {
- memcpy(const_cast<uint8_t*>(data()), buffer, len);
- mDataSize = len;
- mFdsKnown = false;
- }
- return err;
-}
-
-status_t Parcel::appendFrom(Parcel *parcel, size_t offset, size_t len)
-{
- const sp<ProcessState> proc(ProcessState::self());
- status_t err;
- uint8_t *data = parcel->mData;
- size_t *objects = parcel->mObjects;
- size_t size = parcel->mObjectsSize;
- int startPos = mDataPos;
- int firstIndex = -1, lastIndex = -2;
-
- if (len == 0) {
- return NO_ERROR;
- }
-
- // range checks against the source parcel size
- if ((offset > parcel->mDataSize)
- || (len > parcel->mDataSize)
- || (offset + len > parcel->mDataSize)) {
- return BAD_VALUE;
- }
-
- // Count objects in range
- for (int i = 0; i < (int) size; i++) {
- size_t off = objects[i];
- if ((off >= offset) && (off < offset + len)) {
- if (firstIndex == -1) {
- firstIndex = i;
- }
- lastIndex = i;
- }
- }
- int numObjects = lastIndex - firstIndex + 1;
-
- // grow data
- err = growData(len);
- if (err != NO_ERROR) {
- return err;
- }
-
- // append data
- memcpy(mData + mDataPos, data + offset, len);
- mDataPos += len;
- mDataSize += len;
-
- if (numObjects > 0) {
- // grow objects
- if (mObjectsCapacity < mObjectsSize + numObjects) {
- int newSize = ((mObjectsSize + numObjects)*3)/2;
- size_t *objects =
- (size_t*)realloc(mObjects, newSize*sizeof(size_t));
- if (objects == (size_t*)0) {
- return NO_MEMORY;
- }
- mObjects = objects;
- mObjectsCapacity = newSize;
- }
-
- // append and acquire objects
- int idx = mObjectsSize;
- for (int i = firstIndex; i <= lastIndex; i++) {
- size_t off = objects[i] - offset + startPos;
- mObjects[idx++] = off;
- mObjectsSize++;
-
- const flat_binder_object* flat
- = reinterpret_cast<flat_binder_object*>(mData + off);
- acquire_object(proc, *flat, this);
-
- // take note if the object is a file descriptor
- if (flat->type == BINDER_TYPE_FD) {
- mHasFds = mFdsKnown = true;
- }
- }
- }
-
- return NO_ERROR;
-}
-
-bool Parcel::hasFileDescriptors() const
-{
- if (!mFdsKnown) {
- scanForFds();
- }
- return mHasFds;
-}
-
-status_t Parcel::writeInterfaceToken(const String16& interface)
-{
- // currently the interface identification token is just its name as a string
- return writeString16(interface);
-}
-
-bool Parcel::enforceInterface(const String16& interface) const
-{
- String16 str = readString16();
- if (str == interface) {
- return true;
- } else {
- LOGW("**** enforceInterface() expected '%s' but read '%s'\n",
- String8(interface).string(), String8(str).string());
- return false;
- }
-}
-
-const size_t* Parcel::objects() const
-{
- return mObjects;
-}
-
-size_t Parcel::objectsCount() const
-{
- return mObjectsSize;
-}
-
-status_t Parcel::errorCheck() const
-{
- return mError;
-}
-
-void Parcel::setError(status_t err)
-{
- mError = err;
-}
-
-status_t Parcel::finishWrite(size_t len)
-{
- //printf("Finish write of %d\n", len);
- mDataPos += len;
- LOGV("finishWrite Setting data pos of %p to %d\n", this, mDataPos);
- if (mDataPos > mDataSize) {
- mDataSize = mDataPos;
- LOGV("finishWrite Setting data size of %p to %d\n", this, mDataSize);
- }
- //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
- return NO_ERROR;
-}
-
-status_t Parcel::writeUnpadded(const void* data, size_t len)
-{
- size_t end = mDataPos + len;
- if (end < mDataPos) {
- // integer overflow
- return BAD_VALUE;
- }
-
- if (end <= mDataCapacity) {
-restart_write:
- memcpy(mData+mDataPos, data, len);
- return finishWrite(len);
- }
-
- status_t err = growData(len);
- if (err == NO_ERROR) goto restart_write;
- return err;
-}
-
-status_t Parcel::write(const void* data, size_t len)
-{
- void* const d = writeInplace(len);
- if (d) {
- memcpy(d, data, len);
- return NO_ERROR;
- }
- return mError;
-}
-
-void* Parcel::writeInplace(size_t len)
-{
- const size_t padded = PAD_SIZE(len);
-
- // sanity check for integer overflow
- if (mDataPos+padded < mDataPos) {
- return NULL;
- }
-
- if ((mDataPos+padded) <= mDataCapacity) {
-restart_write:
- //printf("Writing %ld bytes, padded to %ld\n", len, padded);
- uint8_t* const data = mData+mDataPos;
-
- // Need to pad at end?
- if (padded != len) {
-#if BYTE_ORDER == BIG_ENDIAN
- static const uint32_t mask[4] = {
- 0x00000000, 0xffffff00, 0xffff0000, 0xff000000
- };
-#endif
-#if BYTE_ORDER == LITTLE_ENDIAN
- static const uint32_t mask[4] = {
- 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
- };
-#endif
- //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
- // *reinterpret_cast<void**>(data+padded-4));
- *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
- }
-
- finishWrite(padded);
- return data;
- }
-
- status_t err = growData(padded);
- if (err == NO_ERROR) goto restart_write;
- return NULL;
-}
-
-status_t Parcel::writeInt32(int32_t val)
-{
- if ((mDataPos+sizeof(val)) <= mDataCapacity) {
-restart_write:
- *reinterpret_cast<int32_t*>(mData+mDataPos) = val;
- return finishWrite(sizeof(val));
- }
-
- status_t err = growData(sizeof(val));
- if (err == NO_ERROR) goto restart_write;
- return err;
-}
-
-status_t Parcel::writeInt64(int64_t val)
-{
- if ((mDataPos+sizeof(val)) <= mDataCapacity) {
-restart_write:
- *reinterpret_cast<int64_t*>(mData+mDataPos) = val;
- return finishWrite(sizeof(val));
- }
-
- status_t err = growData(sizeof(val));
- if (err == NO_ERROR) goto restart_write;
- return err;
-}
-
-status_t Parcel::writeFloat(float val)
-{
- if ((mDataPos+sizeof(val)) <= mDataCapacity) {
-restart_write:
- *reinterpret_cast<float*>(mData+mDataPos) = val;
- return finishWrite(sizeof(val));
- }
-
- status_t err = growData(sizeof(val));
- if (err == NO_ERROR) goto restart_write;
- return err;
-}
-
-status_t Parcel::writeDouble(double val)
-{
- if ((mDataPos+sizeof(val)) <= mDataCapacity) {
-restart_write:
- *reinterpret_cast<double*>(mData+mDataPos) = val;
- return finishWrite(sizeof(val));
- }
-
- status_t err = growData(sizeof(val));
- if (err == NO_ERROR) goto restart_write;
- return err;
-}
-
-status_t Parcel::writeCString(const char* str)
-{
- return write(str, strlen(str)+1);
-}
-
-status_t Parcel::writeString8(const String8& str)
-{
- status_t err = writeInt32(str.bytes());
- if (err == NO_ERROR) {
- err = write(str.string(), str.bytes()+1);
- }
- return err;
-}
-
-status_t Parcel::writeString16(const String16& str)
-{
- return writeString16(str.string(), str.size());
-}
-
-status_t Parcel::writeString16(const char16_t* str, size_t len)
-{
- if (str == NULL) return writeInt32(-1);
-
- status_t err = writeInt32(len);
- if (err == NO_ERROR) {
- len *= sizeof(char16_t);
- uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
- if (data) {
- memcpy(data, str, len);
- *reinterpret_cast<char16_t*>(data+len) = 0;
- return NO_ERROR;
- }
- err = mError;
- }
- return err;
-}
-
-status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
-{
- return flatten_binder(ProcessState::self(), val, this);
-}
-
-status_t Parcel::writeWeakBinder(const wp<IBinder>& val)
-{
- return flatten_binder(ProcessState::self(), val, this);
-}
-
-status_t Parcel::writeNativeHandle(const native_handle& handle)
-{
- if (handle.version != sizeof(native_handle))
- return BAD_TYPE;
-
- status_t err;
- err = writeInt32(handle.numFds);
- if (err != NO_ERROR) return err;
-
- err = writeInt32(handle.numInts);
- if (err != NO_ERROR) return err;
-
- for (int i=0 ; err==NO_ERROR && i<handle.numFds ; i++)
- err = writeDupFileDescriptor(handle.data[i]);
-
- if (err != NO_ERROR) {
- LOGD("write native handle, write dup fd failed");
- return err;
- }
-
- err = write(handle.data + handle.numFds, sizeof(int)*handle.numInts);
-
- return err;
-}
-
-status_t Parcel::writeFileDescriptor(int fd)
-{
- flat_binder_object obj;
- obj.type = BINDER_TYPE_FD;
- obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
- obj.handle = fd;
- obj.cookie = (void*)0;
- return writeObject(obj, true);
-}
-
-status_t Parcel::writeDupFileDescriptor(int fd)
-{
- flat_binder_object obj;
- obj.type = BINDER_TYPE_FD;
- obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
- obj.handle = dup(fd);
- obj.cookie = (void*)1;
- return writeObject(obj, true);
-}
-
-status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
-{
- const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
- const bool enoughObjects = mObjectsSize < mObjectsCapacity;
- if (enoughData && enoughObjects) {
-restart_write:
- *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
-
- // Need to write meta-data?
- if (nullMetaData || val.binder != NULL) {
- mObjects[mObjectsSize] = mDataPos;
- acquire_object(ProcessState::self(), val, this);
- mObjectsSize++;
- }
-
- // remember if it's a file descriptor
- if (val.type == BINDER_TYPE_FD) {
- mHasFds = mFdsKnown = true;
- }
-
- return finishWrite(sizeof(flat_binder_object));
- }
-
- if (!enoughData) {
- const status_t err = growData(sizeof(val));
- if (err != NO_ERROR) return err;
- }
- if (!enoughObjects) {
- size_t newSize = ((mObjectsSize+2)*3)/2;
- size_t* objects = (size_t*)realloc(mObjects, newSize*sizeof(size_t));
- if (objects == NULL) return NO_MEMORY;
- mObjects = objects;
- mObjectsCapacity = newSize;
- }
-
- goto restart_write;
-}
-
-
-void Parcel::remove(size_t start, size_t amt)
-{
- LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
-}
-
-status_t Parcel::read(void* outData, size_t len) const
-{
- if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
- memcpy(outData, mData+mDataPos, len);
- mDataPos += PAD_SIZE(len);
- LOGV("read Setting data pos of %p to %d\n", this, mDataPos);
- return NO_ERROR;
- }
- return NOT_ENOUGH_DATA;
-}
-
-const void* Parcel::readInplace(size_t len) const
-{
- if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
- const void* data = mData+mDataPos;
- mDataPos += PAD_SIZE(len);
- LOGV("readInplace Setting data pos of %p to %d\n", this, mDataPos);
- return data;
- }
- return NULL;
-}
-
-status_t Parcel::readInt32(int32_t *pArg) const
-{
- if ((mDataPos+sizeof(int32_t)) <= mDataSize) {
- const void* data = mData+mDataPos;
- mDataPos += sizeof(int32_t);
- *pArg = *reinterpret_cast<const int32_t*>(data);
- return NO_ERROR;
- } else {
- return NOT_ENOUGH_DATA;
- }
-}
-
-int32_t Parcel::readInt32() const
-{
- if ((mDataPos+sizeof(int32_t)) <= mDataSize) {
- const void* data = mData+mDataPos;
- mDataPos += sizeof(int32_t);
- LOGV("readInt32 Setting data pos of %p to %d\n", this, mDataPos);
- return *reinterpret_cast<const int32_t*>(data);
- }
- return 0;
-}
-
-
-status_t Parcel::readInt64(int64_t *pArg) const
-{
- if ((mDataPos+sizeof(int64_t)) <= mDataSize) {
- const void* data = mData+mDataPos;
- mDataPos += sizeof(int64_t);
- *pArg = *reinterpret_cast<const int64_t*>(data);
- LOGV("readInt64 Setting data pos of %p to %d\n", this, mDataPos);
- return NO_ERROR;
- } else {
- return NOT_ENOUGH_DATA;
- }
-}
-
-
-int64_t Parcel::readInt64() const
-{
- if ((mDataPos+sizeof(int64_t)) <= mDataSize) {
- const void* data = mData+mDataPos;
- mDataPos += sizeof(int64_t);
- LOGV("readInt64 Setting data pos of %p to %d\n", this, mDataPos);
- return *reinterpret_cast<const int64_t*>(data);
- }
- return 0;
-}
-
-status_t Parcel::readFloat(float *pArg) const
-{
- if ((mDataPos+sizeof(float)) <= mDataSize) {
- const void* data = mData+mDataPos;
- mDataPos += sizeof(float);
- LOGV("readFloat Setting data pos of %p to %d\n", this, mDataPos);
- *pArg = *reinterpret_cast<const float*>(data);
- return NO_ERROR;
- } else {
- return NOT_ENOUGH_DATA;
- }
-}
-
-
-float Parcel::readFloat() const
-{
- if ((mDataPos+sizeof(float)) <= mDataSize) {
- const void* data = mData+mDataPos;
- mDataPos += sizeof(float);
- LOGV("readFloat Setting data pos of %p to %d\n", this, mDataPos);
- return *reinterpret_cast<const float*>(data);
- }
- return 0;
-}
-
-status_t Parcel::readDouble(double *pArg) const
-{
- if ((mDataPos+sizeof(double)) <= mDataSize) {
- const void* data = mData+mDataPos;
- mDataPos += sizeof(double);
- LOGV("readDouble Setting data pos of %p to %d\n", this, mDataPos);
- *pArg = *reinterpret_cast<const double*>(data);
- return NO_ERROR;
- } else {
- return NOT_ENOUGH_DATA;
- }
-}
-
-
-double Parcel::readDouble() const
-{
- if ((mDataPos+sizeof(double)) <= mDataSize) {
- const void* data = mData+mDataPos;
- mDataPos += sizeof(double);
- LOGV("readDouble Setting data pos of %p to %d\n", this, mDataPos);
- return *reinterpret_cast<const double*>(data);
- }
- return 0;
-}
-
-
-const char* Parcel::readCString() const
-{
- const size_t avail = mDataSize-mDataPos;
- if (avail > 0) {
- const char* str = reinterpret_cast<const char*>(mData+mDataPos);
- // is the string's trailing NUL within the parcel's valid bounds?
- const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
- if (eos) {
- const size_t len = eos - str;
- mDataPos += PAD_SIZE(len+1);
- LOGV("readCString Setting data pos of %p to %d\n", this, mDataPos);
- return str;
- }
- }
- return NULL;
-}
-
-String8 Parcel::readString8() const
-{
- int32_t size = readInt32();
- // watch for potential int overflow adding 1 for trailing NUL
- if (size > 0 && size < INT32_MAX) {
- const char* str = (const char*)readInplace(size+1);
- if (str) return String8(str, size);
- }
- return String8();
-}
-
-String16 Parcel::readString16() const
-{
- size_t len;
- const char16_t* str = readString16Inplace(&len);
- if (str) return String16(str, len);
- LOGE("Reading a NULL string not supported here.");
- return String16();
-}
-
-const char16_t* Parcel::readString16Inplace(size_t* outLen) const
-{
- int32_t size = readInt32();
- // watch for potential int overflow from size+1
- if (size >= 0 && size < INT32_MAX) {
- *outLen = size;
- const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
- if (str != NULL) {
- return str;
- }
- }
- *outLen = 0;
- return NULL;
-}
-
-sp<IBinder> Parcel::readStrongBinder() const
-{
- sp<IBinder> val;
- unflatten_binder(ProcessState::self(), *this, &val);
- return val;
-}
-
-wp<IBinder> Parcel::readWeakBinder() const
-{
- wp<IBinder> val;
- unflatten_binder(ProcessState::self(), *this, &val);
- return val;
-}
-
-
-native_handle* Parcel::readNativeHandle(native_handle* (*alloc)(void*, int, int), void* cookie) const
-{
- int numFds, numInts;
- status_t err;
- err = readInt32(&numFds);
- if (err != NO_ERROR) return 0;
- err = readInt32(&numInts);
- if (err != NO_ERROR) return 0;
-
- native_handle* h;
- if (alloc == 0) {
- size_t size = sizeof(native_handle) + sizeof(int)*(numFds + numInts);
- h = (native_handle*)malloc(size);
- h->version = sizeof(native_handle);
- h->numFds = numFds;
- h->numInts = numInts;
- } else {
- h = alloc(cookie, numFds, numInts);
- if (h->version != sizeof(native_handle)) {
- return 0;
- }
- }
-
- for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
- h->data[i] = dup(readFileDescriptor());
- if (h->data[i] < 0) err = BAD_VALUE;
- }
-
- err = read(h->data + numFds, sizeof(int)*numInts);
-
- if (err != NO_ERROR) {
- if (alloc == 0) {
- free(h);
- }
- h = 0;
- }
- return h;
-}
-
-
-int Parcel::readFileDescriptor() const
-{
- const flat_binder_object* flat = readObject(true);
- if (flat) {
- switch (flat->type) {
- case BINDER_TYPE_FD:
- //LOGI("Returning file descriptor %ld from parcel %p\n", flat->handle, this);
- return flat->handle;
- }
- }
- return BAD_TYPE;
-}
-
-const flat_binder_object* Parcel::readObject(bool nullMetaData) const
-{
- const size_t DPOS = mDataPos;
- if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
- const flat_binder_object* obj
- = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
- mDataPos = DPOS + sizeof(flat_binder_object);
- if (!nullMetaData && (obj->cookie == NULL && obj->binder == NULL)) {
- // When transferring a NULL object, we don't write it into
- // the object list, so we don't want to check for it when
- // reading.
- LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
- return obj;
- }
-
- // Ensure that this object is valid...
- size_t* const OBJS = mObjects;
- const size_t N = mObjectsSize;
- size_t opos = mNextObjectHint;
-
- if (N > 0) {
- LOGV("Parcel %p looking for obj at %d, hint=%d\n",
- this, DPOS, opos);
-
- // Start at the current hint position, looking for an object at
- // the current data position.
- if (opos < N) {
- while (opos < (N-1) && OBJS[opos] < DPOS) {
- opos++;
- }
- } else {
- opos = N-1;
- }
- if (OBJS[opos] == DPOS) {
- // Found it!
- LOGV("Parcel found obj %d at index %d with forward search",
- this, DPOS, opos);
- mNextObjectHint = opos+1;
- LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
- return obj;
- }
-
- // Look backwards for it...
- while (opos > 0 && OBJS[opos] > DPOS) {
- opos--;
- }
- if (OBJS[opos] == DPOS) {
- // Found it!
- LOGV("Parcel found obj %d at index %d with backward search",
- this, DPOS, opos);
- mNextObjectHint = opos+1;
- LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
- return obj;
- }
- }
- LOGW("Attempt to read object from Parcel %p at offset %d that is not in the object list",
- this, DPOS);
- }
- return NULL;
-}
-
-void Parcel::closeFileDescriptors()
-{
- size_t i = mObjectsSize;
- if (i > 0) {
- //LOGI("Closing file descriptors for %d objects...", mObjectsSize);
- }
- while (i > 0) {
- i--;
- const flat_binder_object* flat
- = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
- if (flat->type == BINDER_TYPE_FD) {
- //LOGI("Closing fd: %ld\n", flat->handle);
- close(flat->handle);
- }
- }
-}
-
-const uint8_t* Parcel::ipcData() const
-{
- return mData;
-}
-
-size_t Parcel::ipcDataSize() const
-{
- return (mDataSize > mDataPos ? mDataSize : mDataPos);
-}
-
-const size_t* Parcel::ipcObjects() const
-{
- return mObjects;
-}
-
-size_t Parcel::ipcObjectsCount() const
-{
- return mObjectsSize;
-}
-
-void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
- const size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
-{
- freeDataNoInit();
- mError = NO_ERROR;
- mData = const_cast<uint8_t*>(data);
- mDataSize = mDataCapacity = dataSize;
- //LOGI("setDataReference Setting data size of %p to %lu (pid=%d)\n", this, mDataSize, getpid());
- mDataPos = 0;
- LOGV("setDataReference Setting data pos of %p to %d\n", this, mDataPos);
- mObjects = const_cast<size_t*>(objects);
- mObjectsSize = mObjectsCapacity = objectsCount;
- mNextObjectHint = 0;
- mOwner = relFunc;
- mOwnerCookie = relCookie;
- scanForFds();
-}
-
-void Parcel::print(TextOutput& to, uint32_t flags) const
-{
- to << "Parcel(";
-
- if (errorCheck() != NO_ERROR) {
- const status_t err = errorCheck();
- to << "Error: " << (void*)err << " \"" << strerror(-err) << "\"";
- } else if (dataSize() > 0) {
- const uint8_t* DATA = data();
- to << indent << HexDump(DATA, dataSize()) << dedent;
- const size_t* OBJS = objects();
- const size_t N = objectsCount();
- for (size_t i=0; i<N; i++) {
- const flat_binder_object* flat
- = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
- to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
- << TypeCode(flat->type & 0x7f7f7f00)
- << " = " << flat->binder;
- }
- } else {
- to << "NULL";
- }
-
- to << ")";
-}
-
-void Parcel::releaseObjects()
-{
- const sp<ProcessState> proc(ProcessState::self());
- size_t i = mObjectsSize;
- uint8_t* const data = mData;
- size_t* const objects = mObjects;
- while (i > 0) {
- i--;
- const flat_binder_object* flat
- = reinterpret_cast<flat_binder_object*>(data+objects[i]);
- release_object(proc, *flat, this);
- }
-}
-
-void Parcel::acquireObjects()
-{
- const sp<ProcessState> proc(ProcessState::self());
- size_t i = mObjectsSize;
- uint8_t* const data = mData;
- size_t* const objects = mObjects;
- while (i > 0) {
- i--;
- const flat_binder_object* flat
- = reinterpret_cast<flat_binder_object*>(data+objects[i]);
- acquire_object(proc, *flat, this);
- }
-}
-
-void Parcel::freeData()
-{
- freeDataNoInit();
- initState();
-}
-
-void Parcel::freeDataNoInit()
-{
- if (mOwner) {
- //LOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
- mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
- } else {
- releaseObjects();
- if (mData) free(mData);
- if (mObjects) free(mObjects);
- }
-}
-
-status_t Parcel::growData(size_t len)
-{
- size_t newSize = ((mDataSize+len)*3)/2;
- return (newSize <= mDataSize)
- ? (status_t) NO_MEMORY
- : continueWrite(newSize);
-}
-
-status_t Parcel::restartWrite(size_t desired)
-{
- if (mOwner) {
- freeData();
- return continueWrite(desired);
- }
-
- uint8_t* data = (uint8_t*)realloc(mData, desired);
- if (!data && desired > mDataCapacity) {
- mError = NO_MEMORY;
- return NO_MEMORY;
- }
-
- releaseObjects();
-
- if (data) {
- mData = data;
- mDataCapacity = desired;
- }
-
- mDataSize = mDataPos = 0;
- LOGV("restartWrite Setting data size of %p to %d\n", this, mDataSize);
- LOGV("restartWrite Setting data pos of %p to %d\n", this, mDataPos);
-
- free(mObjects);
- mObjects = NULL;
- mObjectsSize = mObjectsCapacity = 0;
- mNextObjectHint = 0;
- mHasFds = false;
- mFdsKnown = true;
-
- return NO_ERROR;
-}
-
-status_t Parcel::continueWrite(size_t desired)
-{
- // If shrinking, first adjust for any objects that appear
- // after the new data size.
- size_t objectsSize = mObjectsSize;
- if (desired < mDataSize) {
- if (desired == 0) {
- objectsSize = 0;
- } else {
- while (objectsSize > 0) {
- if (mObjects[objectsSize-1] < desired)
- break;
- objectsSize--;
- }
- }
- }
-
- if (mOwner) {
- // If the size is going to zero, just release the owner's data.
- if (desired == 0) {
- freeData();
- return NO_ERROR;
- }
-
- // If there is a different owner, we need to take
- // posession.
- uint8_t* data = (uint8_t*)malloc(desired);
- if (!data) {
- mError = NO_MEMORY;
- return NO_MEMORY;
- }
- size_t* objects = NULL;
-
- if (objectsSize) {
- objects = (size_t*)malloc(objectsSize*sizeof(size_t));
- if (!objects) {
- mError = NO_MEMORY;
- return NO_MEMORY;
- }
-
- // Little hack to only acquire references on objects
- // we will be keeping.
- size_t oldObjectsSize = mObjectsSize;
- mObjectsSize = objectsSize;
- acquireObjects();
- mObjectsSize = oldObjectsSize;
- }
-
- if (mData) {
- memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
- }
- if (objects && mObjects) {
- memcpy(objects, mObjects, objectsSize*sizeof(size_t));
- }
- //LOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
- mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
- mOwner = NULL;
-
- mData = data;
- mObjects = objects;
- mDataSize = (mDataSize < desired) ? mDataSize : desired;
- LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
- mDataCapacity = desired;
- mObjectsSize = mObjectsCapacity = objectsSize;
- mNextObjectHint = 0;
-
- } else if (mData) {
- if (objectsSize < mObjectsSize) {
- // Need to release refs on any objects we are dropping.
- const sp<ProcessState> proc(ProcessState::self());
- for (size_t i=objectsSize; i<mObjectsSize; i++) {
- const flat_binder_object* flat
- = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
- if (flat->type == BINDER_TYPE_FD) {
- // will need to rescan because we may have lopped off the only FDs
- mFdsKnown = false;
- }
- release_object(proc, *flat, this);
- }
- size_t* objects =
- (size_t*)realloc(mObjects, objectsSize*sizeof(size_t));
- if (objects) {
- mObjects = objects;
- }
- mObjectsSize = objectsSize;
- mNextObjectHint = 0;
- }
-
- // We own the data, so we can just do a realloc().
- if (desired > mDataCapacity) {
- uint8_t* data = (uint8_t*)realloc(mData, desired);
- if (data) {
- mData = data;
- mDataCapacity = desired;
- } else if (desired > mDataCapacity) {
- mError = NO_MEMORY;
- return NO_MEMORY;
- }
- } else {
- mDataSize = desired;
- LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
- if (mDataPos > desired) {
- mDataPos = desired;
- LOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
- }
- }
-
- } else {
- // This is the first data. Easy!
- uint8_t* data = (uint8_t*)malloc(desired);
- if (!data) {
- mError = NO_MEMORY;
- return NO_MEMORY;
- }
-
- if(!(mDataCapacity == 0 && mObjects == NULL
- && mObjectsCapacity == 0)) {
- LOGE("continueWrite: %d/%p/%d/%d", mDataCapacity, mObjects, mObjectsCapacity, desired);
- }
-
- mData = data;
- mDataSize = mDataPos = 0;
- LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
- LOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
- mDataCapacity = desired;
- }
-
- return NO_ERROR;
-}
-
-void Parcel::initState()
-{
- mError = NO_ERROR;
- mData = 0;
- mDataSize = 0;
- mDataCapacity = 0;
- mDataPos = 0;
- LOGV("initState Setting data size of %p to %d\n", this, mDataSize);
- LOGV("initState Setting data pos of %p to %d\n", this, mDataPos);
- mObjects = NULL;
- mObjectsSize = 0;
- mObjectsCapacity = 0;
- mNextObjectHint = 0;
- mHasFds = false;
- mFdsKnown = true;
- mOwner = NULL;
-}
-
-void Parcel::scanForFds() const
-{
- bool hasFds = false;
- for (size_t i=0; i<mObjectsSize; i++) {
- const flat_binder_object* flat
- = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
- if (flat->type == BINDER_TYPE_FD) {
- hasFds = true;
- break;
- }
- }
- mHasFds = hasFds;
- mFdsKnown = true;
-}
-
-}; // namespace android
diff --git a/libs/utils/Pipe.cpp b/libs/utils/Pipe.cpp
deleted file mode 100644
index 613906b..0000000
--- a/libs/utils/Pipe.cpp
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Unidirectional pipe.
-//
-
-#include <utils/Pipe.h>
-#include <utils/Log.h>
-
-#if defined(HAVE_WIN32_IPC)
-# include <windows.h>
-#else
-# include <fcntl.h>
-# include <unistd.h>
-# include <errno.h>
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <string.h>
-
-using namespace android;
-
-const unsigned long kInvalidHandle = (unsigned long) -1;
-
-
-/*
- * Constructor. Do little.
- */
-Pipe::Pipe(void)
- : mReadNonBlocking(false), mReadHandle(kInvalidHandle),
- mWriteHandle(kInvalidHandle)
-{
-}
-
-/*
- * Destructor. Use the system-appropriate close call.
- */
-Pipe::~Pipe(void)
-{
-#if defined(HAVE_WIN32_IPC)
- if (mReadHandle != kInvalidHandle) {
- if (!CloseHandle((HANDLE)mReadHandle))
- LOG(LOG_WARN, "pipe", "failed closing read handle (%ld)\n",
- mReadHandle);
- }
- if (mWriteHandle != kInvalidHandle) {
- FlushFileBuffers((HANDLE)mWriteHandle);
- if (!CloseHandle((HANDLE)mWriteHandle))
- LOG(LOG_WARN, "pipe", "failed closing write handle (%ld)\n",
- mWriteHandle);
- }
-#else
- if (mReadHandle != kInvalidHandle) {
- if (close((int) mReadHandle) != 0)
- LOG(LOG_WARN, "pipe", "failed closing read fd (%d)\n",
- (int) mReadHandle);
- }
- if (mWriteHandle != kInvalidHandle) {
- if (close((int) mWriteHandle) != 0)
- LOG(LOG_WARN, "pipe", "failed closing write fd (%d)\n",
- (int) mWriteHandle);
- }
-#endif
-}
-
-/*
- * Create the pipe.
- *
- * Use the POSIX stuff for everything but Windows.
- */
-bool Pipe::create(void)
-{
- assert(mReadHandle == kInvalidHandle);
- assert(mWriteHandle == kInvalidHandle);
-
-#if defined(HAVE_WIN32_IPC)
- /* we use this across processes, so they need to be inheritable */
- HANDLE handles[2];
- SECURITY_ATTRIBUTES saAttr;
-
- saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
- saAttr.bInheritHandle = TRUE;
- saAttr.lpSecurityDescriptor = NULL;
-
- if (!CreatePipe(&handles[0], &handles[1], &saAttr, 0)) {
- LOG(LOG_ERROR, "pipe", "unable to create pipe\n");
- return false;
- }
- mReadHandle = (unsigned long) handles[0];
- mWriteHandle = (unsigned long) handles[1];
- return true;
-#else
- int fds[2];
-
- if (pipe(fds) != 0) {
- LOG(LOG_ERROR, "pipe", "unable to create pipe\n");
- return false;
- }
- mReadHandle = fds[0];
- mWriteHandle = fds[1];
- return true;
-#endif
-}
-
-/*
- * Create a "half pipe". Please, no Segway riding.
- */
-bool Pipe::createReader(unsigned long handle)
-{
- mReadHandle = handle;
- assert(mWriteHandle == kInvalidHandle);
- return true;
-}
-
-/*
- * Create a "half pipe" for writing.
- */
-bool Pipe::createWriter(unsigned long handle)
-{
- mWriteHandle = handle;
- assert(mReadHandle == kInvalidHandle);
- return true;
-}
-
-/*
- * Return "true" if create() has been called successfully.
- */
-bool Pipe::isCreated(void)
-{
- // one or the other should be open
- return (mReadHandle != kInvalidHandle || mWriteHandle != kInvalidHandle);
-}
-
-
-/*
- * Read data from the pipe.
- *
- * For Linux and Darwin, just call read(). For Windows, implement
- * non-blocking reads by calling PeekNamedPipe first.
- */
-int Pipe::read(void* buf, int count)
-{
- assert(mReadHandle != kInvalidHandle);
-
-#if defined(HAVE_WIN32_IPC)
- DWORD totalBytesAvail = count;
- DWORD bytesRead;
-
- if (mReadNonBlocking) {
- // use PeekNamedPipe to adjust read count expectations
- if (!PeekNamedPipe((HANDLE) mReadHandle, NULL, 0, NULL,
- &totalBytesAvail, NULL))
- {
- LOG(LOG_ERROR, "pipe", "PeekNamedPipe failed\n");
- return -1;
- }
-
- if (totalBytesAvail == 0)
- return 0;
- }
-
- if (!ReadFile((HANDLE) mReadHandle, buf, totalBytesAvail, &bytesRead,
- NULL))
- {
- DWORD err = GetLastError();
- if (err == ERROR_HANDLE_EOF || err == ERROR_BROKEN_PIPE)
- return 0;
- LOG(LOG_ERROR, "pipe", "ReadFile failed (err=%ld)\n", err);
- return -1;
- }
-
- return (int) bytesRead;
-#else
- int cc;
- cc = ::read(mReadHandle, buf, count);
- if (cc < 0 && errno == EAGAIN)
- return 0;
- return cc;
-#endif
-}
-
-/*
- * Write data to the pipe.
- *
- * POSIX systems are trivial, Windows uses a different call and doesn't
- * handle non-blocking writes.
- *
- * If we add non-blocking support here, we probably want to make it an
- * all-or-nothing write.
- *
- * DO NOT use LOG() here, we could be writing a log message.
- */
-int Pipe::write(const void* buf, int count)
-{
- assert(mWriteHandle != kInvalidHandle);
-
-#if defined(HAVE_WIN32_IPC)
- DWORD bytesWritten;
-
- if (mWriteNonBlocking) {
- // BUG: can't use PeekNamedPipe() to get the amount of space
- // left. Looks like we need to use "overlapped I/O" functions.
- // I just don't care that much.
- }
-
- if (!WriteFile((HANDLE) mWriteHandle, buf, count, &bytesWritten, NULL)) {
- // can't LOG, use stderr
- fprintf(stderr, "WriteFile failed (err=%ld)\n", GetLastError());
- return -1;
- }
-
- return (int) bytesWritten;
-#else
- int cc;
- cc = ::write(mWriteHandle, buf, count);
- if (cc < 0 && errno == EAGAIN)
- return 0;
- return cc;
-#endif
-}
-
-/*
- * Figure out if there is data available on the read fd.
- *
- * We return "true" on error because we want the caller to try to read
- * from the pipe. They'll notice the read failure and do something
- * appropriate.
- */
-bool Pipe::readReady(void)
-{
- assert(mReadHandle != kInvalidHandle);
-
-#if defined(HAVE_WIN32_IPC)
- DWORD totalBytesAvail;
-
- if (!PeekNamedPipe((HANDLE) mReadHandle, NULL, 0, NULL,
- &totalBytesAvail, NULL))
- {
- LOG(LOG_ERROR, "pipe", "PeekNamedPipe failed\n");
- return true;
- }
-
- return (totalBytesAvail != 0);
-#else
- errno = 0;
- fd_set readfds;
- struct timeval tv = { 0, 0 };
- int cc;
-
- FD_ZERO(&readfds);
- FD_SET(mReadHandle, &readfds);
-
- cc = select(mReadHandle+1, &readfds, NULL, NULL, &tv);
- if (cc < 0) {
- LOG(LOG_ERROR, "pipe", "select() failed\n");
- return true;
- } else if (cc == 0) {
- /* timed out, nothing available */
- return false;
- } else if (cc == 1) {
- /* our fd is ready */
- return true;
- } else {
- LOG(LOG_ERROR, "pipe", "HUH? select() returned > 1\n");
- return true;
- }
-#endif
-}
-
-/*
- * Enable or disable non-blocking mode for the read descriptor.
- *
- * NOTE: the calls succeed under Mac OS X, but the pipe doesn't appear to
- * actually be in non-blocking mode. If this matters -- i.e. you're not
- * using a select() call -- put a call to readReady() in front of the
- * ::read() call, with a PIPE_NONBLOCK_BROKEN #ifdef in the Makefile for
- * Darwin.
- */
-bool Pipe::setReadNonBlocking(bool val)
-{
- assert(mReadHandle != kInvalidHandle);
-
-#if defined(HAVE_WIN32_IPC)
- // nothing to do
-#else
- int flags;
-
- if (fcntl(mReadHandle, F_GETFL, &flags) == -1) {
- LOG(LOG_ERROR, "pipe", "couldn't get flags for pipe read fd\n");
- return false;
- }
- if (val)
- flags |= O_NONBLOCK;
- else
- flags &= ~(O_NONBLOCK);
- if (fcntl(mReadHandle, F_SETFL, &flags) == -1) {
- LOG(LOG_ERROR, "pipe", "couldn't set flags for pipe read fd\n");
- return false;
- }
-#endif
-
- mReadNonBlocking = val;
- return true;
-}
-
-/*
- * Enable or disable non-blocking mode for the write descriptor.
- *
- * As with setReadNonBlocking(), this does not work on the Mac.
- */
-bool Pipe::setWriteNonBlocking(bool val)
-{
- assert(mWriteHandle != kInvalidHandle);
-
-#if defined(HAVE_WIN32_IPC)
- // nothing to do
-#else
- int flags;
-
- if (fcntl(mWriteHandle, F_GETFL, &flags) == -1) {
- LOG(LOG_WARN, "pipe",
- "Warning: couldn't get flags for pipe write fd (errno=%d)\n",
- errno);
- return false;
- }
- if (val)
- flags |= O_NONBLOCK;
- else
- flags &= ~(O_NONBLOCK);
- if (fcntl(mWriteHandle, F_SETFL, &flags) == -1) {
- LOG(LOG_WARN, "pipe",
- "Warning: couldn't set flags for pipe write fd (errno=%d)\n",
- errno);
- return false;
- }
-#endif
-
- mWriteNonBlocking = val;
- return true;
-}
-
-/*
- * Specify whether a file descriptor can be inherited by a child process.
- * Under Linux this means setting the close-on-exec flag, under Windows
- * this is SetHandleInformation(HANDLE_FLAG_INHERIT).
- */
-bool Pipe::disallowReadInherit(void)
-{
- if (mReadHandle == kInvalidHandle)
- return false;
-
-#if defined(HAVE_WIN32_IPC)
- if (SetHandleInformation((HANDLE) mReadHandle, HANDLE_FLAG_INHERIT, 0) == 0)
- return false;
-#else
- if (fcntl((int) mReadHandle, F_SETFD, FD_CLOEXEC) != 0)
- return false;
-#endif
- return true;
-}
-bool Pipe::disallowWriteInherit(void)
-{
- if (mWriteHandle == kInvalidHandle)
- return false;
-
-#if defined(HAVE_WIN32_IPC)
- if (SetHandleInformation((HANDLE) mWriteHandle, HANDLE_FLAG_INHERIT, 0) == 0)
- return false;
-#else
- if (fcntl((int) mWriteHandle, F_SETFD, FD_CLOEXEC) != 0)
- return false;
-#endif
- return true;
-}
-
-/*
- * Close read descriptor.
- */
-bool Pipe::closeRead(void)
-{
- if (mReadHandle == kInvalidHandle)
- return false;
-
-#if defined(HAVE_WIN32_IPC)
- if (mReadHandle != kInvalidHandle) {
- if (!CloseHandle((HANDLE)mReadHandle)) {
- LOG(LOG_WARN, "pipe", "failed closing read handle\n");
- return false;
- }
- }
-#else
- if (mReadHandle != kInvalidHandle) {
- if (close((int) mReadHandle) != 0) {
- LOG(LOG_WARN, "pipe", "failed closing read fd\n");
- return false;
- }
- }
-#endif
- mReadHandle = kInvalidHandle;
- return true;
-}
-
-/*
- * Close write descriptor.
- */
-bool Pipe::closeWrite(void)
-{
- if (mWriteHandle == kInvalidHandle)
- return false;
-
-#if defined(HAVE_WIN32_IPC)
- if (mWriteHandle != kInvalidHandle) {
- if (!CloseHandle((HANDLE)mWriteHandle)) {
- LOG(LOG_WARN, "pipe", "failed closing write handle\n");
- return false;
- }
- }
-#else
- if (mWriteHandle != kInvalidHandle) {
- if (close((int) mWriteHandle) != 0) {
- LOG(LOG_WARN, "pipe", "failed closing write fd\n");
- return false;
- }
- }
-#endif
- mWriteHandle = kInvalidHandle;
- return true;
-}
-
-/*
- * Get the read handle.
- */
-unsigned long Pipe::getReadHandle(void)
-{
- assert(mReadHandle != kInvalidHandle);
-
- return mReadHandle;
-}
-
-/*
- * Get the write handle.
- */
-unsigned long Pipe::getWriteHandle(void)
-{
- assert(mWriteHandle != kInvalidHandle);
-
- return mWriteHandle;
-}
-
diff --git a/libs/utils/ProcessState.cpp b/libs/utils/ProcessState.cpp
deleted file mode 100644
index 4567df6..0000000
--- a/libs/utils/ProcessState.cpp
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "ProcessState"
-
-#include <cutils/process_name.h>
-
-#include <utils/ProcessState.h>
-
-#include <utils/Atomic.h>
-#include <utils/BpBinder.h>
-#include <utils/IPCThreadState.h>
-#include <utils/Log.h>
-#include <utils/String8.h>
-#include <utils/IServiceManager.h>
-#include <utils/String8.h>
-#include <utils/threads.h>
-
-#include <private/utils/binder_module.h>
-#include <private/utils/Static.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-
-#define BINDER_VM_SIZE (1*1024*1024)
-
-static bool gSingleProcess = false;
-
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-// Global variables
-int mArgC;
-const char* const* mArgV;
-int mArgLen;
-
-class PoolThread : public Thread
-{
-public:
- PoolThread(bool isMain)
- : mIsMain(isMain)
- {
- }
-
-protected:
- virtual bool threadLoop()
- {
- IPCThreadState::self()->joinThreadPool(mIsMain);
- return false;
- }
-
- const bool mIsMain;
-};
-
-sp<ProcessState> ProcessState::self()
-{
- if (gProcess != NULL) return gProcess;
-
- AutoMutex _l(gProcessMutex);
- if (gProcess == NULL) gProcess = new ProcessState;
- return gProcess;
-}
-
-void ProcessState::setSingleProcess(bool singleProcess)
-{
- gSingleProcess = singleProcess;
-}
-
-
-void ProcessState::setContextObject(const sp<IBinder>& object)
-{
- setContextObject(object, String16("default"));
-}
-
-sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
-{
- if (supportsProcesses()) {
- return getStrongProxyForHandle(0);
- } else {
- return getContextObject(String16("default"), caller);
- }
-}
-
-void ProcessState::setContextObject(const sp<IBinder>& object, const String16& name)
-{
- AutoMutex _l(mLock);
- mContexts.add(name, object);
-}
-
-sp<IBinder> ProcessState::getContextObject(const String16& name, const sp<IBinder>& caller)
-{
- mLock.lock();
- sp<IBinder> object(
- mContexts.indexOfKey(name) >= 0 ? mContexts.valueFor(name) : NULL);
- mLock.unlock();
-
- //printf("Getting context object %s for %p\n", String8(name).string(), caller.get());
-
- if (object != NULL) return object;
-
- // Don't attempt to retrieve contexts if we manage them
- if (mManagesContexts) {
- LOGE("getContextObject(%s) failed, but we manage the contexts!\n",
- String8(name).string());
- return NULL;
- }
-
- IPCThreadState* ipc = IPCThreadState::self();
- {
- Parcel data, reply;
- // no interface token on this magic transaction
- data.writeString16(name);
- data.writeStrongBinder(caller);
- status_t result = ipc->transact(0 /*magic*/, 0, data, &reply, 0);
- if (result == NO_ERROR) {
- object = reply.readStrongBinder();
- }
- }
-
- ipc->flushCommands();
-
- if (object != NULL) setContextObject(object, name);
- return object;
-}
-
-bool ProcessState::supportsProcesses() const
-{
- return mDriverFD >= 0;
-}
-
-void ProcessState::startThreadPool()
-{
- AutoMutex _l(mLock);
- if (!mThreadPoolStarted) {
- mThreadPoolStarted = true;
- spawnPooledThread(true);
- }
-}
-
-bool ProcessState::isContextManager(void) const
-{
- return mManagesContexts;
-}
-
-bool ProcessState::becomeContextManager(context_check_func checkFunc, void* userData)
-{
- if (!mManagesContexts) {
- AutoMutex _l(mLock);
- mBinderContextCheckFunc = checkFunc;
- mBinderContextUserData = userData;
- if (mDriverFD >= 0) {
- int dummy = 0;
-#if defined(HAVE_ANDROID_OS)
- status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
-#else
- status_t result = INVALID_OPERATION;
-#endif
- if (result == 0) {
- mManagesContexts = true;
- } else if (result == -1) {
- mBinderContextCheckFunc = NULL;
- mBinderContextUserData = NULL;
- LOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
- }
- } else {
- // If there is no driver, our only world is the local
- // process so we can always become the context manager there.
- mManagesContexts = true;
- }
- }
- return mManagesContexts;
-}
-
-ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
-{
- const size_t N=mHandleToObject.size();
- if (N <= (size_t)handle) {
- handle_entry e;
- e.binder = NULL;
- e.refs = NULL;
- status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
- if (err < NO_ERROR) return NULL;
- }
- return &mHandleToObject.editItemAt(handle);
-}
-
-sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
-{
- sp<IBinder> result;
-
- AutoMutex _l(mLock);
-
- handle_entry* e = lookupHandleLocked(handle);
-
- if (e != NULL) {
- // We need to create a new BpBinder if there isn't currently one, OR we
- // are unable to acquire a weak reference on this current one. See comment
- // in getWeakProxyForHandle() for more info about this.
- IBinder* b = e->binder;
- if (b == NULL || !e->refs->attemptIncWeak(this)) {
- b = new BpBinder(handle);
- e->binder = b;
- if (b) e->refs = b->getWeakRefs();
- result = b;
- } else {
- // This little bit of nastyness is to allow us to add a primary
- // reference to the remote proxy when this team doesn't have one
- // but another team is sending the handle to us.
- result.force_set(b);
- e->refs->decWeak(this);
- }
- }
-
- return result;
-}
-
-wp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle)
-{
- wp<IBinder> result;
-
- AutoMutex _l(mLock);
-
- handle_entry* e = lookupHandleLocked(handle);
-
- if (e != NULL) {
- // We need to create a new BpBinder if there isn't currently one, OR we
- // are unable to acquire a weak reference on this current one. The
- // attemptIncWeak() is safe because we know the BpBinder destructor will always
- // call expungeHandle(), which acquires the same lock we are holding now.
- // We need to do this because there is a race condition between someone
- // releasing a reference on this BpBinder, and a new reference on its handle
- // arriving from the driver.
- IBinder* b = e->binder;
- if (b == NULL || !e->refs->attemptIncWeak(this)) {
- b = new BpBinder(handle);
- result = b;
- e->binder = b;
- if (b) e->refs = b->getWeakRefs();
- } else {
- result = b;
- e->refs->decWeak(this);
- }
- }
-
- return result;
-}
-
-void ProcessState::expungeHandle(int32_t handle, IBinder* binder)
-{
- AutoMutex _l(mLock);
-
- handle_entry* e = lookupHandleLocked(handle);
-
- // This handle may have already been replaced with a new BpBinder
- // (if someone failed the AttemptIncWeak() above); we don't want
- // to overwrite it.
- if (e && e->binder == binder) e->binder = NULL;
-}
-
-void ProcessState::setArgs(int argc, const char* const argv[])
-{
- mArgC = argc;
- mArgV = (const char **)argv;
-
- mArgLen = 0;
- for (int i=0; i<argc; i++) {
- mArgLen += strlen(argv[i]) + 1;
- }
- mArgLen--;
-}
-
-int ProcessState::getArgC() const
-{
- return mArgC;
-}
-
-const char* const* ProcessState::getArgV() const
-{
- return mArgV;
-}
-
-void ProcessState::setArgV0(const char* txt)
-{
- if (mArgV != NULL) {
- strncpy((char*)mArgV[0], txt, mArgLen);
- set_process_name(txt);
- }
-}
-
-void ProcessState::spawnPooledThread(bool isMain)
-{
- if (mThreadPoolStarted) {
- int32_t s = android_atomic_add(1, &mThreadPoolSeq);
- char buf[32];
- sprintf(buf, "Binder Thread #%d", s);
- LOGV("Spawning new pooled thread, name=%s\n", buf);
- sp<Thread> t = new PoolThread(isMain);
- t->run(buf);
- }
-}
-
-static int open_driver()
-{
- if (gSingleProcess) {
- return -1;
- }
-
- int fd = open("/dev/binder", O_RDWR);
- if (fd >= 0) {
- fcntl(fd, F_SETFD, FD_CLOEXEC);
- int vers;
-#if defined(HAVE_ANDROID_OS)
- status_t result = ioctl(fd, BINDER_VERSION, &vers);
-#else
- status_t result = -1;
- errno = EPERM;
-#endif
- if (result == -1) {
- LOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
- close(fd);
- fd = -1;
- }
- if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
- LOGE("Binder driver protocol does not match user space protocol!");
- close(fd);
- fd = -1;
- }
-#if defined(HAVE_ANDROID_OS)
- size_t maxThreads = 15;
- result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
- if (result == -1) {
- LOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
- }
-#endif
-
- } else {
- LOGW("Opening '/dev/binder' failed: %s\n", strerror(errno));
- }
- return fd;
-}
-
-ProcessState::ProcessState()
- : mDriverFD(open_driver())
- , mVMStart(MAP_FAILED)
- , mManagesContexts(false)
- , mBinderContextCheckFunc(NULL)
- , mBinderContextUserData(NULL)
- , mThreadPoolStarted(false)
- , mThreadPoolSeq(1)
-{
- if (mDriverFD >= 0) {
- // XXX Ideally, there should be a specific define for whether we
- // have mmap (or whether we could possibly have the kernel module
- // availabla).
-#if !defined(HAVE_WIN32_IPC)
- // mmap the binder, providing a chunk of virtual address space to receive transactions.
- mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
- if (mVMStart == MAP_FAILED) {
- // *sigh*
- LOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
- close(mDriverFD);
- mDriverFD = -1;
- }
-#else
- mDriverFD = -1;
-#endif
- }
- if (mDriverFD < 0) {
- // Need to run without the driver, starting our own thread pool.
- }
-}
-
-ProcessState::~ProcessState()
-{
-}
-
-}; // namespace android
diff --git a/libs/utils/README b/libs/utils/README
deleted file mode 100644
index 36a706d..0000000
--- a/libs/utils/README
+++ /dev/null
@@ -1,14 +0,0 @@
-Android Utility Function Library
-
-If you need a feature that is native to Linux but not present on other
-platforms, construct a platform-dependent implementation that shares
-the Linux interface. That way the actual device runs as "light" as
-possible.
-
-If that isn't feasible, create a system-independent interface and hide
-the details.
-
-The ultimate goal is *not* to create a super-duper platform abstraction
-layer. The goal is to provide an optimized solution for Linux with
-reasonable implementations for other platforms.
-
diff --git a/libs/utils/RefBase.cpp b/libs/utils/RefBase.cpp
deleted file mode 100644
index 0bd1af4..0000000
--- a/libs/utils/RefBase.cpp
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "RefBase"
-
-#include <utils/RefBase.h>
-
-#include <utils/Atomic.h>
-#include <utils/CallStack.h>
-#include <utils/KeyedVector.h>
-#include <utils/Log.h>
-#include <utils/threads.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <typeinfo>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-// compile with refcounting debugging enabled
-#define DEBUG_REFS 0
-#define DEBUG_REFS_ENABLED_BY_DEFAULT 1
-#define DEBUG_REFS_CALLSTACK_ENABLED 1
-
-// log all reference counting operations
-#define PRINT_REFS 0
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-#define INITIAL_STRONG_VALUE (1<<28)
-
-// ---------------------------------------------------------------------------
-
-class RefBase::weakref_impl : public RefBase::weakref_type
-{
-public:
- volatile int32_t mStrong;
- volatile int32_t mWeak;
- RefBase* const mBase;
- volatile int32_t mFlags;
-
-
-#if !DEBUG_REFS
-
- weakref_impl(RefBase* base)
- : mStrong(INITIAL_STRONG_VALUE)
- , mWeak(0)
- , mBase(base)
- , mFlags(0)
- {
- }
-
- void addStrongRef(const void* /*id*/) { }
- void removeStrongRef(const void* /*id*/) { }
- void addWeakRef(const void* /*id*/) { }
- void removeWeakRef(const void* /*id*/) { }
- void printRefs() const { }
- void trackMe(bool, bool) { }
-
-#else
-
- weakref_impl(RefBase* base)
- : mStrong(INITIAL_STRONG_VALUE)
- , mWeak(0)
- , mBase(base)
- , mFlags(0)
- , mStrongRefs(NULL)
- , mWeakRefs(NULL)
- , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT)
- , mRetain(false)
- {
- //LOGI("NEW weakref_impl %p for RefBase %p", this, base);
- }
-
- ~weakref_impl()
- {
- LOG_ALWAYS_FATAL_IF(!mRetain && mStrongRefs != NULL, "Strong references remain!");
- LOG_ALWAYS_FATAL_IF(!mRetain && mWeakRefs != NULL, "Weak references remain!");
- }
-
- void addStrongRef(const void* id)
- {
- addRef(&mStrongRefs, id, mStrong);
- }
-
- void removeStrongRef(const void* id)
- {
- if (!mRetain)
- removeRef(&mStrongRefs, id);
- else
- addRef(&mStrongRefs, id, -mStrong);
- }
-
- void addWeakRef(const void* id)
- {
- addRef(&mWeakRefs, id, mWeak);
- }
-
- void removeWeakRef(const void* id)
- {
- if (!mRetain)
- removeRef(&mWeakRefs, id);
- else
- addRef(&mWeakRefs, id, -mWeak);
- }
-
- void trackMe(bool track, bool retain)
- {
- mTrackEnabled = track;
- mRetain = retain;
- }
-
- void printRefs() const
- {
- String8 text;
-
- {
- AutoMutex _l(const_cast<weakref_impl*>(this)->mMutex);
-
- char buf[128];
- sprintf(buf, "Strong references on RefBase %p (weakref_type %p):\n", mBase, this);
- text.append(buf);
- printRefsLocked(&text, mStrongRefs);
- sprintf(buf, "Weak references on RefBase %p (weakref_type %p):\n", mBase, this);
- text.append(buf);
- printRefsLocked(&text, mWeakRefs);
- }
-
- {
- char name[100];
- snprintf(name, 100, "/data/%p.stack", this);
- int rc = open(name, O_RDWR | O_CREAT | O_APPEND);
- if (rc >= 0) {
- write(rc, text.string(), text.length());
- close(rc);
- LOGD("STACK TRACE for %p saved in %s", this, name);
- }
- else LOGE("FAILED TO PRINT STACK TRACE for %p in %s: %s", this,
- name, strerror(errno));
- }
- }
-
-private:
- struct ref_entry
- {
- ref_entry* next;
- const void* id;
-#if DEBUG_REFS_CALLSTACK_ENABLED
- CallStack stack;
-#endif
- int32_t ref;
- };
-
- void addRef(ref_entry** refs, const void* id, int32_t mRef)
- {
- if (mTrackEnabled) {
- AutoMutex _l(mMutex);
- ref_entry* ref = new ref_entry;
- // Reference count at the time of the snapshot, but before the
- // update. Positive value means we increment, negative--we
- // decrement the reference count.
- ref->ref = mRef;
- ref->id = id;
-#if DEBUG_REFS_CALLSTACK_ENABLED
- ref->stack.update(2);
-#endif
-
- ref->next = *refs;
- *refs = ref;
- }
- }
-
- void removeRef(ref_entry** refs, const void* id)
- {
- if (mTrackEnabled) {
- AutoMutex _l(mMutex);
-
- ref_entry* ref = *refs;
- while (ref != NULL) {
- if (ref->id == id) {
- *refs = ref->next;
- delete ref;
- return;
- }
-
- refs = &ref->next;
- ref = *refs;
- }
-
- LOG_ALWAYS_FATAL("RefBase: removing id %p on RefBase %p (weakref_type %p) that doesn't exist!",
- id, mBase, this);
- }
- }
-
- void printRefsLocked(String8* out, const ref_entry* refs) const
- {
- char buf[128];
- while (refs) {
- char inc = refs->ref >= 0 ? '+' : '-';
- sprintf(buf, "\t%c ID %p (ref %d):\n",
- inc, refs->id, refs->ref);
- out->append(buf);
-#if DEBUG_REFS_CALLSTACK_ENABLED
- out->append(refs->stack.toString("\t\t"));
-#else
- out->append("\t\t(call stacks disabled)");
-#endif
- refs = refs->next;
- }
- }
-
- Mutex mMutex;
- ref_entry* mStrongRefs;
- ref_entry* mWeakRefs;
-
- bool mTrackEnabled;
- // Collect stack traces on addref and removeref, instead of deleting the stack references
- // on removeref that match the address ones.
- bool mRetain;
-
-#if 0
- void addRef(KeyedVector<const void*, int32_t>* refs, const void* id)
- {
- AutoMutex _l(mMutex);
- ssize_t i = refs->indexOfKey(id);
- if (i >= 0) {
- ++(refs->editValueAt(i));
- } else {
- i = refs->add(id, 1);
- }
- }
-
- void removeRef(KeyedVector<const void*, int32_t>* refs, const void* id)
- {
- AutoMutex _l(mMutex);
- ssize_t i = refs->indexOfKey(id);
- LOG_ALWAYS_FATAL_IF(i < 0, "RefBase: removing id %p that doesn't exist!", id);
- if (i >= 0) {
- int32_t val = --(refs->editValueAt(i));
- if (val == 0) {
- refs->removeItemsAt(i);
- }
- }
- }
-
- void printRefs(const KeyedVector<const void*, int32_t>& refs)
- {
- const size_t N=refs.size();
- for (size_t i=0; i<N; i++) {
- printf("\tID %p: %d remain\n", refs.keyAt(i), refs.valueAt(i));
- }
- }
-
- mutable Mutex mMutex;
- KeyedVector<const void*, int32_t> mStrongRefs;
- KeyedVector<const void*, int32_t> mWeakRefs;
-#endif
-
-#endif
-};
-
-// ---------------------------------------------------------------------------
-
-void RefBase::incStrong(const void* id) const
-{
- weakref_impl* const refs = mRefs;
- refs->addWeakRef(id);
- refs->incWeak(id);
-
- refs->addStrongRef(id);
- const int32_t c = android_atomic_inc(&refs->mStrong);
- LOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
-#if PRINT_REFS
- LOGD("incStrong of %p from %p: cnt=%d\n", this, id, c);
-#endif
- if (c != INITIAL_STRONG_VALUE) {
- return;
- }
-
- android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
- const_cast<RefBase*>(this)->onFirstRef();
-}
-
-void RefBase::decStrong(const void* id) const
-{
- weakref_impl* const refs = mRefs;
- refs->removeStrongRef(id);
- const int32_t c = android_atomic_dec(&refs->mStrong);
-#if PRINT_REFS
- LOGD("decStrong of %p from %p: cnt=%d\n", this, id, c);
-#endif
- LOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
- if (c == 1) {
- const_cast<RefBase*>(this)->onLastStrongRef(id);
- if ((refs->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {
- delete this;
- }
- }
- refs->removeWeakRef(id);
- refs->decWeak(id);
-}
-
-void RefBase::forceIncStrong(const void* id) const
-{
- weakref_impl* const refs = mRefs;
- refs->addWeakRef(id);
- refs->incWeak(id);
-
- refs->addStrongRef(id);
- const int32_t c = android_atomic_inc(&refs->mStrong);
- LOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow",
- refs);
-#if PRINT_REFS
- LOGD("forceIncStrong of %p from %p: cnt=%d\n", this, id, c);
-#endif
-
- switch (c) {
- case INITIAL_STRONG_VALUE:
- android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
- // fall through...
- case 0:
- const_cast<RefBase*>(this)->onFirstRef();
- }
-}
-
-int32_t RefBase::getStrongCount() const
-{
- return mRefs->mStrong;
-}
-
-
-
-RefBase* RefBase::weakref_type::refBase() const
-{
- return static_cast<const weakref_impl*>(this)->mBase;
-}
-
-void RefBase::weakref_type::incWeak(const void* id)
-{
- weakref_impl* const impl = static_cast<weakref_impl*>(this);
- impl->addWeakRef(id);
- const int32_t c = android_atomic_inc(&impl->mWeak);
- LOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
-}
-
-void RefBase::weakref_type::decWeak(const void* id)
-{
- weakref_impl* const impl = static_cast<weakref_impl*>(this);
- impl->removeWeakRef(id);
- const int32_t c = android_atomic_dec(&impl->mWeak);
- LOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
- if (c != 1) return;
-
- if ((impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {
- if (impl->mStrong == INITIAL_STRONG_VALUE)
- delete impl->mBase;
- else {
-// LOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
- delete impl;
- }
- } else {
- impl->mBase->onLastWeakRef(id);
- if ((impl->mFlags&OBJECT_LIFETIME_FOREVER) != OBJECT_LIFETIME_FOREVER) {
- delete impl->mBase;
- }
- }
-}
-
-bool RefBase::weakref_type::attemptIncStrong(const void* id)
-{
- incWeak(id);
-
- weakref_impl* const impl = static_cast<weakref_impl*>(this);
-
- int32_t curCount = impl->mStrong;
- LOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow",
- this);
- while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
- if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
- break;
- }
- curCount = impl->mStrong;
- }
-
- if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
- bool allow;
- if (curCount == INITIAL_STRONG_VALUE) {
- // Attempting to acquire first strong reference... this is allowed
- // if the object does NOT have a longer lifetime (meaning the
- // implementation doesn't need to see this), or if the implementation
- // allows it to happen.
- allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK
- || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
- } else {
- // Attempting to revive the object... this is allowed
- // if the object DOES have a longer lifetime (so we can safely
- // call the object with only a weak ref) and the implementation
- // allows it to happen.
- allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK
- && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
- }
- if (!allow) {
- decWeak(id);
- return false;
- }
- curCount = android_atomic_inc(&impl->mStrong);
-
- // If the strong reference count has already been incremented by
- // someone else, the implementor of onIncStrongAttempted() is holding
- // an unneeded reference. So call onLastStrongRef() here to remove it.
- // (No, this is not pretty.) Note that we MUST NOT do this if we
- // are in fact acquiring the first reference.
- if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) {
- impl->mBase->onLastStrongRef(id);
- }
- }
-
- impl->addWeakRef(id);
- impl->addStrongRef(id);
-
-#if PRINT_REFS
- LOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount);
-#endif
-
- if (curCount == INITIAL_STRONG_VALUE) {
- android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong);
- impl->mBase->onFirstRef();
- }
-
- return true;
-}
-
-bool RefBase::weakref_type::attemptIncWeak(const void* id)
-{
- weakref_impl* const impl = static_cast<weakref_impl*>(this);
-
- int32_t curCount = impl->mWeak;
- LOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow",
- this);
- while (curCount > 0) {
- if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mWeak) == 0) {
- break;
- }
- curCount = impl->mWeak;
- }
-
- if (curCount > 0) {
- impl->addWeakRef(id);
- }
-
- return curCount > 0;
-}
-
-int32_t RefBase::weakref_type::getWeakCount() const
-{
- return static_cast<const weakref_impl*>(this)->mWeak;
-}
-
-void RefBase::weakref_type::printRefs() const
-{
- static_cast<const weakref_impl*>(this)->printRefs();
-}
-
-void RefBase::weakref_type::trackMe(bool enable, bool retain)
-{
- static_cast<const weakref_impl*>(this)->trackMe(enable, retain);
-}
-
-RefBase::weakref_type* RefBase::createWeak(const void* id) const
-{
- mRefs->incWeak(id);
- return mRefs;
-}
-
-RefBase::weakref_type* RefBase::getWeakRefs() const
-{
- return mRefs;
-}
-
-RefBase::RefBase()
- : mRefs(new weakref_impl(this))
-{
-// LOGV("Creating refs %p with RefBase %p\n", mRefs, this);
-}
-
-RefBase::~RefBase()
-{
-// LOGV("Destroying RefBase %p (refs %p)\n", this, mRefs);
- if (mRefs->mWeak == 0) {
-// LOGV("Freeing refs %p of old RefBase %p\n", mRefs, this);
- delete mRefs;
- }
-}
-
-void RefBase::extendObjectLifetime(int32_t mode)
-{
- android_atomic_or(mode, &mRefs->mFlags);
-}
-
-void RefBase::onFirstRef()
-{
-}
-
-void RefBase::onLastStrongRef(const void* /*id*/)
-{
-}
-
-bool RefBase::onIncStrongAttempted(uint32_t flags, const void* id)
-{
- return (flags&FIRST_INC_STRONG) ? true : false;
-}
-
-void RefBase::onLastWeakRef(const void* /*id*/)
-{
-}
-
-}; // namespace android
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
deleted file mode 100644
index 71e7cd7..0000000
--- a/libs/utils/ResourceTypes.cpp
+++ /dev/null
@@ -1,3983 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "ResourceType"
-//#define LOG_NDEBUG 0
-
-#include <utils/Atomic.h>
-#include <utils/ByteOrder.h>
-#include <utils/Debug.h>
-#include <utils/ResourceTypes.h>
-#include <utils/String16.h>
-#include <utils/String8.h>
-#include <utils/TextOutput.h>
-#include <utils/Log.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <memory.h>
-#include <ctype.h>
-#include <stdint.h>
-
-#ifndef INT32_MAX
-#define INT32_MAX ((int32_t)(2147483647))
-#endif
-
-#define POOL_NOISY(x) //x
-#define XML_NOISY(x) //x
-#define TABLE_NOISY(x) //x
-#define TABLE_GETENTRY(x) //x
-#define TABLE_SUPER_NOISY(x) //x
-#define LOAD_TABLE_NOISY(x) //x
-
-namespace android {
-
-#ifdef HAVE_WINSOCK
-#undef nhtol
-#undef htonl
-
-#ifdef HAVE_LITTLE_ENDIAN
-#define ntohl(x) ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )
-#define htonl(x) ntohl(x)
-#define ntohs(x) ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) )
-#define htons(x) ntohs(x)
-#else
-#define ntohl(x) (x)
-#define htonl(x) (x)
-#define ntohs(x) (x)
-#define htons(x) (x)
-#endif
-#endif
-
-static void printToLogFunc(void* cookie, const char* txt)
-{
- LOGV("%s", txt);
-}
-
-// Standard C isspace() is only required to look at the low byte of its input, so
-// produces incorrect results for UTF-16 characters. For safety's sake, assume that
-// any high-byte UTF-16 code point is not whitespace.
-inline int isspace16(char16_t c) {
- return (c < 0x0080 && isspace(c));
-}
-
-// range checked; guaranteed to NUL-terminate within the stated number of available slots
-// NOTE: if this truncates the dst string due to running out of space, no attempt is
-// made to avoid splitting surrogate pairs.
-static void strcpy16_dtoh(uint16_t* dst, const uint16_t* src, size_t avail)
-{
- uint16_t* last = dst + avail - 1;
- while (*src && (dst < last)) {
- char16_t s = dtohs(*src);
- *dst++ = s;
- src++;
- }
- *dst = 0;
-}
-
-static status_t validate_chunk(const ResChunk_header* chunk,
- size_t minSize,
- const uint8_t* dataEnd,
- const char* name)
-{
- const uint16_t headerSize = dtohs(chunk->headerSize);
- const uint32_t size = dtohl(chunk->size);
-
- if (headerSize >= minSize) {
- if (headerSize <= size) {
- if (((headerSize|size)&0x3) == 0) {
- if ((ssize_t)size <= (dataEnd-((const uint8_t*)chunk))) {
- return NO_ERROR;
- }
- LOGW("%s data size %p extends beyond resource end %p.",
- name, (void*)size,
- (void*)(dataEnd-((const uint8_t*)chunk)));
- return BAD_TYPE;
- }
- LOGW("%s size 0x%x or headerSize 0x%x is not on an integer boundary.",
- name, (int)size, (int)headerSize);
- return BAD_TYPE;
- }
- LOGW("%s size %p is smaller than header size %p.",
- name, (void*)size, (void*)(int)headerSize);
- return BAD_TYPE;
- }
- LOGW("%s header size %p is too small.",
- name, (void*)(int)headerSize);
- return BAD_TYPE;
-}
-
-inline void Res_value::copyFrom_dtoh(const Res_value& src)
-{
- size = dtohs(src.size);
- res0 = src.res0;
- dataType = src.dataType;
- data = dtohl(src.data);
-}
-
-void Res_png_9patch::deviceToFile()
-{
- for (int i = 0; i < numXDivs; i++) {
- xDivs[i] = htonl(xDivs[i]);
- }
- for (int i = 0; i < numYDivs; i++) {
- yDivs[i] = htonl(yDivs[i]);
- }
- paddingLeft = htonl(paddingLeft);
- paddingRight = htonl(paddingRight);
- paddingTop = htonl(paddingTop);
- paddingBottom = htonl(paddingBottom);
- for (int i=0; i<numColors; i++) {
- colors[i] = htonl(colors[i]);
- }
-}
-
-void Res_png_9patch::fileToDevice()
-{
- for (int i = 0; i < numXDivs; i++) {
- xDivs[i] = ntohl(xDivs[i]);
- }
- for (int i = 0; i < numYDivs; i++) {
- yDivs[i] = ntohl(yDivs[i]);
- }
- paddingLeft = ntohl(paddingLeft);
- paddingRight = ntohl(paddingRight);
- paddingTop = ntohl(paddingTop);
- paddingBottom = ntohl(paddingBottom);
- for (int i=0; i<numColors; i++) {
- colors[i] = ntohl(colors[i]);
- }
-}
-
-size_t Res_png_9patch::serializedSize()
-{
- // The size of this struct is 32 bytes on the 32-bit target system
- // 4 * int8_t
- // 4 * int32_t
- // 3 * pointer
- return 32
- + numXDivs * sizeof(int32_t)
- + numYDivs * sizeof(int32_t)
- + numColors * sizeof(uint32_t);
-}
-
-void* Res_png_9patch::serialize()
-{
- void* newData = malloc(serializedSize());
- serialize(newData);
- return newData;
-}
-
-void Res_png_9patch::serialize(void * outData)
-{
- char* data = (char*) outData;
- memmove(data, &wasDeserialized, 4); // copy wasDeserialized, numXDivs, numYDivs, numColors
- memmove(data + 12, &paddingLeft, 16); // copy paddingXXXX
- data += 32;
-
- memmove(data, this->xDivs, numXDivs * sizeof(int32_t));
- data += numXDivs * sizeof(int32_t);
- memmove(data, this->yDivs, numYDivs * sizeof(int32_t));
- data += numYDivs * sizeof(int32_t);
- memmove(data, this->colors, numColors * sizeof(uint32_t));
-}
-
-static void deserializeInternal(const void* inData, Res_png_9patch* outData) {
- char* patch = (char*) inData;
- if (inData != outData) {
- memmove(&outData->wasDeserialized, patch, 4); // copy wasDeserialized, numXDivs, numYDivs, numColors
- memmove(&outData->paddingLeft, patch + 12, 4); // copy wasDeserialized, numXDivs, numYDivs, numColors
- }
- outData->wasDeserialized = true;
- char* data = (char*)outData;
- data += sizeof(Res_png_9patch);
- outData->xDivs = (int32_t*) data;
- data += outData->numXDivs * sizeof(int32_t);
- outData->yDivs = (int32_t*) data;
- data += outData->numYDivs * sizeof(int32_t);
- outData->colors = (uint32_t*) data;
-}
-
-Res_png_9patch* Res_png_9patch::deserialize(const void* inData)
-{
- if (sizeof(void*) != sizeof(int32_t)) {
- LOGE("Cannot deserialize on non 32-bit system\n");
- return NULL;
- }
- deserializeInternal(inData, (Res_png_9patch*) inData);
- return (Res_png_9patch*) inData;
-}
-
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-
-ResStringPool::ResStringPool()
- : mError(NO_INIT), mOwnedData(NULL)
-{
-}
-
-ResStringPool::ResStringPool(const void* data, size_t size, bool copyData)
- : mError(NO_INIT), mOwnedData(NULL)
-{
- setTo(data, size, copyData);
-}
-
-ResStringPool::~ResStringPool()
-{
- uninit();
-}
-
-status_t ResStringPool::setTo(const void* data, size_t size, bool copyData)
-{
- if (!data || !size) {
- return (mError=BAD_TYPE);
- }
-
- uninit();
-
- const bool notDeviceEndian = htods(0xf0) != 0xf0;
-
- if (copyData || notDeviceEndian) {
- mOwnedData = malloc(size);
- if (mOwnedData == NULL) {
- return (mError=NO_MEMORY);
- }
- memcpy(mOwnedData, data, size);
- data = mOwnedData;
- }
-
- mHeader = (const ResStringPool_header*)data;
-
- if (notDeviceEndian) {
- ResStringPool_header* h = const_cast<ResStringPool_header*>(mHeader);
- h->header.headerSize = dtohs(mHeader->header.headerSize);
- h->header.type = dtohs(mHeader->header.type);
- h->header.size = dtohl(mHeader->header.size);
- h->stringCount = dtohl(mHeader->stringCount);
- h->styleCount = dtohl(mHeader->styleCount);
- h->flags = dtohl(mHeader->flags);
- h->stringsStart = dtohl(mHeader->stringsStart);
- h->stylesStart = dtohl(mHeader->stylesStart);
- }
-
- if (mHeader->header.headerSize > mHeader->header.size
- || mHeader->header.size > size) {
- LOGW("Bad string block: header size %d or total size %d is larger than data size %d\n",
- (int)mHeader->header.headerSize, (int)mHeader->header.size, (int)size);
- return (mError=BAD_TYPE);
- }
- mSize = mHeader->header.size;
- mEntries = (const uint32_t*)
- (((const uint8_t*)data)+mHeader->header.headerSize);
-
- if (mHeader->stringCount > 0) {
- if ((mHeader->stringCount*sizeof(uint32_t) < mHeader->stringCount) // uint32 overflow?
- || (mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t)))
- > size) {
- LOGW("Bad string block: entry of %d items extends past data size %d\n",
- (int)(mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t))),
- (int)size);
- return (mError=BAD_TYPE);
- }
- mStrings = (const char16_t*)
- (((const uint8_t*)data)+mHeader->stringsStart);
- if (mHeader->stringsStart >= (mHeader->header.size-sizeof(uint16_t))) {
- LOGW("Bad string block: string pool starts at %d, after total size %d\n",
- (int)mHeader->stringsStart, (int)mHeader->header.size);
- return (mError=BAD_TYPE);
- }
- if (mHeader->styleCount == 0) {
- mStringPoolSize =
- (mHeader->header.size-mHeader->stringsStart)/sizeof(uint16_t);
- } else {
- // check invariant: styles follow the strings
- if (mHeader->stylesStart <= mHeader->stringsStart) {
- LOGW("Bad style block: style block starts at %d, before strings at %d\n",
- (int)mHeader->stylesStart, (int)mHeader->stringsStart);
- return (mError=BAD_TYPE);
- }
- mStringPoolSize =
- (mHeader->stylesStart-mHeader->stringsStart)/sizeof(uint16_t);
- }
-
- // check invariant: stringCount > 0 requires a string pool to exist
- if (mStringPoolSize == 0) {
- LOGW("Bad string block: stringCount is %d but pool size is 0\n", (int)mHeader->stringCount);
- return (mError=BAD_TYPE);
- }
-
- if (notDeviceEndian) {
- size_t i;
- uint32_t* e = const_cast<uint32_t*>(mEntries);
- for (i=0; i<mHeader->stringCount; i++) {
- e[i] = dtohl(mEntries[i]);
- }
- char16_t* s = const_cast<char16_t*>(mStrings);
- for (i=0; i<mStringPoolSize; i++) {
- s[i] = dtohs(mStrings[i]);
- }
- }
-
- if (mStrings[mStringPoolSize-1] != 0) {
- LOGW("Bad string block: last string is not 0-terminated\n");
- return (mError=BAD_TYPE);
- }
- } else {
- mStrings = NULL;
- mStringPoolSize = 0;
- }
-
- if (mHeader->styleCount > 0) {
- mEntryStyles = mEntries + mHeader->stringCount;
- // invariant: integer overflow in calculating mEntryStyles
- if (mEntryStyles < mEntries) {
- LOGW("Bad string block: integer overflow finding styles\n");
- return (mError=BAD_TYPE);
- }
-
- if (((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader) > (int)size) {
- LOGW("Bad string block: entry of %d styles extends past data size %d\n",
- (int)((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader),
- (int)size);
- return (mError=BAD_TYPE);
- }
- mStyles = (const uint32_t*)
- (((const uint8_t*)data)+mHeader->stylesStart);
- if (mHeader->stylesStart >= mHeader->header.size) {
- LOGW("Bad string block: style pool starts %d, after total size %d\n",
- (int)mHeader->stylesStart, (int)mHeader->header.size);
- return (mError=BAD_TYPE);
- }
- mStylePoolSize =
- (mHeader->header.size-mHeader->stylesStart)/sizeof(uint32_t);
-
- if (notDeviceEndian) {
- size_t i;
- uint32_t* e = const_cast<uint32_t*>(mEntryStyles);
- for (i=0; i<mHeader->styleCount; i++) {
- e[i] = dtohl(mEntryStyles[i]);
- }
- uint32_t* s = const_cast<uint32_t*>(mStyles);
- for (i=0; i<mStylePoolSize; i++) {
- s[i] = dtohl(mStyles[i]);
- }
- }
-
- const ResStringPool_span endSpan = {
- { htodl(ResStringPool_span::END) },
- htodl(ResStringPool_span::END), htodl(ResStringPool_span::END)
- };
- if (memcmp(&mStyles[mStylePoolSize-(sizeof(endSpan)/sizeof(uint32_t))],
- &endSpan, sizeof(endSpan)) != 0) {
- LOGW("Bad string block: last style is not 0xFFFFFFFF-terminated\n");
- return (mError=BAD_TYPE);
- }
- } else {
- mEntryStyles = NULL;
- mStyles = NULL;
- mStylePoolSize = 0;
- }
-
- return (mError=NO_ERROR);
-}
-
-status_t ResStringPool::getError() const
-{
- return mError;
-}
-
-void ResStringPool::uninit()
-{
- mError = NO_INIT;
- if (mOwnedData) {
- free(mOwnedData);
- mOwnedData = NULL;
- }
-}
-
-const uint16_t* ResStringPool::stringAt(size_t idx, size_t* outLen) const
-{
- if (mError == NO_ERROR && idx < mHeader->stringCount) {
- const uint32_t off = (mEntries[idx]/sizeof(uint16_t));
- if (off < (mStringPoolSize-1)) {
- const char16_t* str = mStrings+off;
- *outLen = *str;
- if ((*str)&0x8000) {
- str++;
- *outLen = (((*outLen)&0x7fff)<<16) + *str;
- }
- if ((uint32_t)(str+1+*outLen-mStrings) < mStringPoolSize) {
- return str+1;
- } else {
- LOGW("Bad string block: string #%d extends to %d, past end at %d\n",
- (int)idx, (int)(str+1+*outLen-mStrings), (int)mStringPoolSize);
- }
- } else {
- LOGW("Bad string block: string #%d entry is at %d, past end at %d\n",
- (int)idx, (int)(off*sizeof(uint16_t)),
- (int)(mStringPoolSize*sizeof(uint16_t)));
- }
- }
- return NULL;
-}
-
-const ResStringPool_span* ResStringPool::styleAt(const ResStringPool_ref& ref) const
-{
- return styleAt(ref.index);
-}
-
-const ResStringPool_span* ResStringPool::styleAt(size_t idx) const
-{
- if (mError == NO_ERROR && idx < mHeader->styleCount) {
- const uint32_t off = (mEntryStyles[idx]/sizeof(uint32_t));
- if (off < mStylePoolSize) {
- return (const ResStringPool_span*)(mStyles+off);
- } else {
- LOGW("Bad string block: style #%d entry is at %d, past end at %d\n",
- (int)idx, (int)(off*sizeof(uint32_t)),
- (int)(mStylePoolSize*sizeof(uint32_t)));
- }
- }
- return NULL;
-}
-
-ssize_t ResStringPool::indexOfString(const char16_t* str, size_t strLen) const
-{
- if (mError != NO_ERROR) {
- return mError;
- }
-
- size_t len;
-
- if (mHeader->flags&ResStringPool_header::SORTED_FLAG) {
- // Do a binary search for the string...
- ssize_t l = 0;
- ssize_t h = mHeader->stringCount-1;
-
- ssize_t mid;
- while (l <= h) {
- mid = l + (h - l)/2;
- const char16_t* s = stringAt(mid, &len);
- int c = s ? strzcmp16(s, len, str, strLen) : -1;
- POOL_NOISY(printf("Looking for %s, at %s, cmp=%d, l/mid/h=%d/%d/%d\n",
- String8(str).string(),
- String8(s).string(),
- c, (int)l, (int)mid, (int)h));
- if (c == 0) {
- return mid;
- } else if (c < 0) {
- l = mid + 1;
- } else {
- h = mid - 1;
- }
- }
- } else {
- // It is unusual to get the ID from an unsorted string block...
- // most often this happens because we want to get IDs for style
- // span tags; since those always appear at the end of the string
- // block, start searching at the back.
- for (int i=mHeader->stringCount-1; i>=0; i--) {
- const char16_t* s = stringAt(i, &len);
- POOL_NOISY(printf("Looking for %s, at %s, i=%d\n",
- String8(str, strLen).string(),
- String8(s).string(),
- i));
- if (s && strzcmp16(s, len, str, strLen) == 0) {
- return i;
- }
- }
- }
-
- return NAME_NOT_FOUND;
-}
-
-size_t ResStringPool::size() const
-{
- return (mError == NO_ERROR) ? mHeader->stringCount : 0;
-}
-
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-
-ResXMLParser::ResXMLParser(const ResXMLTree& tree)
- : mTree(tree), mEventCode(BAD_DOCUMENT)
-{
-}
-
-void ResXMLParser::restart()
-{
- mCurNode = NULL;
- mEventCode = mTree.mError == NO_ERROR ? START_DOCUMENT : BAD_DOCUMENT;
-}
-
-ResXMLParser::event_code_t ResXMLParser::getEventType() const
-{
- return mEventCode;
-}
-
-ResXMLParser::event_code_t ResXMLParser::next()
-{
- if (mEventCode == START_DOCUMENT) {
- mCurNode = mTree.mRootNode;
- mCurExt = mTree.mRootExt;
- return (mEventCode=mTree.mRootCode);
- } else if (mEventCode >= FIRST_CHUNK_CODE) {
- return nextNode();
- }
- return mEventCode;
-}
-
-const int32_t ResXMLParser::getCommentID() const
-{
- return mCurNode != NULL ? dtohl(mCurNode->comment.index) : -1;
-}
-
-const uint16_t* ResXMLParser::getComment(size_t* outLen) const
-{
- int32_t id = getCommentID();
- return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-const uint32_t ResXMLParser::getLineNumber() const
-{
- return mCurNode != NULL ? dtohl(mCurNode->lineNumber) : -1;
-}
-
-const int32_t ResXMLParser::getTextID() const
-{
- if (mEventCode == TEXT) {
- return dtohl(((const ResXMLTree_cdataExt*)mCurExt)->data.index);
- }
- return -1;
-}
-
-const uint16_t* ResXMLParser::getText(size_t* outLen) const
-{
- int32_t id = getTextID();
- return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-ssize_t ResXMLParser::getTextValue(Res_value* outValue) const
-{
- if (mEventCode == TEXT) {
- outValue->copyFrom_dtoh(((const ResXMLTree_cdataExt*)mCurExt)->typedData);
- return sizeof(Res_value);
- }
- return BAD_TYPE;
-}
-
-const int32_t ResXMLParser::getNamespacePrefixID() const
-{
- if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) {
- return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->prefix.index);
- }
- return -1;
-}
-
-const uint16_t* ResXMLParser::getNamespacePrefix(size_t* outLen) const
-{
- int32_t id = getNamespacePrefixID();
- //printf("prefix=%d event=%p\n", id, mEventCode);
- return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-const int32_t ResXMLParser::getNamespaceUriID() const
-{
- if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) {
- return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->uri.index);
- }
- return -1;
-}
-
-const uint16_t* ResXMLParser::getNamespaceUri(size_t* outLen) const
-{
- int32_t id = getNamespaceUriID();
- //printf("uri=%d event=%p\n", id, mEventCode);
- return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-const int32_t ResXMLParser::getElementNamespaceID() const
-{
- if (mEventCode == START_TAG) {
- return dtohl(((const ResXMLTree_attrExt*)mCurExt)->ns.index);
- }
- if (mEventCode == END_TAG) {
- return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->ns.index);
- }
- return -1;
-}
-
-const uint16_t* ResXMLParser::getElementNamespace(size_t* outLen) const
-{
- int32_t id = getElementNamespaceID();
- return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-const int32_t ResXMLParser::getElementNameID() const
-{
- if (mEventCode == START_TAG) {
- return dtohl(((const ResXMLTree_attrExt*)mCurExt)->name.index);
- }
- if (mEventCode == END_TAG) {
- return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->name.index);
- }
- return -1;
-}
-
-const uint16_t* ResXMLParser::getElementName(size_t* outLen) const
-{
- int32_t id = getElementNameID();
- return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-size_t ResXMLParser::getAttributeCount() const
-{
- if (mEventCode == START_TAG) {
- return dtohs(((const ResXMLTree_attrExt*)mCurExt)->attributeCount);
- }
- return 0;
-}
-
-const int32_t ResXMLParser::getAttributeNamespaceID(size_t idx) const
-{
- if (mEventCode == START_TAG) {
- const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
- if (idx < dtohs(tag->attributeCount)) {
- const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
- (((const uint8_t*)tag)
- + dtohs(tag->attributeStart)
- + (dtohs(tag->attributeSize)*idx));
- return dtohl(attr->ns.index);
- }
- }
- return -2;
-}
-
-const uint16_t* ResXMLParser::getAttributeNamespace(size_t idx, size_t* outLen) const
-{
- int32_t id = getAttributeNamespaceID(idx);
- //printf("attribute namespace=%d idx=%d event=%p\n", id, idx, mEventCode);
- //XML_NOISY(printf("getAttributeNamespace 0x%x=0x%x\n", idx, id));
- return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-const int32_t ResXMLParser::getAttributeNameID(size_t idx) const
-{
- if (mEventCode == START_TAG) {
- const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
- if (idx < dtohs(tag->attributeCount)) {
- const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
- (((const uint8_t*)tag)
- + dtohs(tag->attributeStart)
- + (dtohs(tag->attributeSize)*idx));
- return dtohl(attr->name.index);
- }
- }
- return -1;
-}
-
-const uint16_t* ResXMLParser::getAttributeName(size_t idx, size_t* outLen) const
-{
- int32_t id = getAttributeNameID(idx);
- //printf("attribute name=%d idx=%d event=%p\n", id, idx, mEventCode);
- //XML_NOISY(printf("getAttributeName 0x%x=0x%x\n", idx, id));
- return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-const uint32_t ResXMLParser::getAttributeNameResID(size_t idx) const
-{
- int32_t id = getAttributeNameID(idx);
- if (id >= 0 && (size_t)id < mTree.mNumResIds) {
- return dtohl(mTree.mResIds[id]);
- }
- return 0;
-}
-
-const int32_t ResXMLParser::getAttributeValueStringID(size_t idx) const
-{
- if (mEventCode == START_TAG) {
- const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
- if (idx < dtohs(tag->attributeCount)) {
- const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
- (((const uint8_t*)tag)
- + dtohs(tag->attributeStart)
- + (dtohs(tag->attributeSize)*idx));
- return dtohl(attr->rawValue.index);
- }
- }
- return -1;
-}
-
-const uint16_t* ResXMLParser::getAttributeStringValue(size_t idx, size_t* outLen) const
-{
- int32_t id = getAttributeValueStringID(idx);
- //XML_NOISY(printf("getAttributeValue 0x%x=0x%x\n", idx, id));
- return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-int32_t ResXMLParser::getAttributeDataType(size_t idx) const
-{
- if (mEventCode == START_TAG) {
- const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
- if (idx < dtohs(tag->attributeCount)) {
- const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
- (((const uint8_t*)tag)
- + dtohs(tag->attributeStart)
- + (dtohs(tag->attributeSize)*idx));
- return attr->typedValue.dataType;
- }
- }
- return Res_value::TYPE_NULL;
-}
-
-int32_t ResXMLParser::getAttributeData(size_t idx) const
-{
- if (mEventCode == START_TAG) {
- const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
- if (idx < dtohs(tag->attributeCount)) {
- const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
- (((const uint8_t*)tag)
- + dtohs(tag->attributeStart)
- + (dtohs(tag->attributeSize)*idx));
- return dtohl(attr->typedValue.data);
- }
- }
- return 0;
-}
-
-ssize_t ResXMLParser::getAttributeValue(size_t idx, Res_value* outValue) const
-{
- if (mEventCode == START_TAG) {
- const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
- if (idx < dtohs(tag->attributeCount)) {
- const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
- (((const uint8_t*)tag)
- + dtohs(tag->attributeStart)
- + (dtohs(tag->attributeSize)*idx));
- outValue->copyFrom_dtoh(attr->typedValue);
- return sizeof(Res_value);
- }
- }
- return BAD_TYPE;
-}
-
-ssize_t ResXMLParser::indexOfAttribute(const char* ns, const char* attr) const
-{
- String16 nsStr(ns != NULL ? ns : "");
- String16 attrStr(attr);
- return indexOfAttribute(ns ? nsStr.string() : NULL, ns ? nsStr.size() : 0,
- attrStr.string(), attrStr.size());
-}
-
-ssize_t ResXMLParser::indexOfAttribute(const char16_t* ns, size_t nsLen,
- const char16_t* attr, size_t attrLen) const
-{
- if (mEventCode == START_TAG) {
- const size_t N = getAttributeCount();
- for (size_t i=0; i<N; i++) {
- size_t curNsLen, curAttrLen;
- const char16_t* curNs = getAttributeNamespace(i, &curNsLen);
- const char16_t* curAttr = getAttributeName(i, &curAttrLen);
- //printf("%d: ns=%p attr=%p curNs=%p curAttr=%p\n",
- // i, ns, attr, curNs, curAttr);
- //printf(" --> attr=%s, curAttr=%s\n",
- // String8(attr).string(), String8(curAttr).string());
- if (attr && curAttr && (strzcmp16(attr, attrLen, curAttr, curAttrLen) == 0)) {
- if (ns == NULL) {
- if (curNs == NULL) return i;
- } else if (curNs != NULL) {
- //printf(" --> ns=%s, curNs=%s\n",
- // String8(ns).string(), String8(curNs).string());
- if (strzcmp16(ns, nsLen, curNs, curNsLen) == 0) return i;
- }
- }
- }
- }
-
- return NAME_NOT_FOUND;
-}
-
-ssize_t ResXMLParser::indexOfID() const
-{
- if (mEventCode == START_TAG) {
- const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->idIndex);
- if (idx > 0) return (idx-1);
- }
- return NAME_NOT_FOUND;
-}
-
-ssize_t ResXMLParser::indexOfClass() const
-{
- if (mEventCode == START_TAG) {
- const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->classIndex);
- if (idx > 0) return (idx-1);
- }
- return NAME_NOT_FOUND;
-}
-
-ssize_t ResXMLParser::indexOfStyle() const
-{
- if (mEventCode == START_TAG) {
- const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->styleIndex);
- if (idx > 0) return (idx-1);
- }
- return NAME_NOT_FOUND;
-}
-
-ResXMLParser::event_code_t ResXMLParser::nextNode()
-{
- if (mEventCode < 0) {
- return mEventCode;
- }
-
- do {
- const ResXMLTree_node* next = (const ResXMLTree_node*)
- (((const uint8_t*)mCurNode) + dtohl(mCurNode->header.size));
- //LOGW("Next node: prev=%p, next=%p\n", mCurNode, next);
-
- if (((const uint8_t*)next) >= mTree.mDataEnd) {
- mCurNode = NULL;
- return (mEventCode=END_DOCUMENT);
- }
-
- if (mTree.validateNode(next) != NO_ERROR) {
- mCurNode = NULL;
- return (mEventCode=BAD_DOCUMENT);
- }
-
- mCurNode = next;
- const uint16_t headerSize = dtohs(next->header.headerSize);
- const uint32_t totalSize = dtohl(next->header.size);
- mCurExt = ((const uint8_t*)next) + headerSize;
- size_t minExtSize = 0;
- event_code_t eventCode = (event_code_t)dtohs(next->header.type);
- switch ((mEventCode=eventCode)) {
- case RES_XML_START_NAMESPACE_TYPE:
- case RES_XML_END_NAMESPACE_TYPE:
- minExtSize = sizeof(ResXMLTree_namespaceExt);
- break;
- case RES_XML_START_ELEMENT_TYPE:
- minExtSize = sizeof(ResXMLTree_attrExt);
- break;
- case RES_XML_END_ELEMENT_TYPE:
- minExtSize = sizeof(ResXMLTree_endElementExt);
- break;
- case RES_XML_CDATA_TYPE:
- minExtSize = sizeof(ResXMLTree_cdataExt);
- break;
- default:
- LOGW("Unknown XML block: header type %d in node at %d\n",
- (int)dtohs(next->header.type),
- (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader)));
- continue;
- }
-
- if ((totalSize-headerSize) < minExtSize) {
- LOGW("Bad XML block: header type 0x%x in node at 0x%x has size %d, need %d\n",
- (int)dtohs(next->header.type),
- (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader)),
- (int)(totalSize-headerSize), (int)minExtSize);
- return (mEventCode=BAD_DOCUMENT);
- }
-
- //printf("CurNode=%p, CurExt=%p, headerSize=%d, minExtSize=%d\n",
- // mCurNode, mCurExt, headerSize, minExtSize);
-
- return eventCode;
- } while (true);
-}
-
-void ResXMLParser::getPosition(ResXMLParser::ResXMLPosition* pos) const
-{
- pos->eventCode = mEventCode;
- pos->curNode = mCurNode;
- pos->curExt = mCurExt;
-}
-
-void ResXMLParser::setPosition(const ResXMLParser::ResXMLPosition& pos)
-{
- mEventCode = pos.eventCode;
- mCurNode = pos.curNode;
- mCurExt = pos.curExt;
-}
-
-
-// --------------------------------------------------------------------
-
-static volatile int32_t gCount = 0;
-
-ResXMLTree::ResXMLTree()
- : ResXMLParser(*this)
- , mError(NO_INIT), mOwnedData(NULL)
-{
- //LOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1);
- restart();
-}
-
-ResXMLTree::ResXMLTree(const void* data, size_t size, bool copyData)
- : ResXMLParser(*this)
- , mError(NO_INIT), mOwnedData(NULL)
-{
- //LOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1);
- setTo(data, size, copyData);
-}
-
-ResXMLTree::~ResXMLTree()
-{
- //LOGI("Destroying ResXMLTree in %p #%d\n", this, android_atomic_dec(&gCount)-1);
- uninit();
-}
-
-status_t ResXMLTree::setTo(const void* data, size_t size, bool copyData)
-{
- uninit();
- mEventCode = START_DOCUMENT;
-
- if (copyData) {
- mOwnedData = malloc(size);
- if (mOwnedData == NULL) {
- return (mError=NO_MEMORY);
- }
- memcpy(mOwnedData, data, size);
- data = mOwnedData;
- }
-
- mHeader = (const ResXMLTree_header*)data;
- mSize = dtohl(mHeader->header.size);
- if (dtohs(mHeader->header.headerSize) > mSize || mSize > size) {
- LOGW("Bad XML block: header size %d or total size %d is larger than data size %d\n",
- (int)dtohs(mHeader->header.headerSize),
- (int)dtohl(mHeader->header.size), (int)size);
- mError = BAD_TYPE;
- restart();
- return mError;
- }
- mDataEnd = ((const uint8_t*)mHeader) + mSize;
-
- mStrings.uninit();
- mRootNode = NULL;
- mResIds = NULL;
- mNumResIds = 0;
-
- // First look for a couple interesting chunks: the string block
- // and first XML node.
- const ResChunk_header* chunk =
- (const ResChunk_header*)(((const uint8_t*)mHeader) + dtohs(mHeader->header.headerSize));
- const ResChunk_header* lastChunk = chunk;
- while (((const uint8_t*)chunk) < (mDataEnd-sizeof(ResChunk_header)) &&
- ((const uint8_t*)chunk) < (mDataEnd-dtohl(chunk->size))) {
- status_t err = validate_chunk(chunk, sizeof(ResChunk_header), mDataEnd, "XML");
- if (err != NO_ERROR) {
- mError = err;
- goto done;
- }
- const uint16_t type = dtohs(chunk->type);
- const size_t size = dtohl(chunk->size);
- XML_NOISY(printf("Scanning @ %p: type=0x%x, size=0x%x\n",
- (void*)(((uint32_t)chunk)-((uint32_t)mHeader)), type, size));
- if (type == RES_STRING_POOL_TYPE) {
- mStrings.setTo(chunk, size);
- } else if (type == RES_XML_RESOURCE_MAP_TYPE) {
- mResIds = (const uint32_t*)
- (((const uint8_t*)chunk)+dtohs(chunk->headerSize));
- mNumResIds = (dtohl(chunk->size)-dtohs(chunk->headerSize))/sizeof(uint32_t);
- } else if (type >= RES_XML_FIRST_CHUNK_TYPE
- && type <= RES_XML_LAST_CHUNK_TYPE) {
- if (validateNode((const ResXMLTree_node*)chunk) != NO_ERROR) {
- mError = BAD_TYPE;
- goto done;
- }
- mCurNode = (const ResXMLTree_node*)lastChunk;
- if (nextNode() == BAD_DOCUMENT) {
- mError = BAD_TYPE;
- goto done;
- }
- mRootNode = mCurNode;
- mRootExt = mCurExt;
- mRootCode = mEventCode;
- break;
- } else {
- XML_NOISY(printf("Skipping unknown chunk!\n"));
- }
- lastChunk = chunk;
- chunk = (const ResChunk_header*)
- (((const uint8_t*)chunk) + size);
- }
-
- if (mRootNode == NULL) {
- LOGW("Bad XML block: no root element node found\n");
- mError = BAD_TYPE;
- goto done;
- }
-
- mError = mStrings.getError();
-
-done:
- restart();
- return mError;
-}
-
-status_t ResXMLTree::getError() const
-{
- return mError;
-}
-
-void ResXMLTree::uninit()
-{
- mError = NO_INIT;
- if (mOwnedData) {
- free(mOwnedData);
- mOwnedData = NULL;
- }
- restart();
-}
-
-const ResStringPool& ResXMLTree::getStrings() const
-{
- return mStrings;
-}
-
-status_t ResXMLTree::validateNode(const ResXMLTree_node* node) const
-{
- const uint16_t eventCode = dtohs(node->header.type);
-
- status_t err = validate_chunk(
- &node->header, sizeof(ResXMLTree_node),
- mDataEnd, "ResXMLTree_node");
-
- if (err >= NO_ERROR) {
- // Only perform additional validation on START nodes
- if (eventCode != RES_XML_START_ELEMENT_TYPE) {
- return NO_ERROR;
- }
-
- const uint16_t headerSize = dtohs(node->header.headerSize);
- const uint32_t size = dtohl(node->header.size);
- const ResXMLTree_attrExt* attrExt = (const ResXMLTree_attrExt*)
- (((const uint8_t*)node) + headerSize);
- // check for sensical values pulled out of the stream so far...
- if ((size >= headerSize + sizeof(ResXMLTree_attrExt))
- && ((void*)attrExt > (void*)node)) {
- const size_t attrSize = ((size_t)dtohs(attrExt->attributeSize))
- * dtohs(attrExt->attributeCount);
- if ((dtohs(attrExt->attributeStart)+attrSize) <= (size-headerSize)) {
- return NO_ERROR;
- }
- LOGW("Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\n",
- (unsigned int)(dtohs(attrExt->attributeStart)+attrSize),
- (unsigned int)(size-headerSize));
- }
- else {
- LOGW("Bad XML start block: node header size 0x%x, size 0x%x\n",
- (unsigned int)headerSize, (unsigned int)size);
- }
- return BAD_TYPE;
- }
-
- return err;
-
-#if 0
- const bool isStart = dtohs(node->header.type) == RES_XML_START_ELEMENT_TYPE;
-
- const uint16_t headerSize = dtohs(node->header.headerSize);
- const uint32_t size = dtohl(node->header.size);
-
- if (headerSize >= (isStart ? sizeof(ResXMLTree_attrNode) : sizeof(ResXMLTree_node))) {
- if (size >= headerSize) {
- if (((const uint8_t*)node) <= (mDataEnd-size)) {
- if (!isStart) {
- return NO_ERROR;
- }
- if ((((size_t)dtohs(node->attributeSize))*dtohs(node->attributeCount))
- <= (size-headerSize)) {
- return NO_ERROR;
- }
- LOGW("Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\n",
- ((int)dtohs(node->attributeSize))*dtohs(node->attributeCount),
- (int)(size-headerSize));
- return BAD_TYPE;
- }
- LOGW("Bad XML block: node at 0x%x extends beyond data end 0x%x\n",
- (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)), (int)mSize);
- return BAD_TYPE;
- }
- LOGW("Bad XML block: node at 0x%x header size 0x%x smaller than total size 0x%x\n",
- (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)),
- (int)headerSize, (int)size);
- return BAD_TYPE;
- }
- LOGW("Bad XML block: node at 0x%x header size 0x%x too small\n",
- (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)),
- (int)headerSize);
- return BAD_TYPE;
-#endif
-}
-
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-
-struct ResTable::Header
-{
- Header() : ownedData(NULL), header(NULL) { }
-
- void* ownedData;
- const ResTable_header* header;
- size_t size;
- const uint8_t* dataEnd;
- size_t index;
- void* cookie;
-
- ResStringPool values;
-};
-
-struct ResTable::Type
-{
- Type(const Header* _header, const Package* _package, size_t count)
- : header(_header), package(_package), entryCount(count),
- typeSpec(NULL), typeSpecFlags(NULL) { }
- const Header* const header;
- const Package* const package;
- const size_t entryCount;
- const ResTable_typeSpec* typeSpec;
- const uint32_t* typeSpecFlags;
- Vector<const ResTable_type*> configs;
-};
-
-struct ResTable::Package
-{
- Package(const Header* _header, const ResTable_package* _package)
- : header(_header), package(_package) { }
- ~Package()
- {
- size_t i = types.size();
- while (i > 0) {
- i--;
- delete types[i];
- }
- }
-
- const Header* const header;
- const ResTable_package* const package;
- Vector<Type*> types;
-
- const Type* getType(size_t idx) const {
- return idx < types.size() ? types[idx] : NULL;
- }
-};
-
-// A group of objects describing a particular resource package.
-// The first in 'package' is always the root object (from the resource
-// table that defined the package); the ones after are skins on top of it.
-struct ResTable::PackageGroup
-{
- PackageGroup(const String16& _name, uint32_t _id)
- : name(_name), id(_id), typeCount(0), bags(NULL) { }
- ~PackageGroup() {
- clearBagCache();
- const size_t N = packages.size();
- for (size_t i=0; i<N; i++) {
- delete packages[i];
- }
- }
-
- void clearBagCache() {
- if (bags) {
- TABLE_NOISY(printf("bags=%p\n", bags));
- Package* pkg = packages[0];
- TABLE_NOISY(printf("typeCount=%x\n", typeCount));
- for (size_t i=0; i<typeCount; i++) {
- TABLE_NOISY(printf("type=%d\n", i));
- const Type* type = pkg->getType(i);
- if (type != NULL) {
- bag_set** typeBags = bags[i];
- TABLE_NOISY(printf("typeBags=%p\n", typeBags));
- if (typeBags) {
- TABLE_NOISY(printf("type->entryCount=%x\n", type->entryCount));
- const size_t N = type->entryCount;
- for (size_t j=0; j<N; j++) {
- if (typeBags[j] && typeBags[j] != (bag_set*)0xFFFFFFFF)
- free(typeBags[j]);
- }
- free(typeBags);
- }
- }
- }
- free(bags);
- bags = NULL;
- }
- }
-
- String16 const name;
- uint32_t const id;
- Vector<Package*> packages;
-
- // Taken from the root package.
- ResStringPool typeStrings;
- ResStringPool keyStrings;
- size_t typeCount;
-
- // Computed attribute bags, first indexed by the type and second
- // by the entry in that type.
- bag_set*** bags;
-};
-
-struct ResTable::bag_set
-{
- size_t numAttrs; // number in array
- size_t availAttrs; // total space in array
- uint32_t typeSpecFlags;
- // Followed by 'numAttr' bag_entry structures.
-};
-
-ResTable::Theme::Theme(const ResTable& table)
- : mTable(table)
-{
- memset(mPackages, 0, sizeof(mPackages));
-}
-
-ResTable::Theme::~Theme()
-{
- for (size_t i=0; i<Res_MAXPACKAGE; i++) {
- package_info* pi = mPackages[i];
- if (pi != NULL) {
- free_package(pi);
- }
- }
-}
-
-void ResTable::Theme::free_package(package_info* pi)
-{
- for (size_t j=0; j<pi->numTypes; j++) {
- theme_entry* te = pi->types[j].entries;
- if (te != NULL) {
- free(te);
- }
- }
- free(pi);
-}
-
-ResTable::Theme::package_info* ResTable::Theme::copy_package(package_info* pi)
-{
- package_info* newpi = (package_info*)malloc(
- sizeof(package_info) + (pi->numTypes*sizeof(type_info)));
- newpi->numTypes = pi->numTypes;
- for (size_t j=0; j<newpi->numTypes; j++) {
- size_t cnt = pi->types[j].numEntries;
- newpi->types[j].numEntries = cnt;
- theme_entry* te = pi->types[j].entries;
- if (te != NULL) {
- theme_entry* newte = (theme_entry*)malloc(cnt*sizeof(theme_entry));
- newpi->types[j].entries = newte;
- memcpy(newte, te, cnt*sizeof(theme_entry));
- } else {
- newpi->types[j].entries = NULL;
- }
- }
- return newpi;
-}
-
-status_t ResTable::Theme::applyStyle(uint32_t resID, bool force)
-{
- const bag_entry* bag;
- uint32_t bagTypeSpecFlags = 0;
- mTable.lock();
- const ssize_t N = mTable.getBagLocked(resID, &bag, &bagTypeSpecFlags);
- TABLE_NOISY(LOGV("Applying style 0x%08x to theme %p, count=%d", resID, this, N));
- if (N < 0) {
- mTable.unlock();
- return N;
- }
-
- uint32_t curPackage = 0xffffffff;
- ssize_t curPackageIndex = 0;
- package_info* curPI = NULL;
- uint32_t curType = 0xffffffff;
- size_t numEntries = 0;
- theme_entry* curEntries = NULL;
-
- const bag_entry* end = bag + N;
- while (bag < end) {
- const uint32_t attrRes = bag->map.name.ident;
- const uint32_t p = Res_GETPACKAGE(attrRes);
- const uint32_t t = Res_GETTYPE(attrRes);
- const uint32_t e = Res_GETENTRY(attrRes);
-
- if (curPackage != p) {
- const ssize_t pidx = mTable.getResourcePackageIndex(attrRes);
- if (pidx < 0) {
- LOGE("Style contains key with bad package: 0x%08x\n", attrRes);
- bag++;
- continue;
- }
- curPackage = p;
- curPackageIndex = pidx;
- curPI = mPackages[pidx];
- if (curPI == NULL) {
- PackageGroup* const grp = mTable.mPackageGroups[pidx];
- int cnt = grp->typeCount;
- curPI = (package_info*)malloc(
- sizeof(package_info) + (cnt*sizeof(type_info)));
- curPI->numTypes = cnt;
- memset(curPI->types, 0, cnt*sizeof(type_info));
- mPackages[pidx] = curPI;
- }
- curType = 0xffffffff;
- }
- if (curType != t) {
- if (t >= curPI->numTypes) {
- LOGE("Style contains key with bad type: 0x%08x\n", attrRes);
- bag++;
- continue;
- }
- curType = t;
- curEntries = curPI->types[t].entries;
- if (curEntries == NULL) {
- PackageGroup* const grp = mTable.mPackageGroups[curPackageIndex];
- const Type* type = grp->packages[0]->getType(t);
- int cnt = type != NULL ? type->entryCount : 0;
- curEntries = (theme_entry*)malloc(cnt*sizeof(theme_entry));
- memset(curEntries, Res_value::TYPE_NULL, cnt*sizeof(theme_entry));
- curPI->types[t].numEntries = cnt;
- curPI->types[t].entries = curEntries;
- }
- numEntries = curPI->types[t].numEntries;
- }
- if (e >= numEntries) {
- LOGE("Style contains key with bad entry: 0x%08x\n", attrRes);
- bag++;
- continue;
- }
- theme_entry* curEntry = curEntries + e;
- TABLE_NOISY(LOGV("Attr 0x%08x: type=0x%x, data=0x%08x; curType=0x%x",
- attrRes, bag->map.value.dataType, bag->map.value.data,
- curEntry->value.dataType));
- if (force || curEntry->value.dataType == Res_value::TYPE_NULL) {
- curEntry->stringBlock = bag->stringBlock;
- curEntry->typeSpecFlags |= bagTypeSpecFlags;
- curEntry->value = bag->map.value;
- }
-
- bag++;
- }
-
- mTable.unlock();
-
- //LOGI("Applying style 0x%08x (force=%d) theme %p...\n", resID, force, this);
- //dumpToLog();
-
- return NO_ERROR;
-}
-
-status_t ResTable::Theme::setTo(const Theme& other)
-{
- //LOGI("Setting theme %p from theme %p...\n", this, &other);
- //dumpToLog();
- //other.dumpToLog();
-
- if (&mTable == &other.mTable) {
- for (size_t i=0; i<Res_MAXPACKAGE; i++) {
- if (mPackages[i] != NULL) {
- free_package(mPackages[i]);
- }
- if (other.mPackages[i] != NULL) {
- mPackages[i] = copy_package(other.mPackages[i]);
- } else {
- mPackages[i] = NULL;
- }
- }
- } else {
- // @todo: need to really implement this, not just copy
- // the system package (which is still wrong because it isn't
- // fixing up resource references).
- for (size_t i=0; i<Res_MAXPACKAGE; i++) {
- if (mPackages[i] != NULL) {
- free_package(mPackages[i]);
- }
- if (i == 0 && other.mPackages[i] != NULL) {
- mPackages[i] = copy_package(other.mPackages[i]);
- } else {
- mPackages[i] = NULL;
- }
- }
- }
-
- //LOGI("Final theme:");
- //dumpToLog();
-
- return NO_ERROR;
-}
-
-ssize_t ResTable::Theme::getAttribute(uint32_t resID, Res_value* outValue,
- uint32_t* outTypeSpecFlags) const
-{
- int cnt = 20;
-
- if (outTypeSpecFlags != NULL) *outTypeSpecFlags = 0;
-
- do {
- const ssize_t p = mTable.getResourcePackageIndex(resID);
- const uint32_t t = Res_GETTYPE(resID);
- const uint32_t e = Res_GETENTRY(resID);
-
- TABLE_NOISY(LOGV("Looking up attr 0x%08x in theme %p", resID, this));
-
- if (p >= 0) {
- const package_info* const pi = mPackages[p];
- if (pi != NULL) {
- if (t < pi->numTypes) {
- const type_info& ti = pi->types[t];
- if (e < ti.numEntries) {
- const theme_entry& te = ti.entries[e];
- if (outTypeSpecFlags != NULL) {
- *outTypeSpecFlags |= te.typeSpecFlags;
- }
- const uint8_t type = te.value.dataType;
- if (type == Res_value::TYPE_ATTRIBUTE) {
- if (cnt > 0) {
- cnt--;
- resID = te.value.data;
- continue;
- }
- LOGW("Too many attribute references, stopped at: 0x%08x\n", resID);
- return BAD_INDEX;
- } else if (type != Res_value::TYPE_NULL) {
- *outValue = te.value;
- return te.stringBlock;
- }
- return BAD_INDEX;
- }
- }
- }
- }
- break;
-
- } while (true);
-
- return BAD_INDEX;
-}
-
-ssize_t ResTable::Theme::resolveAttributeReference(Res_value* inOutValue,
- ssize_t blockIndex, uint32_t* outLastRef,
- uint32_t* inoutTypeSpecFlags) const
-{
- //printf("Resolving type=0x%x\n", inOutValue->dataType);
- if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) {
- uint32_t newTypeSpecFlags;
- blockIndex = getAttribute(inOutValue->data, inOutValue, &newTypeSpecFlags);
- if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newTypeSpecFlags;
- //printf("Retrieved attribute new type=0x%x\n", inOutValue->dataType);
- if (blockIndex < 0) {
- return blockIndex;
- }
- }
- return mTable.resolveReference(inOutValue, blockIndex, outLastRef);
-}
-
-void ResTable::Theme::dumpToLog() const
-{
- LOGI("Theme %p:\n", this);
- for (size_t i=0; i<Res_MAXPACKAGE; i++) {
- package_info* pi = mPackages[i];
- if (pi == NULL) continue;
-
- LOGI(" Package #0x%02x:\n", (int)(i+1));
- for (size_t j=0; j<pi->numTypes; j++) {
- type_info& ti = pi->types[j];
- if (ti.numEntries == 0) continue;
-
- LOGI(" Type #0x%02x:\n", (int)(j+1));
- for (size_t k=0; k<ti.numEntries; k++) {
- theme_entry& te = ti.entries[k];
- if (te.value.dataType == Res_value::TYPE_NULL) continue;
- LOGI(" 0x%08x: t=0x%x, d=0x%08x (block=%d)\n",
- (int)Res_MAKEID(i, j, k),
- te.value.dataType, (int)te.value.data, (int)te.stringBlock);
- }
- }
- }
-}
-
-ResTable::ResTable()
- : mError(NO_INIT)
-{
- memset(&mParams, 0, sizeof(mParams));
- memset(mPackageMap, 0, sizeof(mPackageMap));
- //LOGI("Creating ResTable %p\n", this);
-}
-
-ResTable::ResTable(const void* data, size_t size, void* cookie, bool copyData)
- : mError(NO_INIT)
-{
- memset(&mParams, 0, sizeof(mParams));
- memset(mPackageMap, 0, sizeof(mPackageMap));
- add(data, size, cookie, copyData);
- LOG_FATAL_IF(mError != NO_ERROR, "Error parsing resource table");
- //LOGI("Creating ResTable %p\n", this);
-}
-
-ResTable::~ResTable()
-{
- //LOGI("Destroying ResTable in %p\n", this);
- uninit();
-}
-
-inline ssize_t ResTable::getResourcePackageIndex(uint32_t resID) const
-{
- return ((ssize_t)mPackageMap[Res_GETPACKAGE(resID)+1])-1;
-}
-
-status_t ResTable::add(const void* data, size_t size, void* cookie, bool copyData)
-{
- return add(data, size, cookie, NULL, copyData);
-}
-
-status_t ResTable::add(Asset* asset, void* cookie, bool copyData)
-{
- const void* data = asset->getBuffer(true);
- if (data == NULL) {
- LOGW("Unable to get buffer of resource asset file");
- return UNKNOWN_ERROR;
- }
- size_t size = (size_t)asset->getLength();
- return add(data, size, cookie, asset, copyData);
-}
-
-status_t ResTable::add(const void* data, size_t size, void* cookie,
- Asset* asset, bool copyData)
-{
- if (!data) return NO_ERROR;
- Header* header = new Header;
- header->index = mHeaders.size();
- header->cookie = cookie;
- mHeaders.add(header);
-
- const bool notDeviceEndian = htods(0xf0) != 0xf0;
-
- LOAD_TABLE_NOISY(
- LOGV("Adding resources to ResTable: data=%p, size=0x%x, cookie=%p, asset=%p, copy=%d\n",
- data, size, cookie, asset, copyData));
-
- if (copyData || notDeviceEndian) {
- header->ownedData = malloc(size);
- if (header->ownedData == NULL) {
- return (mError=NO_MEMORY);
- }
- memcpy(header->ownedData, data, size);
- data = header->ownedData;
- }
-
- header->header = (const ResTable_header*)data;
- header->size = dtohl(header->header->header.size);
- //LOGI("Got size 0x%x, again size 0x%x, raw size 0x%x\n", header->size,
- // dtohl(header->header->header.size), header->header->header.size);
- LOAD_TABLE_NOISY(LOGV("Loading ResTable @%p:\n", header->header));
- LOAD_TABLE_NOISY(printHexData(2, header->header, header->size < 256 ? header->size : 256,
- 16, 16, 0, false, printToLogFunc));
- if (dtohs(header->header->header.headerSize) > header->size
- || header->size > size) {
- LOGW("Bad resource table: header size 0x%x or total size 0x%x is larger than data size 0x%x\n",
- (int)dtohs(header->header->header.headerSize),
- (int)header->size, (int)size);
- return (mError=BAD_TYPE);
- }
- if (((dtohs(header->header->header.headerSize)|header->size)&0x3) != 0) {
- LOGW("Bad resource table: header size 0x%x or total size 0x%x is not on an integer boundary\n",
- (int)dtohs(header->header->header.headerSize),
- (int)header->size);
- return (mError=BAD_TYPE);
- }
- header->dataEnd = ((const uint8_t*)header->header) + header->size;
-
- // Iterate through all chunks.
- size_t curPackage = 0;
-
- const ResChunk_header* chunk =
- (const ResChunk_header*)(((const uint8_t*)header->header)
- + dtohs(header->header->header.headerSize));
- while (((const uint8_t*)chunk) <= (header->dataEnd-sizeof(ResChunk_header)) &&
- ((const uint8_t*)chunk) <= (header->dataEnd-dtohl(chunk->size))) {
- status_t err = validate_chunk(chunk, sizeof(ResChunk_header), header->dataEnd, "ResTable");
- if (err != NO_ERROR) {
- return (mError=err);
- }
- TABLE_NOISY(LOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
- dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
- (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
- const size_t csize = dtohl(chunk->size);
- const uint16_t ctype = dtohs(chunk->type);
- if (ctype == RES_STRING_POOL_TYPE) {
- if (header->values.getError() != NO_ERROR) {
- // Only use the first string chunk; ignore any others that
- // may appear.
- status_t err = header->values.setTo(chunk, csize);
- if (err != NO_ERROR) {
- return (mError=err);
- }
- } else {
- LOGW("Multiple string chunks found in resource table.");
- }
- } else if (ctype == RES_TABLE_PACKAGE_TYPE) {
- if (curPackage >= dtohl(header->header->packageCount)) {
- LOGW("More package chunks were found than the %d declared in the header.",
- dtohl(header->header->packageCount));
- return (mError=BAD_TYPE);
- }
- if (parsePackage((ResTable_package*)chunk, header) != NO_ERROR) {
- return mError;
- }
- curPackage++;
- } else {
- LOGW("Unknown chunk type %p in table at %p.\n",
- (void*)(int)(ctype),
- (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header)));
- }
- chunk = (const ResChunk_header*)
- (((const uint8_t*)chunk) + csize);
- }
-
- if (curPackage < dtohl(header->header->packageCount)) {
- LOGW("Fewer package chunks (%d) were found than the %d declared in the header.",
- (int)curPackage, dtohl(header->header->packageCount));
- return (mError=BAD_TYPE);
- }
- mError = header->values.getError();
- if (mError != NO_ERROR) {
- LOGW("No string values found in resource table!");
- }
- TABLE_NOISY(LOGV("Returning from add with mError=%d\n", mError));
- return mError;
-}
-
-status_t ResTable::getError() const
-{
- return mError;
-}
-
-void ResTable::uninit()
-{
- mError = NO_INIT;
- size_t N = mPackageGroups.size();
- for (size_t i=0; i<N; i++) {
- PackageGroup* g = mPackageGroups[i];
- delete g;
- }
- N = mHeaders.size();
- for (size_t i=0; i<N; i++) {
- Header* header = mHeaders[i];
- if (header->ownedData) {
- free(header->ownedData);
- }
- delete header;
- }
-
- mPackageGroups.clear();
- mHeaders.clear();
-}
-
-bool ResTable::getResourceName(uint32_t resID, resource_name* outName) const
-{
- if (mError != NO_ERROR) {
- return false;
- }
-
- const ssize_t p = getResourcePackageIndex(resID);
- const int t = Res_GETTYPE(resID);
- const int e = Res_GETENTRY(resID);
-
- if (p < 0) {
- LOGW("No package identifier when getting name for resource number 0x%08x", resID);
- return false;
- }
- if (t < 0) {
- LOGW("No type identifier when getting name for resource number 0x%08x", resID);
- return false;
- }
-
- const PackageGroup* const grp = mPackageGroups[p];
- if (grp == NULL) {
- LOGW("Bad identifier when getting name for resource number 0x%08x", resID);
- return false;
- }
- if (grp->packages.size() > 0) {
- const Package* const package = grp->packages[0];
-
- const ResTable_type* type;
- const ResTable_entry* entry;
- ssize_t offset = getEntry(package, t, e, NULL, &type, &entry, NULL);
- if (offset <= 0) {
- return false;
- }
-
- outName->package = grp->name.string();
- outName->packageLen = grp->name.size();
- outName->type = grp->typeStrings.stringAt(t, &outName->typeLen);
- outName->name = grp->keyStrings.stringAt(
- dtohl(entry->key.index), &outName->nameLen);
- return true;
- }
-
- return false;
-}
-
-ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag,
- uint32_t* outSpecFlags, ResTable_config* outConfig) const
-{
- if (mError != NO_ERROR) {
- return mError;
- }
-
- const ssize_t p = getResourcePackageIndex(resID);
- const int t = Res_GETTYPE(resID);
- const int e = Res_GETENTRY(resID);
-
- if (p < 0) {
- LOGW("No package identifier when getting value for resource number 0x%08x", resID);
- return BAD_INDEX;
- }
- if (t < 0) {
- LOGW("No type identifier when getting value for resource number 0x%08x", resID);
- return BAD_INDEX;
- }
-
- const Res_value* bestValue = NULL;
- const Package* bestPackage = NULL;
- ResTable_config bestItem;
- memset(&bestItem, 0, sizeof(bestItem)); // make the compiler shut up
-
- if (outSpecFlags != NULL) *outSpecFlags = 0;
-
- // Look through all resource packages, starting with the most
- // recently added.
- const PackageGroup* const grp = mPackageGroups[p];
- if (grp == NULL) {
- LOGW("Bad identifier when getting value for resource number 0x%08x", resID);
- return false;
- }
- size_t ip = grp->packages.size();
- while (ip > 0) {
- ip--;
-
- const Package* const package = grp->packages[ip];
-
- const ResTable_type* type;
- const ResTable_entry* entry;
- const Type* typeClass;
- ssize_t offset = getEntry(package, t, e, &mParams, &type, &entry, &typeClass);
- if (offset <= 0) {
- if (offset < 0) {
- LOGW("Failure getting entry for 0x%08x (t=%d e=%d) in package %d: 0x%08x\n",
- resID, t, e, (int)ip, (int)offset);
- return offset;
- }
- continue;
- }
-
- if ((dtohs(entry->flags)&entry->FLAG_COMPLEX) != 0) {
- if (!mayBeBag) {
- LOGW("Requesting resource %p failed because it is complex\n",
- (void*)resID);
- }
- continue;
- }
-
- TABLE_NOISY(aout << "Resource type data: "
- << HexDump(type, dtohl(type->header.size)) << endl);
-
- if ((size_t)offset > (dtohl(type->header.size)-sizeof(Res_value))) {
- LOGW("ResTable_item at %d is beyond type chunk data %d",
- (int)offset, dtohl(type->header.size));
- return BAD_TYPE;
- }
-
- const Res_value* item =
- (const Res_value*)(((const uint8_t*)type) + offset);
- ResTable_config thisConfig;
- thisConfig.copyFromDtoH(type->config);
-
- if (outSpecFlags != NULL) {
- if (typeClass->typeSpecFlags != NULL) {
- *outSpecFlags |= dtohl(typeClass->typeSpecFlags[e]);
- } else {
- *outSpecFlags = -1;
- }
- }
-
- if (bestPackage != NULL && bestItem.isBetterThan(thisConfig)) {
- continue;
- }
-
- bestItem = thisConfig;
- bestValue = item;
- bestPackage = package;
- }
-
- TABLE_NOISY(printf("Found result: package %p\n", bestPackage));
-
- if (bestValue) {
- outValue->size = dtohs(bestValue->size);
- outValue->res0 = bestValue->res0;
- outValue->dataType = bestValue->dataType;
- outValue->data = dtohl(bestValue->data);
- if (outConfig != NULL) {
- *outConfig = bestItem;
- }
- TABLE_NOISY(size_t len;
- printf("Found value: pkg=%d, type=%d, str=%s, int=%d\n",
- bestPackage->header->index,
- outValue->dataType,
- outValue->dataType == bestValue->TYPE_STRING
- ? String8(bestPackage->header->values.stringAt(
- outValue->data, &len)).string()
- : "",
- outValue->data));
- return bestPackage->header->index;
- }
-
- return BAD_INDEX;
-}
-
-ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex,
- uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags) const
-{
- int count=0;
- while (blockIndex >= 0 && value->dataType == value->TYPE_REFERENCE
- && value->data != 0 && count < 20) {
- if (outLastRef) *outLastRef = value->data;
- uint32_t lastRef = value->data;
- uint32_t newFlags = 0;
- const ssize_t newIndex = getResource(value->data, value, true, &newFlags);
- //LOGI("Resolving reference d=%p: newIndex=%d, t=0x%02x, d=%p\n",
- // (void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data);
- //printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex);
- if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newFlags;
- if (newIndex < 0) {
- // This can fail if the resource being referenced is a style...
- // in this case, just return the reference, and expect the
- // caller to deal with.
- return blockIndex;
- }
- blockIndex = newIndex;
- count++;
- }
- return blockIndex;
-}
-
-const char16_t* ResTable::valueToString(
- const Res_value* value, size_t stringBlock,
- char16_t tmpBuffer[TMP_BUFFER_SIZE], size_t* outLen)
-{
- if (!value) {
- return NULL;
- }
- if (value->dataType == value->TYPE_STRING) {
- return getTableStringBlock(stringBlock)->stringAt(value->data, outLen);
- }
- // XXX do int to string conversions.
- return NULL;
-}
-
-ssize_t ResTable::lockBag(uint32_t resID, const bag_entry** outBag) const
-{
- mLock.lock();
- ssize_t err = getBagLocked(resID, outBag);
- if (err < NO_ERROR) {
- //printf("*** get failed! unlocking\n");
- mLock.unlock();
- }
- return err;
-}
-
-void ResTable::unlockBag(const bag_entry* bag) const
-{
- //printf("<<< unlockBag %p\n", this);
- mLock.unlock();
-}
-
-void ResTable::lock() const
-{
- mLock.lock();
-}
-
-void ResTable::unlock() const
-{
- mLock.unlock();
-}
-
-ssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag,
- uint32_t* outTypeSpecFlags) const
-{
- if (mError != NO_ERROR) {
- return mError;
- }
-
- const ssize_t p = getResourcePackageIndex(resID);
- const int t = Res_GETTYPE(resID);
- const int e = Res_GETENTRY(resID);
-
- if (p < 0) {
- LOGW("Invalid package identifier when getting bag for resource number 0x%08x", resID);
- return BAD_INDEX;
- }
- if (t < 0) {
- LOGW("No type identifier when getting bag for resource number 0x%08x", resID);
- return BAD_INDEX;
- }
-
- //printf("Get bag: id=0x%08x, p=%d, t=%d\n", resID, p, t);
- PackageGroup* const grp = mPackageGroups[p];
- if (grp == NULL) {
- LOGW("Bad identifier when getting bag for resource number 0x%08x", resID);
- return false;
- }
-
- if (t >= (int)grp->typeCount) {
- LOGW("Type identifier 0x%x is larger than type count 0x%x",
- t+1, (int)grp->typeCount);
- return BAD_INDEX;
- }
-
- const Package* const basePackage = grp->packages[0];
-
- const Type* const typeConfigs = basePackage->getType(t);
-
- const size_t NENTRY = typeConfigs->entryCount;
- if (e >= (int)NENTRY) {
- LOGW("Entry identifier 0x%x is larger than entry count 0x%x",
- e, (int)typeConfigs->entryCount);
- return BAD_INDEX;
- }
-
- // First see if we've already computed this bag...
- if (grp->bags) {
- bag_set** typeSet = grp->bags[t];
- if (typeSet) {
- bag_set* set = typeSet[e];
- if (set) {
- if (set != (bag_set*)0xFFFFFFFF) {
- if (outTypeSpecFlags != NULL) {
- *outTypeSpecFlags = set->typeSpecFlags;
- }
- *outBag = (bag_entry*)(set+1);
- //LOGI("Found existing bag for: %p\n", (void*)resID);
- return set->numAttrs;
- }
- LOGW("Attempt to retrieve bag 0x%08x which is invalid or in a cycle.",
- resID);
- return BAD_INDEX;
- }
- }
- }
-
- // Bag not found, we need to compute it!
- if (!grp->bags) {
- grp->bags = (bag_set***)malloc(sizeof(bag_set*)*grp->typeCount);
- if (!grp->bags) return NO_MEMORY;
- memset(grp->bags, 0, sizeof(bag_set*)*grp->typeCount);
- }
-
- bag_set** typeSet = grp->bags[t];
- if (!typeSet) {
- typeSet = (bag_set**)malloc(sizeof(bag_set*)*NENTRY);
- if (!typeSet) return NO_MEMORY;
- memset(typeSet, 0, sizeof(bag_set*)*NENTRY);
- grp->bags[t] = typeSet;
- }
-
- // Mark that we are currently working on this one.
- typeSet[e] = (bag_set*)0xFFFFFFFF;
-
- // This is what we are building.
- bag_set* set = NULL;
-
- TABLE_NOISY(LOGI("Building bag: %p\n", (void*)resID));
-
- // Now collect all bag attributes from all packages.
- size_t ip = grp->packages.size();
- while (ip > 0) {
- ip--;
-
- const Package* const package = grp->packages[ip];
-
- const ResTable_type* type;
- const ResTable_entry* entry;
- const Type* typeClass;
- LOGV("Getting entry pkg=%p, t=%d, e=%d\n", package, t, e);
- ssize_t offset = getEntry(package, t, e, &mParams, &type, &entry, &typeClass);
- LOGV("Resulting offset=%d\n", offset);
- if (offset <= 0) {
- if (offset < 0) {
- if (set) free(set);
- return offset;
- }
- continue;
- }
-
- if ((dtohs(entry->flags)&entry->FLAG_COMPLEX) == 0) {
- LOGW("Skipping entry %p in package table %d because it is not complex!\n",
- (void*)resID, (int)ip);
- continue;
- }
-
- const uint16_t entrySize = dtohs(entry->size);
- const uint32_t parent = entrySize >= sizeof(ResTable_map_entry)
- ? dtohl(((const ResTable_map_entry*)entry)->parent.ident) : 0;
- const uint32_t count = entrySize >= sizeof(ResTable_map_entry)
- ? dtohl(((const ResTable_map_entry*)entry)->count) : 0;
-
- size_t N = count;
-
- TABLE_NOISY(LOGI("Found map: size=%p parent=%p count=%d\n",
- entrySize, parent, count));
-
- if (set == NULL) {
- // If this map inherits from another, we need to start
- // with its parent's values. Otherwise start out empty.
- TABLE_NOISY(printf("Creating new bag, entrySize=0x%08x, parent=0x%08x\n",
- entrySize, parent));
- if (parent) {
- const bag_entry* parentBag;
- uint32_t parentTypeSpecFlags = 0;
- const ssize_t NP = getBagLocked(parent, &parentBag, &parentTypeSpecFlags);
- const size_t NT = ((NP >= 0) ? NP : 0) + N;
- set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*NT);
- if (set == NULL) {
- return NO_MEMORY;
- }
- if (NP > 0) {
- memcpy(set+1, parentBag, NP*sizeof(bag_entry));
- set->numAttrs = NP;
- TABLE_NOISY(LOGI("Initialized new bag with %d inherited attributes.\n", NP));
- } else {
- TABLE_NOISY(LOGI("Initialized new bag with no inherited attributes.\n"));
- set->numAttrs = 0;
- }
- set->availAttrs = NT;
- set->typeSpecFlags = parentTypeSpecFlags;
- } else {
- set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*N);
- if (set == NULL) {
- return NO_MEMORY;
- }
- set->numAttrs = 0;
- set->availAttrs = N;
- set->typeSpecFlags = 0;
- }
- }
-
- if (typeClass->typeSpecFlags != NULL) {
- set->typeSpecFlags |= dtohl(typeClass->typeSpecFlags[e]);
- } else {
- set->typeSpecFlags = -1;
- }
-
- // Now merge in the new attributes...
- ssize_t curOff = offset;
- const ResTable_map* map;
- bag_entry* entries = (bag_entry*)(set+1);
- size_t curEntry = 0;
- uint32_t pos = 0;
- TABLE_NOISY(LOGI("Starting with set %p, entries=%p, avail=%d\n",
- set, entries, set->availAttrs));
- while (pos < count) {
- TABLE_NOISY(printf("Now at %p\n", (void*)curOff));
-
- if ((size_t)curOff > (dtohl(type->header.size)-sizeof(ResTable_map))) {
- LOGW("ResTable_map at %d is beyond type chunk data %d",
- (int)curOff, dtohl(type->header.size));
- return BAD_TYPE;
- }
- map = (const ResTable_map*)(((const uint8_t*)type) + curOff);
- N++;
-
- const uint32_t newName = htodl(map->name.ident);
- bool isInside;
- uint32_t oldName = 0;
- while ((isInside=(curEntry < set->numAttrs))
- && (oldName=entries[curEntry].map.name.ident) < newName) {
- TABLE_NOISY(printf("#%d: Keeping existing attribute: 0x%08x\n",
- curEntry, entries[curEntry].map.name.ident));
- curEntry++;
- }
-
- if ((!isInside) || oldName != newName) {
- // This is a new attribute... figure out what to do with it.
- if (set->numAttrs >= set->availAttrs) {
- // Need to alloc more memory...
- const size_t newAvail = set->availAttrs+N;
- set = (bag_set*)realloc(set,
- sizeof(bag_set)
- + sizeof(bag_entry)*newAvail);
- if (set == NULL) {
- return NO_MEMORY;
- }
- set->availAttrs = newAvail;
- entries = (bag_entry*)(set+1);
- TABLE_NOISY(printf("Reallocated set %p, entries=%p, avail=%d\n",
- set, entries, set->availAttrs));
- }
- if (isInside) {
- // Going in the middle, need to make space.
- memmove(entries+curEntry+1, entries+curEntry,
- sizeof(bag_entry)*(set->numAttrs-curEntry));
- set->numAttrs++;
- }
- TABLE_NOISY(printf("#%d: Inserting new attribute: 0x%08x\n",
- curEntry, newName));
- } else {
- TABLE_NOISY(printf("#%d: Replacing existing attribute: 0x%08x\n",
- curEntry, oldName));
- }
-
- bag_entry* cur = entries+curEntry;
-
- cur->stringBlock = package->header->index;
- cur->map.name.ident = newName;
- cur->map.value.copyFrom_dtoh(map->value);
- TABLE_NOISY(printf("Setting entry #%d %p: block=%d, name=0x%08x, type=%d, data=0x%08x\n",
- curEntry, cur, cur->stringBlock, cur->map.name.ident,
- cur->map.value.dataType, cur->map.value.data));
-
- // On to the next!
- curEntry++;
- pos++;
- const size_t size = dtohs(map->value.size);
- curOff += size + sizeof(*map)-sizeof(map->value);
- };
- if (curEntry > set->numAttrs) {
- set->numAttrs = curEntry;
- }
- }
-
- // And this is it...
- typeSet[e] = set;
- if (set) {
- if (outTypeSpecFlags != NULL) {
- *outTypeSpecFlags = set->typeSpecFlags;
- }
- *outBag = (bag_entry*)(set+1);
- TABLE_NOISY(LOGI("Returning %d attrs\n", set->numAttrs));
- return set->numAttrs;
- }
- return BAD_INDEX;
-}
-
-void ResTable::setParameters(const ResTable_config* params)
-{
- mLock.lock();
- TABLE_GETENTRY(LOGI("Setting parameters: imsi:%d/%d lang:%c%c cnt:%c%c "
- "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
- params->mcc, params->mnc,
- params->language[0] ? params->language[0] : '-',
- params->language[1] ? params->language[1] : '-',
- params->country[0] ? params->country[0] : '-',
- params->country[1] ? params->country[1] : '-',
- params->orientation,
- params->touchscreen,
- params->density,
- params->keyboard,
- params->inputFlags,
- params->navigation,
- params->screenWidth,
- params->screenHeight));
- mParams = *params;
- for (size_t i=0; i<mPackageGroups.size(); i++) {
- TABLE_NOISY(LOGI("CLEARING BAGS FOR GROUP %d!", i));
- mPackageGroups[i]->clearBagCache();
- }
- mLock.unlock();
-}
-
-void ResTable::getParameters(ResTable_config* params) const
-{
- mLock.lock();
- *params = mParams;
- mLock.unlock();
-}
-
-struct id_name_map {
- uint32_t id;
- size_t len;
- char16_t name[6];
-};
-
-const static id_name_map ID_NAMES[] = {
- { ResTable_map::ATTR_TYPE, 5, { '^', 't', 'y', 'p', 'e' } },
- { ResTable_map::ATTR_L10N, 5, { '^', 'l', '1', '0', 'n' } },
- { ResTable_map::ATTR_MIN, 4, { '^', 'm', 'i', 'n' } },
- { ResTable_map::ATTR_MAX, 4, { '^', 'm', 'a', 'x' } },
- { ResTable_map::ATTR_OTHER, 6, { '^', 'o', 't', 'h', 'e', 'r' } },
- { ResTable_map::ATTR_ZERO, 5, { '^', 'z', 'e', 'r', 'o' } },
- { ResTable_map::ATTR_ONE, 4, { '^', 'o', 'n', 'e' } },
- { ResTable_map::ATTR_TWO, 4, { '^', 't', 'w', 'o' } },
- { ResTable_map::ATTR_FEW, 4, { '^', 'f', 'e', 'w' } },
- { ResTable_map::ATTR_MANY, 5, { '^', 'm', 'a', 'n', 'y' } },
-};
-
-uint32_t ResTable::identifierForName(const char16_t* name, size_t nameLen,
- const char16_t* type, size_t typeLen,
- const char16_t* package,
- size_t packageLen,
- uint32_t* outTypeSpecFlags) const
-{
- TABLE_SUPER_NOISY(printf("Identifier for name: error=%d\n", mError));
-
- // Check for internal resource identifier as the very first thing, so
- // that we will always find them even when there are no resources.
- if (name[0] == '^') {
- const int N = (sizeof(ID_NAMES)/sizeof(ID_NAMES[0]));
- size_t len;
- for (int i=0; i<N; i++) {
- const id_name_map* m = ID_NAMES + i;
- len = m->len;
- if (len != nameLen) {
- continue;
- }
- for (size_t j=1; j<len; j++) {
- if (m->name[j] != name[j]) {
- goto nope;
- }
- }
- return m->id;
-nope:
- ;
- }
- if (nameLen > 7) {
- if (name[1] == 'i' && name[2] == 'n'
- && name[3] == 'd' && name[4] == 'e' && name[5] == 'x'
- && name[6] == '_') {
- int index = atoi(String8(name + 7, nameLen - 7).string());
- if (Res_CHECKID(index)) {
- LOGW("Array resource index: %d is too large.",
- index);
- return 0;
- }
- return Res_MAKEARRAY(index);
- }
- }
- return 0;
- }
-
- if (mError != NO_ERROR) {
- return 0;
- }
-
- // Figure out the package and type we are looking in...
-
- const char16_t* packageEnd = NULL;
- const char16_t* typeEnd = NULL;
- const char16_t* const nameEnd = name+nameLen;
- const char16_t* p = name;
- while (p < nameEnd) {
- if (*p == ':') packageEnd = p;
- else if (*p == '/') typeEnd = p;
- p++;
- }
- if (*name == '@') name++;
- if (name >= nameEnd) {
- return 0;
- }
-
- if (packageEnd) {
- package = name;
- packageLen = packageEnd-name;
- name = packageEnd+1;
- } else if (!package) {
- return 0;
- }
-
- if (typeEnd) {
- type = name;
- typeLen = typeEnd-name;
- name = typeEnd+1;
- } else if (!type) {
- return 0;
- }
-
- if (name >= nameEnd) {
- return 0;
- }
- nameLen = nameEnd-name;
-
- TABLE_NOISY(printf("Looking for identifier: type=%s, name=%s, package=%s\n",
- String8(type, typeLen).string(),
- String8(name, nameLen).string(),
- String8(package, packageLen).string()));
-
- const size_t NG = mPackageGroups.size();
- for (size_t ig=0; ig<NG; ig++) {
- const PackageGroup* group = mPackageGroups[ig];
-
- if (strzcmp16(package, packageLen,
- group->name.string(), group->name.size())) {
- TABLE_NOISY(printf("Skipping package group: %s\n", String8(group->name).string()));
- continue;
- }
-
- const ssize_t ti = group->typeStrings.indexOfString(type, typeLen);
- if (ti < 0) {
- TABLE_NOISY(printf("Type not found in package %s\n", String8(group->name).string()));
- continue;
- }
-
- const ssize_t ei = group->keyStrings.indexOfString(name, nameLen);
- if (ei < 0) {
- TABLE_NOISY(printf("Name not found in package %s\n", String8(group->name).string()));
- continue;
- }
-
- TABLE_NOISY(printf("Search indices: type=%d, name=%d\n", ti, ei));
-
- const Type* const typeConfigs = group->packages[0]->getType(ti);
- if (typeConfigs == NULL || typeConfigs->configs.size() <= 0) {
- TABLE_NOISY(printf("Expected type structure not found in package %s for idnex %d\n",
- String8(group->name).string(), ti));
- }
-
- size_t NTC = typeConfigs->configs.size();
- for (size_t tci=0; tci<NTC; tci++) {
- const ResTable_type* const ty = typeConfigs->configs[tci];
- const uint32_t typeOffset = dtohl(ty->entriesStart);
-
- const uint8_t* const end = ((const uint8_t*)ty) + dtohl(ty->header.size);
- const uint32_t* const eindex = (const uint32_t*)
- (((const uint8_t*)ty) + dtohs(ty->header.headerSize));
-
- const size_t NE = dtohl(ty->entryCount);
- for (size_t i=0; i<NE; i++) {
- uint32_t offset = dtohl(eindex[i]);
- if (offset == ResTable_type::NO_ENTRY) {
- continue;
- }
-
- offset += typeOffset;
-
- if (offset > (dtohl(ty->header.size)-sizeof(ResTable_entry))) {
- LOGW("ResTable_entry at %d is beyond type chunk data %d",
- offset, dtohl(ty->header.size));
- return 0;
- }
- if ((offset&0x3) != 0) {
- LOGW("ResTable_entry at %d (pkg=%d type=%d ent=%d) is not on an integer boundary when looking for %s:%s/%s",
- (int)offset, (int)group->id, (int)ti+1, (int)i,
- String8(package, packageLen).string(),
- String8(type, typeLen).string(),
- String8(name, nameLen).string());
- return 0;
- }
-
- const ResTable_entry* const entry = (const ResTable_entry*)
- (((const uint8_t*)ty) + offset);
- if (dtohs(entry->size) < sizeof(*entry)) {
- LOGW("ResTable_entry size %d is too small", dtohs(entry->size));
- return BAD_TYPE;
- }
-
- TABLE_SUPER_NOISY(printf("Looking at entry #%d: want str %d, have %d\n",
- i, ei, dtohl(entry->key.index)));
- if (dtohl(entry->key.index) == (size_t)ei) {
- if (outTypeSpecFlags) {
- *outTypeSpecFlags = typeConfigs->typeSpecFlags[i];
- }
- return Res_MAKEID(group->id-1, ti, i);
- }
- }
- }
- }
-
- return 0;
-}
-
-bool ResTable::expandResourceRef(const uint16_t* refStr, size_t refLen,
- String16* outPackage,
- String16* outType,
- String16* outName,
- const String16* defType,
- const String16* defPackage,
- const char** outErrorMsg)
-{
- const char16_t* packageEnd = NULL;
- const char16_t* typeEnd = NULL;
- const char16_t* p = refStr;
- const char16_t* const end = p + refLen;
- while (p < end) {
- if (*p == ':') packageEnd = p;
- else if (*p == '/') {
- typeEnd = p;
- break;
- }
- p++;
- }
- p = refStr;
- if (*p == '@') p++;
-
- if (packageEnd) {
- *outPackage = String16(p, packageEnd-p);
- p = packageEnd+1;
- } else {
- if (!defPackage) {
- if (outErrorMsg) {
- *outErrorMsg = "No resource package specified";
- }
- return false;
- }
- *outPackage = *defPackage;
- }
- if (typeEnd) {
- *outType = String16(p, typeEnd-p);
- p = typeEnd+1;
- } else {
- if (!defType) {
- if (outErrorMsg) {
- *outErrorMsg = "No resource type specified";
- }
- return false;
- }
- *outType = *defType;
- }
- *outName = String16(p, end-p);
- return true;
-}
-
-static uint32_t get_hex(char c, bool* outError)
-{
- if (c >= '0' && c <= '9') {
- return c - '0';
- } else if (c >= 'a' && c <= 'f') {
- return c - 'a' + 0xa;
- } else if (c >= 'A' && c <= 'F') {
- return c - 'A' + 0xa;
- }
- *outError = true;
- return 0;
-}
-
-struct unit_entry
-{
- const char* name;
- size_t len;
- uint8_t type;
- uint32_t unit;
- float scale;
-};
-
-static const unit_entry unitNames[] = {
- { "px", strlen("px"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PX, 1.0f },
- { "dip", strlen("dip"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f },
- { "dp", strlen("dp"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f },
- { "sp", strlen("sp"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_SP, 1.0f },
- { "pt", strlen("pt"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PT, 1.0f },
- { "in", strlen("in"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_IN, 1.0f },
- { "mm", strlen("mm"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_MM, 1.0f },
- { "%", strlen("%"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION, 1.0f/100 },
- { "%p", strlen("%p"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION_PARENT, 1.0f/100 },
- { NULL, 0, 0, 0, 0 }
-};
-
-static bool parse_unit(const char* str, Res_value* outValue,
- float* outScale, const char** outEnd)
-{
- const char* end = str;
- while (*end != 0 && !isspace((unsigned char)*end)) {
- end++;
- }
- const size_t len = end-str;
-
- const char* realEnd = end;
- while (*realEnd != 0 && isspace((unsigned char)*realEnd)) {
- realEnd++;
- }
- if (*realEnd != 0) {
- return false;
- }
-
- const unit_entry* cur = unitNames;
- while (cur->name) {
- if (len == cur->len && strncmp(cur->name, str, len) == 0) {
- outValue->dataType = cur->type;
- outValue->data = cur->unit << Res_value::COMPLEX_UNIT_SHIFT;
- *outScale = cur->scale;
- *outEnd = end;
- //printf("Found unit %s for %s\n", cur->name, str);
- return true;
- }
- cur++;
- }
-
- return false;
-}
-
-
-bool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue)
-{
- while (len > 0 && isspace16(*s)) {
- s++;
- len--;
- }
-
- if (len <= 0) {
- return false;
- }
-
- size_t i = 0;
- int32_t val = 0;
- bool neg = false;
-
- if (*s == '-') {
- neg = true;
- i++;
- }
-
- if (s[i] < '0' || s[i] > '9') {
- return false;
- }
-
- // Decimal or hex?
- if (s[i] == '0' && s[i+1] == 'x') {
- if (outValue)
- outValue->dataType = outValue->TYPE_INT_HEX;
- i += 2;
- bool error = false;
- while (i < len && !error) {
- val = (val*16) + get_hex(s[i], &error);
- i++;
- }
- if (error) {
- return false;
- }
- } else {
- if (outValue)
- outValue->dataType = outValue->TYPE_INT_DEC;
- while (i < len) {
- if (s[i] < '0' || s[i] > '9') {
- return false;
- }
- val = (val*10) + s[i]-'0';
- i++;
- }
- }
-
- if (neg) val = -val;
-
- while (i < len && isspace16(s[i])) {
- i++;
- }
-
- if (i == len) {
- if (outValue)
- outValue->data = val;
- return true;
- }
-
- return false;
-}
-
-bool ResTable::stringToFloat(const char16_t* s, size_t len, Res_value* outValue)
-{
- while (len > 0 && isspace16(*s)) {
- s++;
- len--;
- }
-
- if (len <= 0) {
- return false;
- }
-
- char buf[128];
- int i=0;
- while (len > 0 && *s != 0 && i < 126) {
- if (*s > 255) {
- return false;
- }
- buf[i++] = *s++;
- len--;
- }
-
- if (len > 0) {
- return false;
- }
- if (buf[0] < '0' && buf[0] > '9' && buf[0] != '.') {
- return false;
- }
-
- buf[i] = 0;
- const char* end;
- float f = strtof(buf, (char**)&end);
-
- if (*end != 0 && !isspace((unsigned char)*end)) {
- // Might be a unit...
- float scale;
- if (parse_unit(end, outValue, &scale, &end)) {
- f *= scale;
- const bool neg = f < 0;
- if (neg) f = -f;
- uint64_t bits = (uint64_t)(f*(1<<23)+.5f);
- uint32_t radix;
- uint32_t shift;
- if ((bits&0x7fffff) == 0) {
- // Always use 23p0 if there is no fraction, just to make
- // things easier to read.
- radix = Res_value::COMPLEX_RADIX_23p0;
- shift = 23;
- } else if ((bits&0xffffffffff800000LL) == 0) {
- // Magnitude is zero -- can fit in 0 bits of precision.
- radix = Res_value::COMPLEX_RADIX_0p23;
- shift = 0;
- } else if ((bits&0xffffffff80000000LL) == 0) {
- // Magnitude can fit in 8 bits of precision.
- radix = Res_value::COMPLEX_RADIX_8p15;
- shift = 8;
- } else if ((bits&0xffffff8000000000LL) == 0) {
- // Magnitude can fit in 16 bits of precision.
- radix = Res_value::COMPLEX_RADIX_16p7;
- shift = 16;
- } else {
- // Magnitude needs entire range, so no fractional part.
- radix = Res_value::COMPLEX_RADIX_23p0;
- shift = 23;
- }
- int32_t mantissa = (int32_t)(
- (bits>>shift) & Res_value::COMPLEX_MANTISSA_MASK);
- if (neg) {
- mantissa = (-mantissa) & Res_value::COMPLEX_MANTISSA_MASK;
- }
- outValue->data |=
- (radix<<Res_value::COMPLEX_RADIX_SHIFT)
- | (mantissa<<Res_value::COMPLEX_MANTISSA_SHIFT);
- //printf("Input value: %f 0x%016Lx, mult: %f, radix: %d, shift: %d, final: 0x%08x\n",
- // f * (neg ? -1 : 1), bits, f*(1<<23),
- // radix, shift, outValue->data);
- return true;
- }
- return false;
- }
-
- while (*end != 0 && isspace((unsigned char)*end)) {
- end++;
- }
-
- if (*end == 0) {
- if (outValue) {
- outValue->dataType = outValue->TYPE_FLOAT;
- *(float*)(&outValue->data) = f;
- return true;
- }
- }
-
- return false;
-}
-
-bool ResTable::stringToValue(Res_value* outValue, String16* outString,
- const char16_t* s, size_t len,
- bool preserveSpaces, bool coerceType,
- uint32_t attrID,
- const String16* defType,
- const String16* defPackage,
- Accessor* accessor,
- void* accessorCookie,
- uint32_t attrType,
- bool enforcePrivate) const
-{
- bool localizationSetting = accessor != NULL && accessor->getLocalizationSetting();
- const char* errorMsg = NULL;
-
- outValue->size = sizeof(Res_value);
- outValue->res0 = 0;
-
- // First strip leading/trailing whitespace. Do this before handling
- // escapes, so they can be used to force whitespace into the string.
- if (!preserveSpaces) {
- while (len > 0 && isspace16(*s)) {
- s++;
- len--;
- }
- while (len > 0 && isspace16(s[len-1])) {
- len--;
- }
- // If the string ends with '\', then we keep the space after it.
- if (len > 0 && s[len-1] == '\\' && s[len] != 0) {
- len++;
- }
- }
-
- //printf("Value for: %s\n", String8(s, len).string());
-
- uint32_t l10nReq = ResTable_map::L10N_NOT_REQUIRED;
- uint32_t attrMin = 0x80000000, attrMax = 0x7fffffff;
- bool fromAccessor = false;
- if (attrID != 0 && !Res_INTERNALID(attrID)) {
- const ssize_t p = getResourcePackageIndex(attrID);
- const bag_entry* bag;
- ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;
- //printf("For attr 0x%08x got bag of %d\n", attrID, cnt);
- if (cnt >= 0) {
- while (cnt > 0) {
- //printf("Entry 0x%08x = 0x%08x\n", bag->map.name.ident, bag->map.value.data);
- switch (bag->map.name.ident) {
- case ResTable_map::ATTR_TYPE:
- attrType = bag->map.value.data;
- break;
- case ResTable_map::ATTR_MIN:
- attrMin = bag->map.value.data;
- break;
- case ResTable_map::ATTR_MAX:
- attrMax = bag->map.value.data;
- break;
- case ResTable_map::ATTR_L10N:
- l10nReq = bag->map.value.data;
- break;
- }
- bag++;
- cnt--;
- }
- unlockBag(bag);
- } else if (accessor && accessor->getAttributeType(attrID, &attrType)) {
- fromAccessor = true;
- if (attrType == ResTable_map::TYPE_ENUM
- || attrType == ResTable_map::TYPE_FLAGS
- || attrType == ResTable_map::TYPE_INTEGER) {
- accessor->getAttributeMin(attrID, &attrMin);
- accessor->getAttributeMax(attrID, &attrMax);
- }
- if (localizationSetting) {
- l10nReq = accessor->getAttributeL10N(attrID);
- }
- }
- }
-
- const bool canStringCoerce =
- coerceType && (attrType&ResTable_map::TYPE_STRING) != 0;
-
- if (*s == '@') {
- outValue->dataType = outValue->TYPE_REFERENCE;
-
- // Note: we don't check attrType here because the reference can
- // be to any other type; we just need to count on the client making
- // sure the referenced type is correct.
-
- //printf("Looking up ref: %s\n", String8(s, len).string());
-
- // It's a reference!
- if (len == 5 && s[1]=='n' && s[2]=='u' && s[3]=='l' && s[4]=='l') {
- outValue->data = 0;
- return true;
- } else {
- bool createIfNotFound = false;
- const char16_t* resourceRefName;
- int resourceNameLen;
- if (len > 2 && s[1] == '+') {
- createIfNotFound = true;
- resourceRefName = s + 2;
- resourceNameLen = len - 2;
- } else if (len > 2 && s[1] == '*') {
- enforcePrivate = false;
- resourceRefName = s + 2;
- resourceNameLen = len - 2;
- } else {
- createIfNotFound = false;
- resourceRefName = s + 1;
- resourceNameLen = len - 1;
- }
- String16 package, type, name;
- if (!expandResourceRef(resourceRefName,resourceNameLen, &package, &type, &name,
- defType, defPackage, &errorMsg)) {
- if (accessor != NULL) {
- accessor->reportError(accessorCookie, errorMsg);
- }
- return false;
- }
-
- uint32_t specFlags = 0;
- uint32_t rid = identifierForName(name.string(), name.size(), type.string(),
- type.size(), package.string(), package.size(), &specFlags);
- if (rid != 0) {
- if (enforcePrivate) {
- if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) {
- if (accessor != NULL) {
- accessor->reportError(accessorCookie, "Resource is not public.");
- }
- return false;
- }
- }
- if (!accessor) {
- outValue->data = rid;
- return true;
- }
- rid = Res_MAKEID(
- accessor->getRemappedPackage(Res_GETPACKAGE(rid)),
- Res_GETTYPE(rid), Res_GETENTRY(rid));
- TABLE_NOISY(printf("Incl %s:%s/%s: 0x%08x\n",
- String8(package).string(), String8(type).string(),
- String8(name).string(), rid));
- outValue->data = rid;
- return true;
- }
-
- if (accessor) {
- uint32_t rid = accessor->getCustomResourceWithCreation(package, type, name,
- createIfNotFound);
- if (rid != 0) {
- TABLE_NOISY(printf("Pckg %s:%s/%s: 0x%08x\n",
- String8(package).string(), String8(type).string(),
- String8(name).string(), rid));
- outValue->data = rid;
- return true;
- }
- }
- }
-
- if (accessor != NULL) {
- accessor->reportError(accessorCookie, "No resource found that matches the given name");
- }
- return false;
- }
-
- // if we got to here, and localization is required and it's not a reference,
- // complain and bail.
- if (l10nReq == ResTable_map::L10N_SUGGESTED) {
- if (localizationSetting) {
- if (accessor != NULL) {
- accessor->reportError(accessorCookie, "This attribute must be localized.");
- }
- }
- }
-
- if (*s == '#') {
- // It's a color! Convert to an integer of the form 0xaarrggbb.
- uint32_t color = 0;
- bool error = false;
- if (len == 4) {
- outValue->dataType = outValue->TYPE_INT_COLOR_RGB4;
- color |= 0xFF000000;
- color |= get_hex(s[1], &error) << 20;
- color |= get_hex(s[1], &error) << 16;
- color |= get_hex(s[2], &error) << 12;
- color |= get_hex(s[2], &error) << 8;
- color |= get_hex(s[3], &error) << 4;
- color |= get_hex(s[3], &error);
- } else if (len == 5) {
- outValue->dataType = outValue->TYPE_INT_COLOR_ARGB4;
- color |= get_hex(s[1], &error) << 28;
- color |= get_hex(s[1], &error) << 24;
- color |= get_hex(s[2], &error) << 20;
- color |= get_hex(s[2], &error) << 16;
- color |= get_hex(s[3], &error) << 12;
- color |= get_hex(s[3], &error) << 8;
- color |= get_hex(s[4], &error) << 4;
- color |= get_hex(s[4], &error);
- } else if (len == 7) {
- outValue->dataType = outValue->TYPE_INT_COLOR_RGB8;
- color |= 0xFF000000;
- color |= get_hex(s[1], &error) << 20;
- color |= get_hex(s[2], &error) << 16;
- color |= get_hex(s[3], &error) << 12;
- color |= get_hex(s[4], &error) << 8;
- color |= get_hex(s[5], &error) << 4;
- color |= get_hex(s[6], &error);
- } else if (len == 9) {
- outValue->dataType = outValue->TYPE_INT_COLOR_ARGB8;
- color |= get_hex(s[1], &error) << 28;
- color |= get_hex(s[2], &error) << 24;
- color |= get_hex(s[3], &error) << 20;
- color |= get_hex(s[4], &error) << 16;
- color |= get_hex(s[5], &error) << 12;
- color |= get_hex(s[6], &error) << 8;
- color |= get_hex(s[7], &error) << 4;
- color |= get_hex(s[8], &error);
- } else {
- error = true;
- }
- if (!error) {
- if ((attrType&ResTable_map::TYPE_COLOR) == 0) {
- if (!canStringCoerce) {
- if (accessor != NULL) {
- accessor->reportError(accessorCookie,
- "Color types not allowed");
- }
- return false;
- }
- } else {
- outValue->data = color;
- //printf("Color input=%s, output=0x%x\n", String8(s, len).string(), color);
- return true;
- }
- } else {
- if ((attrType&ResTable_map::TYPE_COLOR) != 0) {
- if (accessor != NULL) {
- accessor->reportError(accessorCookie, "Color value not valid --"
- " must be #rgb, #argb, #rrggbb, or #aarrggbb");
- }
- #if 0
- fprintf(stderr, "%s: Color ID %s value %s is not valid\n",
- "Resource File", //(const char*)in->getPrintableSource(),
- String8(*curTag).string(),
- String8(s, len).string());
- #endif
- return false;
- }
- }
- }
-
- if (*s == '?') {
- outValue->dataType = outValue->TYPE_ATTRIBUTE;
-
- // Note: we don't check attrType here because the reference can
- // be to any other type; we just need to count on the client making
- // sure the referenced type is correct.
-
- //printf("Looking up attr: %s\n", String8(s, len).string());
-
- static const String16 attr16("attr");
- String16 package, type, name;
- if (!expandResourceRef(s+1, len-1, &package, &type, &name,
- &attr16, defPackage, &errorMsg)) {
- if (accessor != NULL) {
- accessor->reportError(accessorCookie, errorMsg);
- }
- return false;
- }
-
- //printf("Pkg: %s, Type: %s, Name: %s\n",
- // String8(package).string(), String8(type).string(),
- // String8(name).string());
- uint32_t specFlags = 0;
- uint32_t rid =
- identifierForName(name.string(), name.size(),
- type.string(), type.size(),
- package.string(), package.size(), &specFlags);
- if (rid != 0) {
- if (enforcePrivate) {
- if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) {
- if (accessor != NULL) {
- accessor->reportError(accessorCookie, "Attribute is not public.");
- }
- return false;
- }
- }
- if (!accessor) {
- outValue->data = rid;
- return true;
- }
- rid = Res_MAKEID(
- accessor->getRemappedPackage(Res_GETPACKAGE(rid)),
- Res_GETTYPE(rid), Res_GETENTRY(rid));
- //printf("Incl %s:%s/%s: 0x%08x\n",
- // String8(package).string(), String8(type).string(),
- // String8(name).string(), rid);
- outValue->data = rid;
- return true;
- }
-
- if (accessor) {
- uint32_t rid = accessor->getCustomResource(package, type, name);
- if (rid != 0) {
- //printf("Mine %s:%s/%s: 0x%08x\n",
- // String8(package).string(), String8(type).string(),
- // String8(name).string(), rid);
- outValue->data = rid;
- return true;
- }
- }
-
- if (accessor != NULL) {
- accessor->reportError(accessorCookie, "No resource found that matches the given name");
- }
- return false;
- }
-
- if (stringToInt(s, len, outValue)) {
- if ((attrType&ResTable_map::TYPE_INTEGER) == 0) {
- // If this type does not allow integers, but does allow floats,
- // fall through on this error case because the float type should
- // be able to accept any integer value.
- if (!canStringCoerce && (attrType&ResTable_map::TYPE_FLOAT) == 0) {
- if (accessor != NULL) {
- accessor->reportError(accessorCookie, "Integer types not allowed");
- }
- return false;
- }
- } else {
- if (((int32_t)outValue->data) < ((int32_t)attrMin)
- || ((int32_t)outValue->data) > ((int32_t)attrMax)) {
- if (accessor != NULL) {
- accessor->reportError(accessorCookie, "Integer value out of range");
- }
- return false;
- }
- return true;
- }
- }
-
- if (stringToFloat(s, len, outValue)) {
- if (outValue->dataType == Res_value::TYPE_DIMENSION) {
- if ((attrType&ResTable_map::TYPE_DIMENSION) != 0) {
- return true;
- }
- if (!canStringCoerce) {
- if (accessor != NULL) {
- accessor->reportError(accessorCookie, "Dimension types not allowed");
- }
- return false;
- }
- } else if (outValue->dataType == Res_value::TYPE_FRACTION) {
- if ((attrType&ResTable_map::TYPE_FRACTION) != 0) {
- return true;
- }
- if (!canStringCoerce) {
- if (accessor != NULL) {
- accessor->reportError(accessorCookie, "Fraction types not allowed");
- }
- return false;
- }
- } else if ((attrType&ResTable_map::TYPE_FLOAT) == 0) {
- if (!canStringCoerce) {
- if (accessor != NULL) {
- accessor->reportError(accessorCookie, "Float types not allowed");
- }
- return false;
- }
- } else {
- return true;
- }
- }
-
- if (len == 4) {
- if ((s[0] == 't' || s[0] == 'T') &&
- (s[1] == 'r' || s[1] == 'R') &&
- (s[2] == 'u' || s[2] == 'U') &&
- (s[3] == 'e' || s[3] == 'E')) {
- if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) {
- if (!canStringCoerce) {
- if (accessor != NULL) {
- accessor->reportError(accessorCookie, "Boolean types not allowed");
- }
- return false;
- }
- } else {
- outValue->dataType = outValue->TYPE_INT_BOOLEAN;
- outValue->data = (uint32_t)-1;
- return true;
- }
- }
- }
-
- if (len == 5) {
- if ((s[0] == 'f' || s[0] == 'F') &&
- (s[1] == 'a' || s[1] == 'A') &&
- (s[2] == 'l' || s[2] == 'L') &&
- (s[3] == 's' || s[3] == 'S') &&
- (s[4] == 'e' || s[4] == 'E')) {
- if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) {
- if (!canStringCoerce) {
- if (accessor != NULL) {
- accessor->reportError(accessorCookie, "Boolean types not allowed");
- }
- return false;
- }
- } else {
- outValue->dataType = outValue->TYPE_INT_BOOLEAN;
- outValue->data = 0;
- return true;
- }
- }
- }
-
- if ((attrType&ResTable_map::TYPE_ENUM) != 0) {
- const ssize_t p = getResourcePackageIndex(attrID);
- const bag_entry* bag;
- ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;
- //printf("Got %d for enum\n", cnt);
- if (cnt >= 0) {
- resource_name rname;
- while (cnt > 0) {
- if (!Res_INTERNALID(bag->map.name.ident)) {
- //printf("Trying attr #%08x\n", bag->map.name.ident);
- if (getResourceName(bag->map.name.ident, &rname)) {
- #if 0
- printf("Matching %s against %s (0x%08x)\n",
- String8(s, len).string(),
- String8(rname.name, rname.nameLen).string(),
- bag->map.name.ident);
- #endif
- if (strzcmp16(s, len, rname.name, rname.nameLen) == 0) {
- outValue->dataType = bag->map.value.dataType;
- outValue->data = bag->map.value.data;
- unlockBag(bag);
- return true;
- }
- }
-
- }
- bag++;
- cnt--;
- }
- unlockBag(bag);
- }
-
- if (fromAccessor) {
- if (accessor->getAttributeEnum(attrID, s, len, outValue)) {
- return true;
- }
- }
- }
-
- if ((attrType&ResTable_map::TYPE_FLAGS) != 0) {
- const ssize_t p = getResourcePackageIndex(attrID);
- const bag_entry* bag;
- ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;
- //printf("Got %d for flags\n", cnt);
- if (cnt >= 0) {
- bool failed = false;
- resource_name rname;
- outValue->dataType = Res_value::TYPE_INT_HEX;
- outValue->data = 0;
- const char16_t* end = s + len;
- const char16_t* pos = s;
- while (pos < end && !failed) {
- const char16_t* start = pos;
- end++;
- while (pos < end && *pos != '|') {
- pos++;
- }
- //printf("Looking for: %s\n", String8(start, pos-start).string());
- const bag_entry* bagi = bag;
- ssize_t i;
- for (i=0; i<cnt; i++, bagi++) {
- if (!Res_INTERNALID(bagi->map.name.ident)) {
- //printf("Trying attr #%08x\n", bagi->map.name.ident);
- if (getResourceName(bagi->map.name.ident, &rname)) {
- #if 0
- printf("Matching %s against %s (0x%08x)\n",
- String8(start,pos-start).string(),
- String8(rname.name, rname.nameLen).string(),
- bagi->map.name.ident);
- #endif
- if (strzcmp16(start, pos-start, rname.name, rname.nameLen) == 0) {
- outValue->data |= bagi->map.value.data;
- break;
- }
- }
- }
- }
- if (i >= cnt) {
- // Didn't find this flag identifier.
- failed = true;
- }
- if (pos < end) {
- pos++;
- }
- }
- unlockBag(bag);
- if (!failed) {
- //printf("Final flag value: 0x%lx\n", outValue->data);
- return true;
- }
- }
-
-
- if (fromAccessor) {
- if (accessor->getAttributeFlags(attrID, s, len, outValue)) {
- //printf("Final flag value: 0x%lx\n", outValue->data);
- return true;
- }
- }
- }
-
- if ((attrType&ResTable_map::TYPE_STRING) == 0) {
- if (accessor != NULL) {
- accessor->reportError(accessorCookie, "String types not allowed");
- }
- return false;
- }
-
- // Generic string handling...
- outValue->dataType = outValue->TYPE_STRING;
- if (outString) {
- bool failed = collectString(outString, s, len, preserveSpaces, &errorMsg);
- if (accessor != NULL) {
- accessor->reportError(accessorCookie, errorMsg);
- }
- return failed;
- }
-
- return true;
-}
-
-bool ResTable::collectString(String16* outString,
- const char16_t* s, size_t len,
- bool preserveSpaces,
- const char** outErrorMsg,
- bool append)
-{
- String16 tmp;
-
- char quoted = 0;
- const char16_t* p = s;
- while (p < (s+len)) {
- while (p < (s+len)) {
- const char16_t c = *p;
- if (c == '\\') {
- break;
- }
- if (!preserveSpaces) {
- if (quoted == 0 && isspace16(c)
- && (c != ' ' || isspace16(*(p+1)))) {
- break;
- }
- if (c == '"' && (quoted == 0 || quoted == '"')) {
- break;
- }
- if (c == '\'' && (quoted == 0 || quoted == '\'')) {
- break;
- }
- }
- p++;
- }
- if (p < (s+len)) {
- if (p > s) {
- tmp.append(String16(s, p-s));
- }
- if (!preserveSpaces && (*p == '"' || *p == '\'')) {
- if (quoted == 0) {
- quoted = *p;
- } else {
- quoted = 0;
- }
- p++;
- } else if (!preserveSpaces && isspace16(*p)) {
- // Space outside of a quote -- consume all spaces and
- // leave a single plain space char.
- tmp.append(String16(" "));
- p++;
- while (p < (s+len) && isspace16(*p)) {
- p++;
- }
- } else if (*p == '\\') {
- p++;
- if (p < (s+len)) {
- switch (*p) {
- case 't':
- tmp.append(String16("\t"));
- break;
- case 'n':
- tmp.append(String16("\n"));
- break;
- case '#':
- tmp.append(String16("#"));
- break;
- case '@':
- tmp.append(String16("@"));
- break;
- case '?':
- tmp.append(String16("?"));
- break;
- case '"':
- tmp.append(String16("\""));
- break;
- case '\'':
- tmp.append(String16("'"));
- break;
- case '\\':
- tmp.append(String16("\\"));
- break;
- case 'u':
- {
- char16_t chr = 0;
- int i = 0;
- while (i < 4 && p[1] != 0) {
- p++;
- i++;
- int c;
- if (*p >= '0' && *p <= '9') {
- c = *p - '0';
- } else if (*p >= 'a' && *p <= 'f') {
- c = *p - 'a' + 10;
- } else if (*p >= 'A' && *p <= 'F') {
- c = *p - 'A' + 10;
- } else {
- if (outErrorMsg) {
- *outErrorMsg = "Bad character in \\u unicode escape sequence";
- }
- return false;
- }
- chr = (chr<<4) | c;
- }
- tmp.append(String16(&chr, 1));
- } break;
- default:
- // ignore unknown escape chars.
- break;
- }
- p++;
- }
- }
- len -= (p-s);
- s = p;
- }
- }
-
- if (tmp.size() != 0) {
- if (len > 0) {
- tmp.append(String16(s, len));
- }
- if (append) {
- outString->append(tmp);
- } else {
- outString->setTo(tmp);
- }
- } else {
- if (append) {
- outString->append(String16(s, len));
- } else {
- outString->setTo(s, len);
- }
- }
-
- return true;
-}
-
-size_t ResTable::getBasePackageCount() const
-{
- if (mError != NO_ERROR) {
- return 0;
- }
- return mPackageGroups.size();
-}
-
-const char16_t* ResTable::getBasePackageName(size_t idx) const
-{
- if (mError != NO_ERROR) {
- return 0;
- }
- LOG_FATAL_IF(idx >= mPackageGroups.size(),
- "Requested package index %d past package count %d",
- (int)idx, (int)mPackageGroups.size());
- return mPackageGroups[idx]->name.string();
-}
-
-uint32_t ResTable::getBasePackageId(size_t idx) const
-{
- if (mError != NO_ERROR) {
- return 0;
- }
- LOG_FATAL_IF(idx >= mPackageGroups.size(),
- "Requested package index %d past package count %d",
- (int)idx, (int)mPackageGroups.size());
- return mPackageGroups[idx]->id;
-}
-
-size_t ResTable::getTableCount() const
-{
- return mHeaders.size();
-}
-
-const ResStringPool* ResTable::getTableStringBlock(size_t index) const
-{
- return &mHeaders[index]->values;
-}
-
-void* ResTable::getTableCookie(size_t index) const
-{
- return mHeaders[index]->cookie;
-}
-
-void ResTable::getConfigurations(Vector<ResTable_config>* configs) const
-{
- const size_t I = mPackageGroups.size();
- for (size_t i=0; i<I; i++) {
- const PackageGroup* packageGroup = mPackageGroups[i];
- const size_t J = packageGroup->packages.size();
- for (size_t j=0; j<J; j++) {
- const Package* package = packageGroup->packages[j];
- const size_t K = package->types.size();
- for (size_t k=0; k<K; k++) {
- const Type* type = package->types[k];
- if (type == NULL) continue;
- const size_t L = type->configs.size();
- for (size_t l=0; l<L; l++) {
- const ResTable_type* config = type->configs[l];
- const ResTable_config* cfg = &config->config;
- // only insert unique
- const size_t M = configs->size();
- size_t m;
- for (m=0; m<M; m++) {
- if (0 == (*configs)[m].compare(*cfg)) {
- break;
- }
- }
- // if we didn't find it
- if (m == M) {
- configs->add(*cfg);
- }
- }
- }
- }
- }
-}
-
-void ResTable::getLocales(Vector<String8>* locales) const
-{
- Vector<ResTable_config> configs;
- LOGD("calling getConfigurations");
- getConfigurations(&configs);
- LOGD("called getConfigurations size=%d", (int)configs.size());
- const size_t I = configs.size();
- for (size_t i=0; i<I; i++) {
- char locale[6];
- configs[i].getLocale(locale);
- const size_t J = locales->size();
- size_t j;
- for (j=0; j<J; j++) {
- if (0 == strcmp(locale, (*locales)[j].string())) {
- break;
- }
- }
- if (j == J) {
- locales->add(String8(locale));
- }
- }
-}
-
-ssize_t ResTable::getEntry(
- const Package* package, int typeIndex, int entryIndex,
- const ResTable_config* config,
- const ResTable_type** outType, const ResTable_entry** outEntry,
- const Type** outTypeClass) const
-{
- LOGV("Getting entry from package %p\n", package);
- const ResTable_package* const pkg = package->package;
-
- const Type* allTypes = package->getType(typeIndex);
- LOGV("allTypes=%p\n", allTypes);
- if (allTypes == NULL) {
- LOGV("Skipping entry type index 0x%02x because type is NULL!\n", typeIndex);
- return 0;
- }
-
- if ((size_t)entryIndex >= allTypes->entryCount) {
- LOGW("getEntry failing because entryIndex %d is beyond type entryCount %d",
- entryIndex, (int)allTypes->entryCount);
- return BAD_TYPE;
- }
-
- const ResTable_type* type = NULL;
- uint32_t offset = ResTable_type::NO_ENTRY;
- ResTable_config bestConfig;
- memset(&bestConfig, 0, sizeof(bestConfig)); // make the compiler shut up
-
- const size_t NT = allTypes->configs.size();
- for (size_t i=0; i<NT; i++) {
- const ResTable_type* const thisType = allTypes->configs[i];
- if (thisType == NULL) continue;
-
- ResTable_config thisConfig;
- thisConfig.copyFromDtoH(thisType->config);
-
- TABLE_GETENTRY(LOGI("Match entry 0x%x in type 0x%x (sz 0x%x): imsi:%d/%d=%d/%d lang:%c%c=%c%c cnt:%c%c=%c%c "
- "orien:%d=%d touch:%d=%d density:%d=%d key:%d=%d inp:%d=%d nav:%d=%d w:%d=%d h:%d=%d\n",
- entryIndex, typeIndex+1, dtohl(thisType->config.size),
- thisConfig.mcc, thisConfig.mnc,
- config ? config->mcc : 0, config ? config->mnc : 0,
- thisConfig.language[0] ? thisConfig.language[0] : '-',
- thisConfig.language[1] ? thisConfig.language[1] : '-',
- config && config->language[0] ? config->language[0] : '-',
- config && config->language[1] ? config->language[1] : '-',
- thisConfig.country[0] ? thisConfig.country[0] : '-',
- thisConfig.country[1] ? thisConfig.country[1] : '-',
- config && config->country[0] ? config->country[0] : '-',
- config && config->country[1] ? config->country[1] : '-',
- thisConfig.orientation,
- config ? config->orientation : 0,
- thisConfig.touchscreen,
- config ? config->touchscreen : 0,
- thisConfig.density,
- config ? config->density : 0,
- thisConfig.keyboard,
- config ? config->keyboard : 0,
- thisConfig.inputFlags,
- config ? config->inputFlags : 0,
- thisConfig.navigation,
- config ? config->navigation : 0,
- thisConfig.screenWidth,
- config ? config->screenWidth : 0,
- thisConfig.screenHeight,
- config ? config->screenHeight : 0));
-
- // Check to make sure this one is valid for the current parameters.
- if (config && !thisConfig.match(*config)) {
- TABLE_GETENTRY(LOGI("Does not match config!\n"));
- continue;
- }
-
- // Check if there is the desired entry in this type.
-
- const uint8_t* const end = ((const uint8_t*)thisType)
- + dtohl(thisType->header.size);
- const uint32_t* const eindex = (const uint32_t*)
- (((const uint8_t*)thisType) + dtohs(thisType->header.headerSize));
-
- uint32_t thisOffset = dtohl(eindex[entryIndex]);
- if (thisOffset == ResTable_type::NO_ENTRY) {
- TABLE_GETENTRY(LOGI("Skipping because it is not defined!\n"));
- continue;
- }
-
- if (type != NULL) {
- // Check if this one is less specific than the last found. If so,
- // we will skip it. We check starting with things we most care
- // about to those we least care about.
- if (!thisConfig.isBetterThan(bestConfig, config)) {
- TABLE_GETENTRY(LOGI("This config is worse than last!\n"));
- continue;
- }
- }
-
- type = thisType;
- offset = thisOffset;
- bestConfig = thisConfig;
- TABLE_GETENTRY(LOGI("Best entry so far -- using it!\n"));
- if (!config) break;
- }
-
- if (type == NULL) {
- TABLE_GETENTRY(LOGI("No value found for requested entry!\n"));
- return BAD_INDEX;
- }
-
- offset += dtohl(type->entriesStart);
- TABLE_NOISY(aout << "Looking in resource table " << package->header->header
- << ", typeOff="
- << (void*)(((const char*)type)-((const char*)package->header->header))
- << ", offset=" << (void*)offset << endl);
-
- if (offset > (dtohl(type->header.size)-sizeof(ResTable_entry))) {
- LOGW("ResTable_entry at 0x%x is beyond type chunk data 0x%x",
- offset, dtohl(type->header.size));
- return BAD_TYPE;
- }
- if ((offset&0x3) != 0) {
- LOGW("ResTable_entry at 0x%x is not on an integer boundary",
- offset);
- return BAD_TYPE;
- }
-
- const ResTable_entry* const entry = (const ResTable_entry*)
- (((const uint8_t*)type) + offset);
- if (dtohs(entry->size) < sizeof(*entry)) {
- LOGW("ResTable_entry size 0x%x is too small", dtohs(entry->size));
- return BAD_TYPE;
- }
-
- *outType = type;
- *outEntry = entry;
- if (outTypeClass != NULL) {
- *outTypeClass = allTypes;
- }
- return offset + dtohs(entry->size);
-}
-
-status_t ResTable::parsePackage(const ResTable_package* const pkg,
- const Header* const header)
-{
- const uint8_t* base = (const uint8_t*)pkg;
- status_t err = validate_chunk(&pkg->header, sizeof(*pkg),
- header->dataEnd, "ResTable_package");
- if (err != NO_ERROR) {
- return (mError=err);
- }
-
- const size_t pkgSize = dtohl(pkg->header.size);
-
- if (dtohl(pkg->typeStrings) >= pkgSize) {
- LOGW("ResTable_package type strings at %p are past chunk size %p.",
- (void*)dtohl(pkg->typeStrings), (void*)pkgSize);
- return (mError=BAD_TYPE);
- }
- if ((dtohl(pkg->typeStrings)&0x3) != 0) {
- LOGW("ResTable_package type strings at %p is not on an integer boundary.",
- (void*)dtohl(pkg->typeStrings));
- return (mError=BAD_TYPE);
- }
- if (dtohl(pkg->keyStrings) >= pkgSize) {
- LOGW("ResTable_package key strings at %p are past chunk size %p.",
- (void*)dtohl(pkg->keyStrings), (void*)pkgSize);
- return (mError=BAD_TYPE);
- }
- if ((dtohl(pkg->keyStrings)&0x3) != 0) {
- LOGW("ResTable_package key strings at %p is not on an integer boundary.",
- (void*)dtohl(pkg->keyStrings));
- return (mError=BAD_TYPE);
- }
-
- Package* package = NULL;
- PackageGroup* group = NULL;
- uint32_t id = dtohl(pkg->id);
- if (id != 0 && id < 256) {
- size_t idx = mPackageMap[id];
- if (idx == 0) {
- idx = mPackageGroups.size()+1;
-
- char16_t tmpName[sizeof(pkg->name)/sizeof(char16_t)];
- strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(char16_t));
- group = new PackageGroup(String16(tmpName), id);
- if (group == NULL) {
- return (mError=NO_MEMORY);
- }
-
- err = group->typeStrings.setTo(base+dtohl(pkg->typeStrings),
- header->dataEnd-(base+dtohl(pkg->typeStrings)));
- if (err != NO_ERROR) {
- return (mError=err);
- }
- err = group->keyStrings.setTo(base+dtohl(pkg->keyStrings),
- header->dataEnd-(base+dtohl(pkg->keyStrings)));
- if (err != NO_ERROR) {
- return (mError=err);
- }
-
- //printf("Adding new package id %d at index %d\n", id, idx);
- err = mPackageGroups.add(group);
- if (err < NO_ERROR) {
- return (mError=err);
- }
- mPackageMap[id] = (uint8_t)idx;
- } else {
- group = mPackageGroups.itemAt(idx-1);
- if (group == NULL) {
- return (mError=UNKNOWN_ERROR);
- }
- }
- package = new Package(header, pkg);
- if (package == NULL) {
- return (mError=NO_MEMORY);
- }
- err = group->packages.add(package);
- if (err < NO_ERROR) {
- return (mError=err);
- }
- } else {
- LOG_ALWAYS_FATAL("Skins not supported!");
- return NO_ERROR;
- }
-
-
- // Iterate through all chunks.
- size_t curPackage = 0;
-
- const ResChunk_header* chunk =
- (const ResChunk_header*)(((const uint8_t*)pkg)
- + dtohs(pkg->header.headerSize));
- const uint8_t* endPos = ((const uint8_t*)pkg) + dtohs(pkg->header.size);
- while (((const uint8_t*)chunk) <= (endPos-sizeof(ResChunk_header)) &&
- ((const uint8_t*)chunk) <= (endPos-dtohl(chunk->size))) {
- TABLE_NOISY(LOGV("PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
- dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
- (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
- const size_t csize = dtohl(chunk->size);
- const uint16_t ctype = dtohs(chunk->type);
- if (ctype == RES_TABLE_TYPE_SPEC_TYPE) {
- const ResTable_typeSpec* typeSpec = (const ResTable_typeSpec*)(chunk);
- err = validate_chunk(&typeSpec->header, sizeof(*typeSpec),
- endPos, "ResTable_typeSpec");
- if (err != NO_ERROR) {
- return (mError=err);
- }
-
- const size_t typeSpecSize = dtohl(typeSpec->header.size);
-
- LOAD_TABLE_NOISY(printf("TypeSpec off %p: type=0x%x, headerSize=0x%x, size=%p\n",
- (void*)(base-(const uint8_t*)chunk),
- dtohs(typeSpec->header.type),
- dtohs(typeSpec->header.headerSize),
- (void*)typeSize));
- // look for block overrun or int overflow when multiplying by 4
- if ((dtohl(typeSpec->entryCount) > (INT32_MAX/sizeof(uint32_t))
- || dtohs(typeSpec->header.headerSize)+(sizeof(uint32_t)*dtohl(typeSpec->entryCount))
- > typeSpecSize)) {
- LOGW("ResTable_typeSpec entry index to %p extends beyond chunk end %p.",
- (void*)(dtohs(typeSpec->header.headerSize)
- +(sizeof(uint32_t)*dtohl(typeSpec->entryCount))),
- (void*)typeSpecSize);
- return (mError=BAD_TYPE);
- }
-
- if (typeSpec->id == 0) {
- LOGW("ResTable_type has an id of 0.");
- return (mError=BAD_TYPE);
- }
-
- while (package->types.size() < typeSpec->id) {
- package->types.add(NULL);
- }
- Type* t = package->types[typeSpec->id-1];
- if (t == NULL) {
- t = new Type(header, package, dtohl(typeSpec->entryCount));
- package->types.editItemAt(typeSpec->id-1) = t;
- } else if (dtohl(typeSpec->entryCount) != t->entryCount) {
- LOGW("ResTable_typeSpec entry count inconsistent: given %d, previously %d",
- (int)dtohl(typeSpec->entryCount), (int)t->entryCount);
- return (mError=BAD_TYPE);
- }
- t->typeSpecFlags = (const uint32_t*)(
- ((const uint8_t*)typeSpec) + dtohs(typeSpec->header.headerSize));
- t->typeSpec = typeSpec;
-
- } else if (ctype == RES_TABLE_TYPE_TYPE) {
- const ResTable_type* type = (const ResTable_type*)(chunk);
- err = validate_chunk(&type->header, sizeof(*type)-sizeof(ResTable_config)+4,
- endPos, "ResTable_type");
- if (err != NO_ERROR) {
- return (mError=err);
- }
-
- const size_t typeSize = dtohl(type->header.size);
-
- LOAD_TABLE_NOISY(printf("Type off %p: type=0x%x, headerSize=0x%x, size=%p\n",
- (void*)(base-(const uint8_t*)chunk),
- dtohs(type->header.type),
- dtohs(type->header.headerSize),
- (void*)typeSize));
- if (dtohs(type->header.headerSize)+(sizeof(uint32_t)*dtohl(type->entryCount))
- > typeSize) {
- LOGW("ResTable_type entry index to %p extends beyond chunk end %p.",
- (void*)(dtohs(type->header.headerSize)
- +(sizeof(uint32_t)*dtohl(type->entryCount))),
- (void*)typeSize);
- return (mError=BAD_TYPE);
- }
- if (dtohl(type->entryCount) != 0
- && dtohl(type->entriesStart) > (typeSize-sizeof(ResTable_entry))) {
- LOGW("ResTable_type entriesStart at %p extends beyond chunk end %p.",
- (void*)dtohl(type->entriesStart), (void*)typeSize);
- return (mError=BAD_TYPE);
- }
- if (type->id == 0) {
- LOGW("ResTable_type has an id of 0.");
- return (mError=BAD_TYPE);
- }
-
- while (package->types.size() < type->id) {
- package->types.add(NULL);
- }
- Type* t = package->types[type->id-1];
- if (t == NULL) {
- t = new Type(header, package, dtohl(type->entryCount));
- package->types.editItemAt(type->id-1) = t;
- } else if (dtohl(type->entryCount) != t->entryCount) {
- LOGW("ResTable_type entry count inconsistent: given %d, previously %d",
- (int)dtohl(type->entryCount), (int)t->entryCount);
- return (mError=BAD_TYPE);
- }
-
- TABLE_GETENTRY(
- ResTable_config thisConfig;
- thisConfig.copyFromDtoH(type->config);
- LOGI("Adding config to type %d: imsi:%d/%d lang:%c%c cnt:%c%c "
- "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
- type->id,
- thisConfig.mcc, thisConfig.mnc,
- thisConfig.language[0] ? thisConfig.language[0] : '-',
- thisConfig.language[1] ? thisConfig.language[1] : '-',
- thisConfig.country[0] ? thisConfig.country[0] : '-',
- thisConfig.country[1] ? thisConfig.country[1] : '-',
- thisConfig.orientation,
- thisConfig.touchscreen,
- thisConfig.density,
- thisConfig.keyboard,
- thisConfig.inputFlags,
- thisConfig.navigation,
- thisConfig.screenWidth,
- thisConfig.screenHeight));
- t->configs.add(type);
- } else {
- status_t err = validate_chunk(chunk, sizeof(ResChunk_header),
- endPos, "ResTable_package:unknown");
- if (err != NO_ERROR) {
- return (mError=err);
- }
- }
- chunk = (const ResChunk_header*)
- (((const uint8_t*)chunk) + csize);
- }
-
- if (group->typeCount == 0) {
- group->typeCount = package->types.size();
- }
-
- return NO_ERROR;
-}
-
-#ifndef HAVE_ANDROID_OS
-#define CHAR16_TO_CSTR(c16, len) (String8(String16(c16,len)).string())
-
-#define CHAR16_ARRAY_EQ(constant, var, len) \
- ((len == (sizeof(constant)/sizeof(constant[0]))) && (0 == memcmp((var), (constant), (len))))
-
-void ResTable::print() const
-{
- printf("mError=0x%x (%s)\n", mError, strerror(mError));
-#if 0
- printf("mParams=%c%c-%c%c,\n",
- mParams.language[0], mParams.language[1],
- mParams.country[0], mParams.country[1]);
-#endif
- size_t pgCount = mPackageGroups.size();
- printf("Package Groups (%d)\n", (int)pgCount);
- for (size_t pgIndex=0; pgIndex<pgCount; pgIndex++) {
- const PackageGroup* pg = mPackageGroups[pgIndex];
- printf("Package Group %d id=%d packageCount=%d name=%s\n",
- (int)pgIndex, pg->id, (int)pg->packages.size(),
- String8(pg->name).string());
-
- size_t pkgCount = pg->packages.size();
- for (size_t pkgIndex=0; pkgIndex<pkgCount; pkgIndex++) {
- const Package* pkg = pg->packages[pkgIndex];
- size_t typeCount = pkg->types.size();
- printf(" Package %d id=%d name=%s typeCount=%d\n", (int)pkgIndex,
- pkg->package->id, String8(String16(pkg->package->name)).string(),
- (int)typeCount);
- for (size_t typeIndex=0; typeIndex<typeCount; typeIndex++) {
- const Type* typeConfigs = pkg->getType(typeIndex);
- if (typeConfigs == NULL) {
- printf(" type %d NULL\n", (int)typeIndex);
- continue;
- }
- const size_t NTC = typeConfigs->configs.size();
- printf(" type %d configCount=%d entryCount=%d\n",
- (int)typeIndex, (int)NTC, (int)typeConfigs->entryCount);
- if (typeConfigs->typeSpecFlags != NULL) {
- for (size_t entryIndex=0; entryIndex<typeConfigs->entryCount; entryIndex++) {
- uint32_t resID = (0xff000000 & ((pkg->package->id)<<24))
- | (0x00ff0000 & ((typeIndex+1)<<16))
- | (0x0000ffff & (entryIndex));
- resource_name resName;
- this->getResourceName(resID, &resName);
- printf(" spec resource 0x%08x %s:%s/%s: flags=0x%08x\n",
- resID,
- CHAR16_TO_CSTR(resName.package, resName.packageLen),
- CHAR16_TO_CSTR(resName.type, resName.typeLen),
- CHAR16_TO_CSTR(resName.name, resName.nameLen),
- dtohl(typeConfigs->typeSpecFlags[entryIndex]));
- }
- }
- for (size_t configIndex=0; configIndex<NTC; configIndex++) {
- const ResTable_type* type = typeConfigs->configs[configIndex];
- if ((((uint64_t)type)&0x3) != 0) {
- printf(" NON-INTEGER ResTable_type ADDRESS: %p\n", type);
- continue;
- }
- printf(" config %d lang=%c%c cnt=%c%c orien=%d touch=%d density=%d key=%d infl=%d nav=%d w=%d h=%d\n",
- (int)configIndex,
- type->config.language[0] ? type->config.language[0] : '-',
- type->config.language[1] ? type->config.language[1] : '-',
- type->config.country[0] ? type->config.country[0] : '-',
- type->config.country[1] ? type->config.country[1] : '-',
- type->config.orientation,
- type->config.touchscreen,
- dtohs(type->config.density),
- type->config.keyboard,
- type->config.inputFlags,
- type->config.navigation,
- dtohs(type->config.screenWidth),
- dtohs(type->config.screenHeight));
- size_t entryCount = dtohl(type->entryCount);
- uint32_t entriesStart = dtohl(type->entriesStart);
- if ((entriesStart&0x3) != 0) {
- printf(" NON-INTEGER ResTable_type entriesStart OFFSET: %p\n", (void*)entriesStart);
- continue;
- }
- uint32_t typeSize = dtohl(type->header.size);
- if ((typeSize&0x3) != 0) {
- printf(" NON-INTEGER ResTable_type header.size: %p\n", (void*)typeSize);
- continue;
- }
- for (size_t entryIndex=0; entryIndex<entryCount; entryIndex++) {
-
- const uint8_t* const end = ((const uint8_t*)type)
- + dtohl(type->header.size);
- const uint32_t* const eindex = (const uint32_t*)
- (((const uint8_t*)type) + dtohs(type->header.headerSize));
-
- uint32_t thisOffset = dtohl(eindex[entryIndex]);
- if (thisOffset == ResTable_type::NO_ENTRY) {
- continue;
- }
-
- uint32_t resID = (0xff000000 & ((pkg->package->id)<<24))
- | (0x00ff0000 & ((typeIndex+1)<<16))
- | (0x0000ffff & (entryIndex));
- resource_name resName;
- this->getResourceName(resID, &resName);
- printf(" resource 0x%08x %s:%s/%s: ", resID,
- CHAR16_TO_CSTR(resName.package, resName.packageLen),
- CHAR16_TO_CSTR(resName.type, resName.typeLen),
- CHAR16_TO_CSTR(resName.name, resName.nameLen));
- if ((thisOffset&0x3) != 0) {
- printf("NON-INTEGER OFFSET: %p\n", (void*)thisOffset);
- continue;
- }
- if ((thisOffset+sizeof(ResTable_entry)) > typeSize) {
- printf("OFFSET OUT OF BOUNDS: %p+%p (size is %p)\n",
- (void*)entriesStart, (void*)thisOffset,
- (void*)typeSize);
- continue;
- }
-
- const ResTable_entry* ent = (const ResTable_entry*)
- (((const uint8_t*)type) + entriesStart + thisOffset);
- if (((entriesStart + thisOffset)&0x3) != 0) {
- printf("NON-INTEGER ResTable_entry OFFSET: %p\n",
- (void*)(entriesStart + thisOffset));
- continue;
- }
- if ((dtohs(ent->flags)&ResTable_entry::FLAG_COMPLEX) != 0) {
- printf("<bag>");
- } else {
- uint16_t esize = dtohs(ent->size);
- if ((esize&0x3) != 0) {
- printf("NON-INTEGER ResTable_entry SIZE: %p\n", (void*)esize);
- continue;
- }
- if ((thisOffset+esize) > typeSize) {
- printf("ResTable_entry OUT OF BOUNDS: %p+%p+%p (size is %p)\n",
- (void*)entriesStart, (void*)thisOffset,
- (void*)esize, (void*)typeSize);
- continue;
- }
-
- const Res_value* value = (const Res_value*)
- (((const uint8_t*)ent) + esize);
- printf("t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)",
- (int)value->dataType, (int)dtohl(value->data),
- (int)dtohs(value->size), (int)value->res0);
- }
-
- if ((dtohs(ent->flags)&ResTable_entry::FLAG_PUBLIC) != 0) {
- printf(" (PUBLIC)");
- }
- printf("\n");
- }
- }
- }
- }
- }
-}
-
-#endif // HAVE_ANDROID_OS
-
-} // namespace android
diff --git a/libs/utils/SharedBuffer.cpp b/libs/utils/SharedBuffer.cpp
deleted file mode 100644
index 3555fb7..0000000
--- a/libs/utils/SharedBuffer.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <utils/SharedBuffer.h>
-#include <utils/Atomic.h>
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-SharedBuffer* SharedBuffer::alloc(size_t size)
-{
- SharedBuffer* sb = static_cast<SharedBuffer *>(malloc(sizeof(SharedBuffer) + size));
- if (sb) {
- sb->mRefs = 1;
- sb->mSize = size;
- }
- return sb;
-}
-
-
-ssize_t SharedBuffer::dealloc(const SharedBuffer* released)
-{
- if (released->mRefs != 0) return -1; // XXX: invalid operation
- free(const_cast<SharedBuffer*>(released));
- return 0;
-}
-
-SharedBuffer* SharedBuffer::edit() const
-{
- if (onlyOwner()) {
- return const_cast<SharedBuffer*>(this);
- }
- SharedBuffer* sb = alloc(mSize);
- if (sb) {
- memcpy(sb->data(), data(), size());
- release();
- }
- return sb;
-}
-
-SharedBuffer* SharedBuffer::editResize(size_t newSize) const
-{
- if (onlyOwner()) {
- SharedBuffer* buf = const_cast<SharedBuffer*>(this);
- if (buf->mSize == newSize) return buf;
- buf = (SharedBuffer*)realloc(buf, sizeof(SharedBuffer) + newSize);
- if (buf != NULL) {
- buf->mSize = newSize;
- return buf;
- }
- }
- SharedBuffer* sb = alloc(newSize);
- if (sb) {
- const size_t mySize = mSize;
- memcpy(sb->data(), data(), newSize < mySize ? newSize : mySize);
- release();
- }
- return sb;
-}
-
-SharedBuffer* SharedBuffer::attemptEdit() const
-{
- if (onlyOwner()) {
- return const_cast<SharedBuffer*>(this);
- }
- return 0;
-}
-
-SharedBuffer* SharedBuffer::reset(size_t new_size) const
-{
- // cheap-o-reset.
- SharedBuffer* sb = alloc(new_size);
- if (sb) {
- release();
- }
- return sb;
-}
-
-void SharedBuffer::acquire() const {
- android_atomic_inc(&mRefs);
-}
-
-int32_t SharedBuffer::release(uint32_t flags) const
-{
- int32_t prev = 1;
- if (onlyOwner() || ((prev = android_atomic_dec(&mRefs)) == 1)) {
- mRefs = 0;
- if ((flags & eKeepStorage) == 0) {
- free(const_cast<SharedBuffer*>(this));
- }
- }
- return prev;
-}
-
-
-}; // namespace android
diff --git a/libs/utils/Socket.cpp b/libs/utils/Socket.cpp
deleted file mode 100644
index 51509a3..0000000
--- a/libs/utils/Socket.cpp
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Internet address class.
-//
-
-#ifdef HAVE_WINSOCK
-// This needs to come first, or Cygwin gets concerned about a potential
-// clash between WinSock and <sys/types.h>.
-# include <winsock2.h>
-#endif
-
-#include <utils/Socket.h>
-#include <utils/inet_address.h>
-#include <utils/Log.h>
-#include <utils/Timers.h>
-
-#ifndef HAVE_WINSOCK
-# include <sys/types.h>
-# include <sys/socket.h>
-# include <netinet/in.h>
-# include <arpa/inet.h>
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-using namespace android;
-
-
-/*
- * ===========================================================================
- * Socket
- * ===========================================================================
- */
-
-#ifndef INVALID_SOCKET
-# define INVALID_SOCKET (-1)
-#endif
-#define UNDEF_SOCKET ((unsigned long) INVALID_SOCKET)
-
-/*static*/ bool Socket::mBootInitialized = false;
-
-/*
- * Extract system-dependent error code.
- */
-static inline int getSocketError(void) {
-#ifdef HAVE_WINSOCK
- return WSAGetLastError();
-#else
- return errno;
-#endif
-}
-
-/*
- * One-time initialization for socket code.
- */
-/*static*/ bool Socket::bootInit(void)
-{
-#ifdef HAVE_WINSOCK
- WSADATA wsaData;
- int err;
-
- err = WSAStartup(MAKEWORD(2, 0), &wsaData);
- if (err != 0) {
- LOG(LOG_ERROR, "socket", "Unable to start WinSock\n");
- return false;
- }
-
- LOG(LOG_INFO, "socket", "Using WinSock v%d.%d\n",
- LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
-#endif
-
- mBootInitialized = true;
- return true;
-}
-
-/*
- * One-time shutdown for socket code.
- */
-/*static*/ void Socket::finalShutdown(void)
-{
-#ifdef HAVE_WINSOCK
- WSACleanup();
-#endif
- mBootInitialized = false;
-}
-
-
-/*
- * Simple constructor. Allow the application to create us and then make
- * bind/connect calls.
- */
-Socket::Socket(void)
- : mSock(UNDEF_SOCKET)
-{
- if (!mBootInitialized)
- LOG(LOG_WARN, "socket", "WARNING: sockets not initialized\n");
-}
-
-/*
- * Destructor. Closes the socket and resets our storage.
- */
-Socket::~Socket(void)
-{
- close();
-}
-
-
-/*
- * Create a socket and connect to the specified host and port.
- */
-int Socket::connect(const char* host, int port)
-{
- if (mSock != UNDEF_SOCKET) {
- LOG(LOG_WARN, "socket", "Socket already connected\n");
- return -1;
- }
-
- InetSocketAddress sockAddr;
- if (!sockAddr.create(host, port))
- return -1;
-
- //return doConnect(sockAddr);
- int foo;
- foo = doConnect(sockAddr);
- return foo;
-}
-
-/*
- * Create a socket and connect to the specified host and port.
- */
-int Socket::connect(const InetAddress* addr, int port)
-{
- if (mSock != UNDEF_SOCKET) {
- LOG(LOG_WARN, "socket", "Socket already connected\n");
- return -1;
- }
-
- InetSocketAddress sockAddr;
- if (!sockAddr.create(addr, port))
- return -1;
-
- return doConnect(sockAddr);
-}
-
-/*
- * Finish creating a socket by connecting to the remote host.
- *
- * Returns 0 on success.
- */
-int Socket::doConnect(const InetSocketAddress& sockAddr)
-{
-#ifdef HAVE_WINSOCK
- SOCKET sock;
-#else
- int sock;
-#endif
- const InetAddress* addr = sockAddr.getAddress();
- int port = sockAddr.getPort();
- struct sockaddr_in inaddr;
- DurationTimer connectTimer;
-
- assert(sizeof(struct sockaddr_in) == addr->getAddressLength());
- memcpy(&inaddr, addr->getAddress(), addr->getAddressLength());
- inaddr.sin_port = htons(port);
-
- //fprintf(stderr, "--- connecting to %s:%d\n",
- // sockAddr.getHostName(), port);
-
- sock = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (sock == INVALID_SOCKET) {
- int err = getSocketError();
- LOG(LOG_ERROR, "socket", "Unable to create socket (err=%d)\n", err);
- return (err != 0) ? err : -1;
- }
-
- connectTimer.start();
-
- if (::connect(sock, (struct sockaddr*) &inaddr, sizeof(inaddr)) != 0) {
- int err = getSocketError();
- LOG(LOG_WARN, "socket", "Connect to %s:%d failed: %d\n",
- sockAddr.getHostName(), port, err);
- return (err != 0) ? err : -1;
- }
-
- connectTimer.stop();
- if ((long) connectTimer.durationUsecs() > 100000) {
- LOG(LOG_INFO, "socket",
- "Connect to %s:%d took %.3fs\n", sockAddr.getHostName(),
- port, ((long) connectTimer.durationUsecs()) / 1000000.0);
- }
-
- mSock = (unsigned long) sock;
- LOG(LOG_VERBOSE, "socket",
- "--- connected to %s:%d\n", sockAddr.getHostName(), port);
- return 0;
-}
-
-
-/*
- * Close the socket if it needs closing.
- */
-bool Socket::close(void)
-{
- if (mSock != UNDEF_SOCKET) {
- //fprintf(stderr, "--- closing socket %lu\n", mSock);
-#ifdef HAVE_WINSOCK
- if (::closesocket((SOCKET) mSock) != 0)
- return false;
-#else
- if (::close((int) mSock) != 0)
- return false;
-#endif
- }
-
- mSock = UNDEF_SOCKET;
-
- return true;
-}
-
-/*
- * Read data from socket.
- *
- * Standard semantics: read up to "len" bytes into "buf". Returns the
- * number of bytes read, or less than zero on error.
- */
-int Socket::read(void* buf, ssize_t len) const
-{
- if (mSock == UNDEF_SOCKET) {
- LOG(LOG_ERROR, "socket", "ERROR: read on invalid socket\n");
- return -500;
- }
-
-#ifdef HAVE_WINSOCK
- SOCKET sock = (SOCKET) mSock;
-#else
- int sock = (int) mSock;
-#endif
- int cc;
-
- cc = recv(sock, (char*)buf, len, 0);
- if (cc < 0) {
- int err = getSocketError();
- return (err > 0) ? -err : -1;
- }
-
- return cc;
-}
-
-/*
- * Write data to a socket.
- *
- * Standard semantics: write up to "len" bytes into "buf". Returns the
- * number of bytes written, or less than zero on error.
- */
-int Socket::write(const void* buf, ssize_t len) const
-{
- if (mSock == UNDEF_SOCKET) {
- LOG(LOG_ERROR, "socket", "ERROR: write on invalid socket\n");
- return -500;
- }
-
-#ifdef HAVE_WINSOCK
- SOCKET sock = (SOCKET) mSock;
-#else
- int sock = (int) mSock;
-#endif
- int cc;
-
- cc = send(sock, (const char*)buf, len, 0);
- if (cc < 0) {
- int err = getSocketError();
- return (err > 0) ? -err : -1;
- }
-
- return cc;
-}
-
-
-/*
- * ===========================================================================
- * Socket tests
- * ===========================================================================
- */
-
-/*
- * Read all data from the socket. The data is read into a buffer that
- * expands as needed.
- *
- * On exit, the buffer is returned, and the length of the data is stored
- * in "*sz". A null byte is added to the end, but is not included in
- * the length.
- */
-static char* socketReadAll(const Socket& s, int *sz)
-{
- int max, r;
- char *data, *ptr, *tmp;
-
- data = (char*) malloc(max = 32768);
- if (data == NULL)
- return NULL;
-
- ptr = data;
-
- for (;;) {
- if ((ptr - data) == max) {
- tmp = (char*) realloc(data, max *= 2);
- if(tmp == 0) {
- free(data);
- return 0;
- }
- }
- r = s.read(ptr, max - (ptr - data));
- if (r == 0)
- break;
- if (r < 0) {
- LOG(LOG_WARN, "socket", "WARNING: socket read failed (res=%d)\n",r);
- break;
- }
- ptr += r;
- }
-
- if ((ptr - data) == max) {
- tmp = (char*) realloc(data, max + 1);
- if (tmp == NULL) {
- free(data);
- return NULL;
- }
- }
- *ptr = '\0';
- *sz = (ptr - data);
- return data;
-}
-
-/*
- * Exercise the Socket class.
- */
-void android::TestSockets(void)
-{
- printf("----- SOCKET TEST ------\n");
- Socket::bootInit();
-
- char* buf = NULL;
- int len, cc;
- const char* kTestStr =
- "GET / HTTP/1.0\n"
- "Connection: close\n"
- "\n";
-
- Socket sock;
- if (sock.connect("www.google.com", 80) != 0) {
- fprintf(stderr, "socket connected failed\n");
- goto bail;
- }
-
- cc = sock.write(kTestStr, strlen(kTestStr));
- if (cc != (int) strlen(kTestStr)) {
- fprintf(stderr, "write failed, res=%d\n", cc);
- goto bail;
- }
- buf = socketReadAll(sock, &len);
-
- printf("GOT '%s'\n", buf);
-
-bail:
- sock.close();
- free(buf);
-}
-
diff --git a/libs/utils/Static.cpp b/libs/utils/Static.cpp
deleted file mode 100644
index 93f7e4f..0000000
--- a/libs/utils/Static.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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.
- */
-
-// All static variables go here, to control initialization and
-// destruction order in the library.
-
-#include <private/utils/Static.h>
-
-#include <utils/BufferedTextOutput.h>
-#include <utils/IPCThreadState.h>
-#include <utils/Log.h>
-
-namespace android {
-
-class LibUtilsFirstStatics
-{
-public:
- LibUtilsFirstStatics()
- {
- initialize_string8();
- initialize_string16();
- }
-
- ~LibUtilsFirstStatics()
- {
- terminate_string16();
- terminate_string8();
- }
-};
-
-static LibUtilsFirstStatics gFirstStatics;
-int gDarwinCantLoadAllObjects = 1;
-
-// ------------ Text output streams
-
-Vector<int32_t> gTextBuffers;
-
-class LogTextOutput : public BufferedTextOutput
-{
-public:
- LogTextOutput() : BufferedTextOutput(MULTITHREADED) { }
- virtual ~LogTextOutput() { };
-
-protected:
- virtual status_t writeLines(const struct iovec& vec, size_t N)
- {
- android_writevLog(&vec, N);
- return NO_ERROR;
- }
-};
-
-class FdTextOutput : public BufferedTextOutput
-{
-public:
- FdTextOutput(int fd) : BufferedTextOutput(MULTITHREADED), mFD(fd) { }
- virtual ~FdTextOutput() { };
-
-protected:
- virtual status_t writeLines(const struct iovec& vec, size_t N)
- {
- writev(mFD, &vec, N);
- return NO_ERROR;
- }
-
-private:
- int mFD;
-};
-
-static LogTextOutput gLogTextOutput;
-static FdTextOutput gStdoutTextOutput(STDOUT_FILENO);
-static FdTextOutput gStderrTextOutput(STDERR_FILENO);
-
-TextOutput& alog(gLogTextOutput);
-TextOutput& aout(gStdoutTextOutput);
-TextOutput& aerr(gStderrTextOutput);
-
-#ifndef LIBUTILS_NATIVE
-
-// ------------ ProcessState.cpp
-
-Mutex gProcessMutex;
-sp<ProcessState> gProcess;
-
-class LibUtilsIPCtStatics
-{
-public:
- LibUtilsIPCtStatics()
- {
- }
-
- ~LibUtilsIPCtStatics()
- {
- IPCThreadState::shutdown();
- }
-};
-
-static LibUtilsIPCtStatics gIPCStatics;
-
-// ------------ ServiceManager.cpp
-
-Mutex gDefaultServiceManagerLock;
-sp<IServiceManager> gDefaultServiceManager;
-sp<IPermissionController> gPermissionController;
-
-#endif
-
-} // namespace android
diff --git a/libs/utils/StopWatch.cpp b/libs/utils/StopWatch.cpp
deleted file mode 100644
index 68a1c52..0000000
--- a/libs/utils/StopWatch.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "StopWatch"
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <utils/StopWatch.h>
-
-/*****************************************************************************/
-
-namespace android {
-
-
-StopWatch::StopWatch(const char *name, int clock, uint32_t flags)
- : mName(name), mClock(clock), mFlags(flags),
- mStartTime(0), mNumLaps(0)
-{
- mStartTime = systemTime(mClock);
-}
-
-StopWatch::~StopWatch()
-{
- nsecs_t elapsed = elapsedTime();
- const int n = mNumLaps;
- LOGD("StopWatch %s (us): %lld ", mName, ns2us(elapsed));
- for (int i=0 ; i<n ; i++) {
- const nsecs_t soFar = mLaps[i].soFar;
- const nsecs_t thisLap = mLaps[i].thisLap;
- LOGD(" [%d: %lld, %lld]", i, ns2us(soFar), ns2us(thisLap));
- }
-}
-
-const char* StopWatch::name() const
-{
- return mName;
-}
-
-nsecs_t StopWatch::lap()
-{
- nsecs_t elapsed = elapsedTime();
- if (mNumLaps >= 8) {
- elapsed = 0;
- } else {
- const int n = mNumLaps;
- mLaps[n].soFar = elapsed;
- mLaps[n].thisLap = n ? (elapsed - mLaps[n-1].soFar) : elapsed;
- mNumLaps = n+1;
- }
- return elapsed;
-}
-
-nsecs_t StopWatch::elapsedTime() const
-{
- return systemTime(mClock) - mStartTime;
-}
-
-
-/*****************************************************************************/
-
-}; // namespace android
-
diff --git a/libs/utils/String16.cpp b/libs/utils/String16.cpp
deleted file mode 100644
index 1f81cad..0000000
--- a/libs/utils/String16.cpp
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- * 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.
- */
-
-#include <utils/String16.h>
-
-#include <utils/Debug.h>
-#include <utils/Log.h>
-#include <utils/String8.h>
-#include <utils/TextOutput.h>
-#include <utils/threads.h>
-
-#include <private/utils/Static.h>
-
-#ifdef HAVE_WINSOCK
-# undef nhtol
-# undef htonl
-# undef nhtos
-# undef htons
-
-# ifdef HAVE_LITTLE_ENDIAN
-# define ntohl(x) ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )
-# define htonl(x) ntohl(x)
-# define ntohs(x) ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) )
-# define htons(x) ntohs(x)
-# else
-# define ntohl(x) (x)
-# define htonl(x) (x)
-# define ntohs(x) (x)
-# define htons(x) (x)
-# endif
-#else
-# include <netinet/in.h>
-#endif
-
-#include <memory.h>
-#include <stdio.h>
-#include <ctype.h>
-
-// ---------------------------------------------------------------------------
-
-int strcmp16(const char16_t *s1, const char16_t *s2)
-{
- char16_t ch;
- int d = 0;
-
- while ( 1 ) {
- d = (int)(ch = *s1++) - (int)*s2++;
- if ( d || !ch )
- break;
- }
-
- return d;
-}
-
-int strncmp16(const char16_t *s1, const char16_t *s2, size_t n)
-{
- char16_t ch;
- int d = 0;
-
- while ( n-- ) {
- d = (int)(ch = *s1++) - (int)*s2++;
- if ( d || !ch )
- break;
- }
-
- return d;
-}
-
-char16_t *strcpy16(char16_t *dst, const char16_t *src)
-{
- char16_t *q = dst;
- const char16_t *p = src;
- char16_t ch;
-
- do {
- *q++ = ch = *p++;
- } while ( ch );
-
- return dst;
-}
-
-size_t strlen16(const char16_t *s)
-{
- const char16_t *ss = s;
- while ( *ss )
- ss++;
- return ss-s;
-}
-
-
-char16_t *strncpy16(char16_t *dst, const char16_t *src, size_t n)
-{
- char16_t *q = dst;
- const char16_t *p = src;
- char ch;
-
- while (n) {
- n--;
- *q++ = ch = *p++;
- if ( !ch )
- break;
- }
-
- *q = 0;
-
- return dst;
-}
-
-size_t strnlen16(const char16_t *s, size_t maxlen)
-{
- const char16_t *ss = s;
-
- /* Important: the maxlen test must precede the reference through ss;
- since the byte beyond the maximum may segfault */
- while ((maxlen > 0) && *ss) {
- ss++;
- maxlen--;
- }
- return ss-s;
-}
-
-int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2)
-{
- const char16_t* e1 = s1+n1;
- const char16_t* e2 = s2+n2;
-
- while (s1 < e1 && s2 < e2) {
- const int d = (int)*s1++ - (int)*s2++;
- if (d) {
- return d;
- }
- }
-
- return n1 < n2
- ? (0 - (int)*s2)
- : (n1 > n2
- ? ((int)*s1 - 0)
- : 0);
-}
-
-int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2)
-{
- const char16_t* e1 = s1H+n1;
- const char16_t* e2 = s2N+n2;
-
- while (s1H < e1 && s2N < e2) {
- const char16_t c2 = ntohs(*s2N);
- const int d = (int)*s1H++ - (int)c2;
- s2N++;
- if (d) {
- return d;
- }
- }
-
- return n1 < n2
- ? (0 - (int)ntohs(*s2N))
- : (n1 > n2
- ? ((int)*s1H - 0)
- : 0);
-}
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-static inline size_t
-utf8_char_len(uint8_t ch)
-{
- return ((0xe5000000 >> ((ch >> 3) & 0x1e)) & 3) + 1;
-}
-
-#define UTF8_SHIFT_AND_MASK(unicode, byte) (unicode)<<=6; (unicode) |= (0x3f & (byte));
-
-static inline uint32_t
-utf8_to_utf32(const uint8_t *src, size_t length)
-{
- uint32_t unicode;
-
- switch (length)
- {
- case 1:
- return src[0];
- case 2:
- unicode = src[0] & 0x1f;
- UTF8_SHIFT_AND_MASK(unicode, src[1])
- return unicode;
- case 3:
- unicode = src[0] & 0x0f;
- UTF8_SHIFT_AND_MASK(unicode, src[1])
- UTF8_SHIFT_AND_MASK(unicode, src[2])
- return unicode;
- case 4:
- unicode = src[0] & 0x07;
- UTF8_SHIFT_AND_MASK(unicode, src[1])
- UTF8_SHIFT_AND_MASK(unicode, src[2])
- UTF8_SHIFT_AND_MASK(unicode, src[3])
- return unicode;
- default:
- return 0xffff;
- }
-
- //printf("Char at %p: len=%d, utf-16=%p\n", src, length, (void*)result);
-}
-
-// ---------------------------------------------------------------------------
-
-static SharedBuffer* gEmptyStringBuf = NULL;
-static char16_t* gEmptyString = NULL;
-
-static inline char16_t* getEmptyString()
-{
- gEmptyStringBuf->acquire();
- return gEmptyString;
-}
-
-void initialize_string16()
-{
- SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t));
- char16_t* str = (char16_t*)buf->data();
- *str = 0;
- gEmptyStringBuf = buf;
- gEmptyString = str;
-}
-
-void terminate_string16()
-{
- SharedBuffer::bufferFromData(gEmptyString)->release();
- gEmptyStringBuf = NULL;
- gEmptyString = NULL;
-}
-
-// ---------------------------------------------------------------------------
-
-// Note: not dealing with generating surrogate pairs.
-static char16_t* allocFromUTF8(const char* in, size_t len)
-{
- if (len == 0) return getEmptyString();
-
- size_t chars = 0;
- const char* end = in+len;
- const char* p = in;
-
- while (p < end) {
- chars++;
- p += utf8_char_len(*p);
- }
-
- SharedBuffer* buf = SharedBuffer::alloc((chars+1)*sizeof(char16_t));
- if (buf) {
- p = in;
- char16_t* str = (char16_t*)buf->data();
- char16_t* d = str;
- while (p < end) {
- size_t len = utf8_char_len(*p);
- *d++ = (char16_t)utf8_to_utf32((const uint8_t*)p, len);
- p += len;
- }
- *d = 0;
-
- //printf("Created UTF-16 string from UTF-8 \"%s\":", in);
- //printHexData(1, str, buf->size(), 16, 1);
- //printf("\n");
-
- return str;
- }
-
- return getEmptyString();
-}
-
-// ---------------------------------------------------------------------------
-
-String16::String16()
- : mString(getEmptyString())
-{
-}
-
-String16::String16(const String16& o)
- : mString(o.mString)
-{
- SharedBuffer::bufferFromData(mString)->acquire();
-}
-
-String16::String16(const String16& o, size_t len, size_t begin)
- : mString(getEmptyString())
-{
- setTo(o, len, begin);
-}
-
-String16::String16(const char16_t* o)
-{
- size_t len = strlen16(o);
- SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
- LOG_ASSERT(buf, "Unable to allocate shared buffer");
- if (buf) {
- char16_t* str = (char16_t*)buf->data();
- strcpy16(str, o);
- mString = str;
- return;
- }
-
- mString = getEmptyString();
-}
-
-String16::String16(const char16_t* o, size_t len)
-{
- SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
- LOG_ASSERT(buf, "Unable to allocate shared buffer");
- if (buf) {
- char16_t* str = (char16_t*)buf->data();
- memcpy(str, o, len*sizeof(char16_t));
- str[len] = 0;
- mString = str;
- return;
- }
-
- mString = getEmptyString();
-}
-
-String16::String16(const String8& o)
- : mString(allocFromUTF8(o.string(), o.size()))
-{
-}
-
-String16::String16(const char* o)
- : mString(allocFromUTF8(o, strlen(o)))
-{
-}
-
-String16::String16(const char* o, size_t len)
- : mString(allocFromUTF8(o, len))
-{
-}
-
-String16::~String16()
-{
- SharedBuffer::bufferFromData(mString)->release();
-}
-
-void String16::setTo(const String16& other)
-{
- SharedBuffer::bufferFromData(other.mString)->acquire();
- SharedBuffer::bufferFromData(mString)->release();
- mString = other.mString;
-}
-
-status_t String16::setTo(const String16& other, size_t len, size_t begin)
-{
- const size_t N = other.size();
- if (begin >= N) {
- SharedBuffer::bufferFromData(mString)->release();
- mString = getEmptyString();
- return NO_ERROR;
- }
- if ((begin+len) > N) len = N-begin;
- if (begin == 0 && len == N) {
- setTo(other);
- return NO_ERROR;
- }
-
- if (&other == this) {
- LOG_ALWAYS_FATAL("Not implemented");
- }
-
- return setTo(other.string()+begin, len);
-}
-
-status_t String16::setTo(const char16_t* other)
-{
- return setTo(other, strlen16(other));
-}
-
-status_t String16::setTo(const char16_t* other, size_t len)
-{
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
- ->editResize((len+1)*sizeof(char16_t));
- if (buf) {
- char16_t* str = (char16_t*)buf->data();
- memcpy(str, other, len*sizeof(char16_t));
- str[len] = 0;
- mString = str;
- return NO_ERROR;
- }
- return NO_MEMORY;
-}
-
-status_t String16::append(const String16& other)
-{
- const size_t myLen = size();
- const size_t otherLen = other.size();
- if (myLen == 0) {
- setTo(other);
- return NO_ERROR;
- } else if (otherLen == 0) {
- return NO_ERROR;
- }
-
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
- ->editResize((myLen+otherLen+1)*sizeof(char16_t));
- if (buf) {
- char16_t* str = (char16_t*)buf->data();
- memcpy(str+myLen, other, (otherLen+1)*sizeof(char16_t));
- mString = str;
- return NO_ERROR;
- }
- return NO_MEMORY;
-}
-
-status_t String16::append(const char16_t* chrs, size_t otherLen)
-{
- const size_t myLen = size();
- if (myLen == 0) {
- setTo(chrs, otherLen);
- return NO_ERROR;
- } else if (otherLen == 0) {
- return NO_ERROR;
- }
-
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
- ->editResize((myLen+otherLen+1)*sizeof(char16_t));
- if (buf) {
- char16_t* str = (char16_t*)buf->data();
- memcpy(str+myLen, chrs, otherLen*sizeof(char16_t));
- str[myLen+otherLen] = 0;
- mString = str;
- return NO_ERROR;
- }
- return NO_MEMORY;
-}
-
-status_t String16::insert(size_t pos, const char16_t* chrs)
-{
- return insert(pos, chrs, strlen16(chrs));
-}
-
-status_t String16::insert(size_t pos, const char16_t* chrs, size_t len)
-{
- const size_t myLen = size();
- if (myLen == 0) {
- return setTo(chrs, len);
- return NO_ERROR;
- } else if (len == 0) {
- return NO_ERROR;
- }
-
- if (pos > myLen) pos = myLen;
-
- #if 0
- printf("Insert in to %s: pos=%d, len=%d, myLen=%d, chrs=%s\n",
- String8(*this).string(), pos,
- len, myLen, String8(chrs, len).string());
- #endif
-
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
- ->editResize((myLen+len+1)*sizeof(char16_t));
- if (buf) {
- char16_t* str = (char16_t*)buf->data();
- if (pos < myLen) {
- memmove(str+pos+len, str+pos, (myLen-pos)*sizeof(char16_t));
- }
- memcpy(str+pos, chrs, len*sizeof(char16_t));
- str[myLen+len] = 0;
- mString = str;
- #if 0
- printf("Result (%d chrs): %s\n", size(), String8(*this).string());
- #endif
- return NO_ERROR;
- }
- return NO_MEMORY;
-}
-
-ssize_t String16::findFirst(char16_t c) const
-{
- const char16_t* str = string();
- const char16_t* p = str;
- const char16_t* e = p + size();
- while (p < e) {
- if (*p == c) {
- return p-str;
- }
- p++;
- }
- return -1;
-}
-
-ssize_t String16::findLast(char16_t c) const
-{
- const char16_t* str = string();
- const char16_t* p = str;
- const char16_t* e = p + size();
- while (p < e) {
- e--;
- if (*e == c) {
- return e-str;
- }
- }
- return -1;
-}
-
-bool String16::startsWith(const String16& prefix) const
-{
- const size_t ps = prefix.size();
- if (ps > size()) return false;
- return strzcmp16(mString, ps, prefix.string(), ps) == 0;
-}
-
-bool String16::startsWith(const char16_t* prefix) const
-{
- const size_t ps = strlen16(prefix);
- if (ps > size()) return false;
- return strncmp16(mString, prefix, ps) == 0;
-}
-
-status_t String16::makeLower()
-{
- const size_t N = size();
- const char16_t* str = string();
- char16_t* edit = NULL;
- for (size_t i=0; i<N; i++) {
- const char16_t v = str[i];
- if (v >= 'A' && v <= 'Z') {
- if (!edit) {
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
- if (!buf) {
- return NO_MEMORY;
- }
- edit = (char16_t*)buf->data();
- mString = str = edit;
- }
- edit[i] = tolower((char)v);
- }
- }
- return NO_ERROR;
-}
-
-status_t String16::replaceAll(char16_t replaceThis, char16_t withThis)
-{
- const size_t N = size();
- const char16_t* str = string();
- char16_t* edit = NULL;
- for (size_t i=0; i<N; i++) {
- if (str[i] == replaceThis) {
- if (!edit) {
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
- if (!buf) {
- return NO_MEMORY;
- }
- edit = (char16_t*)buf->data();
- mString = str = edit;
- }
- edit[i] = withThis;
- }
- }
- return NO_ERROR;
-}
-
-status_t String16::remove(size_t len, size_t begin)
-{
- const size_t N = size();
- if (begin >= N) {
- SharedBuffer::bufferFromData(mString)->release();
- mString = getEmptyString();
- return NO_ERROR;
- }
- if ((begin+len) > N) len = N-begin;
- if (begin == 0 && len == N) {
- return NO_ERROR;
- }
-
- if (begin > 0) {
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
- ->editResize((N+1)*sizeof(char16_t));
- if (!buf) {
- return NO_MEMORY;
- }
- char16_t* str = (char16_t*)buf->data();
- memmove(str, str+begin, (N-begin+1)*sizeof(char16_t));
- mString = str;
- }
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
- ->editResize((len+1)*sizeof(char16_t));
- if (buf) {
- char16_t* str = (char16_t*)buf->data();
- str[len] = 0;
- mString = str;
- return NO_ERROR;
- }
- return NO_MEMORY;
-}
-
-TextOutput& operator<<(TextOutput& to, const String16& val)
-{
- to << String8(val).string();
- return to;
-}
-
-}; // namespace android
diff --git a/libs/utils/String8.cpp b/libs/utils/String8.cpp
deleted file mode 100644
index c50d343..0000000
--- a/libs/utils/String8.cpp
+++ /dev/null
@@ -1,604 +0,0 @@
-/*
- * 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.
- */
-
-#include <utils/String8.h>
-
-#include <utils/Log.h>
-#include <utils/String16.h>
-#include <utils/TextOutput.h>
-#include <utils/threads.h>
-
-#include <private/utils/Static.h>
-
-#include <ctype.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-static const uint32_t kByteMask = 0x000000BF;
-static const uint32_t kByteMark = 0x00000080;
-
-// Surrogates aren't valid for UTF-32 characters, so define some
-// constants that will let us screen them out.
-static const uint32_t kUnicodeSurrogateHighStart = 0x0000D800;
-static const uint32_t kUnicodeSurrogateHighEnd = 0x0000DBFF;
-static const uint32_t kUnicodeSurrogateLowStart = 0x0000DC00;
-static const uint32_t kUnicodeSurrogateLowEnd = 0x0000DFFF;
-static const uint32_t kUnicodeSurrogateStart = kUnicodeSurrogateHighStart;
-static const uint32_t kUnicodeSurrogateEnd = kUnicodeSurrogateLowEnd;
-
-// Mask used to set appropriate bits in first byte of UTF-8 sequence,
-// indexed by number of bytes in the sequence.
-static const uint32_t kFirstByteMark[] = {
- 0x00000000, 0x00000000, 0x000000C0, 0x000000E0, 0x000000F0
-};
-
-// Separator used by resource paths. This is not platform dependent contrary
-// to OS_PATH_SEPARATOR.
-#define RES_PATH_SEPARATOR '/'
-
-// Return number of utf8 bytes required for the character.
-static size_t utf32_to_utf8_bytes(uint32_t srcChar)
-{
- size_t bytesToWrite;
-
- // Figure out how many bytes the result will require.
- if (srcChar < 0x00000080)
- {
- bytesToWrite = 1;
- }
- else if (srcChar < 0x00000800)
- {
- bytesToWrite = 2;
- }
- else if (srcChar < 0x00010000)
- {
- if ((srcChar < kUnicodeSurrogateStart)
- || (srcChar > kUnicodeSurrogateEnd))
- {
- bytesToWrite = 3;
- }
- else
- {
- // Surrogates are invalid UTF-32 characters.
- return 0;
- }
- }
- // Max code point for Unicode is 0x0010FFFF.
- else if (srcChar < 0x00110000)
- {
- bytesToWrite = 4;
- }
- else
- {
- // Invalid UTF-32 character.
- return 0;
- }
-
- return bytesToWrite;
-}
-
-// Write out the source character to <dstP>.
-
-static void utf32_to_utf8(uint8_t* dstP, uint32_t srcChar, size_t bytes)
-{
- dstP += bytes;
- switch (bytes)
- { /* note: everything falls through. */
- case 4: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
- case 3: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
- case 2: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
- case 1: *--dstP = (uint8_t)(srcChar | kFirstByteMark[bytes]);
- }
-}
-
-// ---------------------------------------------------------------------------
-
-static SharedBuffer* gEmptyStringBuf = NULL;
-static char* gEmptyString = NULL;
-
-extern int gDarwinCantLoadAllObjects;
-int gDarwinIsReallyAnnoying;
-
-static inline char* getEmptyString()
-{
- gEmptyStringBuf->acquire();
- return gEmptyString;
-}
-
-void initialize_string8()
-{
-#ifdef LIBUTILS_NATIVE
- // Bite me, Darwin!
- gDarwinIsReallyAnnoying = gDarwinCantLoadAllObjects;
-#endif
-
- SharedBuffer* buf = SharedBuffer::alloc(1);
- char* str = (char*)buf->data();
- *str = 0;
- gEmptyStringBuf = buf;
- gEmptyString = str;
-}
-
-void terminate_string8()
-{
- SharedBuffer::bufferFromData(gEmptyString)->release();
- gEmptyStringBuf = NULL;
- gEmptyString = NULL;
-}
-
-// ---------------------------------------------------------------------------
-
-static char* allocFromUTF8(const char* in, size_t len)
-{
- if (len > 0) {
- SharedBuffer* buf = SharedBuffer::alloc(len+1);
- LOG_ASSERT(buf, "Unable to allocate shared buffer");
- if (buf) {
- char* str = (char*)buf->data();
- memcpy(str, in, len);
- str[len] = 0;
- return str;
- }
- return NULL;
- }
-
- return getEmptyString();
-}
-
-// Note: not dealing with expanding surrogate pairs.
-static char* allocFromUTF16(const char16_t* in, size_t len)
-{
- if (len == 0) return getEmptyString();
-
- size_t bytes = 0;
- const char16_t* end = in+len;
- const char16_t* p = in;
-
- while (p < end) {
- bytes += utf32_to_utf8_bytes(*p);
- p++;
- }
-
- SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
- LOG_ASSERT(buf, "Unable to allocate shared buffer");
- if (buf) {
- p = in;
- char* str = (char*)buf->data();
- char* d = str;
- while (p < end) {
- uint32_t c = *p++;
- size_t len = utf32_to_utf8_bytes(c);
- utf32_to_utf8((uint8_t*)d, c, len);
- d += len;
- }
- *d = 0;
-
- return str;
- }
-
- return getEmptyString();
-}
-
-// ---------------------------------------------------------------------------
-
-String8::String8()
- : mString(getEmptyString())
-{
-}
-
-String8::String8(const String8& o)
- : mString(o.mString)
-{
- SharedBuffer::bufferFromData(mString)->acquire();
-}
-
-String8::String8(const char* o)
- : mString(allocFromUTF8(o, strlen(o)))
-{
- if (mString == NULL) {
- mString = getEmptyString();
- }
-}
-
-String8::String8(const char* o, size_t len)
- : mString(allocFromUTF8(o, len))
-{
- if (mString == NULL) {
- mString = getEmptyString();
- }
-}
-
-String8::String8(const String16& o)
- : mString(allocFromUTF16(o.string(), o.size()))
-{
-}
-
-String8::String8(const char16_t* o)
- : mString(allocFromUTF16(o, strlen16(o)))
-{
-}
-
-String8::String8(const char16_t* o, size_t len)
- : mString(allocFromUTF16(o, len))
-{
-}
-
-String8::~String8()
-{
- SharedBuffer::bufferFromData(mString)->release();
-}
-
-void String8::setTo(const String8& other)
-{
- SharedBuffer::bufferFromData(other.mString)->acquire();
- SharedBuffer::bufferFromData(mString)->release();
- mString = other.mString;
-}
-
-status_t String8::setTo(const char* other)
-{
- SharedBuffer::bufferFromData(mString)->release();
- mString = allocFromUTF8(other, strlen(other));
- if (mString) return NO_ERROR;
-
- mString = getEmptyString();
- return NO_MEMORY;
-}
-
-status_t String8::setTo(const char* other, size_t len)
-{
- SharedBuffer::bufferFromData(mString)->release();
- mString = allocFromUTF8(other, len);
- if (mString) return NO_ERROR;
-
- mString = getEmptyString();
- return NO_MEMORY;
-}
-
-status_t String8::setTo(const char16_t* other, size_t len)
-{
- SharedBuffer::bufferFromData(mString)->release();
- mString = allocFromUTF16(other, len);
- if (mString) return NO_ERROR;
-
- mString = getEmptyString();
- return NO_MEMORY;
-}
-
-status_t String8::append(const String8& other)
-{
- const size_t otherLen = other.bytes();
- if (bytes() == 0) {
- setTo(other);
- return NO_ERROR;
- } else if (otherLen == 0) {
- return NO_ERROR;
- }
-
- return real_append(other.string(), otherLen);
-}
-
-status_t String8::append(const char* other)
-{
- return append(other, strlen(other));
-}
-
-status_t String8::append(const char* other, size_t otherLen)
-{
- if (bytes() == 0) {
- return setTo(other, otherLen);
- } else if (otherLen == 0) {
- return NO_ERROR;
- }
-
- return real_append(other, otherLen);
-}
-
-status_t String8::real_append(const char* other, size_t otherLen)
-{
- const size_t myLen = bytes();
-
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
- ->editResize(myLen+otherLen+1);
- if (buf) {
- char* str = (char*)buf->data();
- mString = str;
- str += myLen;
- memcpy(str, other, otherLen);
- str[otherLen] = '\0';
- return NO_ERROR;
- }
- return NO_MEMORY;
-}
-
-char* String8::lockBuffer(size_t size)
-{
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
- ->editResize(size+1);
- if (buf) {
- char* str = (char*)buf->data();
- mString = str;
- return str;
- }
- return NULL;
-}
-
-void String8::unlockBuffer()
-{
- unlockBuffer(strlen(mString));
-}
-
-status_t String8::unlockBuffer(size_t size)
-{
- if (size != this->size()) {
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
- ->editResize(size+1);
- if (buf) {
- char* str = (char*)buf->data();
- str[size] = 0;
- mString = str;
- return NO_ERROR;
- }
- }
-
- return NO_MEMORY;
-}
-
-ssize_t String8::find(const char* other, size_t start) const
-{
- size_t len = size();
- if (start >= len) {
- return -1;
- }
- const char* s = mString+start;
- const char* p = strstr(s, other);
- return p ? p-mString : -1;
-}
-
-void String8::toLower()
-{
- toLower(0, size());
-}
-
-void String8::toLower(size_t start, size_t length)
-{
- const size_t len = size();
- if (start >= len) {
- return;
- }
- if (start+length > len) {
- length = len-start;
- }
- char* buf = lockBuffer(len);
- buf += start;
- while (length > 0) {
- *buf = tolower(*buf);
- buf++;
- length--;
- }
- unlockBuffer(len);
-}
-
-void String8::toUpper()
-{
- toUpper(0, size());
-}
-
-void String8::toUpper(size_t start, size_t length)
-{
- const size_t len = size();
- if (start >= len) {
- return;
- }
- if (start+length > len) {
- length = len-start;
- }
- char* buf = lockBuffer(len);
- buf += start;
- while (length > 0) {
- *buf = toupper(*buf);
- buf++;
- length--;
- }
- unlockBuffer(len);
-}
-
-TextOutput& operator<<(TextOutput& to, const String8& val)
-{
- to << val.string();
- return to;
-}
-
-// ---------------------------------------------------------------------------
-// Path functions
-
-
-void String8::setPathName(const char* name)
-{
- setPathName(name, strlen(name));
-}
-
-void String8::setPathName(const char* name, size_t len)
-{
- char* buf = lockBuffer(len);
-
- memcpy(buf, name, len);
-
- // remove trailing path separator, if present
- if (len > 0 && buf[len-1] == OS_PATH_SEPARATOR)
- len--;
-
- buf[len] = '\0';
-
- unlockBuffer(len);
-}
-
-String8 String8::getPathLeaf(void) const
-{
- const char* cp;
- const char*const buf = mString;
-
- cp = strrchr(buf, OS_PATH_SEPARATOR);
- if (cp == NULL)
- return String8(*this);
- else
- return String8(cp+1);
-}
-
-String8 String8::getPathDir(void) const
-{
- const char* cp;
- const char*const str = mString;
-
- cp = strrchr(str, OS_PATH_SEPARATOR);
- if (cp == NULL)
- return String8("");
- else
- return String8(str, cp - str);
-}
-
-String8 String8::walkPath(String8* outRemains) const
-{
- const char* cp;
- const char*const str = mString;
- const char* buf = str;
-
- cp = strchr(buf, OS_PATH_SEPARATOR);
- if (cp == buf) {
- // don't include a leading '/'.
- buf = buf+1;
- cp = strchr(buf, OS_PATH_SEPARATOR);
- }
-
- if (cp == NULL) {
- String8 res = buf != str ? String8(buf) : *this;
- if (outRemains) *outRemains = String8("");
- return res;
- }
-
- String8 res(buf, cp-buf);
- if (outRemains) *outRemains = String8(cp+1);
- return res;
-}
-
-/*
- * Helper function for finding the start of an extension in a pathname.
- *
- * Returns a pointer inside mString, or NULL if no extension was found.
- */
-char* String8::find_extension(void) const
-{
- const char* lastSlash;
- const char* lastDot;
- int extLen;
- const char* const str = mString;
-
- // only look at the filename
- lastSlash = strrchr(str, OS_PATH_SEPARATOR);
- if (lastSlash == NULL)
- lastSlash = str;
- else
- lastSlash++;
-
- // find the last dot
- lastDot = strrchr(lastSlash, '.');
- if (lastDot == NULL)
- return NULL;
-
- // looks good, ship it
- return const_cast<char*>(lastDot);
-}
-
-String8 String8::getPathExtension(void) const
-{
- char* ext;
-
- ext = find_extension();
- if (ext != NULL)
- return String8(ext);
- else
- return String8("");
-}
-
-String8 String8::getBasePath(void) const
-{
- char* ext;
- const char* const str = mString;
-
- ext = find_extension();
- if (ext == NULL)
- return String8(*this);
- else
- return String8(str, ext - str);
-}
-
-String8& String8::appendPath(const char* name)
-{
- // TODO: The test below will fail for Win32 paths. Fix later or ignore.
- if (name[0] != OS_PATH_SEPARATOR) {
- if (*name == '\0') {
- // nothing to do
- return *this;
- }
-
- size_t len = length();
- if (len == 0) {
- // no existing filename, just use the new one
- setPathName(name);
- return *this;
- }
-
- // make room for oldPath + '/' + newPath
- int newlen = strlen(name);
-
- char* buf = lockBuffer(len+1+newlen);
-
- // insert a '/' if needed
- if (buf[len-1] != OS_PATH_SEPARATOR)
- buf[len++] = OS_PATH_SEPARATOR;
-
- memcpy(buf+len, name, newlen+1);
- len += newlen;
-
- unlockBuffer(len);
-
- return *this;
- } else {
- setPathName(name);
- return *this;
- }
-}
-
-String8& String8::convertToResPath()
-{
-#if OS_PATH_SEPARATOR != RES_PATH_SEPARATOR
- size_t len = length();
- if (len > 0) {
- char * buf = lockBuffer(len);
- for (char * end = buf + len; buf < end; ++buf) {
- if (*buf == OS_PATH_SEPARATOR)
- *buf = RES_PATH_SEPARATOR;
- }
- unlockBuffer(len);
- }
-#endif
- return *this;
-}
-
-
-}; // namespace android
diff --git a/libs/utils/SystemClock.cpp b/libs/utils/SystemClock.cpp
deleted file mode 100644
index 2bdc0ce..0000000
--- a/libs/utils/SystemClock.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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.
- */
-
-
-/*
- * System clock functions.
- */
-
-#if HAVE_ANDROID_OS
-#include <linux/ioctl.h>
-#include <linux/rtc.h>
-#include <utils/Atomic.h>
-#include <linux/android_alarm.h>
-#endif
-
-#include <sys/time.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-
-#include <utils/SystemClock.h>
-#include <utils/Timers.h>
-
-#define LOG_TAG "SystemClock"
-#include "utils/Log.h"
-
-namespace android {
-
-/*
- * Set the current time. This only works when running as root.
- */
-int setCurrentTimeMillis(int64_t millis)
-{
-#if WIN32
- // not implemented
- return -1;
-#else
- struct timeval tv;
-#if HAVE_ANDROID_OS
- struct timespec ts;
- int fd;
- int res;
-#endif
- int ret = 0;
-
- if (millis <= 0 || millis / 1000LL >= INT_MAX) {
- return -1;
- }
-
- tv.tv_sec = (time_t) (millis / 1000LL);
- tv.tv_usec = (suseconds_t) ((millis % 1000LL) * 1000LL);
-
- LOGD("Setting time of day to sec=%d\n", (int) tv.tv_sec);
-
-#if HAVE_ANDROID_OS
- fd = open("/dev/alarm", O_RDWR);
- if(fd < 0) {
- LOGW("Unable to open alarm driver: %s\n", strerror(errno));
- return -1;
- }
- ts.tv_sec = tv.tv_sec;
- ts.tv_nsec = tv.tv_usec * 1000;
- res = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
- if(res < 0) {
- LOGW("Unable to set rtc to %ld: %s\n", tv.tv_sec, strerror(errno));
- ret = -1;
- }
- close(fd);
-#else
- if (settimeofday(&tv, NULL) != 0) {
- LOGW("Unable to set clock to %d.%d: %s\n",
- (int) tv.tv_sec, (int) tv.tv_usec, strerror(errno));
- ret = -1;
- }
-#endif
-
- return ret;
-#endif // WIN32
-}
-
-/*
- * native public static long uptimeMillis();
- */
-int64_t uptimeMillis()
-{
- int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- return (int64_t) nanoseconds_to_milliseconds(when);
-}
-
-/*
- * native public static long elapsedRealtime();
- */
-int64_t elapsedRealtime()
-{
-#if HAVE_ANDROID_OS
- static int s_fd = -1;
-
- if (s_fd == -1) {
- int fd = open("/dev/alarm", O_RDONLY);
- if (android_atomic_cmpxchg(-1, fd, &s_fd)) {
- close(fd);
- }
- }
-
- struct timespec ts;
- int result = ioctl(s_fd,
- ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts);
-
- if (result == 0) {
- int64_t when = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
- return (int64_t) nanoseconds_to_milliseconds(when);
- } else {
- // XXX: there was an error, probably because the driver didn't
- // exist ... this should return
- // a real error, like an exception!
- int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- return (int64_t) nanoseconds_to_milliseconds(when);
- }
-#else
- int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- return (int64_t) nanoseconds_to_milliseconds(when);
-#endif
-}
-
-}; // namespace android
diff --git a/libs/utils/TextOutput.cpp b/libs/utils/TextOutput.cpp
deleted file mode 100644
index cebee99..0000000
--- a/libs/utils/TextOutput.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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.
- */
-
-#include <utils/TextOutput.h>
-
-#include <utils/Debug.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-TextOutput& operator<<(TextOutput& to, bool val)
-{
- if (val) to.print("true", 4);
- else to.print("false", 5);
- return to;
-}
-
-TextOutput& operator<<(TextOutput& to, int val)
-{
- char buf[16];
- sprintf(buf, "%d", val);
- to.print(buf, strlen(buf));
- return to;
-}
-
-TextOutput& operator<<(TextOutput& to, long val)
-{
- char buf[16];
- sprintf(buf, "%ld", val);
- to.print(buf, strlen(buf));
- return to;
-}
-
-TextOutput& operator<<(TextOutput& to, unsigned int val)
-{
- char buf[16];
- sprintf(buf, "%u", val);
- to.print(buf, strlen(buf));
- return to;
-}
-
-TextOutput& operator<<(TextOutput& to, unsigned long val)
-{
- char buf[16];
- sprintf(buf, "%lu", val);
- to.print(buf, strlen(buf));
- return to;
-}
-
-TextOutput& operator<<(TextOutput& to, long long val)
-{
- char buf[32];
- sprintf(buf, "%Ld", val);
- to.print(buf, strlen(buf));
- return to;
-}
-
-TextOutput& operator<<(TextOutput& to, unsigned long long val)
-{
- char buf[32];
- sprintf(buf, "%Lu", val);
- to.print(buf, strlen(buf));
- return to;
-}
-
-static TextOutput& print_float(TextOutput& to, double value)
-{
- char buf[64];
- sprintf(buf, "%g", value);
- if( !strchr(buf, '.') && !strchr(buf, 'e') &&
- !strchr(buf, 'E') ) {
- strncat(buf, ".0", sizeof(buf)-1);
- }
- to.print(buf, strlen(buf));
- return to;
-}
-
-TextOutput& operator<<(TextOutput& to, float val)
-{
- return print_float(to,val);
-}
-
-TextOutput& operator<<(TextOutput& to, double val)
-{
- return print_float(to,val);
-}
-
-TextOutput& operator<<(TextOutput& to, const void* val)
-{
- char buf[16];
- sprintf(buf, "%p", val);
- to.print(buf, strlen(buf));
- return to;
-}
-
-static void textOutputPrinter(void* cookie, const char* txt)
-{
- ((TextOutput*)cookie)->print(txt, strlen(txt));
-}
-
-TextOutput& operator<<(TextOutput& to, const TypeCode& val)
-{
- printTypeCode(val.typeCode(), textOutputPrinter, (void*)&to);
- return to;
-}
-
-HexDump::HexDump(const void *buf, size_t size, size_t bytesPerLine)
- : mBuffer(buf)
- , mSize(size)
- , mBytesPerLine(bytesPerLine)
- , mSingleLineCutoff(16)
- , mAlignment(4)
- , mCArrayStyle(false)
-{
- if (bytesPerLine >= 16) mAlignment = 4;
- else if (bytesPerLine >= 8) mAlignment = 2;
- else mAlignment = 1;
-}
-
-TextOutput& operator<<(TextOutput& to, const HexDump& val)
-{
- printHexData(0, val.buffer(), val.size(), val.bytesPerLine(),
- val.singleLineCutoff(), val.alignment(), val.carrayStyle(),
- textOutputPrinter, (void*)&to);
- return to;
-}
-
-}; // namespace android
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
deleted file mode 100644
index 74271ba..0000000
--- a/libs/utils/Threads.cpp
+++ /dev/null
@@ -1,1126 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "libutils.threads"
-
-#include <utils/threads.h>
-#include <utils/Log.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <memory.h>
-#include <errno.h>
-#include <assert.h>
-#include <unistd.h>
-
-#if defined(HAVE_PTHREADS)
-# include <pthread.h>
-# include <sched.h>
-# include <sys/resource.h>
-#elif defined(HAVE_WIN32_THREADS)
-# include <windows.h>
-# include <stdint.h>
-# include <process.h>
-# define HAVE_CREATETHREAD // Cygwin, vs. HAVE__BEGINTHREADEX for MinGW
-#endif
-
-#if defined(HAVE_FUTEX)
-#include <private/utils/futex_synchro.h>
-#endif
-
-#if defined(HAVE_PRCTL)
-#include <sys/prctl.h>
-#endif
-
-/*
- * ===========================================================================
- * Thread wrappers
- * ===========================================================================
- */
-
-using namespace android;
-
-// ----------------------------------------------------------------------------
-#if defined(HAVE_PTHREADS)
-#if 0
-#pragma mark -
-#pragma mark PTHREAD
-#endif
-// ----------------------------------------------------------------------------
-
-/*
- * Create and run a new thead.
- *
- * We create it "detached", so it cleans up after itself.
- */
-
-typedef void* (*android_pthread_entry)(void*);
-
-struct thread_data_t {
- thread_func_t entryFunction;
- void* userData;
- int priority;
- char * threadName;
-
- // we use this trampoline when we need to set the priority with
- // nice/setpriority.
- static int trampoline(const thread_data_t* t) {
- thread_func_t f = t->entryFunction;
- void* u = t->userData;
- int prio = t->priority;
- char * name = t->threadName;
- delete t;
- setpriority(PRIO_PROCESS, 0, prio);
- if (name) {
-#if defined(HAVE_PRCTL)
- // Mac OS doesn't have this, and we build libutil for the host too
- int hasAt = 0;
- int hasDot = 0;
- char *s = name;
- while (*s) {
- if (*s == '.') hasDot = 1;
- else if (*s == '@') hasAt = 1;
- s++;
- }
- int len = s - name;
- if (len < 15 || hasAt || !hasDot) {
- s = name;
- } else {
- s = name + len - 15;
- }
- prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
-#endif
- free(name);
- }
- return f(u);
- }
-};
-
-int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
- void *userData,
- const char* threadName,
- int32_t threadPriority,
- size_t threadStackSize,
- android_thread_id_t *threadId)
-{
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
-#ifdef HAVE_ANDROID_OS /* valgrind is rejecting RT-priority create reqs */
- if (threadPriority != PRIORITY_DEFAULT || threadName != NULL) {
- // We could avoid the trampoline if there was a way to get to the
- // android_thread_id_t (pid) from pthread_t
- thread_data_t* t = new thread_data_t;
- t->priority = threadPriority;
- t->threadName = threadName ? strdup(threadName) : NULL;
- t->entryFunction = entryFunction;
- t->userData = userData;
- entryFunction = (android_thread_func_t)&thread_data_t::trampoline;
- userData = t;
- }
-#endif
-
- if (threadStackSize) {
- pthread_attr_setstacksize(&attr, threadStackSize);
- }
-
- errno = 0;
- pthread_t thread;
- int result = pthread_create(&thread, &attr,
- (android_pthread_entry)entryFunction, userData);
- if (result != 0) {
- LOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, errno=%d)\n"
- "(android threadPriority=%d)",
- entryFunction, result, errno, threadPriority);
- return 0;
- }
-
- if (threadId != NULL) {
- *threadId = (android_thread_id_t)thread; // XXX: this is not portable
- }
- return 1;
-}
-
-android_thread_id_t androidGetThreadId()
-{
- return (android_thread_id_t)pthread_self();
-}
-
-// ----------------------------------------------------------------------------
-#elif defined(HAVE_WIN32_THREADS)
-#if 0
-#pragma mark -
-#pragma mark WIN32_THREADS
-#endif
-// ----------------------------------------------------------------------------
-
-/*
- * Trampoline to make us __stdcall-compliant.
- *
- * We're expected to delete "vDetails" when we're done.
- */
-struct threadDetails {
- int (*func)(void*);
- void* arg;
-};
-static __stdcall unsigned int threadIntermediary(void* vDetails)
-{
- struct threadDetails* pDetails = (struct threadDetails*) vDetails;
- int result;
-
- result = (*(pDetails->func))(pDetails->arg);
-
- delete pDetails;
-
- LOG(LOG_VERBOSE, "thread", "thread exiting\n");
- return (unsigned int) result;
-}
-
-/*
- * Create and run a new thread.
- */
-static bool doCreateThread(android_thread_func_t fn, void* arg, android_thread_id_t *id)
-{
- HANDLE hThread;
- struct threadDetails* pDetails = new threadDetails; // must be on heap
- unsigned int thrdaddr;
-
- pDetails->func = fn;
- pDetails->arg = arg;
-
-#if defined(HAVE__BEGINTHREADEX)
- hThread = (HANDLE) _beginthreadex(NULL, 0, threadIntermediary, pDetails, 0,
- &thrdaddr);
- if (hThread == 0)
-#elif defined(HAVE_CREATETHREAD)
- hThread = CreateThread(NULL, 0,
- (LPTHREAD_START_ROUTINE) threadIntermediary,
- (void*) pDetails, 0, (DWORD*) &thrdaddr);
- if (hThread == NULL)
-#endif
- {
- LOG(LOG_WARN, "thread", "WARNING: thread create failed\n");
- return false;
- }
-
-#if defined(HAVE_CREATETHREAD)
- /* close the management handle */
- CloseHandle(hThread);
-#endif
-
- if (id != NULL) {
- *id = (android_thread_id_t)thrdaddr;
- }
-
- return true;
-}
-
-int androidCreateRawThreadEtc(android_thread_func_t fn,
- void *userData,
- const char* threadName,
- int32_t threadPriority,
- size_t threadStackSize,
- android_thread_id_t *threadId)
-{
- return doCreateThread( fn, userData, threadId);
-}
-
-android_thread_id_t androidGetThreadId()
-{
- return (android_thread_id_t)GetCurrentThreadId();
-}
-
-// ----------------------------------------------------------------------------
-#else
-#error "Threads not supported"
-#endif
-
-// ----------------------------------------------------------------------------
-
-#if 0
-#pragma mark -
-#pragma mark Common Thread functions
-#endif
-
-int androidCreateThread(android_thread_func_t fn, void* arg)
-{
- return createThreadEtc(fn, arg);
-}
-
-int androidCreateThreadGetID(android_thread_func_t fn, void *arg, android_thread_id_t *id)
-{
- return createThreadEtc(fn, arg, "android:unnamed_thread",
- PRIORITY_DEFAULT, 0, id);
-}
-
-static android_create_thread_fn gCreateThreadFn = androidCreateRawThreadEtc;
-
-int androidCreateThreadEtc(android_thread_func_t entryFunction,
- void *userData,
- const char* threadName,
- int32_t threadPriority,
- size_t threadStackSize,
- android_thread_id_t *threadId)
-{
- return gCreateThreadFn(entryFunction, userData, threadName,
- threadPriority, threadStackSize, threadId);
-}
-
-void androidSetCreateThreadFunc(android_create_thread_fn func)
-{
- gCreateThreadFn = func;
-}
-
-namespace android {
-
-/*
- * ===========================================================================
- * Mutex class
- * ===========================================================================
- */
-
-#if 0
-#pragma mark -
-#pragma mark Mutex
-#endif
-
-#if defined(HAVE_PTHREADS) && !defined(HAVE_FUTEX)
-/*
- * Simple pthread wrapper.
- */
-
-Mutex::Mutex()
-{
- _init();
-}
-
-Mutex::Mutex(const char* name)
-{
- // XXX: name not used for now
- _init();
-}
-
-void Mutex::_init()
-{
- pthread_mutex_t* pMutex = new pthread_mutex_t;
- pthread_mutex_init(pMutex, NULL);
- mState = pMutex;
-}
-
-Mutex::~Mutex()
-{
- delete (pthread_mutex_t*) mState;
-}
-
-status_t Mutex::lock()
-{
- int res;
- while ((res=pthread_mutex_lock((pthread_mutex_t*) mState)) == EINTR) ;
- return -res;
-}
-
-void Mutex::unlock()
-{
- pthread_mutex_unlock((pthread_mutex_t*) mState);
-}
-
-status_t Mutex::tryLock()
-{
- int res;
- while ((res=pthread_mutex_trylock((pthread_mutex_t*) mState)) == EINTR) ;
- return -res;
-}
-
-#elif defined(HAVE_FUTEX)
-#if 0
-#pragma mark -
-#endif
-
-#define STATE ((futex_mutex_t*) (&mState))
-
-Mutex::Mutex()
-{
- _init();
-}
-
-Mutex::Mutex(const char* name)
-{
- _init();
-}
-
-void
-Mutex::_init()
-{
- futex_mutex_init(STATE);
-}
-
-Mutex::~Mutex()
-{
-}
-
-status_t Mutex::lock()
-{
- int res;
- while ((res=futex_mutex_lock(STATE, FUTEX_WAIT_INFINITE)) == EINTR) ;
- return -res;
-}
-
-void Mutex::unlock()
-{
- futex_mutex_unlock(STATE);
-}
-
-status_t Mutex::tryLock()
-{
- int res;
- while ((res=futex_mutex_trylock(STATE)) == EINTR) ;
- return -res;
-}
-#undef STATE
-
-#elif defined(HAVE_WIN32_THREADS)
-#if 0
-#pragma mark -
-#endif
-
-Mutex::Mutex()
-{
- HANDLE hMutex;
-
- assert(sizeof(hMutex) == sizeof(mState));
-
- hMutex = CreateMutex(NULL, FALSE, NULL);
- mState = (void*) hMutex;
-}
-
-Mutex::Mutex(const char* name)
-{
- // XXX: name not used for now
- HANDLE hMutex;
-
- hMutex = CreateMutex(NULL, FALSE, NULL);
- mState = (void*) hMutex;
-}
-
-Mutex::~Mutex()
-{
- CloseHandle((HANDLE) mState);
-}
-
-status_t Mutex::lock()
-{
- DWORD dwWaitResult;
- dwWaitResult = WaitForSingleObject((HANDLE) mState, INFINITE);
- return dwWaitResult != WAIT_OBJECT_0 ? -1 : NO_ERROR;
-}
-
-void Mutex::unlock()
-{
- if (!ReleaseMutex((HANDLE) mState))
- LOG(LOG_WARN, "thread", "WARNING: bad result from unlocking mutex\n");
-}
-
-status_t Mutex::tryLock()
-{
- DWORD dwWaitResult;
-
- dwWaitResult = WaitForSingleObject((HANDLE) mState, 0);
- if (dwWaitResult != WAIT_OBJECT_0 && dwWaitResult != WAIT_TIMEOUT)
- LOG(LOG_WARN, "thread", "WARNING: bad result from try-locking mutex\n");
- return (dwWaitResult == WAIT_OBJECT_0) ? 0 : -1;
-}
-
-#else
-#error "Somebody forgot to implement threads for this platform."
-#endif
-
-
-/*
- * ===========================================================================
- * Condition class
- * ===========================================================================
- */
-
-#if 0
-#pragma mark -
-#pragma mark Condition
-#endif
-
-#if defined(HAVE_PTHREADS) && !defined(HAVE_FUTEX)
-
-/*
- * Constructor. This is a simple pthread wrapper.
- */
-Condition::Condition()
-{
- pthread_cond_t* pCond = new pthread_cond_t;
-
- pthread_cond_init(pCond, NULL);
- mState = pCond;
-}
-
-/*
- * Destructor.
- */
-Condition::~Condition()
-{
- pthread_cond_destroy((pthread_cond_t*) mState);
- delete (pthread_cond_t*) mState;
-}
-
-/*
- * Wait on a condition variable. Lock the mutex before calling.
- */
-
-status_t Condition::wait(Mutex& mutex)
-{
- assert(mutex.mState != NULL);
-
- int cc;
- while ((cc = pthread_cond_wait((pthread_cond_t*)mState,
- (pthread_mutex_t*) mutex.mState)) == EINTR) ;
- return -cc;
-}
-
-status_t Condition::wait(Mutex& mutex, nsecs_t abstime)
-{
- assert(mutex.mState != NULL);
-
- struct timespec ts;
- ts.tv_sec = abstime/1000000000;
- ts.tv_nsec = abstime-(ts.tv_sec*1000000000);
-
- int cc;
- while ((cc = pthread_cond_timedwait((pthread_cond_t*)mState,
- (pthread_mutex_t*) mutex.mState, &ts)) == EINTR) ;
- return -cc;
-}
-
-status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime)
-{
- return wait(mutex, systemTime()+reltime);
-}
-
-/*
- * Signal the condition variable, allowing one thread to continue.
- */
-void Condition::signal()
-{
- pthread_cond_signal((pthread_cond_t*) mState);
-}
-
-/*
- * Signal the condition variable, allowing all threads to continue.
- */
-void Condition::broadcast()
-{
- pthread_cond_broadcast((pthread_cond_t*) mState);
-}
-
-#elif defined(HAVE_FUTEX)
-#if 0
-#pragma mark -
-#endif
-
-#define STATE ((futex_cond_t*) (&mState))
-
-/*
- * Constructor. This is a simple pthread wrapper.
- */
-Condition::Condition()
-{
- futex_cond_init(STATE);
-}
-
-/*
- * Destructor.
- */
-Condition::~Condition()
-{
-}
-
-/*
- * Wait on a condition variable. Lock the mutex before calling.
- */
-
-status_t Condition::wait(Mutex& mutex)
-{
- assert(mutex.mState != NULL);
-
- int res;
- while ((res = futex_cond_wait(STATE,
- (futex_mutex_t*)(&mutex.mState), FUTEX_WAIT_INFINITE)) == -EINTR) ;
-
- return -res;
-}
-
-status_t Condition::wait(Mutex& mutex, nsecs_t abstime)
-{
- nsecs_t reltime = abstime - systemTime();
- if (reltime <= 0) return true;
- return waitRelative(mutex, reltime);
-}
-
-status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime)
-{
- assert(mutex.mState != NULL);
- int res;
- unsigned msec = ns2ms(reltime);
- if(msec == 0)
- return true;
- // This code will not time out at the correct time if interrupted by signals
- while ((res = futex_cond_wait(STATE,
- (futex_mutex_t*)(&mutex.mState), msec)) == -EINTR) ;
- return res;
-}
-
-/*
- * Signal the condition variable, allowing one thread to continue.
- */
-void Condition::signal()
-{
- futex_cond_signal(STATE);
-}
-
-/*
- * Signal the condition variable, allowing all threads to continue.
- */
-void Condition::broadcast()
-{
- futex_cond_broadcast(STATE);
-}
-
-#undef STATE
-
-#elif defined(HAVE_WIN32_THREADS)
-#if 0
-#pragma mark -
-#endif
-
-/*
- * Windows doesn't have a condition variable solution. It's possible
- * to create one, but it's easy to get it wrong. For a discussion, and
- * the origin of this implementation, see:
- *
- * http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
- *
- * The implementation shown on the page does NOT follow POSIX semantics.
- * As an optimization they require acquiring the external mutex before
- * calling signal() and broadcast(), whereas POSIX only requires grabbing
- * it before calling wait(). The implementation here has been un-optimized
- * to have the correct behavior.
- */
-typedef struct WinCondition {
- // Number of waiting threads.
- int waitersCount;
-
- // Serialize access to waitersCount.
- CRITICAL_SECTION waitersCountLock;
-
- // Semaphore used to queue up threads waiting for the condition to
- // become signaled.
- HANDLE sema;
-
- // An auto-reset event used by the broadcast/signal thread to wait
- // for all the waiting thread(s) to wake up and be released from
- // the semaphore.
- HANDLE waitersDone;
-
- // This mutex wouldn't be necessary if we required that the caller
- // lock the external mutex before calling signal() and broadcast().
- // I'm trying to mimic pthread semantics though.
- HANDLE internalMutex;
-
- // Keeps track of whether we were broadcasting or signaling. This
- // allows us to optimize the code if we're just signaling.
- bool wasBroadcast;
-
- status_t wait(WinCondition* condState, HANDLE hMutex, nsecs_t* abstime)
- {
- // Increment the wait count, avoiding race conditions.
- EnterCriticalSection(&condState->waitersCountLock);
- condState->waitersCount++;
- //printf("+++ wait: incr waitersCount to %d (tid=%ld)\n",
- // condState->waitersCount, getThreadId());
- LeaveCriticalSection(&condState->waitersCountLock);
-
- DWORD timeout = INFINITE;
- if (abstime) {
- nsecs_t reltime = *abstime - systemTime();
- if (reltime < 0)
- reltime = 0;
- timeout = reltime/1000000;
- }
-
- // Atomically release the external mutex and wait on the semaphore.
- DWORD res =
- SignalObjectAndWait(hMutex, condState->sema, timeout, FALSE);
-
- //printf("+++ wait: awake (tid=%ld)\n", getThreadId());
-
- // Reacquire lock to avoid race conditions.
- EnterCriticalSection(&condState->waitersCountLock);
-
- // No longer waiting.
- condState->waitersCount--;
-
- // Check to see if we're the last waiter after a broadcast.
- bool lastWaiter = (condState->wasBroadcast && condState->waitersCount == 0);
-
- //printf("+++ wait: lastWaiter=%d (wasBc=%d wc=%d)\n",
- // lastWaiter, condState->wasBroadcast, condState->waitersCount);
-
- LeaveCriticalSection(&condState->waitersCountLock);
-
- // If we're the last waiter thread during this particular broadcast
- // then signal broadcast() that we're all awake. It'll drop the
- // internal mutex.
- if (lastWaiter) {
- // Atomically signal the "waitersDone" event and wait until we
- // can acquire the internal mutex. We want to do this in one step
- // because it ensures that everybody is in the mutex FIFO before
- // any thread has a chance to run. Without it, another thread
- // could wake up, do work, and hop back in ahead of us.
- SignalObjectAndWait(condState->waitersDone, condState->internalMutex,
- INFINITE, FALSE);
- } else {
- // Grab the internal mutex.
- WaitForSingleObject(condState->internalMutex, INFINITE);
- }
-
- // Release the internal and grab the external.
- ReleaseMutex(condState->internalMutex);
- WaitForSingleObject(hMutex, INFINITE);
-
- return res == WAIT_OBJECT_0 ? NO_ERROR : -1;
- }
-} WinCondition;
-
-/*
- * Constructor. Set up the WinCondition stuff.
- */
-Condition::Condition()
-{
- WinCondition* condState = new WinCondition;
-
- condState->waitersCount = 0;
- condState->wasBroadcast = false;
- // semaphore: no security, initial value of 0
- condState->sema = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
- InitializeCriticalSection(&condState->waitersCountLock);
- // auto-reset event, not signaled initially
- condState->waitersDone = CreateEvent(NULL, FALSE, FALSE, NULL);
- // used so we don't have to lock external mutex on signal/broadcast
- condState->internalMutex = CreateMutex(NULL, FALSE, NULL);
-
- mState = condState;
-}
-
-/*
- * Destructor. Free Windows resources as well as our allocated storage.
- */
-Condition::~Condition()
-{
- WinCondition* condState = (WinCondition*) mState;
- if (condState != NULL) {
- CloseHandle(condState->sema);
- CloseHandle(condState->waitersDone);
- delete condState;
- }
-}
-
-
-status_t Condition::wait(Mutex& mutex)
-{
- WinCondition* condState = (WinCondition*) mState;
- HANDLE hMutex = (HANDLE) mutex.mState;
-
- return ((WinCondition*)mState)->wait(condState, hMutex, NULL);
-}
-
-status_t Condition::wait(Mutex& mutex, nsecs_t abstime)
-{
- WinCondition* condState = (WinCondition*) mState;
- HANDLE hMutex = (HANDLE) mutex.mState;
-
- return ((WinCondition*)mState)->wait(condState, hMutex, &abstime);
-}
-
-status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime)
-{
- return wait(mutex, systemTime()+reltime);
-}
-
-/*
- * Signal the condition variable, allowing one thread to continue.
- */
-void Condition::signal()
-{
- WinCondition* condState = (WinCondition*) mState;
-
- // Lock the internal mutex. This ensures that we don't clash with
- // broadcast().
- WaitForSingleObject(condState->internalMutex, INFINITE);
-
- EnterCriticalSection(&condState->waitersCountLock);
- bool haveWaiters = (condState->waitersCount > 0);
- LeaveCriticalSection(&condState->waitersCountLock);
-
- // If no waiters, then this is a no-op. Otherwise, knock the semaphore
- // down a notch.
- if (haveWaiters)
- ReleaseSemaphore(condState->sema, 1, 0);
-
- // Release internal mutex.
- ReleaseMutex(condState->internalMutex);
-}
-
-/*
- * Signal the condition variable, allowing all threads to continue.
- *
- * First we have to wake up all threads waiting on the semaphore, then
- * we wait until all of the threads have actually been woken before
- * releasing the internal mutex. This ensures that all threads are woken.
- */
-void Condition::broadcast()
-{
- WinCondition* condState = (WinCondition*) mState;
-
- // Lock the internal mutex. This keeps the guys we're waking up
- // from getting too far.
- WaitForSingleObject(condState->internalMutex, INFINITE);
-
- EnterCriticalSection(&condState->waitersCountLock);
- bool haveWaiters = false;
-
- if (condState->waitersCount > 0) {
- haveWaiters = true;
- condState->wasBroadcast = true;
- }
-
- if (haveWaiters) {
- // Wake up all the waiters.
- ReleaseSemaphore(condState->sema, condState->waitersCount, 0);
-
- LeaveCriticalSection(&condState->waitersCountLock);
-
- // Wait for all awakened threads to acquire the counting semaphore.
- // The last guy who was waiting sets this.
- WaitForSingleObject(condState->waitersDone, INFINITE);
-
- // Reset wasBroadcast. (No crit section needed because nobody
- // else can wake up to poke at it.)
- condState->wasBroadcast = 0;
- } else {
- // nothing to do
- LeaveCriticalSection(&condState->waitersCountLock);
- }
-
- // Release internal mutex.
- ReleaseMutex(condState->internalMutex);
-}
-
-#else
-#error "condition variables not supported on this platform"
-#endif
-
-
-/*
- * ===========================================================================
- * ReadWriteLock class
- * ===========================================================================
- */
-
-#if 0
-#pragma mark -
-#pragma mark ReadWriteLock
-#endif
-
-/*
- * Add a reader. Readers are nice. They share.
- */
-void ReadWriteLock::lockForRead()
-{
- mLock.lock();
- while (mNumWriters > 0) {
- LOG(LOG_DEBUG, "thread", "+++ lockForRead: waiting\n");
- mReadWaiter.wait(mLock);
- }
- assert(mNumWriters == 0);
- mNumReaders++;
-#if defined(PRINT_RENDER_TIMES)
- if (mNumReaders == 1)
- mDebugTimer.start();
-#endif
- mLock.unlock();
-}
-
-/*
- * Try to add a reader. If it doesn't work right away, return "false".
- */
-bool ReadWriteLock::tryLockForRead()
-{
- mLock.lock();
- if (mNumWriters > 0) {
- mLock.unlock();
- return false;
- }
- assert(mNumWriters == 0);
- mNumReaders++;
-#if defined(PRINT_RENDER_TIMES)
- if (mNumReaders == 1)
- mDebugTimer.start();
-#endif
- mLock.unlock();
- return true;
-}
-
-/*
- * Remove a reader.
- */
-void ReadWriteLock::unlockForRead()
-{
- mLock.lock();
- if (mNumReaders == 0) {
- LOG(LOG_WARN, "thread",
- "WARNING: unlockForRead requested, but not locked\n");
- return;
- }
- assert(mNumReaders > 0);
- assert(mNumWriters == 0);
- mNumReaders--;
- if (mNumReaders == 0) { // last reader?
-#if defined(PRINT_RENDER_TIMES)
- mDebugTimer.stop();
- printf(" rdlk held %.3f msec\n",
- (double) mDebugTimer.durationUsecs() / 1000.0);
-#endif
- //printf("+++ signaling writers (if any)\n");
- mWriteWaiter.signal(); // wake one writer (if any)
- }
- mLock.unlock();
-}
-
-/*
- * Add a writer. This requires exclusive access to the object.
- */
-void ReadWriteLock::lockForWrite()
-{
- mLock.lock();
- while (mNumReaders > 0 || mNumWriters > 0) {
- LOG(LOG_DEBUG, "thread", "+++ lockForWrite: waiting\n");
- mWriteWaiter.wait(mLock);
- }
- assert(mNumReaders == 0);
- assert(mNumWriters == 0);
- mNumWriters++;
-#if defined(PRINT_RENDER_TIMES)
- mDebugTimer.start();
-#endif
- mLock.unlock();
-}
-
-/*
- * Try to add a writer. If it doesn't work right away, return "false".
- */
-bool ReadWriteLock::tryLockForWrite()
-{
- mLock.lock();
- if (mNumReaders > 0 || mNumWriters > 0) {
- mLock.unlock();
- return false;
- }
- assert(mNumReaders == 0);
- assert(mNumWriters == 0);
- mNumWriters++;
-#if defined(PRINT_RENDER_TIMES)
- mDebugTimer.start();
-#endif
- mLock.unlock();
- return true;
-}
-
-/*
- * Remove a writer.
- */
-void ReadWriteLock::unlockForWrite()
-{
- mLock.lock();
- if (mNumWriters == 0) {
- LOG(LOG_WARN, "thread",
- "WARNING: unlockForWrite requested, but not locked\n");
- return;
- }
- assert(mNumWriters == 1);
- mNumWriters--;
-#if defined(PRINT_RENDER_TIMES)
- mDebugTimer.stop();
- //printf(" wrlk held %.3f msec\n",
- // (double) mDebugTimer.durationUsecs() / 1000.0);
-#endif
- // mWriteWaiter.signal(); // should other writers get first dibs?
- //printf("+++ signaling readers (if any)\n");
- mReadWaiter.broadcast(); // wake all readers (if any)
- mLock.unlock();
-}
-
-// ----------------------------------------------------------------------------
-
-#if 0
-#pragma mark -
-#pragma mark Thread::Thread
-#endif
-
-/*
- * This is our thread object!
- */
-
-Thread::Thread(bool canCallJava)
- : mCanCallJava(canCallJava),
- mThread(thread_id_t(-1)),
- mLock("Thread::mLock"),
- mStatus(NO_ERROR),
- mExitPending(false), mRunning(false)
-{
-}
-
-Thread::~Thread()
-{
-}
-
-status_t Thread::readyToRun()
-{
- return NO_ERROR;
-}
-
-status_t Thread::run(const char* name, int32_t priority, size_t stack)
-{
- Mutex::Autolock _l(mLock);
-
- if (mRunning) {
- // thread already started
- return INVALID_OPERATION;
- }
-
- // reset status and exitPending to their default value, so we can
- // try again after an error happened (either below, or in readyToRun())
- mStatus = NO_ERROR;
- mExitPending = false;
- mThread = thread_id_t(-1);
-
- // hold a strong reference on ourself
- mHoldSelf = this;
-
- bool res;
- if (mCanCallJava) {
- res = createThreadEtc(_threadLoop,
- this, name, priority, stack, &mThread);
- } else {
- res = androidCreateRawThreadEtc(_threadLoop,
- this, name, priority, stack, &mThread);
- }
-
- if (res == false) {
- mStatus = UNKNOWN_ERROR; // something happened!
- mRunning = false;
- mThread = thread_id_t(-1);
- }
-
- if (mStatus < 0) {
- // something happened, don't leak
- mHoldSelf.clear();
- }
-
- return mStatus;
-}
-
-int Thread::_threadLoop(void* user)
-{
- Thread* const self = static_cast<Thread*>(user);
- sp<Thread> strong(self->mHoldSelf);
- wp<Thread> weak(strong);
- self->mHoldSelf.clear();
-
- // we're about to run...
- self->mStatus = self->readyToRun();
- if (self->mStatus!=NO_ERROR || self->mExitPending) {
- // pretend the thread never started...
- self->mExitPending = false;
- self->mRunning = false;
- return 0;
- }
-
- // thread is running now
- self->mRunning = true;
-
- do {
- bool result = self->threadLoop();
- if (result == false || self->mExitPending) {
- self->mExitPending = true;
- self->mLock.lock();
- self->mRunning = false;
- self->mThreadExitedCondition.signal();
- self->mLock.unlock();
- break;
- }
-
- // Release our strong reference, to let a chance to the thread
- // to die a peaceful death.
- strong.clear();
- // And immediately, reacquire a strong reference for the next loop
- strong = weak.promote();
- } while(strong != 0);
-
- return 0;
-}
-
-void Thread::requestExit()
-{
- mExitPending = true;
-}
-
-status_t Thread::requestExitAndWait()
-{
- if (mStatus == OK) {
-
- if (mThread == getThreadId()) {
- LOGW(
- "Thread (this=%p): don't call waitForExit() from this "
- "Thread object's thread. It's a guaranteed deadlock!",
- this);
- return WOULD_BLOCK;
- }
-
- requestExit();
-
- Mutex::Autolock _l(mLock);
- while (mRunning == true) {
- mThreadExitedCondition.wait(mLock);
- }
- mExitPending = false;
- }
- return mStatus;
-}
-
-bool Thread::exitPending() const
-{
- return mExitPending;
-}
-
-
-
-}; // namespace android
diff --git a/libs/utils/TimerProbe.cpp b/libs/utils/TimerProbe.cpp
deleted file mode 100644
index 835480d..0000000
--- a/libs/utils/TimerProbe.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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.
- */
-
-#include <utils/TimerProbe.h>
-
-#if ENABLE_TIMER_PROBE
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "time"
-
-namespace android {
-
-Vector<TimerProbe::Bucket> TimerProbe::gBuckets;
-TimerProbe* TimerProbe::gExecuteChain;
-int TimerProbe::gIndent;
-timespec TimerProbe::gRealBase;
-
-TimerProbe::TimerProbe(const char tag[], int* slot) : mTag(tag)
-{
- mNext = gExecuteChain;
- gExecuteChain = this;
- mIndent = gIndent;
- gIndent += 1;
- if (mIndent > 0) {
- if (*slot == 0) {
- int count = gBuckets.add();
- *slot = count;
- Bucket& bucket = gBuckets.editItemAt(count);
- memset(&bucket, 0, sizeof(Bucket));
- bucket.mTag = tag;
- bucket.mSlotPtr = slot;
- bucket.mIndent = mIndent;
- }
- mBucket = *slot;
- }
- clock_gettime(CLOCK_REALTIME, &mRealStart);
- if (gRealBase.tv_sec == 0)
- gRealBase = mRealStart;
- clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &mPStart);
- clock_gettime(CLOCK_THREAD_CPUTIME_ID, &mTStart);
-}
-
-void TimerProbe::end()
-{
- timespec realEnd, pEnd, tEnd;
- clock_gettime(CLOCK_REALTIME, &realEnd);
- clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &pEnd);
- clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tEnd);
- print(realEnd, pEnd, tEnd);
- mTag = NULL;
-}
-
-TimerProbe::~TimerProbe()
-{
- if (mTag != NULL)
- end();
- gExecuteChain = mNext;
- gIndent--;
-}
-
-
-uint32_t TimerProbe::ElapsedTime(const timespec& start, const timespec& end)
-{
- int sec = end.tv_sec - start.tv_sec;
- int nsec = end.tv_nsec - start.tv_nsec;
- if (nsec < 0) {
- sec--;
- nsec += 1000000000;
- }
- return sec * 1000000 + nsec / 1000;
-}
-
-void TimerProbe::print(const timespec& r, const timespec& p,
- const timespec& t) const
-{
- uint32_t es = ElapsedTime(gRealBase, mRealStart);
- uint32_t er = ElapsedTime(mRealStart, r);
- uint32_t ep = ElapsedTime(mPStart, p);
- uint32_t et = ElapsedTime(mTStart, t);
- if (mIndent > 0) {
- Bucket& bucket = gBuckets.editItemAt(mBucket);
- if (bucket.mStart == 0)
- bucket.mStart = es;
- bucket.mReal += er;
- bucket.mProcess += ep;
- bucket.mThread += et;
- bucket.mCount++;
- return;
- }
- int index = 0;
- int buckets = gBuckets.size();
- int count = 1;
- const char* tag = mTag;
- int indent = mIndent;
- do {
- LOGD("%-30.30s: (%3d) %-5.*s time=%-10.3f real=%7dus process=%7dus (%3d%%) thread=%7dus (%3d%%)\n",
- tag, count, indent > 5 ? 5 : indent, "+++++", es / 1000000.0,
- er, ep, ep * 100 / er, et, et * 100 / er);
- if (index >= buckets)
- break;
- Bucket& bucket = gBuckets.editItemAt(index);
- count = bucket.mCount;
- es = bucket.mStart;
- er = bucket.mReal;
- ep = bucket.mProcess;
- et = bucket.mThread;
- tag = bucket.mTag;
- indent = bucket.mIndent;
- *bucket.mSlotPtr = 0;
- } while (++index); // always true
- gBuckets.clear();
-}
-
-}; // namespace android
-
-#endif
diff --git a/libs/utils/Timers.cpp b/libs/utils/Timers.cpp
deleted file mode 100644
index 2abc811..0000000
--- a/libs/utils/Timers.cpp
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * 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.
-//
-#include <utils/Timers.h>
-#include <utils/ported.h> // may need usleep
-#include <utils/Log.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <time.h>
-#include <errno.h>
-
-#ifdef HAVE_WIN32_THREADS
-#include <windows.h>
-#endif
-
-nsecs_t systemTime(int clock)
-{
-#if defined(HAVE_POSIX_CLOCKS)
- static const clockid_t clocks[] = {
- CLOCK_REALTIME,
- CLOCK_MONOTONIC,
- CLOCK_PROCESS_CPUTIME_ID,
- CLOCK_THREAD_CPUTIME_ID
- };
- struct timespec t;
- t.tv_sec = t.tv_nsec = 0;
- clock_gettime(clocks[clock], &t);
- return nsecs_t(t.tv_sec)*1000000000LL + t.tv_nsec;
-#else
- // we don't support the clocks here.
- struct timeval t;
- t.tv_sec = t.tv_usec = 0;
- gettimeofday(&t, NULL);
- return nsecs_t(t.tv_sec)*1000000000LL + nsecs_t(t.tv_usec)*1000LL;
-#endif
-}
-
-//#define MONITOR_USLEEP
-
-/*
- * Sleep long enough that we'll wake up "interval" milliseconds after
- * the previous snooze.
- *
- * The "nextTick" argument is updated on each call, and should be passed
- * in every time. Set its fields to zero on the first call.
- *
- * Returns the #of intervals we have overslept, which will be zero if we're
- * on time. [Currently just returns 0 or 1.]
- */
-int sleepForInterval(long interval, struct timeval* pNextTick)
-{
- struct timeval now;
- long long timeBeforeNext;
- long sleepTime = 0;
- bool overSlept = false;
- //int usleepBias = 0;
-
-#ifdef USLEEP_BIAS
- /*
- * Linux likes to add 9000ms or so.
- * [not using this for now]
- */
- //usleepBias = USLEEP_BIAS;
-#endif
-
- gettimeofday(&now, NULL);
-
- if (pNextTick->tv_sec == 0) {
- /* special-case for first time through */
- *pNextTick = now;
- sleepTime = interval;
- android::DurationTimer::addToTimeval(pNextTick, interval);
- } else {
- /*
- * Compute how much time there is before the next tick. If this
- * value is negative, we've run over. If we've run over a little
- * bit we can shorten the next frame to keep the pace steady, but
- * if we've dramatically overshot we need to re-sync.
- */
- timeBeforeNext = android::DurationTimer::subtractTimevals(pNextTick, &now);
- //printf("TOP: now=%ld.%ld next=%ld.%ld diff=%ld\n",
- // now.tv_sec, now.tv_usec, pNextTick->tv_sec, pNextTick->tv_usec,
- // (long) timeBeforeNext);
- if (timeBeforeNext < -interval) {
- /* way over */
- overSlept = true;
- sleepTime = 0;
- *pNextTick = now;
- } else if (timeBeforeNext <= 0) {
- /* slightly over, keep the pace steady */
- overSlept = true;
- sleepTime = 0;
- } else if (timeBeforeNext <= interval) {
- /* right on schedule */
- sleepTime = timeBeforeNext;
- } else if (timeBeforeNext > interval && timeBeforeNext <= 2*interval) {
- /* sleep call returned early; do a longer sleep this time */
- sleepTime = timeBeforeNext;
- } else if (timeBeforeNext > interval) {
- /* we went back in time -- somebody updated system clock? */
- /* (could also be a *seriously* broken usleep()) */
- LOG(LOG_DEBUG, "",
- " Impossible: timeBeforeNext = %ld\n", (long)timeBeforeNext);
- sleepTime = 0;
- *pNextTick = now;
- }
- android::DurationTimer::addToTimeval(pNextTick, interval);
- }
- //printf(" Before sleep: now=%ld.%ld next=%ld.%ld sleepTime=%ld\n",
- // now.tv_sec, now.tv_usec, pNextTick->tv_sec, pNextTick->tv_usec,
- // sleepTime);
-
- /*
- * Sleep for the designated period of time.
- *
- * Linux tends to sleep for longer than requested, often by 17-18ms.
- * MinGW tends to sleep for less than requested, by as much as 14ms,
- * but occasionally oversleeps for 40+ms (looks like some external
- * factors plus round-off on a 64Hz clock). Cygwin is pretty steady.
- *
- * If you start the MinGW version, and then launch the Cygwin version,
- * the MinGW clock becomes more erratic. Not entirely sure why.
- *
- * (There's a lot of stuff here; it's really just a usleep() call with
- * a bunch of instrumentation.)
- */
- if (sleepTime > 0) {
-#if defined(MONITOR_USLEEP)
- struct timeval before, after;
- long long actual;
-
- gettimeofday(&before, NULL);
- usleep((long) sleepTime);
- gettimeofday(&after, NULL);
-
- /* check usleep() accuracy; default Linux threads are pretty sloppy */
- actual = android::DurationTimer::subtractTimevals(&after, &before);
- if ((long) actual < sleepTime - 14000 /*(sleepTime/10)*/ ||
- (long) actual > sleepTime + 20000 /*(sleepTime/10)*/)
- {
- LOG(LOG_DEBUG, "", " Odd usleep: req=%ld, actual=%ld\n", sleepTime,
- (long) actual);
- }
-#else
-#ifdef HAVE_WIN32_THREADS
- Sleep( sleepTime/1000 );
-#else
- usleep((long) sleepTime);
-#endif
-#endif
- }
-
- //printf("slept %d\n", sleepTime);
-
- if (overSlept)
- return 1; // close enough
- else
- return 0;
-}
-
-
-/*
- * ===========================================================================
- * DurationTimer
- * ===========================================================================
- */
-
-using namespace android;
-
-// Start the timer.
-void DurationTimer::start(void)
-{
- gettimeofday(&mStartWhen, NULL);
-}
-
-// Stop the timer.
-void DurationTimer::stop(void)
-{
- gettimeofday(&mStopWhen, NULL);
-}
-
-// Get the duration in microseconds.
-long long DurationTimer::durationUsecs(void) const
-{
- return (long) subtractTimevals(&mStopWhen, &mStartWhen);
-}
-
-// Subtract two timevals. Returns the difference (ptv1-ptv2) in
-// microseconds.
-/*static*/ long long DurationTimer::subtractTimevals(const struct timeval* ptv1,
- const struct timeval* ptv2)
-{
- long long stop = ((long long) ptv1->tv_sec) * 1000000LL +
- ((long long) ptv1->tv_usec);
- long long start = ((long long) ptv2->tv_sec) * 1000000LL +
- ((long long) ptv2->tv_usec);
- return stop - start;
-}
-
-// Add the specified amount of time to the timeval.
-/*static*/ void DurationTimer::addToTimeval(struct timeval* ptv, long usec)
-{
- if (usec < 0) {
- LOG(LOG_WARN, "", "Negative values not supported in addToTimeval\n");
- return;
- }
-
- // normalize tv_usec if necessary
- if (ptv->tv_usec >= 1000000) {
- ptv->tv_sec += ptv->tv_usec / 1000000;
- ptv->tv_usec %= 1000000;
- }
-
- ptv->tv_usec += usec % 1000000;
- if (ptv->tv_usec >= 1000000) {
- ptv->tv_usec -= 1000000;
- ptv->tv_sec++;
- }
- ptv->tv_sec += usec / 1000000;
-}
-
diff --git a/libs/utils/Unicode.cpp b/libs/utils/Unicode.cpp
deleted file mode 100644
index 33f535f..0000000
--- a/libs/utils/Unicode.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * 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.
- */
-
-#include "utils/AndroidUnicode.h"
-#include "characterData.h"
-
-#define LOG_TAG "Unicode"
-#include "utils/Log.h"
-
-// ICU headers for using macros
-#include <unicode/utf16.h>
-
-#define MIN_RADIX 2
-#define MAX_RADIX 36
-
-#define TYPE_SHIFT 0
-#define TYPE_MASK ((1<<5)-1)
-
-#define DIRECTION_SHIFT (TYPE_SHIFT+5)
-#define DIRECTION_MASK ((1<<5)-1)
-
-#define MIRRORED_SHIFT (DIRECTION_SHIFT+5)
-#define MIRRORED_MASK ((1<<1)-1)
-
-#define TOUPPER_SHIFT (MIRRORED_SHIFT+1)
-#define TOUPPER_MASK ((1<<6)-1)
-
-#define TOLOWER_SHIFT (TOUPPER_SHIFT+6)
-#define TOLOWER_MASK ((1<<6)-1)
-
-#define TOTITLE_SHIFT (TOLOWER_SHIFT+6)
-#define TOTITLE_MASK ((1<<2)-1)
-
-#define MIRROR_SHIFT (TOTITLE_SHIFT+2)
-#define MIRROR_MASK ((1<<5)-1)
-
-#define NUMERIC_SHIFT (TOTITLE_SHIFT+2)
-#define NUMERIC_MASK ((1<<7)-1)
-
-#define DECOMPOSITION_SHIFT (11)
-#define DECOMPOSITION_MASK ((1<<5)-1)
-
-/*
- * Returns the value stored in the CharacterData tables that contains
- * an index into the packed data table and the decomposition type.
- */
-static uint16_t findCharacterValue(UChar32 c)
-{
- LOG_ASSERT(c >= 0 && c <= 0x10FFFF, "findCharacterValue received an invalid codepoint");
- if (c < 256)
- return CharacterData::LATIN1_DATA[c];
-
- // Rotate the bits because the tables are separated into even and odd codepoints
- c = (c >> 1) | ((c & 1) << 20);
-
- CharacterData::Range search = CharacterData::FULL_DATA[c >> 16];
- const uint32_t* array = search.array;
-
- // This trick is so that that compare in the while loop does not
- // need to shift the array entry down by 16
- c <<= 16;
- c |= 0xFFFF;
-
- int high = (int)search.length - 1;
- int low = 0;
-
- if (high < 0)
- return 0;
-
- while (low < high - 1)
- {
- int probe = (high + low) >> 1;
-
- // The entries contain the codepoint in the high 16 bits and the index
- // into PACKED_DATA in the low 16.
- if (array[probe] > (unsigned)c)
- high = probe;
- else
- low = probe;
- }
-
- LOG_ASSERT((array[low] <= (unsigned)c), "A suitable range was not found");
- return array[low] & 0xFFFF;
-}
-
-uint32_t android::Unicode::getPackedData(UChar32 c)
-{
- // findCharacterValue returns a 16-bit value with the top 5 bits containing a decomposition type
- // and the remaining bits containing an index.
- return CharacterData::PACKED_DATA[findCharacterValue(c) & 0x7FF];
-}
-
-android::Unicode::CharType android::Unicode::getType(UChar32 c)
-{
- if (c < 0 || c >= 0x10FFFF)
- return CHARTYPE_UNASSIGNED;
- return (CharType)((getPackedData(c) >> TYPE_SHIFT) & TYPE_MASK);
-}
-
-android::Unicode::DecompositionType android::Unicode::getDecompositionType(UChar32 c)
-{
- // findCharacterValue returns a 16-bit value with the top 5 bits containing a decomposition type
- // and the remaining bits containing an index.
- return (DecompositionType)((findCharacterValue(c) >> DECOMPOSITION_SHIFT) & DECOMPOSITION_MASK);
-}
-
-int android::Unicode::getDigitValue(UChar32 c, int radix)
-{
- if (radix < MIN_RADIX || radix > MAX_RADIX)
- return -1;
-
- int tempValue = radix;
-
- if (c >= '0' && c <= '9')
- tempValue = c - '0';
- else if (c >= 'a' && c <= 'z')
- tempValue = c - 'a' + 10;
- else if (c >= 'A' && c <= 'Z')
- tempValue = c - 'A' + 10;
-
- return tempValue < radix ? tempValue : -1;
-}
-
-int android::Unicode::getNumericValue(UChar32 c)
-{
- if (isMirrored(c))
- return -1;
-
- return (int) CharacterData::NUMERICS[((getPackedData(c) >> NUMERIC_SHIFT) & NUMERIC_MASK)];
-}
-
-UChar32 android::Unicode::toLower(UChar32 c)
-{
- return c + CharacterData::LCDIFF[(getPackedData(c) >> TOLOWER_SHIFT) & TOLOWER_MASK];
-}
-
-UChar32 android::Unicode::toUpper(UChar32 c)
-{
- return c + CharacterData::UCDIFF[(getPackedData(c) >> TOUPPER_SHIFT) & TOUPPER_MASK];
-}
-
-android::Unicode::Direction android::Unicode::getDirectionality(UChar32 c)
-{
- uint32_t data = getPackedData(c);
-
- if (0 == data)
- return DIRECTIONALITY_UNDEFINED;
-
- Direction d = (Direction) ((data >> DIRECTION_SHIFT) & DIRECTION_MASK);
-
- if (DIRECTION_MASK == d)
- return DIRECTIONALITY_UNDEFINED;
-
- return d;
-}
-
-bool android::Unicode::isMirrored(UChar32 c)
-{
- return ((getPackedData(c) >> MIRRORED_SHIFT) & MIRRORED_MASK) != 0;
-}
-
-UChar32 android::Unicode::toMirror(UChar32 c)
-{
- if (!isMirrored(c))
- return c;
-
- return c + CharacterData::MIRROR_DIFF[(getPackedData(c) >> MIRROR_SHIFT) & MIRROR_MASK];
-}
-
-UChar32 android::Unicode::toTitle(UChar32 c)
-{
- int32_t diff = CharacterData::TCDIFF[(getPackedData(c) >> TOTITLE_SHIFT) & TOTITLE_MASK];
-
- if (TOTITLE_MASK == diff)
- return toUpper(c);
-
- return c + diff;
-}
-
-
diff --git a/libs/utils/VectorImpl.cpp b/libs/utils/VectorImpl.cpp
deleted file mode 100644
index 2c2d667..0000000
--- a/libs/utils/VectorImpl.cpp
+++ /dev/null
@@ -1,611 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "Vector"
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <utils/SharedBuffer.h>
-#include <utils/VectorImpl.h>
-
-/*****************************************************************************/
-
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-const size_t kMinVectorCapacity = 4;
-
-static inline size_t max(size_t a, size_t b) {
- return a>b ? a : b;
-}
-
-// ----------------------------------------------------------------------------
-
-VectorImpl::VectorImpl(size_t itemSize, uint32_t flags)
- : mStorage(0), mCount(0), mFlags(flags), mItemSize(itemSize)
-{
-}
-
-VectorImpl::VectorImpl(const VectorImpl& rhs)
- : mStorage(rhs.mStorage), mCount(rhs.mCount),
- mFlags(rhs.mFlags), mItemSize(rhs.mItemSize)
-{
- if (mStorage) {
- SharedBuffer::sharedBuffer(mStorage)->acquire();
- }
-}
-
-VectorImpl::~VectorImpl()
-{
- LOG_ASSERT(!mCount,
- "[%p] "
- "subclasses of VectorImpl must call finish_vector()"
- " in their destructor. Leaking %d bytes.",
- this, (int)(mCount*mItemSize));
- // We can't call _do_destroy() here because the vtable is already gone.
-}
-
-VectorImpl& VectorImpl::operator = (const VectorImpl& rhs)
-{
- LOG_ASSERT(mItemSize == rhs.mItemSize,
- "Vector<> have different types (this=%p, rhs=%p)", this, &rhs);
- if (this != &rhs) {
- release_storage();
- if (rhs.mCount) {
- mStorage = rhs.mStorage;
- mCount = rhs.mCount;
- SharedBuffer::sharedBuffer(mStorage)->acquire();
- } else {
- mStorage = 0;
- mCount = 0;
- }
- }
- return *this;
-}
-
-void* VectorImpl::editArrayImpl()
-{
- if (mStorage) {
- SharedBuffer* sb = SharedBuffer::sharedBuffer(mStorage)->attemptEdit();
- if (sb == 0) {
- sb = SharedBuffer::alloc(capacity() * mItemSize);
- if (sb) {
- _do_copy(sb->data(), mStorage, mCount);
- release_storage();
- mStorage = sb->data();
- }
- }
- }
- return mStorage;
-}
-
-size_t VectorImpl::capacity() const
-{
- if (mStorage) {
- return SharedBuffer::sharedBuffer(mStorage)->size() / mItemSize;
- }
- return 0;
-}
-
-ssize_t VectorImpl::insertVectorAt(const VectorImpl& vector, size_t index)
-{
- if (index > size())
- return BAD_INDEX;
- void* where = _grow(index, vector.size());
- if (where) {
- _do_copy(where, vector.arrayImpl(), vector.size());
- }
- return where ? index : (ssize_t)NO_MEMORY;
-}
-
-ssize_t VectorImpl::appendVector(const VectorImpl& vector)
-{
- return insertVectorAt(vector, size());
-}
-
-ssize_t VectorImpl::insertAt(size_t index, size_t numItems)
-{
- return insertAt(0, index, numItems);
-}
-
-ssize_t VectorImpl::insertAt(const void* item, size_t index, size_t numItems)
-{
- if (index > size())
- return BAD_INDEX;
- void* where = _grow(index, numItems);
- if (where) {
- if (item) {
- _do_splat(where, item, numItems);
- } else {
- _do_construct(where, numItems);
- }
- }
- return where ? index : (ssize_t)NO_MEMORY;
-}
-
-static int sortProxy(const void* lhs, const void* rhs, void* func)
-{
- return (*(VectorImpl::compar_t)func)(lhs, rhs);
-}
-
-status_t VectorImpl::sort(VectorImpl::compar_t cmp)
-{
- return sort(sortProxy, (void*)cmp);
-}
-
-status_t VectorImpl::sort(VectorImpl::compar_r_t cmp, void* state)
-{
- // the sort must be stable. we're using insertion sort which
- // is well suited for small and already sorted arrays
- // for big arrays, it could be better to use mergesort
- const ssize_t count = size();
- if (count > 1) {
- void* array = const_cast<void*>(arrayImpl());
- void* temp = 0;
- ssize_t i = 1;
- while (i < count) {
- void* item = reinterpret_cast<char*>(array) + mItemSize*(i);
- void* curr = reinterpret_cast<char*>(array) + mItemSize*(i-1);
- if (cmp(curr, item, state) > 0) {
-
- if (!temp) {
- // we're going to have to modify the array...
- array = editArrayImpl();
- if (!array) return NO_MEMORY;
- temp = malloc(mItemSize);
- if (!temp) return NO_MEMORY;
- _do_construct(temp, 1);
- item = reinterpret_cast<char*>(array) + mItemSize*(i);
- curr = reinterpret_cast<char*>(array) + mItemSize*(i-1);
- }
-
- _do_copy(temp, item, 1);
-
- ssize_t j = i-1;
- void* next = reinterpret_cast<char*>(array) + mItemSize*(i);
- do {
- _do_copy(next, curr, 1);
- next = curr;
- --j;
- curr = reinterpret_cast<char*>(array) + mItemSize*(j);
- } while (j>=0 && (cmp(curr, temp, state) > 0));
-
- _do_copy(next, temp, 1);
- }
- i++;
- }
-
- if (temp) {
- _do_destroy(temp, 1);
- free(temp);
- }
- }
- return NO_ERROR;
-}
-
-void VectorImpl::pop()
-{
- if (size())
- removeItemsAt(size()-1, 1);
-}
-
-void VectorImpl::push()
-{
- push(0);
-}
-
-void VectorImpl::push(const void* item)
-{
- insertAt(item, size());
-}
-
-ssize_t VectorImpl::add()
-{
- return add(0);
-}
-
-ssize_t VectorImpl::add(const void* item)
-{
- return insertAt(item, size());
-}
-
-ssize_t VectorImpl::replaceAt(size_t index)
-{
- return replaceAt(0, index);
-}
-
-ssize_t VectorImpl::replaceAt(const void* prototype, size_t index)
-{
- LOG_ASSERT(index<size(),
- "[%p] replace: index=%d, size=%d", this, (int)index, (int)size());
-
- void* item = editItemLocation(index);
- if (item == 0)
- return NO_MEMORY;
- _do_destroy(item, 1);
- if (prototype == 0) {
- _do_construct(item, 1);
- } else {
- _do_copy(item, prototype, 1);
- }
- return ssize_t(index);
-}
-
-ssize_t VectorImpl::removeItemsAt(size_t index, size_t count)
-{
- LOG_ASSERT((index+count)<=size(),
- "[%p] remove: index=%d, count=%d, size=%d",
- this, (int)index, (int)count, (int)size());
-
- if ((index+count) > size())
- return BAD_VALUE;
- _shrink(index, count);
- return index;
-}
-
-void VectorImpl::finish_vector()
-{
- release_storage();
- mStorage = 0;
- mCount = 0;
-}
-
-void VectorImpl::clear()
-{
- _shrink(0, mCount);
-}
-
-void* VectorImpl::editItemLocation(size_t index)
-{
- LOG_ASSERT(index<capacity(),
- "[%p] itemLocation: index=%d, capacity=%d, count=%d",
- this, (int)index, (int)capacity(), (int)mCount);
-
- void* buffer = editArrayImpl();
- if (buffer)
- return reinterpret_cast<char*>(buffer) + index*mItemSize;
- return 0;
-}
-
-const void* VectorImpl::itemLocation(size_t index) const
-{
- LOG_ASSERT(index<capacity(),
- "[%p] editItemLocation: index=%d, capacity=%d, count=%d",
- this, (int)index, (int)capacity(), (int)mCount);
-
- const void* buffer = arrayImpl();
- if (buffer)
- return reinterpret_cast<const char*>(buffer) + index*mItemSize;
- return 0;
-}
-
-ssize_t VectorImpl::setCapacity(size_t new_capacity)
-{
- size_t current_capacity = capacity();
- ssize_t amount = new_capacity - size();
- if (amount <= 0) {
- // we can't reduce the capacity
- return current_capacity;
- }
- SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
- if (sb) {
- void* array = sb->data();
- _do_copy(array, mStorage, size());
- release_storage();
- mStorage = const_cast<void*>(array);
- } else {
- return NO_MEMORY;
- }
- return new_capacity;
-}
-
-void VectorImpl::release_storage()
-{
- if (mStorage) {
- const SharedBuffer* sb = SharedBuffer::sharedBuffer(mStorage);
- if (sb->release(SharedBuffer::eKeepStorage) == 1) {
- _do_destroy(mStorage, mCount);
- SharedBuffer::dealloc(sb);
- }
- }
-}
-
-void* VectorImpl::_grow(size_t where, size_t amount)
-{
-// LOGV("_grow(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
-// this, (int)where, (int)amount, (int)mCount, (int)capacity());
-
- if (where > mCount)
- where = mCount;
-
- const size_t new_size = mCount + amount;
- if (capacity() < new_size) {
- const size_t new_capacity = max(kMinVectorCapacity, ((new_size*3)+1)/2);
-// LOGV("grow vector %p, new_capacity=%d", this, (int)new_capacity);
- if ((mStorage) &&
- (mCount==where) &&
- (mFlags & HAS_TRIVIAL_COPY) &&
- (mFlags & HAS_TRIVIAL_DTOR))
- {
- const SharedBuffer* cur_sb = SharedBuffer::sharedBuffer(mStorage);
- SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize);
- mStorage = sb->data();
- } else {
- SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
- if (sb) {
- void* array = sb->data();
- if (where>0) {
- _do_copy(array, mStorage, where);
- }
- if (mCount>where) {
- const void* from = reinterpret_cast<const uint8_t *>(mStorage) + where*mItemSize;
- void* dest = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
- _do_copy(dest, from, mCount-where);
- }
- release_storage();
- mStorage = const_cast<void*>(array);
- }
- }
- } else {
- ssize_t s = mCount-where;
- if (s>0) {
- void* array = editArrayImpl();
- void* to = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
- const void* from = reinterpret_cast<const uint8_t *>(array) + where*mItemSize;
- _do_move_forward(to, from, s);
- }
- }
- mCount += amount;
- void* free_space = const_cast<void*>(itemLocation(where));
- return free_space;
-}
-
-void VectorImpl::_shrink(size_t where, size_t amount)
-{
- if (!mStorage)
- return;
-
-// LOGV("_shrink(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
-// this, (int)where, (int)amount, (int)mCount, (int)capacity());
-
- if (where >= mCount)
- where = mCount - amount;
-
- const size_t new_size = mCount - amount;
- if (new_size*3 < capacity()) {
- const size_t new_capacity = max(kMinVectorCapacity, new_size*2);
-// LOGV("shrink vector %p, new_capacity=%d", this, (int)new_capacity);
- if ((where == mCount-amount) &&
- (mFlags & HAS_TRIVIAL_COPY) &&
- (mFlags & HAS_TRIVIAL_DTOR))
- {
- const SharedBuffer* cur_sb = SharedBuffer::sharedBuffer(mStorage);
- SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize);
- mStorage = sb->data();
- } else {
- SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
- if (sb) {
- void* array = sb->data();
- if (where>0) {
- _do_copy(array, mStorage, where);
- }
- if (mCount > where+amount) {
- const void* from = reinterpret_cast<const uint8_t *>(mStorage) + (where+amount)*mItemSize;
- void* dest = reinterpret_cast<uint8_t *>(array) + where*mItemSize;
- _do_copy(dest, from, mCount-(where+amount));
- }
- release_storage();
- mStorage = const_cast<void*>(array);
- }
- }
- } else {
- void* array = editArrayImpl();
- void* to = reinterpret_cast<uint8_t *>(array) + where*mItemSize;
- _do_destroy(to, amount);
- ssize_t s = mCount-(where+amount);
- if (s>0) {
- const void* from = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
- _do_move_backward(to, from, s);
- }
- }
-
- // adjust the number of items...
- mCount -= amount;
-}
-
-size_t VectorImpl::itemSize() const {
- return mItemSize;
-}
-
-void VectorImpl::_do_construct(void* storage, size_t num) const
-{
- if (!(mFlags & HAS_TRIVIAL_CTOR)) {
- do_construct(storage, num);
- }
-}
-
-void VectorImpl::_do_destroy(void* storage, size_t num) const
-{
- if (!(mFlags & HAS_TRIVIAL_DTOR)) {
- do_destroy(storage, num);
- }
-}
-
-void VectorImpl::_do_copy(void* dest, const void* from, size_t num) const
-{
- if (!(mFlags & HAS_TRIVIAL_COPY)) {
- do_copy(dest, from, num);
- } else {
- memcpy(dest, from, num*itemSize());
- }
-}
-
-void VectorImpl::_do_splat(void* dest, const void* item, size_t num) const {
- do_splat(dest, item, num);
-}
-
-void VectorImpl::_do_move_forward(void* dest, const void* from, size_t num) const {
- do_move_forward(dest, from, num);
-}
-
-void VectorImpl::_do_move_backward(void* dest, const void* from, size_t num) const {
- do_move_backward(dest, from, num);
-}
-
-void VectorImpl::reservedVectorImpl1() { }
-void VectorImpl::reservedVectorImpl2() { }
-void VectorImpl::reservedVectorImpl3() { }
-void VectorImpl::reservedVectorImpl4() { }
-void VectorImpl::reservedVectorImpl5() { }
-void VectorImpl::reservedVectorImpl6() { }
-void VectorImpl::reservedVectorImpl7() { }
-void VectorImpl::reservedVectorImpl8() { }
-
-/*****************************************************************************/
-
-SortedVectorImpl::SortedVectorImpl(size_t itemSize, uint32_t flags)
- : VectorImpl(itemSize, flags)
-{
-}
-
-SortedVectorImpl::SortedVectorImpl(const VectorImpl& rhs)
-: VectorImpl(rhs)
-{
-}
-
-SortedVectorImpl::~SortedVectorImpl()
-{
-}
-
-SortedVectorImpl& SortedVectorImpl::operator = (const SortedVectorImpl& rhs)
-{
- return static_cast<SortedVectorImpl&>( VectorImpl::operator = (static_cast<const VectorImpl&>(rhs)) );
-}
-
-ssize_t SortedVectorImpl::indexOf(const void* item) const
-{
- return _indexOrderOf(item);
-}
-
-size_t SortedVectorImpl::orderOf(const void* item) const
-{
- size_t o;
- _indexOrderOf(item, &o);
- return o;
-}
-
-ssize_t SortedVectorImpl::_indexOrderOf(const void* item, size_t* order) const
-{
- // binary search
- ssize_t err = NAME_NOT_FOUND;
- ssize_t l = 0;
- ssize_t h = size()-1;
- ssize_t mid;
- const void* a = arrayImpl();
- const size_t s = itemSize();
- while (l <= h) {
- mid = l + (h - l)/2;
- const void* const curr = reinterpret_cast<const char *>(a) + (mid*s);
- const int c = do_compare(curr, item);
- if (c == 0) {
- err = l = mid;
- break;
- } else if (c < 0) {
- l = mid + 1;
- } else {
- h = mid - 1;
- }
- }
- if (order) *order = l;
- return err;
-}
-
-ssize_t SortedVectorImpl::add(const void* item)
-{
- size_t order;
- ssize_t index = _indexOrderOf(item, &order);
- if (index < 0) {
- index = VectorImpl::insertAt(item, order, 1);
- } else {
- index = VectorImpl::replaceAt(item, index);
- }
- return index;
-}
-
-ssize_t SortedVectorImpl::merge(const VectorImpl& vector)
-{
- // naive merge...
- if (!vector.isEmpty()) {
- const void* buffer = vector.arrayImpl();
- const size_t is = itemSize();
- size_t s = vector.size();
- for (size_t i=0 ; i<s ; i++) {
- ssize_t err = add( reinterpret_cast<const char*>(buffer) + i*is );
- if (err<0) {
- return err;
- }
- }
- }
- return NO_ERROR;
-}
-
-ssize_t SortedVectorImpl::merge(const SortedVectorImpl& vector)
-{
- // we've merging a sorted vector... nice!
- ssize_t err = NO_ERROR;
- if (!vector.isEmpty()) {
- // first take care of the case where the vectors are sorted together
- if (do_compare(vector.itemLocation(vector.size()-1), arrayImpl()) <= 0) {
- err = VectorImpl::insertVectorAt(static_cast<const VectorImpl&>(vector), 0);
- } else if (do_compare(vector.arrayImpl(), itemLocation(size()-1)) >= 0) {
- err = VectorImpl::appendVector(static_cast<const VectorImpl&>(vector));
- } else {
- // this could be made a little better
- err = merge(static_cast<const VectorImpl&>(vector));
- }
- }
- return err;
-}
-
-ssize_t SortedVectorImpl::remove(const void* item)
-{
- ssize_t i = indexOf(item);
- if (i>=0) {
- VectorImpl::removeItemsAt(i, 1);
- }
- return i;
-}
-
-void SortedVectorImpl::reservedSortedVectorImpl1() { };
-void SortedVectorImpl::reservedSortedVectorImpl2() { };
-void SortedVectorImpl::reservedSortedVectorImpl3() { };
-void SortedVectorImpl::reservedSortedVectorImpl4() { };
-void SortedVectorImpl::reservedSortedVectorImpl5() { };
-void SortedVectorImpl::reservedSortedVectorImpl6() { };
-void SortedVectorImpl::reservedSortedVectorImpl7() { };
-void SortedVectorImpl::reservedSortedVectorImpl8() { };
-
-
-/*****************************************************************************/
-
-}; // namespace android
-
diff --git a/libs/utils/ZipEntry.cpp b/libs/utils/ZipEntry.cpp
deleted file mode 100644
index fbc9e67..0000000
--- a/libs/utils/ZipEntry.cpp
+++ /dev/null
@@ -1,696 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Access to entries in a Zip archive.
-//
-
-#define LOG_TAG "zip"
-
-#include "utils/ZipEntry.h"
-#include "utils/Log.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-using namespace android;
-
-/*
- * Initialize a new ZipEntry structure from a FILE* positioned at a
- * CentralDirectoryEntry.
- *
- * On exit, the file pointer will be at the start of the next CDE or
- * at the EOCD.
- */
-status_t ZipEntry::initFromCDE(FILE* fp)
-{
- status_t result;
- long posn;
- bool hasDD;
-
- //LOGV("initFromCDE ---\n");
-
- /* read the CDE */
- result = mCDE.read(fp);
- if (result != NO_ERROR) {
- LOGD("mCDE.read failed\n");
- return result;
- }
-
- //mCDE.dump();
-
- /* using the info in the CDE, go load up the LFH */
- posn = ftell(fp);
- if (fseek(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) {
- LOGD("local header seek failed (%ld)\n",
- mCDE.mLocalHeaderRelOffset);
- return UNKNOWN_ERROR;
- }
-
- result = mLFH.read(fp);
- if (result != NO_ERROR) {
- LOGD("mLFH.read failed\n");
- return result;
- }
-
- if (fseek(fp, posn, SEEK_SET) != 0)
- return UNKNOWN_ERROR;
-
- //mLFH.dump();
-
- /*
- * We *might* need to read the Data Descriptor at this point and
- * integrate it into the LFH. If this bit is set, the CRC-32,
- * compressed size, and uncompressed size will be zero. In practice
- * these seem to be rare.
- */
- hasDD = (mLFH.mGPBitFlag & kUsesDataDescr) != 0;
- if (hasDD) {
- // do something clever
- //LOGD("+++ has data descriptor\n");
- }
-
- /*
- * Sanity-check the LFH. Note that this will fail if the "kUsesDataDescr"
- * flag is set, because the LFH is incomplete. (Not a problem, since we
- * prefer the CDE values.)
- */
- if (!hasDD && !compareHeaders()) {
- LOGW("WARNING: header mismatch\n");
- // keep going?
- }
-
- /*
- * If the mVersionToExtract is greater than 20, we may have an
- * issue unpacking the record -- could be encrypted, compressed
- * with something we don't support, or use Zip64 extensions. We
- * can defer worrying about that to when we're extracting data.
- */
-
- return NO_ERROR;
-}
-
-/*
- * Initialize a new entry. Pass in the file name and an optional comment.
- *
- * Initializes the CDE and the LFH.
- */
-void ZipEntry::initNew(const char* fileName, const char* comment)
-{
- assert(fileName != NULL && *fileName != '\0'); // name required
-
- /* most fields are properly initialized by constructor */
- mCDE.mVersionMadeBy = kDefaultMadeBy;
- mCDE.mVersionToExtract = kDefaultVersion;
- mCDE.mCompressionMethod = kCompressStored;
- mCDE.mFileNameLength = strlen(fileName);
- if (comment != NULL)
- mCDE.mFileCommentLength = strlen(comment);
- mCDE.mExternalAttrs = 0x81b60020; // matches what WinZip does
-
- if (mCDE.mFileNameLength > 0) {
- mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1];
- strcpy((char*) mCDE.mFileName, fileName);
- }
- if (mCDE.mFileCommentLength > 0) {
- /* TODO: stop assuming null-terminated ASCII here? */
- mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1];
- strcpy((char*) mCDE.mFileComment, comment);
- }
-
- copyCDEtoLFH();
-}
-
-/*
- * Initialize a new entry, starting with the ZipEntry from a different
- * archive.
- *
- * Initializes the CDE and the LFH.
- */
-status_t ZipEntry::initFromExternal(const ZipFile* pZipFile,
- const ZipEntry* pEntry)
-{
- /*
- * Copy everything in the CDE over, then fix up the hairy bits.
- */
- memcpy(&mCDE, &pEntry->mCDE, sizeof(mCDE));
-
- if (mCDE.mFileNameLength > 0) {
- mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1];
- if (mCDE.mFileName == NULL)
- return NO_MEMORY;
- strcpy((char*) mCDE.mFileName, (char*)pEntry->mCDE.mFileName);
- }
- if (mCDE.mFileCommentLength > 0) {
- mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1];
- if (mCDE.mFileComment == NULL)
- return NO_MEMORY;
- strcpy((char*) mCDE.mFileComment, (char*)pEntry->mCDE.mFileComment);
- }
- if (mCDE.mExtraFieldLength > 0) {
- /* we null-terminate this, though it may not be a string */
- mCDE.mExtraField = new unsigned char[mCDE.mExtraFieldLength+1];
- if (mCDE.mExtraField == NULL)
- return NO_MEMORY;
- memcpy(mCDE.mExtraField, pEntry->mCDE.mExtraField,
- mCDE.mExtraFieldLength+1);
- }
-
- /* construct the LFH from the CDE */
- copyCDEtoLFH();
-
- /*
- * The LFH "extra" field is independent of the CDE "extra", so we
- * handle it here.
- */
- assert(mLFH.mExtraField == NULL);
- mLFH.mExtraFieldLength = pEntry->mLFH.mExtraFieldLength;
- if (mLFH.mExtraFieldLength > 0) {
- mLFH.mExtraField = new unsigned char[mLFH.mExtraFieldLength+1];
- if (mLFH.mExtraField == NULL)
- return NO_MEMORY;
- memcpy(mLFH.mExtraField, pEntry->mLFH.mExtraField,
- mLFH.mExtraFieldLength+1);
- }
-
- return NO_ERROR;
-}
-
-/*
- * Insert pad bytes in the LFH by tweaking the "extra" field. This will
- * potentially confuse something that put "extra" data in here earlier,
- * but I can't find an actual problem.
- */
-status_t ZipEntry::addPadding(int padding)
-{
- if (padding <= 0)
- return INVALID_OPERATION;
-
- //LOGI("HEY: adding %d pad bytes to existing %d in %s\n",
- // padding, mLFH.mExtraFieldLength, mCDE.mFileName);
-
- if (mLFH.mExtraFieldLength > 0) {
- /* extend existing field */
- unsigned char* newExtra;
-
- newExtra = new unsigned char[mLFH.mExtraFieldLength + padding];
- if (newExtra == NULL)
- return NO_MEMORY;
- memset(newExtra + mLFH.mExtraFieldLength, 0, padding);
- memcpy(newExtra, mLFH.mExtraField, mLFH.mExtraFieldLength);
-
- delete[] mLFH.mExtraField;
- mLFH.mExtraField = newExtra;
- mLFH.mExtraFieldLength += padding;
- } else {
- /* create new field */
- mLFH.mExtraField = new unsigned char[padding];
- memset(mLFH.mExtraField, 0, padding);
- mLFH.mExtraFieldLength = padding;
- }
-
- return NO_ERROR;
-}
-
-/*
- * Set the fields in the LFH equal to the corresponding fields in the CDE.
- *
- * This does not touch the LFH "extra" field.
- */
-void ZipEntry::copyCDEtoLFH(void)
-{
- mLFH.mVersionToExtract = mCDE.mVersionToExtract;
- mLFH.mGPBitFlag = mCDE.mGPBitFlag;
- mLFH.mCompressionMethod = mCDE.mCompressionMethod;
- mLFH.mLastModFileTime = mCDE.mLastModFileTime;
- mLFH.mLastModFileDate = mCDE.mLastModFileDate;
- mLFH.mCRC32 = mCDE.mCRC32;
- mLFH.mCompressedSize = mCDE.mCompressedSize;
- mLFH.mUncompressedSize = mCDE.mUncompressedSize;
- mLFH.mFileNameLength = mCDE.mFileNameLength;
- // the "extra field" is independent
-
- delete[] mLFH.mFileName;
- if (mLFH.mFileNameLength > 0) {
- mLFH.mFileName = new unsigned char[mLFH.mFileNameLength+1];
- strcpy((char*) mLFH.mFileName, (const char*) mCDE.mFileName);
- } else {
- mLFH.mFileName = NULL;
- }
-}
-
-/*
- * Set some information about a file after we add it.
- */
-void ZipEntry::setDataInfo(long uncompLen, long compLen, unsigned long crc32,
- int compressionMethod)
-{
- mCDE.mCompressionMethod = compressionMethod;
- mCDE.mCRC32 = crc32;
- mCDE.mCompressedSize = compLen;
- mCDE.mUncompressedSize = uncompLen;
- mCDE.mCompressionMethod = compressionMethod;
- if (compressionMethod == kCompressDeflated) {
- mCDE.mGPBitFlag |= 0x0002; // indicates maximum compression used
- }
- copyCDEtoLFH();
-}
-
-/*
- * See if the data in mCDE and mLFH match up. This is mostly useful for
- * debugging these classes, but it can be used to identify damaged
- * archives.
- *
- * Returns "false" if they differ.
- */
-bool ZipEntry::compareHeaders(void) const
-{
- if (mCDE.mVersionToExtract != mLFH.mVersionToExtract) {
- LOGV("cmp: VersionToExtract\n");
- return false;
- }
- if (mCDE.mGPBitFlag != mLFH.mGPBitFlag) {
- LOGV("cmp: GPBitFlag\n");
- return false;
- }
- if (mCDE.mCompressionMethod != mLFH.mCompressionMethod) {
- LOGV("cmp: CompressionMethod\n");
- return false;
- }
- if (mCDE.mLastModFileTime != mLFH.mLastModFileTime) {
- LOGV("cmp: LastModFileTime\n");
- return false;
- }
- if (mCDE.mLastModFileDate != mLFH.mLastModFileDate) {
- LOGV("cmp: LastModFileDate\n");
- return false;
- }
- if (mCDE.mCRC32 != mLFH.mCRC32) {
- LOGV("cmp: CRC32\n");
- return false;
- }
- if (mCDE.mCompressedSize != mLFH.mCompressedSize) {
- LOGV("cmp: CompressedSize\n");
- return false;
- }
- if (mCDE.mUncompressedSize != mLFH.mUncompressedSize) {
- LOGV("cmp: UncompressedSize\n");
- return false;
- }
- if (mCDE.mFileNameLength != mLFH.mFileNameLength) {
- LOGV("cmp: FileNameLength\n");
- return false;
- }
-#if 0 // this seems to be used for padding, not real data
- if (mCDE.mExtraFieldLength != mLFH.mExtraFieldLength) {
- LOGV("cmp: ExtraFieldLength\n");
- return false;
- }
-#endif
- if (mCDE.mFileName != NULL) {
- if (strcmp((char*) mCDE.mFileName, (char*) mLFH.mFileName) != 0) {
- LOGV("cmp: FileName\n");
- return false;
- }
- }
-
- return true;
-}
-
-
-/*
- * Convert the DOS date/time stamp into a UNIX time stamp.
- */
-time_t ZipEntry::getModWhen(void) const
-{
- struct tm parts;
-
- parts.tm_sec = (mCDE.mLastModFileTime & 0x001f) << 1;
- parts.tm_min = (mCDE.mLastModFileTime & 0x07e0) >> 5;
- parts.tm_hour = (mCDE.mLastModFileTime & 0xf800) >> 11;
- parts.tm_mday = (mCDE.mLastModFileDate & 0x001f);
- parts.tm_mon = ((mCDE.mLastModFileDate & 0x01e0) >> 5) -1;
- parts.tm_year = ((mCDE.mLastModFileDate & 0xfe00) >> 9) + 80;
- parts.tm_wday = parts.tm_yday = 0;
- parts.tm_isdst = -1; // DST info "not available"
-
- return mktime(&parts);
-}
-
-/*
- * Set the CDE/LFH timestamp from UNIX time.
- */
-void ZipEntry::setModWhen(time_t when)
-{
-#ifdef HAVE_LOCALTIME_R
- struct tm tmResult;
-#endif
- time_t even;
- unsigned short zdate, ztime;
-
- struct tm* ptm;
-
- /* round up to an even number of seconds */
- even = (time_t)(((unsigned long)(when) + 1) & (~1));
-
- /* expand */
-#ifdef HAVE_LOCALTIME_R
- ptm = localtime_r(&even, &tmResult);
-#else
- ptm = localtime(&even);
-#endif
-
- int year;
- year = ptm->tm_year;
- if (year < 80)
- year = 80;
-
- zdate = (year - 80) << 9 | (ptm->tm_mon+1) << 5 | ptm->tm_mday;
- ztime = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1;
-
- mCDE.mLastModFileTime = mLFH.mLastModFileTime = ztime;
- mCDE.mLastModFileDate = mLFH.mLastModFileDate = zdate;
-}
-
-
-/*
- * ===========================================================================
- * ZipEntry::LocalFileHeader
- * ===========================================================================
- */
-
-/*
- * Read a local file header.
- *
- * On entry, "fp" points to the signature at the start of the header.
- * On exit, "fp" points to the start of data.
- */
-status_t ZipEntry::LocalFileHeader::read(FILE* fp)
-{
- status_t result = NO_ERROR;
- unsigned char buf[kLFHLen];
-
- assert(mFileName == NULL);
- assert(mExtraField == NULL);
-
- if (fread(buf, 1, kLFHLen, fp) != kLFHLen) {
- result = UNKNOWN_ERROR;
- goto bail;
- }
-
- if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {
- LOGD("whoops: didn't find expected signature\n");
- result = UNKNOWN_ERROR;
- goto bail;
- }
-
- mVersionToExtract = ZipEntry::getShortLE(&buf[0x04]);
- mGPBitFlag = ZipEntry::getShortLE(&buf[0x06]);
- mCompressionMethod = ZipEntry::getShortLE(&buf[0x08]);
- mLastModFileTime = ZipEntry::getShortLE(&buf[0x0a]);
- mLastModFileDate = ZipEntry::getShortLE(&buf[0x0c]);
- mCRC32 = ZipEntry::getLongLE(&buf[0x0e]);
- mCompressedSize = ZipEntry::getLongLE(&buf[0x12]);
- mUncompressedSize = ZipEntry::getLongLE(&buf[0x16]);
- mFileNameLength = ZipEntry::getShortLE(&buf[0x1a]);
- mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1c]);
-
- // TODO: validate sizes
-
- /* grab filename */
- if (mFileNameLength != 0) {
- mFileName = new unsigned char[mFileNameLength+1];
- if (mFileName == NULL) {
- result = NO_MEMORY;
- goto bail;
- }
- if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {
- result = UNKNOWN_ERROR;
- goto bail;
- }
- mFileName[mFileNameLength] = '\0';
- }
-
- /* grab extra field */
- if (mExtraFieldLength != 0) {
- mExtraField = new unsigned char[mExtraFieldLength+1];
- if (mExtraField == NULL) {
- result = NO_MEMORY;
- goto bail;
- }
- if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {
- result = UNKNOWN_ERROR;
- goto bail;
- }
- mExtraField[mExtraFieldLength] = '\0';
- }
-
-bail:
- return result;
-}
-
-/*
- * Write a local file header.
- */
-status_t ZipEntry::LocalFileHeader::write(FILE* fp)
-{
- unsigned char buf[kLFHLen];
-
- ZipEntry::putLongLE(&buf[0x00], kSignature);
- ZipEntry::putShortLE(&buf[0x04], mVersionToExtract);
- ZipEntry::putShortLE(&buf[0x06], mGPBitFlag);
- ZipEntry::putShortLE(&buf[0x08], mCompressionMethod);
- ZipEntry::putShortLE(&buf[0x0a], mLastModFileTime);
- ZipEntry::putShortLE(&buf[0x0c], mLastModFileDate);
- ZipEntry::putLongLE(&buf[0x0e], mCRC32);
- ZipEntry::putLongLE(&buf[0x12], mCompressedSize);
- ZipEntry::putLongLE(&buf[0x16], mUncompressedSize);
- ZipEntry::putShortLE(&buf[0x1a], mFileNameLength);
- ZipEntry::putShortLE(&buf[0x1c], mExtraFieldLength);
-
- if (fwrite(buf, 1, kLFHLen, fp) != kLFHLen)
- return UNKNOWN_ERROR;
-
- /* write filename */
- if (mFileNameLength != 0) {
- if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)
- return UNKNOWN_ERROR;
- }
-
- /* write "extra field" */
- if (mExtraFieldLength != 0) {
- if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)
- return UNKNOWN_ERROR;
- }
-
- return NO_ERROR;
-}
-
-
-/*
- * Dump the contents of a LocalFileHeader object.
- */
-void ZipEntry::LocalFileHeader::dump(void) const
-{
- LOGD(" LocalFileHeader contents:\n");
- LOGD(" versToExt=%u gpBits=0x%04x compression=%u\n",
- mVersionToExtract, mGPBitFlag, mCompressionMethod);
- LOGD(" modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n",
- mLastModFileTime, mLastModFileDate, mCRC32);
- LOGD(" compressedSize=%lu uncompressedSize=%lu\n",
- mCompressedSize, mUncompressedSize);
- LOGD(" filenameLen=%u extraLen=%u\n",
- mFileNameLength, mExtraFieldLength);
- if (mFileName != NULL)
- LOGD(" filename: '%s'\n", mFileName);
-}
-
-
-/*
- * ===========================================================================
- * ZipEntry::CentralDirEntry
- * ===========================================================================
- */
-
-/*
- * Read the central dir entry that appears next in the file.
- *
- * On entry, "fp" should be positioned on the signature bytes for the
- * entry. On exit, "fp" will point at the signature word for the next
- * entry or for the EOCD.
- */
-status_t ZipEntry::CentralDirEntry::read(FILE* fp)
-{
- status_t result = NO_ERROR;
- unsigned char buf[kCDELen];
-
- /* no re-use */
- assert(mFileName == NULL);
- assert(mExtraField == NULL);
- assert(mFileComment == NULL);
-
- if (fread(buf, 1, kCDELen, fp) != kCDELen) {
- result = UNKNOWN_ERROR;
- goto bail;
- }
-
- if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {
- LOGD("Whoops: didn't find expected signature\n");
- result = UNKNOWN_ERROR;
- goto bail;
- }
-
- mVersionMadeBy = ZipEntry::getShortLE(&buf[0x04]);
- mVersionToExtract = ZipEntry::getShortLE(&buf[0x06]);
- mGPBitFlag = ZipEntry::getShortLE(&buf[0x08]);
- mCompressionMethod = ZipEntry::getShortLE(&buf[0x0a]);
- mLastModFileTime = ZipEntry::getShortLE(&buf[0x0c]);
- mLastModFileDate = ZipEntry::getShortLE(&buf[0x0e]);
- mCRC32 = ZipEntry::getLongLE(&buf[0x10]);
- mCompressedSize = ZipEntry::getLongLE(&buf[0x14]);
- mUncompressedSize = ZipEntry::getLongLE(&buf[0x18]);
- mFileNameLength = ZipEntry::getShortLE(&buf[0x1c]);
- mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1e]);
- mFileCommentLength = ZipEntry::getShortLE(&buf[0x20]);
- mDiskNumberStart = ZipEntry::getShortLE(&buf[0x22]);
- mInternalAttrs = ZipEntry::getShortLE(&buf[0x24]);
- mExternalAttrs = ZipEntry::getLongLE(&buf[0x26]);
- mLocalHeaderRelOffset = ZipEntry::getLongLE(&buf[0x2a]);
-
- // TODO: validate sizes and offsets
-
- /* grab filename */
- if (mFileNameLength != 0) {
- mFileName = new unsigned char[mFileNameLength+1];
- if (mFileName == NULL) {
- result = NO_MEMORY;
- goto bail;
- }
- if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {
- result = UNKNOWN_ERROR;
- goto bail;
- }
- mFileName[mFileNameLength] = '\0';
- }
-
- /* read "extra field" */
- if (mExtraFieldLength != 0) {
- mExtraField = new unsigned char[mExtraFieldLength+1];
- if (mExtraField == NULL) {
- result = NO_MEMORY;
- goto bail;
- }
- if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {
- result = UNKNOWN_ERROR;
- goto bail;
- }
- mExtraField[mExtraFieldLength] = '\0';
- }
-
-
- /* grab comment, if any */
- if (mFileCommentLength != 0) {
- mFileComment = new unsigned char[mFileCommentLength+1];
- if (mFileComment == NULL) {
- result = NO_MEMORY;
- goto bail;
- }
- if (fread(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)
- {
- result = UNKNOWN_ERROR;
- goto bail;
- }
- mFileComment[mFileCommentLength] = '\0';
- }
-
-bail:
- return result;
-}
-
-/*
- * Write a central dir entry.
- */
-status_t ZipEntry::CentralDirEntry::write(FILE* fp)
-{
- unsigned char buf[kCDELen];
-
- ZipEntry::putLongLE(&buf[0x00], kSignature);
- ZipEntry::putShortLE(&buf[0x04], mVersionMadeBy);
- ZipEntry::putShortLE(&buf[0x06], mVersionToExtract);
- ZipEntry::putShortLE(&buf[0x08], mGPBitFlag);
- ZipEntry::putShortLE(&buf[0x0a], mCompressionMethod);
- ZipEntry::putShortLE(&buf[0x0c], mLastModFileTime);
- ZipEntry::putShortLE(&buf[0x0e], mLastModFileDate);
- ZipEntry::putLongLE(&buf[0x10], mCRC32);
- ZipEntry::putLongLE(&buf[0x14], mCompressedSize);
- ZipEntry::putLongLE(&buf[0x18], mUncompressedSize);
- ZipEntry::putShortLE(&buf[0x1c], mFileNameLength);
- ZipEntry::putShortLE(&buf[0x1e], mExtraFieldLength);
- ZipEntry::putShortLE(&buf[0x20], mFileCommentLength);
- ZipEntry::putShortLE(&buf[0x22], mDiskNumberStart);
- ZipEntry::putShortLE(&buf[0x24], mInternalAttrs);
- ZipEntry::putLongLE(&buf[0x26], mExternalAttrs);
- ZipEntry::putLongLE(&buf[0x2a], mLocalHeaderRelOffset);
-
- if (fwrite(buf, 1, kCDELen, fp) != kCDELen)
- return UNKNOWN_ERROR;
-
- /* write filename */
- if (mFileNameLength != 0) {
- if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)
- return UNKNOWN_ERROR;
- }
-
- /* write "extra field" */
- if (mExtraFieldLength != 0) {
- if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)
- return UNKNOWN_ERROR;
- }
-
- /* write comment */
- if (mFileCommentLength != 0) {
- if (fwrite(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)
- return UNKNOWN_ERROR;
- }
-
- return NO_ERROR;
-}
-
-/*
- * Dump the contents of a CentralDirEntry object.
- */
-void ZipEntry::CentralDirEntry::dump(void) const
-{
- LOGD(" CentralDirEntry contents:\n");
- LOGD(" versMadeBy=%u versToExt=%u gpBits=0x%04x compression=%u\n",
- mVersionMadeBy, mVersionToExtract, mGPBitFlag, mCompressionMethod);
- LOGD(" modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n",
- mLastModFileTime, mLastModFileDate, mCRC32);
- LOGD(" compressedSize=%lu uncompressedSize=%lu\n",
- mCompressedSize, mUncompressedSize);
- LOGD(" filenameLen=%u extraLen=%u commentLen=%u\n",
- mFileNameLength, mExtraFieldLength, mFileCommentLength);
- LOGD(" diskNumStart=%u intAttr=0x%04x extAttr=0x%08lx relOffset=%lu\n",
- mDiskNumberStart, mInternalAttrs, mExternalAttrs,
- mLocalHeaderRelOffset);
-
- if (mFileName != NULL)
- LOGD(" filename: '%s'\n", mFileName);
- if (mFileComment != NULL)
- LOGD(" comment: '%s'\n", mFileComment);
-}
-
diff --git a/libs/utils/ZipFile.cpp b/libs/utils/ZipFile.cpp
deleted file mode 100644
index 89aa874..0000000
--- a/libs/utils/ZipFile.cpp
+++ /dev/null
@@ -1,1296 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Access to Zip archives.
-//
-
-#define LOG_TAG "zip"
-
-#include "utils/ZipFile.h"
-#include "utils/ZipUtils.h"
-#include "utils/Log.h"
-
-#include <zlib.h>
-#define DEF_MEM_LEVEL 8 // normally in zutil.h?
-
-#include <memory.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <assert.h>
-
-using namespace android;
-
-/*
- * Some environments require the "b", some choke on it.
- */
-#define FILE_OPEN_RO "rb"
-#define FILE_OPEN_RW "r+b"
-#define FILE_OPEN_RW_CREATE "w+b"
-
-/* should live somewhere else? */
-static status_t errnoToStatus(int err)
-{
- if (err == ENOENT)
- return NAME_NOT_FOUND;
- else if (err == EACCES)
- return PERMISSION_DENIED;
- else
- return UNKNOWN_ERROR;
-}
-
-/*
- * Open a file and parse its guts.
- */
-status_t ZipFile::open(const char* zipFileName, int flags)
-{
- bool newArchive = false;
-
- assert(mZipFp == NULL); // no reopen
-
- if ((flags & kOpenTruncate))
- flags |= kOpenCreate; // trunc implies create
-
- if ((flags & kOpenReadOnly) && (flags & kOpenReadWrite))
- return INVALID_OPERATION; // not both
- if (!((flags & kOpenReadOnly) || (flags & kOpenReadWrite)))
- return INVALID_OPERATION; // not neither
- if ((flags & kOpenCreate) && !(flags & kOpenReadWrite))
- return INVALID_OPERATION; // create requires write
-
- if (flags & kOpenTruncate) {
- newArchive = true;
- } else {
- newArchive = (access(zipFileName, F_OK) != 0);
- if (!(flags & kOpenCreate) && newArchive) {
- /* not creating, must already exist */
- LOGD("File %s does not exist", zipFileName);
- return NAME_NOT_FOUND;
- }
- }
-
- /* open the file */
- const char* openflags;
- if (flags & kOpenReadWrite) {
- if (newArchive)
- openflags = FILE_OPEN_RW_CREATE;
- else
- openflags = FILE_OPEN_RW;
- } else {
- openflags = FILE_OPEN_RO;
- }
- mZipFp = fopen(zipFileName, openflags);
- if (mZipFp == NULL) {
- int err = errno;
- LOGD("fopen failed: %d\n", err);
- return errnoToStatus(err);
- }
-
- status_t result;
- if (!newArchive) {
- /*
- * Load the central directory. If that fails, then this probably
- * isn't a Zip archive.
- */
- result = readCentralDir();
- } else {
- /*
- * Newly-created. The EndOfCentralDir constructor actually
- * sets everything to be the way we want it (all zeroes). We
- * set mNeedCDRewrite so that we create *something* if the
- * caller doesn't add any files. (We could also just unlink
- * the file if it's brand new and nothing was added, but that's
- * probably doing more than we really should -- the user might
- * have a need for empty zip files.)
- */
- mNeedCDRewrite = true;
- result = NO_ERROR;
- }
-
- if (flags & kOpenReadOnly)
- mReadOnly = true;
- else
- assert(!mReadOnly);
-
- return result;
-}
-
-/*
- * Return the Nth entry in the archive.
- */
-ZipEntry* ZipFile::getEntryByIndex(int idx) const
-{
- if (idx < 0 || idx >= (int) mEntries.size())
- return NULL;
-
- return mEntries[idx];
-}
-
-/*
- * Find an entry by name.
- */
-ZipEntry* ZipFile::getEntryByName(const char* fileName) const
-{
- /*
- * Do a stupid linear string-compare search.
- *
- * There are various ways to speed this up, especially since it's rare
- * to intermingle changes to the archive with "get by name" calls. We
- * don't want to sort the mEntries vector itself, however, because
- * it's used to recreate the Central Directory.
- *
- * (Hash table works, parallel list of pointers in sorted order is good.)
- */
- int idx;
-
- for (idx = mEntries.size()-1; idx >= 0; idx--) {
- ZipEntry* pEntry = mEntries[idx];
- if (!pEntry->getDeleted() &&
- strcmp(fileName, pEntry->getFileName()) == 0)
- {
- return pEntry;
- }
- }
-
- return NULL;
-}
-
-/*
- * Empty the mEntries vector.
- */
-void ZipFile::discardEntries(void)
-{
- int count = mEntries.size();
-
- while (--count >= 0)
- delete mEntries[count];
-
- mEntries.clear();
-}
-
-
-/*
- * Find the central directory and read the contents.
- *
- * The fun thing about ZIP archives is that they may or may not be
- * readable from start to end. In some cases, notably for archives
- * that were written to stdout, the only length information is in the
- * central directory at the end of the file.
- *
- * Of course, the central directory can be followed by a variable-length
- * comment field, so we have to scan through it backwards. The comment
- * is at most 64K, plus we have 18 bytes for the end-of-central-dir stuff
- * itself, plus apparently sometimes people throw random junk on the end
- * just for the fun of it.
- *
- * This is all a little wobbly. If the wrong value ends up in the EOCD
- * area, we're hosed. This appears to be the way that everbody handles
- * it though, so we're in pretty good company if this fails.
- */
-status_t ZipFile::readCentralDir(void)
-{
- status_t result = NO_ERROR;
- unsigned char* buf = NULL;
- off_t fileLength, seekStart;
- long readAmount;
- int i;
-
- fseek(mZipFp, 0, SEEK_END);
- fileLength = ftell(mZipFp);
- rewind(mZipFp);
-
- /* too small to be a ZIP archive? */
- if (fileLength < EndOfCentralDir::kEOCDLen) {
- LOGD("Length is %ld -- too small\n", (long)fileLength);
- result = INVALID_OPERATION;
- goto bail;
- }
-
- buf = new unsigned char[EndOfCentralDir::kMaxEOCDSearch];
- if (buf == NULL) {
- LOGD("Failure allocating %d bytes for EOCD search",
- EndOfCentralDir::kMaxEOCDSearch);
- result = NO_MEMORY;
- goto bail;
- }
-
- if (fileLength > EndOfCentralDir::kMaxEOCDSearch) {
- seekStart = fileLength - EndOfCentralDir::kMaxEOCDSearch;
- readAmount = EndOfCentralDir::kMaxEOCDSearch;
- } else {
- seekStart = 0;
- readAmount = (long) fileLength;
- }
- if (fseek(mZipFp, seekStart, SEEK_SET) != 0) {
- LOGD("Failure seeking to end of zip at %ld", (long) seekStart);
- result = UNKNOWN_ERROR;
- goto bail;
- }
-
- /* read the last part of the file into the buffer */
- if (fread(buf, 1, readAmount, mZipFp) != (size_t) readAmount) {
- LOGD("short file? wanted %ld\n", readAmount);
- result = UNKNOWN_ERROR;
- goto bail;
- }
-
- /* find the end-of-central-dir magic */
- for (i = readAmount - 4; i >= 0; i--) {
- if (buf[i] == 0x50 &&
- ZipEntry::getLongLE(&buf[i]) == EndOfCentralDir::kSignature)
- {
- LOGV("+++ Found EOCD at buf+%d\n", i);
- break;
- }
- }
- if (i < 0) {
- LOGD("EOCD not found, not Zip\n");
- result = INVALID_OPERATION;
- goto bail;
- }
-
- /* extract eocd values */
- result = mEOCD.readBuf(buf + i, readAmount - i);
- if (result != NO_ERROR) {
- LOGD("Failure reading %ld bytes of EOCD values", readAmount - i);
- goto bail;
- }
- //mEOCD.dump();
-
- if (mEOCD.mDiskNumber != 0 || mEOCD.mDiskWithCentralDir != 0 ||
- mEOCD.mNumEntries != mEOCD.mTotalNumEntries)
- {
- LOGD("Archive spanning not supported\n");
- result = INVALID_OPERATION;
- goto bail;
- }
-
- /*
- * So far so good. "mCentralDirSize" is the size in bytes of the
- * central directory, so we can just seek back that far to find it.
- * We can also seek forward mCentralDirOffset bytes from the
- * start of the file.
- *
- * We're not guaranteed to have the rest of the central dir in the
- * buffer, nor are we guaranteed that the central dir will have any
- * sort of convenient size. We need to skip to the start of it and
- * read the header, then the other goodies.
- *
- * The only thing we really need right now is the file comment, which
- * we're hoping to preserve.
- */
- if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
- LOGD("Failure seeking to central dir offset %ld\n",
- mEOCD.mCentralDirOffset);
- result = UNKNOWN_ERROR;
- goto bail;
- }
-
- /*
- * Loop through and read the central dir entries.
- */
- LOGV("Scanning %d entries...\n", mEOCD.mTotalNumEntries);
- int entry;
- for (entry = 0; entry < mEOCD.mTotalNumEntries; entry++) {
- ZipEntry* pEntry = new ZipEntry;
-
- result = pEntry->initFromCDE(mZipFp);
- if (result != NO_ERROR) {
- LOGD("initFromCDE failed\n");
- delete pEntry;
- goto bail;
- }
-
- mEntries.add(pEntry);
- }
-
-
- /*
- * If all went well, we should now be back at the EOCD.
- */
- {
- unsigned char checkBuf[4];
- if (fread(checkBuf, 1, 4, mZipFp) != 4) {
- LOGD("EOCD check read failed\n");
- result = INVALID_OPERATION;
- goto bail;
- }
- if (ZipEntry::getLongLE(checkBuf) != EndOfCentralDir::kSignature) {
- LOGD("EOCD read check failed\n");
- result = UNKNOWN_ERROR;
- goto bail;
- }
- LOGV("+++ EOCD read check passed\n");
- }
-
-bail:
- delete[] buf;
- return result;
-}
-
-
-/*
- * Add a new file to the archive.
- *
- * This requires creating and populating a ZipEntry structure, and copying
- * the data into the file at the appropriate position. The "appropriate
- * position" is the current location of the central directory, which we
- * casually overwrite (we can put it back later).
- *
- * If we were concerned about safety, we would want to make all changes
- * in a temp file and then overwrite the original after everything was
- * safely written. Not really a concern for us.
- */
-status_t ZipFile::addCommon(const char* fileName, const void* data, size_t size,
- const char* storageName, int sourceType, int compressionMethod,
- ZipEntry** ppEntry)
-{
- ZipEntry* pEntry = NULL;
- status_t result = NO_ERROR;
- long lfhPosn, startPosn, endPosn, uncompressedLen;
- FILE* inputFp = NULL;
- unsigned long crc;
- time_t modWhen;
-
- if (mReadOnly)
- return INVALID_OPERATION;
-
- assert(compressionMethod == ZipEntry::kCompressDeflated ||
- compressionMethod == ZipEntry::kCompressStored);
-
- /* make sure we're in a reasonable state */
- assert(mZipFp != NULL);
- assert(mEntries.size() == mEOCD.mTotalNumEntries);
-
- /* make sure it doesn't already exist */
- if (getEntryByName(storageName) != NULL)
- return ALREADY_EXISTS;
-
- if (!data) {
- inputFp = fopen(fileName, FILE_OPEN_RO);
- if (inputFp == NULL)
- return errnoToStatus(errno);
- }
-
- if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
- result = UNKNOWN_ERROR;
- goto bail;
- }
-
- pEntry = new ZipEntry;
- pEntry->initNew(storageName, NULL);
-
- /*
- * From here on out, failures are more interesting.
- */
- mNeedCDRewrite = true;
-
- /*
- * Write the LFH, even though it's still mostly blank. We need it
- * as a place-holder. In theory the LFH isn't necessary, but in
- * practice some utilities demand it.
- */
- lfhPosn = ftell(mZipFp);
- pEntry->mLFH.write(mZipFp);
- startPosn = ftell(mZipFp);
-
- /*
- * Copy the data in, possibly compressing it as we go.
- */
- if (sourceType == ZipEntry::kCompressStored) {
- if (compressionMethod == ZipEntry::kCompressDeflated) {
- bool failed = false;
- result = compressFpToFp(mZipFp, inputFp, data, size, &crc);
- if (result != NO_ERROR) {
- LOGD("compression failed, storing\n");
- failed = true;
- } else {
- /*
- * Make sure it has compressed "enough". This probably ought
- * to be set through an API call, but I don't expect our
- * criteria to change over time.
- */
- long src = inputFp ? ftell(inputFp) : size;
- long dst = ftell(mZipFp) - startPosn;
- if (dst + (dst / 10) > src) {
- LOGD("insufficient compression (src=%ld dst=%ld), storing\n",
- src, dst);
- failed = true;
- }
- }
-
- if (failed) {
- compressionMethod = ZipEntry::kCompressStored;
- if (inputFp) rewind(inputFp);
- fseek(mZipFp, startPosn, SEEK_SET);
- /* fall through to kCompressStored case */
- }
- }
- /* handle "no compression" request, or failed compression from above */
- if (compressionMethod == ZipEntry::kCompressStored) {
- if (inputFp) {
- result = copyFpToFp(mZipFp, inputFp, &crc);
- } else {
- result = copyDataToFp(mZipFp, data, size, &crc);
- }
- if (result != NO_ERROR) {
- // don't need to truncate; happens in CDE rewrite
- LOGD("failed copying data in\n");
- goto bail;
- }
- }
-
- // currently seeked to end of file
- uncompressedLen = inputFp ? ftell(inputFp) : size;
- } else if (sourceType == ZipEntry::kCompressDeflated) {
- /* we should support uncompressed-from-compressed, but it's not
- * important right now */
- assert(compressionMethod == ZipEntry::kCompressDeflated);
-
- bool scanResult;
- int method;
- long compressedLen;
-
- scanResult = ZipUtils::examineGzip(inputFp, &method, &uncompressedLen,
- &compressedLen, &crc);
- if (!scanResult || method != ZipEntry::kCompressDeflated) {
- LOGD("this isn't a deflated gzip file?");
- result = UNKNOWN_ERROR;
- goto bail;
- }
-
- result = copyPartialFpToFp(mZipFp, inputFp, compressedLen, NULL);
- if (result != NO_ERROR) {
- LOGD("failed copying gzip data in\n");
- goto bail;
- }
- } else {
- assert(false);
- result = UNKNOWN_ERROR;
- goto bail;
- }
-
- /*
- * We could write the "Data Descriptor", but there doesn't seem to
- * be any point since we're going to go back and write the LFH.
- *
- * Update file offsets.
- */
- endPosn = ftell(mZipFp); // seeked to end of compressed data
-
- /*
- * Success! Fill out new values.
- */
- pEntry->setDataInfo(uncompressedLen, endPosn - startPosn, crc,
- compressionMethod);
- modWhen = getModTime(inputFp ? fileno(inputFp) : fileno(mZipFp));
- pEntry->setModWhen(modWhen);
- pEntry->setLFHOffset(lfhPosn);
- mEOCD.mNumEntries++;
- mEOCD.mTotalNumEntries++;
- mEOCD.mCentralDirSize = 0; // mark invalid; set by flush()
- mEOCD.mCentralDirOffset = endPosn;
-
- /*
- * Go back and write the LFH.
- */
- if (fseek(mZipFp, lfhPosn, SEEK_SET) != 0) {
- result = UNKNOWN_ERROR;
- goto bail;
- }
- pEntry->mLFH.write(mZipFp);
-
- /*
- * Add pEntry to the list.
- */
- mEntries.add(pEntry);
- if (ppEntry != NULL)
- *ppEntry = pEntry;
- pEntry = NULL;
-
-bail:
- if (inputFp != NULL)
- fclose(inputFp);
- delete pEntry;
- return result;
-}
-
-/*
- * Add an entry by copying it from another zip file. If "padding" is
- * nonzero, the specified number of bytes will be added to the "extra"
- * field in the header.
- *
- * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
- */
-status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
- int padding, ZipEntry** ppEntry)
-{
- ZipEntry* pEntry = NULL;
- status_t result;
- long lfhPosn, endPosn;
-
- if (mReadOnly)
- return INVALID_OPERATION;
-
- /* make sure we're in a reasonable state */
- assert(mZipFp != NULL);
- assert(mEntries.size() == mEOCD.mTotalNumEntries);
-
- if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
- result = UNKNOWN_ERROR;
- goto bail;
- }
-
- pEntry = new ZipEntry;
- if (pEntry == NULL) {
- result = NO_MEMORY;
- goto bail;
- }
-
- result = pEntry->initFromExternal(pSourceZip, pSourceEntry);
- if (result != NO_ERROR)
- goto bail;
- if (padding != 0) {
- result = pEntry->addPadding(padding);
- if (result != NO_ERROR)
- goto bail;
- }
-
- /*
- * From here on out, failures are more interesting.
- */
- mNeedCDRewrite = true;
-
- /*
- * Write the LFH. Since we're not recompressing the data, we already
- * have all of the fields filled out.
- */
- lfhPosn = ftell(mZipFp);
- pEntry->mLFH.write(mZipFp);
-
- /*
- * Copy the data over.
- *
- * If the "has data descriptor" flag is set, we want to copy the DD
- * fields as well. This is a fixed-size area immediately following
- * the data.
- */
- if (fseek(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0)
- {
- result = UNKNOWN_ERROR;
- goto bail;
- }
-
- off_t copyLen;
- copyLen = pSourceEntry->getCompressedLen();
- if ((pSourceEntry->mLFH.mGPBitFlag & ZipEntry::kUsesDataDescr) != 0)
- copyLen += ZipEntry::kDataDescriptorLen;
-
- if (copyPartialFpToFp(mZipFp, pSourceZip->mZipFp, copyLen, NULL)
- != NO_ERROR)
- {
- LOGW("copy of '%s' failed\n", pEntry->mCDE.mFileName);
- result = UNKNOWN_ERROR;
- goto bail;
- }
-
- /*
- * Update file offsets.
- */
- endPosn = ftell(mZipFp);
-
- /*
- * Success! Fill out new values.
- */
- pEntry->setLFHOffset(lfhPosn); // sets mCDE.mLocalHeaderRelOffset
- mEOCD.mNumEntries++;
- mEOCD.mTotalNumEntries++;
- mEOCD.mCentralDirSize = 0; // mark invalid; set by flush()
- mEOCD.mCentralDirOffset = endPosn;
-
- /*
- * Add pEntry to the list.
- */
- mEntries.add(pEntry);
- if (ppEntry != NULL)
- *ppEntry = pEntry;
- pEntry = NULL;
-
- result = NO_ERROR;
-
-bail:
- delete pEntry;
- return result;
-}
-
-/*
- * Copy all of the bytes in "src" to "dst".
- *
- * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
- * will be seeked immediately past the data.
- */
-status_t ZipFile::copyFpToFp(FILE* dstFp, FILE* srcFp, unsigned long* pCRC32)
-{
- unsigned char tmpBuf[32768];
- size_t count;
-
- *pCRC32 = crc32(0L, Z_NULL, 0);
-
- while (1) {
- count = fread(tmpBuf, 1, sizeof(tmpBuf), srcFp);
- if (ferror(srcFp) || ferror(dstFp))
- return errnoToStatus(errno);
- if (count == 0)
- break;
-
- *pCRC32 = crc32(*pCRC32, tmpBuf, count);
-
- if (fwrite(tmpBuf, 1, count, dstFp) != count) {
- LOGD("fwrite %d bytes failed\n", (int) count);
- return UNKNOWN_ERROR;
- }
- }
-
- return NO_ERROR;
-}
-
-/*
- * Copy all of the bytes in "src" to "dst".
- *
- * On exit, "dstFp" will be seeked immediately past the data.
- */
-status_t ZipFile::copyDataToFp(FILE* dstFp,
- const void* data, size_t size, unsigned long* pCRC32)
-{
- size_t count;
-
- *pCRC32 = crc32(0L, Z_NULL, 0);
- if (size > 0) {
- *pCRC32 = crc32(*pCRC32, (const unsigned char*)data, size);
- if (fwrite(data, 1, size, dstFp) != size) {
- LOGD("fwrite %d bytes failed\n", (int) size);
- return UNKNOWN_ERROR;
- }
- }
-
- return NO_ERROR;
-}
-
-/*
- * Copy some of the bytes in "src" to "dst".
- *
- * If "pCRC32" is NULL, the CRC will not be computed.
- *
- * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
- * will be seeked immediately past the data just written.
- */
-status_t ZipFile::copyPartialFpToFp(FILE* dstFp, FILE* srcFp, long length,
- unsigned long* pCRC32)
-{
- unsigned char tmpBuf[32768];
- size_t count;
-
- if (pCRC32 != NULL)
- *pCRC32 = crc32(0L, Z_NULL, 0);
-
- while (length) {
- long readSize;
-
- readSize = sizeof(tmpBuf);
- if (readSize > length)
- readSize = length;
-
- count = fread(tmpBuf, 1, readSize, srcFp);
- if ((long) count != readSize) { // error or unexpected EOF
- LOGD("fread %d bytes failed\n", (int) readSize);
- return UNKNOWN_ERROR;
- }
-
- if (pCRC32 != NULL)
- *pCRC32 = crc32(*pCRC32, tmpBuf, count);
-
- if (fwrite(tmpBuf, 1, count, dstFp) != count) {
- LOGD("fwrite %d bytes failed\n", (int) count);
- return UNKNOWN_ERROR;
- }
-
- length -= readSize;
- }
-
- return NO_ERROR;
-}
-
-/*
- * Compress all of the data in "srcFp" and write it to "dstFp".
- *
- * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
- * will be seeked immediately past the compressed data.
- */
-status_t ZipFile::compressFpToFp(FILE* dstFp, FILE* srcFp,
- const void* data, size_t size, unsigned long* pCRC32)
-{
- status_t result = NO_ERROR;
- const size_t kBufSize = 32768;
- unsigned char* inBuf = NULL;
- unsigned char* outBuf = NULL;
- z_stream zstream;
- bool atEof = false; // no feof() aviailable yet
- unsigned long crc;
- int zerr;
-
- /*
- * Create an input buffer and an output buffer.
- */
- inBuf = new unsigned char[kBufSize];
- outBuf = new unsigned char[kBufSize];
- if (inBuf == NULL || outBuf == NULL) {
- result = NO_MEMORY;
- goto bail;
- }
-
- /*
- * Initialize the zlib stream.
- */
- memset(&zstream, 0, sizeof(zstream));
- zstream.zalloc = Z_NULL;
- zstream.zfree = Z_NULL;
- zstream.opaque = Z_NULL;
- zstream.next_in = NULL;
- zstream.avail_in = 0;
- zstream.next_out = outBuf;
- zstream.avail_out = kBufSize;
- zstream.data_type = Z_UNKNOWN;
-
- zerr = deflateInit2(&zstream, Z_BEST_COMPRESSION,
- Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
- if (zerr != Z_OK) {
- result = UNKNOWN_ERROR;
- if (zerr == Z_VERSION_ERROR) {
- LOGE("Installed zlib is not compatible with linked version (%s)\n",
- ZLIB_VERSION);
- } else {
- LOGD("Call to deflateInit2 failed (zerr=%d)\n", zerr);
- }
- goto bail;
- }
-
- crc = crc32(0L, Z_NULL, 0);
-
- /*
- * Loop while we have data.
- */
- do {
- size_t getSize;
- int flush;
-
- /* only read if the input buffer is empty */
- if (zstream.avail_in == 0 && !atEof) {
- LOGV("+++ reading %d bytes\n", (int)kBufSize);
- if (data) {
- getSize = size > kBufSize ? kBufSize : size;
- memcpy(inBuf, data, getSize);
- data = ((const char*)data) + getSize;
- size -= getSize;
- } else {
- getSize = fread(inBuf, 1, kBufSize, srcFp);
- if (ferror(srcFp)) {
- LOGD("deflate read failed (errno=%d)\n", errno);
- goto z_bail;
- }
- }
- if (getSize < kBufSize) {
- LOGV("+++ got %d bytes, EOF reached\n",
- (int)getSize);
- atEof = true;
- }
-
- crc = crc32(crc, inBuf, getSize);
-
- zstream.next_in = inBuf;
- zstream.avail_in = getSize;
- }
-
- if (atEof)
- flush = Z_FINISH; /* tell zlib that we're done */
- else
- flush = Z_NO_FLUSH; /* more to come! */
-
- zerr = deflate(&zstream, flush);
- if (zerr != Z_OK && zerr != Z_STREAM_END) {
- LOGD("zlib deflate call failed (zerr=%d)\n", zerr);
- result = UNKNOWN_ERROR;
- goto z_bail;
- }
-
- /* write when we're full or when we're done */
- if (zstream.avail_out == 0 ||
- (zerr == Z_STREAM_END && zstream.avail_out != (uInt) kBufSize))
- {
- LOGV("+++ writing %d bytes\n", (int) (zstream.next_out - outBuf));
- if (fwrite(outBuf, 1, zstream.next_out - outBuf, dstFp) !=
- (size_t)(zstream.next_out - outBuf))
- {
- LOGD("write %d failed in deflate\n",
- (int) (zstream.next_out - outBuf));
- goto z_bail;
- }
-
- zstream.next_out = outBuf;
- zstream.avail_out = kBufSize;
- }
- } while (zerr == Z_OK);
-
- assert(zerr == Z_STREAM_END); /* other errors should've been caught */
-
- *pCRC32 = crc;
-
-z_bail:
- deflateEnd(&zstream); /* free up any allocated structures */
-
-bail:
- delete[] inBuf;
- delete[] outBuf;
-
- return result;
-}
-
-/*
- * Mark an entry as deleted.
- *
- * We will eventually need to crunch the file down, but if several files
- * are being removed (perhaps as part of an "update" process) we can make
- * things considerably faster by deferring the removal to "flush" time.
- */
-status_t ZipFile::remove(ZipEntry* pEntry)
-{
- /*
- * Should verify that pEntry is actually part of this archive, and
- * not some stray ZipEntry from a different file.
- */
-
- /* mark entry as deleted, and mark archive as dirty */
- pEntry->setDeleted();
- mNeedCDRewrite = true;
- return NO_ERROR;
-}
-
-/*
- * Flush any pending writes.
- *
- * In particular, this will crunch out deleted entries, and write the
- * Central Directory and EOCD if we have stomped on them.
- */
-status_t ZipFile::flush(void)
-{
- status_t result = NO_ERROR;
- long eocdPosn;
- int i, count;
-
- if (mReadOnly)
- return INVALID_OPERATION;
- if (!mNeedCDRewrite)
- return NO_ERROR;
-
- assert(mZipFp != NULL);
-
- result = crunchArchive();
- if (result != NO_ERROR)
- return result;
-
- if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0)
- return UNKNOWN_ERROR;
-
- count = mEntries.size();
- for (i = 0; i < count; i++) {
- ZipEntry* pEntry = mEntries[i];
- pEntry->mCDE.write(mZipFp);
- }
-
- eocdPosn = ftell(mZipFp);
- mEOCD.mCentralDirSize = eocdPosn - mEOCD.mCentralDirOffset;
-
- mEOCD.write(mZipFp);
-
- /*
- * If we had some stuff bloat up during compression and get replaced
- * with plain files, or if we deleted some entries, there's a lot
- * of wasted space at the end of the file. Remove it now.
- */
- if (ftruncate(fileno(mZipFp), ftell(mZipFp)) != 0) {
- LOGW("ftruncate failed %ld: %s\n", ftell(mZipFp), strerror(errno));
- // not fatal
- }
-
- /* should we clear the "newly added" flag in all entries now? */
-
- mNeedCDRewrite = false;
- return NO_ERROR;
-}
-
-/*
- * Crunch deleted files out of an archive by shifting the later files down.
- *
- * Because we're not using a temp file, we do the operation inside the
- * current file.
- */
-status_t ZipFile::crunchArchive(void)
-{
- status_t result = NO_ERROR;
- int i, count;
- long delCount, adjust;
-
-#if 0
- printf("CONTENTS:\n");
- for (i = 0; i < (int) mEntries.size(); i++) {
- printf(" %d: lfhOff=%ld del=%d\n",
- i, mEntries[i]->getLFHOffset(), mEntries[i]->getDeleted());
- }
- printf(" END is %ld\n", (long) mEOCD.mCentralDirOffset);
-#endif
-
- /*
- * Roll through the set of files, shifting them as appropriate. We
- * could probably get a slight performance improvement by sliding
- * multiple files down at once (because we could use larger reads
- * when operating on batches of small files), but it's not that useful.
- */
- count = mEntries.size();
- delCount = adjust = 0;
- for (i = 0; i < count; i++) {
- ZipEntry* pEntry = mEntries[i];
- long span;
-
- if (pEntry->getLFHOffset() != 0) {
- long nextOffset;
-
- /* Get the length of this entry by finding the offset
- * of the next entry. Directory entries don't have
- * file offsets, so we need to find the next non-directory
- * entry.
- */
- nextOffset = 0;
- for (int ii = i+1; nextOffset == 0 && ii < count; ii++)
- nextOffset = mEntries[ii]->getLFHOffset();
- if (nextOffset == 0)
- nextOffset = mEOCD.mCentralDirOffset;
- span = nextOffset - pEntry->getLFHOffset();
-
- assert(span >= ZipEntry::LocalFileHeader::kLFHLen);
- } else {
- /* This is a directory entry. It doesn't have
- * any actual file contents, so there's no need to
- * move anything.
- */
- span = 0;
- }
-
- //printf("+++ %d: off=%ld span=%ld del=%d [count=%d]\n",
- // i, pEntry->getLFHOffset(), span, pEntry->getDeleted(), count);
-
- if (pEntry->getDeleted()) {
- adjust += span;
- delCount++;
-
- delete pEntry;
- mEntries.removeAt(i);
-
- /* adjust loop control */
- count--;
- i--;
- } else if (span != 0 && adjust > 0) {
- /* shuffle this entry back */
- //printf("+++ Shuffling '%s' back %ld\n",
- // pEntry->getFileName(), adjust);
- result = filemove(mZipFp, pEntry->getLFHOffset() - adjust,
- pEntry->getLFHOffset(), span);
- if (result != NO_ERROR) {
- /* this is why you use a temp file */
- LOGE("error during crunch - archive is toast\n");
- return result;
- }
-
- pEntry->setLFHOffset(pEntry->getLFHOffset() - adjust);
- }
- }
-
- /*
- * Fix EOCD info. We have to wait until the end to do some of this
- * because we use mCentralDirOffset to determine "span" for the
- * last entry.
- */
- mEOCD.mCentralDirOffset -= adjust;
- mEOCD.mNumEntries -= delCount;
- mEOCD.mTotalNumEntries -= delCount;
- mEOCD.mCentralDirSize = 0; // mark invalid; set by flush()
-
- assert(mEOCD.mNumEntries == mEOCD.mTotalNumEntries);
- assert(mEOCD.mNumEntries == count);
-
- return result;
-}
-
-/*
- * Works like memmove(), but on pieces of a file.
- */
-status_t ZipFile::filemove(FILE* fp, off_t dst, off_t src, size_t n)
-{
- if (dst == src || n <= 0)
- return NO_ERROR;
-
- unsigned char readBuf[32768];
-
- if (dst < src) {
- /* shift stuff toward start of file; must read from start */
- while (n != 0) {
- size_t getSize = sizeof(readBuf);
- if (getSize > n)
- getSize = n;
-
- if (fseek(fp, (long) src, SEEK_SET) != 0) {
- LOGD("filemove src seek %ld failed\n", (long) src);
- return UNKNOWN_ERROR;
- }
-
- if (fread(readBuf, 1, getSize, fp) != getSize) {
- LOGD("filemove read %ld off=%ld failed\n",
- (long) getSize, (long) src);
- return UNKNOWN_ERROR;
- }
-
- if (fseek(fp, (long) dst, SEEK_SET) != 0) {
- LOGD("filemove dst seek %ld failed\n", (long) dst);
- return UNKNOWN_ERROR;
- }
-
- if (fwrite(readBuf, 1, getSize, fp) != getSize) {
- LOGD("filemove write %ld off=%ld failed\n",
- (long) getSize, (long) dst);
- return UNKNOWN_ERROR;
- }
-
- src += getSize;
- dst += getSize;
- n -= getSize;
- }
- } else {
- /* shift stuff toward end of file; must read from end */
- assert(false); // write this someday, maybe
- return UNKNOWN_ERROR;
- }
-
- return NO_ERROR;
-}
-
-
-/*
- * Get the modification time from a file descriptor.
- */
-time_t ZipFile::getModTime(int fd)
-{
- struct stat sb;
-
- if (fstat(fd, &sb) < 0) {
- LOGD("HEY: fstat on fd %d failed\n", fd);
- return (time_t) -1;
- }
-
- return sb.st_mtime;
-}
-
-
-#if 0 /* this is a bad idea */
-/*
- * Get a copy of the Zip file descriptor.
- *
- * We don't allow this if the file was opened read-write because we tend
- * to leave the file contents in an uncertain state between calls to
- * flush(). The duplicated file descriptor should only be valid for reads.
- */
-int ZipFile::getZipFd(void) const
-{
- if (!mReadOnly)
- return INVALID_OPERATION;
- assert(mZipFp != NULL);
-
- int fd;
- fd = dup(fileno(mZipFp));
- if (fd < 0) {
- LOGD("didn't work, errno=%d\n", errno);
- }
-
- return fd;
-}
-#endif
-
-
-#if 0
-/*
- * Expand data.
- */
-bool ZipFile::uncompress(const ZipEntry* pEntry, void* buf) const
-{
- return false;
-}
-#endif
-
-// free the memory when you're done
-void* ZipFile::uncompress(const ZipEntry* entry)
-{
- size_t unlen = entry->getUncompressedLen();
- size_t clen = entry->getCompressedLen();
-
- void* buf = malloc(unlen);
- if (buf == NULL) {
- return NULL;
- }
-
- fseek(mZipFp, 0, SEEK_SET);
-
- off_t offset = entry->getFileOffset();
- if (fseek(mZipFp, offset, SEEK_SET) != 0) {
- goto bail;
- }
-
- switch (entry->getCompressionMethod())
- {
- case ZipEntry::kCompressStored: {
- ssize_t amt = fread(buf, 1, unlen, mZipFp);
- if (amt != (ssize_t)unlen) {
- goto bail;
- }
-#if 0
- printf("data...\n");
- const unsigned char* p = (unsigned char*)buf;
- const unsigned char* end = p+unlen;
- for (int i=0; i<32 && p < end; i++) {
- printf("0x%08x ", (int)(offset+(i*0x10)));
- for (int j=0; j<0x10 && p < end; j++) {
- printf(" %02x", *p);
- p++;
- }
- printf("\n");
- }
-#endif
-
- }
- break;
- case ZipEntry::kCompressDeflated: {
- if (!ZipUtils::inflateToBuffer(mZipFp, buf, unlen, clen)) {
- goto bail;
- }
- }
- break;
- default:
- goto bail;
- }
- return buf;
-
-bail:
- free(buf);
- return NULL;
-}
-
-
-/*
- * ===========================================================================
- * ZipFile::EndOfCentralDir
- * ===========================================================================
- */
-
-/*
- * Read the end-of-central-dir fields.
- *
- * "buf" should be positioned at the EOCD signature, and should contain
- * the entire EOCD area including the comment.
- */
-status_t ZipFile::EndOfCentralDir::readBuf(const unsigned char* buf, int len)
-{
- /* don't allow re-use */
- assert(mComment == NULL);
-
- if (len < kEOCDLen) {
- /* looks like ZIP file got truncated */
- LOGD(" Zip EOCD: expected >= %d bytes, found %d\n",
- kEOCDLen, len);
- return INVALID_OPERATION;
- }
-
- /* this should probably be an assert() */
- if (ZipEntry::getLongLE(&buf[0x00]) != kSignature)
- return UNKNOWN_ERROR;
-
- mDiskNumber = ZipEntry::getShortLE(&buf[0x04]);
- mDiskWithCentralDir = ZipEntry::getShortLE(&buf[0x06]);
- mNumEntries = ZipEntry::getShortLE(&buf[0x08]);
- mTotalNumEntries = ZipEntry::getShortLE(&buf[0x0a]);
- mCentralDirSize = ZipEntry::getLongLE(&buf[0x0c]);
- mCentralDirOffset = ZipEntry::getLongLE(&buf[0x10]);
- mCommentLen = ZipEntry::getShortLE(&buf[0x14]);
-
- // TODO: validate mCentralDirOffset
-
- if (mCommentLen > 0) {
- if (kEOCDLen + mCommentLen > len) {
- LOGD("EOCD(%d) + comment(%d) exceeds len (%d)\n",
- kEOCDLen, mCommentLen, len);
- return UNKNOWN_ERROR;
- }
- mComment = new unsigned char[mCommentLen];
- memcpy(mComment, buf + kEOCDLen, mCommentLen);
- }
-
- return NO_ERROR;
-}
-
-/*
- * Write an end-of-central-directory section.
- */
-status_t ZipFile::EndOfCentralDir::write(FILE* fp)
-{
- unsigned char buf[kEOCDLen];
-
- ZipEntry::putLongLE(&buf[0x00], kSignature);
- ZipEntry::putShortLE(&buf[0x04], mDiskNumber);
- ZipEntry::putShortLE(&buf[0x06], mDiskWithCentralDir);
- ZipEntry::putShortLE(&buf[0x08], mNumEntries);
- ZipEntry::putShortLE(&buf[0x0a], mTotalNumEntries);
- ZipEntry::putLongLE(&buf[0x0c], mCentralDirSize);
- ZipEntry::putLongLE(&buf[0x10], mCentralDirOffset);
- ZipEntry::putShortLE(&buf[0x14], mCommentLen);
-
- if (fwrite(buf, 1, kEOCDLen, fp) != kEOCDLen)
- return UNKNOWN_ERROR;
- if (mCommentLen > 0) {
- assert(mComment != NULL);
- if (fwrite(mComment, mCommentLen, 1, fp) != mCommentLen)
- return UNKNOWN_ERROR;
- }
-
- return NO_ERROR;
-}
-
-/*
- * Dump the contents of an EndOfCentralDir object.
- */
-void ZipFile::EndOfCentralDir::dump(void) const
-{
- LOGD(" EndOfCentralDir contents:\n");
- LOGD(" diskNum=%u diskWCD=%u numEnt=%u totalNumEnt=%u\n",
- mDiskNumber, mDiskWithCentralDir, mNumEntries, mTotalNumEntries);
- LOGD(" centDirSize=%lu centDirOff=%lu commentLen=%u\n",
- mCentralDirSize, mCentralDirOffset, mCommentLen);
-}
-
diff --git a/libs/utils/ZipFileCRO.cpp b/libs/utils/ZipFileCRO.cpp
deleted file mode 100644
index d312daf..0000000
--- a/libs/utils/ZipFileCRO.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.
- */
-
-#include "utils/ZipFileCRO.h"
-#include "utils/ZipFileRO.h"
-
-using namespace android;
-
-ZipFileCRO ZipFileXRO_open(const char* path) {
- ZipFileRO* zip = new ZipFileRO();
- if (zip->open(path) == NO_ERROR) {
- return (ZipFileCRO)zip;
- }
- return NULL;
-}
-
-void ZipFileCRO_destroy(ZipFileCRO zipToken) {
- ZipFileRO* zip = (ZipFileRO*)zipToken;
- delete zip;
-}
-
-ZipEntryCRO ZipFileCRO_findEntryByName(ZipFileCRO zipToken,
- const char* fileName) {
- ZipFileRO* zip = (ZipFileRO*)zipToken;
- return (ZipEntryCRO)zip->findEntryByName(fileName);
-}
-
-bool ZipFileCRO_getEntryInfo(ZipFileCRO zipToken, ZipEntryRO entryToken,
- int* pMethod, long* pUncompLen,
- long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) {
- ZipFileRO* zip = (ZipFileRO*)zipToken;
- ZipEntryRO entry = (ZipEntryRO)entryToken;
- return zip->getEntryInfo(entry, pMethod, pUncompLen, pCompLen, pOffset,
- pModWhen, pCrc32);
-}
-
-bool ZipFileCRO_uncompressEntry(ZipFileCRO zipToken, ZipEntryRO entryToken, int fd) {
- ZipFileRO* zip = (ZipFileRO*)zipToken;
- ZipEntryRO entry = (ZipEntryRO)entryToken;
- return zip->uncompressEntry(entry, fd);
-}
diff --git a/libs/utils/ZipFileRO.cpp b/libs/utils/ZipFileRO.cpp
deleted file mode 100644
index ae8c719..0000000
--- a/libs/utils/ZipFileRO.cpp
+++ /dev/null
@@ -1,724 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Read-only access to Zip archives, with minimal heap allocation.
-//
-#define LOG_TAG "zipro"
-//#define LOG_NDEBUG 0
-#include "utils/ZipFileRO.h"
-#include "utils/Log.h"
-#include "utils/misc.h"
-
-#include <zlib.h>
-
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <assert.h>
-
-using namespace android;
-
-/*
- * Zip file constants.
- */
-#define kEOCDSignature 0x06054b50
-#define kEOCDLen 22
-#define kEOCDNumEntries 8 // offset to #of entries in file
-#define kEOCDFileOffset 16 // offset to central directory
-
-#define kMaxCommentLen 65535 // longest possible in ushort
-#define kMaxEOCDSearch (kMaxCommentLen + kEOCDLen)
-
-#define kLFHSignature 0x04034b50
-#define kLFHLen 30 // excluding variable-len fields
-#define kLFHNameLen 26 // offset to filename length
-#define kLFHExtraLen 28 // offset to extra length
-
-#define kCDESignature 0x02014b50
-#define kCDELen 46 // excluding variable-len fields
-#define kCDEMethod 10 // offset to compression method
-#define kCDEModWhen 12 // offset to modification timestamp
-#define kCDECRC 16 // offset to entry CRC
-#define kCDECompLen 20 // offset to compressed length
-#define kCDEUncompLen 24 // offset to uncompressed length
-#define kCDENameLen 28 // offset to filename length
-#define kCDEExtraLen 30 // offset to extra length
-#define kCDECommentLen 32 // offset to comment length
-#define kCDELocalOffset 42 // offset to local hdr
-
-/*
- * The values we return for ZipEntryRO use 0 as an invalid value, so we
- * want to adjust the hash table index by a fixed amount. Using a large
- * value helps insure that people don't mix & match arguments, e.g. to
- * findEntryByIndex().
- */
-#define kZipEntryAdj 10000
-
-/*
- * Convert a ZipEntryRO to a hash table index, verifying that it's in a
- * valid range.
- */
-int ZipFileRO::entryToIndex(const ZipEntryRO entry) const
-{
- long ent = ((long) entry) - kZipEntryAdj;
- if (ent < 0 || ent >= mHashTableSize || mHashTable[ent].name == NULL) {
- LOGW("Invalid ZipEntryRO %p (%ld)\n", entry, ent);
- return -1;
- }
- return ent;
-}
-
-
-/*
- * Open the specified file read-only. We memory-map the entire thing and
- * close the file before returning.
- */
-status_t ZipFileRO::open(const char* zipFileName)
-{
- int fd = -1;
- off_t length;
-
- assert(mFileMap == NULL);
-
- /*
- * Open and map the specified file.
- */
- fd = ::open(zipFileName, O_RDONLY);
- if (fd < 0) {
- LOGW("Unable to open zip '%s': %s\n", zipFileName, strerror(errno));
- return NAME_NOT_FOUND;
- }
-
- length = lseek(fd, 0, SEEK_END);
- if (length < 0) {
- close(fd);
- return UNKNOWN_ERROR;
- }
-
- mFileMap = new FileMap();
- if (mFileMap == NULL) {
- close(fd);
- return NO_MEMORY;
- }
- if (!mFileMap->create(zipFileName, fd, 0, length, true)) {
- LOGW("Unable to map '%s': %s\n", zipFileName, strerror(errno));
- close(fd);
- return UNKNOWN_ERROR;
- }
-
- mFd = fd;
-
- /*
- * Got it mapped, verify it and create data structures for fast access.
- */
- if (!parseZipArchive()) {
- mFileMap->release();
- mFileMap = NULL;
- return UNKNOWN_ERROR;
- }
-
- return OK;
-}
-
-/*
- * Parse the Zip archive, verifying its contents and initializing internal
- * data structures.
- */
-bool ZipFileRO::parseZipArchive(void)
-{
-#define CHECK_OFFSET(_off) { \
- if ((unsigned int) (_off) >= maxOffset) { \
- LOGE("ERROR: bad offset %u (max %d): %s\n", \
- (unsigned int) (_off), maxOffset, #_off); \
- goto bail; \
- } \
- }
- const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
- const unsigned char* ptr;
- size_t length = mFileMap->getDataLength();
- bool result = false;
- unsigned int i, numEntries, cdOffset;
- unsigned int val;
-
- /*
- * The first 4 bytes of the file will either be the local header
- * signature for the first file (kLFHSignature) or, if the archive doesn't
- * have any files in it, the end-of-central-directory signature
- * (kEOCDSignature).
- */
- val = get4LE(basePtr);
- if (val == kEOCDSignature) {
- LOGI("Found Zip archive, but it looks empty\n");
- goto bail;
- } else if (val != kLFHSignature) {
- LOGV("Not a Zip archive (found 0x%08x)\n", val);
- goto bail;
- }
-
- /*
- * Find the EOCD. We'll find it immediately unless they have a file
- * comment.
- */
- ptr = basePtr + length - kEOCDLen;
-
- while (ptr >= basePtr) {
- if (*ptr == (kEOCDSignature & 0xff) && get4LE(ptr) == kEOCDSignature)
- break;
- ptr--;
- }
- if (ptr < basePtr) {
- LOGI("Could not find end-of-central-directory in Zip\n");
- goto bail;
- }
-
- /*
- * There are two interesting items in the EOCD block: the number of
- * entries in the file, and the file offset of the start of the
- * central directory.
- *
- * (There's actually a count of the #of entries in this file, and for
- * all files which comprise a spanned archive, but for our purposes
- * we're only interested in the current file. Besides, we expect the
- * two to be equivalent for our stuff.)
- */
- numEntries = get2LE(ptr + kEOCDNumEntries);
- cdOffset = get4LE(ptr + kEOCDFileOffset);
-
- /* valid offsets are [0,EOCD] */
- unsigned int maxOffset;
- maxOffset = (ptr - basePtr) +1;
-
- LOGV("+++ numEntries=%d cdOffset=%d\n", numEntries, cdOffset);
- if (numEntries == 0 || cdOffset >= length) {
- LOGW("Invalid entries=%d offset=%d (len=%zd)\n",
- numEntries, cdOffset, length);
- goto bail;
- }
-
- /*
- * Create hash table. We have a minimum 75% load factor, possibly as
- * low as 50% after we round off to a power of 2.
- */
- mNumEntries = numEntries;
- mHashTableSize = roundUpPower2(1 + ((numEntries * 4) / 3));
- mHashTable = (HashEntry*) calloc(1, sizeof(HashEntry) * mHashTableSize);
-
- /*
- * Walk through the central directory, adding entries to the hash
- * table.
- */
- ptr = basePtr + cdOffset;
- for (i = 0; i < numEntries; i++) {
- unsigned int fileNameLen, extraLen, commentLen, localHdrOffset;
- const unsigned char* localHdr;
- unsigned int hash;
-
- if (get4LE(ptr) != kCDESignature) {
- LOGW("Missed a central dir sig (at %d)\n", i);
- goto bail;
- }
- if (ptr + kCDELen > basePtr + length) {
- LOGW("Ran off the end (at %d)\n", i);
- goto bail;
- }
-
- localHdrOffset = get4LE(ptr + kCDELocalOffset);
- CHECK_OFFSET(localHdrOffset);
- fileNameLen = get2LE(ptr + kCDENameLen);
- extraLen = get2LE(ptr + kCDEExtraLen);
- commentLen = get2LE(ptr + kCDECommentLen);
-
- //LOGV("+++ %d: localHdr=%d fnl=%d el=%d cl=%d\n",
- // i, localHdrOffset, fileNameLen, extraLen, commentLen);
- //LOGV(" '%.*s'\n", fileNameLen, ptr + kCDELen);
-
- /* add the CDE filename to the hash table */
- hash = computeHash((const char*)ptr + kCDELen, fileNameLen);
- addToHash((const char*)ptr + kCDELen, fileNameLen, hash);
-
- localHdr = basePtr + localHdrOffset;
- if (get4LE(localHdr) != kLFHSignature) {
- LOGW("Bad offset to local header: %d (at %d)\n",
- localHdrOffset, i);
- goto bail;
- }
-
- ptr += kCDELen + fileNameLen + extraLen + commentLen;
- CHECK_OFFSET(ptr - basePtr);
- }
-
- result = true;
-
-bail:
- return result;
-#undef CHECK_OFFSET
-}
-
-
-/*
- * Simple string hash function for non-null-terminated strings.
- */
-/*static*/ unsigned int ZipFileRO::computeHash(const char* str, int len)
-{
- unsigned int hash = 0;
-
- while (len--)
- hash = hash * 31 + *str++;
-
- return hash;
-}
-
-/*
- * Add a new entry to the hash table.
- */
-void ZipFileRO::addToHash(const char* str, int strLen, unsigned int hash)
-{
- int ent = hash & (mHashTableSize-1);
-
- /*
- * We over-allocate the table, so we're guaranteed to find an empty slot.
- */
- while (mHashTable[ent].name != NULL)
- ent = (ent + 1) & (mHashTableSize-1);
-
- mHashTable[ent].name = str;
- mHashTable[ent].nameLen = strLen;
-}
-
-/*
- * Find a matching entry.
- *
- * Returns 0 if not found.
- */
-ZipEntryRO ZipFileRO::findEntryByName(const char* fileName) const
-{
- int nameLen = strlen(fileName);
- unsigned int hash = computeHash(fileName, nameLen);
- int ent = hash & (mHashTableSize-1);
-
- while (mHashTable[ent].name != NULL) {
- if (mHashTable[ent].nameLen == nameLen &&
- memcmp(mHashTable[ent].name, fileName, nameLen) == 0)
- {
- /* match */
- return (ZipEntryRO) (ent + kZipEntryAdj);
- }
-
- ent = (ent + 1) & (mHashTableSize-1);
- }
-
- return NULL;
-}
-
-/*
- * Find the Nth entry.
- *
- * This currently involves walking through the sparse hash table, counting
- * non-empty entries. If we need to speed this up we can either allocate
- * a parallel lookup table or (perhaps better) provide an iterator interface.
- */
-ZipEntryRO ZipFileRO::findEntryByIndex(int idx) const
-{
- if (idx < 0 || idx >= mNumEntries) {
- LOGW("Invalid index %d\n", idx);
- return NULL;
- }
-
- for (int ent = 0; ent < mHashTableSize; ent++) {
- if (mHashTable[ent].name != NULL) {
- if (idx-- == 0)
- return (ZipEntryRO) (ent + kZipEntryAdj);
- }
- }
-
- return NULL;
-}
-
-/*
- * Get the useful fields from the zip entry.
- *
- * Returns "false" if the offsets to the fields or the contents of the fields
- * appear to be bogus.
- */
-bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, long* pUncompLen,
- long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const
-{
- int ent = entryToIndex(entry);
- if (ent < 0)
- return false;
-
- /*
- * Recover the start of the central directory entry from the filename
- * pointer.
- */
- const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
- const unsigned char* ptr = (const unsigned char*) mHashTable[ent].name;
- size_t zipLength = mFileMap->getDataLength();
-
- ptr -= kCDELen;
-
- int method = get2LE(ptr + kCDEMethod);
- if (pMethod != NULL)
- *pMethod = method;
-
- if (pModWhen != NULL)
- *pModWhen = get4LE(ptr + kCDEModWhen);
- if (pCrc32 != NULL)
- *pCrc32 = get4LE(ptr + kCDECRC);
-
- /*
- * We need to make sure that the lengths are not so large that somebody
- * trying to map the compressed or uncompressed data runs off the end
- * of the mapped region.
- */
- unsigned long localHdrOffset = get4LE(ptr + kCDELocalOffset);
- if (localHdrOffset + kLFHLen >= zipLength) {
- LOGE("ERROR: bad local hdr offset in zip\n");
- return false;
- }
- const unsigned char* localHdr = basePtr + localHdrOffset;
- off_t dataOffset = localHdrOffset + kLFHLen
- + get2LE(localHdr + kLFHNameLen) + get2LE(localHdr + kLFHExtraLen);
- if ((unsigned long) dataOffset >= zipLength) {
- LOGE("ERROR: bad data offset in zip\n");
- return false;
- }
-
- if (pCompLen != NULL) {
- *pCompLen = get4LE(ptr + kCDECompLen);
- if (*pCompLen < 0 || (size_t)(dataOffset + *pCompLen) >= zipLength) {
- LOGE("ERROR: bad compressed length in zip\n");
- return false;
- }
- }
- if (pUncompLen != NULL) {
- *pUncompLen = get4LE(ptr + kCDEUncompLen);
- if (*pUncompLen < 0) {
- LOGE("ERROR: negative uncompressed length in zip\n");
- return false;
- }
- if (method == kCompressStored &&
- (size_t)(dataOffset + *pUncompLen) >= zipLength)
- {
- LOGE("ERROR: bad uncompressed length in zip\n");
- return false;
- }
- }
-
- if (pOffset != NULL) {
- *pOffset = dataOffset;
- }
- return true;
-}
-
-/*
- * Copy the entry's filename to the buffer.
- */
-int ZipFileRO::getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen)
- const
-{
- int ent = entryToIndex(entry);
- if (ent < 0)
- return -1;
-
- int nameLen = mHashTable[ent].nameLen;
- if (bufLen < nameLen+1)
- return nameLen+1;
-
- memcpy(buffer, mHashTable[ent].name, nameLen);
- buffer[nameLen] = '\0';
- return 0;
-}
-
-/*
- * Create a new FileMap object that spans the data in "entry".
- */
-FileMap* ZipFileRO::createEntryFileMap(ZipEntryRO entry) const
-{
- /*
- * TODO: the efficient way to do this is to modify FileMap to allow
- * sub-regions of a file to be mapped. A reference-counting scheme
- * can manage the base memory mapping. For now, we just create a brand
- * new mapping off of the Zip archive file descriptor.
- */
-
- FileMap* newMap;
- long compLen;
- off_t offset;
-
- if (!getEntryInfo(entry, NULL, NULL, &compLen, &offset, NULL, NULL))
- return NULL;
-
- newMap = new FileMap();
- if (!newMap->create(mFileMap->getFileName(), mFd, offset, compLen, true)) {
- newMap->release();
- return NULL;
- }
-
- return newMap;
-}
-
-/*
- * Uncompress an entry, in its entirety, into the provided output buffer.
- *
- * This doesn't verify the data's CRC, which might be useful for
- * uncompressed data. The caller should be able to manage it.
- */
-bool ZipFileRO::uncompressEntry(ZipEntryRO entry, void* buffer) const
-{
- const int kSequentialMin = 32768;
- bool result = false;
- int ent = entryToIndex(entry);
- if (ent < 0)
- return -1;
-
- const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
- int method;
- long uncompLen, compLen;
- off_t offset;
-
- getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
-
- /*
- * Experiment with madvise hint. When we want to uncompress a file,
- * we pull some stuff out of the central dir entry and then hit a
- * bunch of compressed or uncompressed data sequentially. The CDE
- * visit will cause a limited amount of read-ahead because it's at
- * the end of the file. We could end up doing lots of extra disk
- * access if the file we're prying open is small. Bottom line is we
- * probably don't want to turn MADV_SEQUENTIAL on and leave it on.
- *
- * So, if the compressed size of the file is above a certain minimum
- * size, temporarily boost the read-ahead in the hope that the extra
- * pair of system calls are negated by a reduction in page faults.
- */
- if (compLen > kSequentialMin)
- mFileMap->advise(FileMap::SEQUENTIAL);
-
- if (method == kCompressStored) {
- memcpy(buffer, basePtr + offset, uncompLen);
- } else {
- if (!inflateBuffer(buffer, basePtr + offset, uncompLen, compLen))
- goto bail;
- }
-
- if (compLen > kSequentialMin)
- mFileMap->advise(FileMap::NORMAL);
-
- result = true;
-
-bail:
- return result;
-}
-
-/*
- * Uncompress an entry, in its entirety, to an open file descriptor.
- *
- * This doesn't verify the data's CRC, but probably should.
- */
-bool ZipFileRO::uncompressEntry(ZipEntryRO entry, int fd) const
-{
- bool result = false;
- int ent = entryToIndex(entry);
- if (ent < 0)
- return -1;
-
- const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
- int method;
- long uncompLen, compLen;
- off_t offset;
-
- getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
-
- if (method == kCompressStored) {
- ssize_t actual;
-
- actual = write(fd, basePtr + offset, uncompLen);
- if (actual < 0) {
- LOGE("Write failed: %s\n", strerror(errno));
- goto bail;
- } else if (actual != uncompLen) {
- LOGE("Partial write during uncompress (%d of %ld)\n",
- (int)actual, uncompLen);
- goto bail;
- } else {
- LOGI("+++ successful write\n");
- }
- } else {
- if (!inflateBuffer(fd, basePtr+offset, uncompLen, compLen))
- goto bail;
- }
-
- result = true;
-
-bail:
- return result;
-}
-
-/*
- * Uncompress "deflate" data from one buffer to another.
- */
-/*static*/ bool ZipFileRO::inflateBuffer(void* outBuf, const void* inBuf,
- long uncompLen, long compLen)
-{
- bool result = false;
- z_stream zstream;
- int zerr;
-
- /*
- * Initialize the zlib stream struct.
- */
- memset(&zstream, 0, sizeof(zstream));
- zstream.zalloc = Z_NULL;
- zstream.zfree = Z_NULL;
- zstream.opaque = Z_NULL;
- zstream.next_in = (Bytef*)inBuf;
- zstream.avail_in = compLen;
- zstream.next_out = (Bytef*) outBuf;
- zstream.avail_out = uncompLen;
- zstream.data_type = Z_UNKNOWN;
-
- /*
- * Use the undocumented "negative window bits" feature to tell zlib
- * that there's no zlib header waiting for it.
- */
- zerr = inflateInit2(&zstream, -MAX_WBITS);
- if (zerr != Z_OK) {
- if (zerr == Z_VERSION_ERROR) {
- LOGE("Installed zlib is not compatible with linked version (%s)\n",
- ZLIB_VERSION);
- } else {
- LOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
- }
- goto bail;
- }
-
- /*
- * Expand data.
- */
- zerr = inflate(&zstream, Z_FINISH);
- if (zerr != Z_STREAM_END) {
- LOGW("Zip inflate failed, zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)\n",
- zerr, zstream.next_in, zstream.avail_in,
- zstream.next_out, zstream.avail_out);
- goto z_bail;
- }
-
- /* paranoia */
- if ((long) zstream.total_out != uncompLen) {
- LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
- zstream.total_out, uncompLen);
- goto z_bail;
- }
-
- result = true;
-
-z_bail:
- inflateEnd(&zstream); /* free up any allocated structures */
-
-bail:
- return result;
-}
-
-/*
- * Uncompress "deflate" data from one buffer to an open file descriptor.
- */
-/*static*/ bool ZipFileRO::inflateBuffer(int fd, const void* inBuf,
- long uncompLen, long compLen)
-{
- bool result = false;
- const int kWriteBufSize = 32768;
- unsigned char writeBuf[kWriteBufSize];
- z_stream zstream;
- int zerr;
-
- /*
- * Initialize the zlib stream struct.
- */
- memset(&zstream, 0, sizeof(zstream));
- zstream.zalloc = Z_NULL;
- zstream.zfree = Z_NULL;
- zstream.opaque = Z_NULL;
- zstream.next_in = (Bytef*)inBuf;
- zstream.avail_in = compLen;
- zstream.next_out = (Bytef*) writeBuf;
- zstream.avail_out = sizeof(writeBuf);
- zstream.data_type = Z_UNKNOWN;
-
- /*
- * Use the undocumented "negative window bits" feature to tell zlib
- * that there's no zlib header waiting for it.
- */
- zerr = inflateInit2(&zstream, -MAX_WBITS);
- if (zerr != Z_OK) {
- if (zerr == Z_VERSION_ERROR) {
- LOGE("Installed zlib is not compatible with linked version (%s)\n",
- ZLIB_VERSION);
- } else {
- LOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
- }
- goto bail;
- }
-
- /*
- * Loop while we have more to do.
- */
- do {
- /*
- * Expand data.
- */
- zerr = inflate(&zstream, Z_NO_FLUSH);
- if (zerr != Z_OK && zerr != Z_STREAM_END) {
- LOGW("zlib inflate: zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)\n",
- zerr, zstream.next_in, zstream.avail_in,
- zstream.next_out, zstream.avail_out);
- goto z_bail;
- }
-
- /* write when we're full or when we're done */
- if (zstream.avail_out == 0 ||
- (zerr == Z_STREAM_END && zstream.avail_out != sizeof(writeBuf)))
- {
- long writeSize = zstream.next_out - writeBuf;
- int cc = write(fd, writeBuf, writeSize);
- if (cc != (int) writeSize) {
- LOGW("write failed in inflate (%d vs %ld)\n", cc, writeSize);
- goto z_bail;
- }
-
- zstream.next_out = writeBuf;
- zstream.avail_out = sizeof(writeBuf);
- }
- } while (zerr == Z_OK);
-
- assert(zerr == Z_STREAM_END); /* other errors should've been caught */
-
- /* paranoia */
- if ((long) zstream.total_out != uncompLen) {
- LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
- zstream.total_out, uncompLen);
- goto z_bail;
- }
-
- result = true;
-
-z_bail:
- inflateEnd(&zstream); /* free up any allocated structures */
-
-bail:
- return result;
-}
diff --git a/libs/utils/ZipUtils.cpp b/libs/utils/ZipUtils.cpp
deleted file mode 100644
index bfbacfe..0000000
--- a/libs/utils/ZipUtils.cpp
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Misc zip/gzip utility functions.
-//
-
-#define LOG_TAG "ziputil"
-
-#include "utils/ZipUtils.h"
-#include "utils/ZipFileRO.h"
-#include "utils/Log.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include <zlib.h>
-
-using namespace android;
-
-/*
- * Utility function that expands zip/gzip "deflate" compressed data
- * into a buffer.
- *
- * "fd" is an open file positioned at the start of the "deflate" data
- * "buf" must hold at least "uncompressedLen" bytes.
- */
-/*static*/ bool ZipUtils::inflateToBuffer(int fd, void* buf,
- long uncompressedLen, long compressedLen)
-{
- bool result = false;
- const unsigned long kReadBufSize = 32768;
- unsigned char* readBuf = NULL;
- z_stream zstream;
- int zerr;
- unsigned long compRemaining;
-
- assert(uncompressedLen >= 0);
- assert(compressedLen >= 0);
-
- readBuf = new unsigned char[kReadBufSize];
- if (readBuf == NULL)
- goto bail;
- compRemaining = compressedLen;
-
- /*
- * Initialize the zlib stream.
- */
- memset(&zstream, 0, sizeof(zstream));
- zstream.zalloc = Z_NULL;
- zstream.zfree = Z_NULL;
- zstream.opaque = Z_NULL;
- zstream.next_in = NULL;
- zstream.avail_in = 0;
- zstream.next_out = (Bytef*) buf;
- zstream.avail_out = uncompressedLen;
- zstream.data_type = Z_UNKNOWN;
-
- /*
- * Use the undocumented "negative window bits" feature to tell zlib
- * that there's no zlib header waiting for it.
- */
- zerr = inflateInit2(&zstream, -MAX_WBITS);
- if (zerr != Z_OK) {
- if (zerr == Z_VERSION_ERROR) {
- LOGE("Installed zlib is not compatible with linked version (%s)\n",
- ZLIB_VERSION);
- } else {
- LOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
- }
- goto bail;
- }
-
- /*
- * Loop while we have data.
- */
- do {
- unsigned long getSize;
-
- /* read as much as we can */
- if (zstream.avail_in == 0) {
- getSize = (compRemaining > kReadBufSize) ?
- kReadBufSize : compRemaining;
- LOGV("+++ reading %ld bytes (%ld left)\n",
- getSize, compRemaining);
-
- int cc = read(fd, readBuf, getSize);
- if (cc != (int) getSize) {
- LOGD("inflate read failed (%d vs %ld)\n",
- cc, getSize);
- goto z_bail;
- }
-
- compRemaining -= getSize;
-
- zstream.next_in = readBuf;
- zstream.avail_in = getSize;
- }
-
- /* uncompress the data */
- zerr = inflate(&zstream, Z_NO_FLUSH);
- if (zerr != Z_OK && zerr != Z_STREAM_END) {
- LOGD("zlib inflate call failed (zerr=%d)\n", zerr);
- goto z_bail;
- }
-
- /* output buffer holds all, so no need to write the output */
- } while (zerr == Z_OK);
-
- assert(zerr == Z_STREAM_END); /* other errors should've been caught */
-
- if ((long) zstream.total_out != uncompressedLen) {
- LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
- zstream.total_out, uncompressedLen);
- goto z_bail;
- }
-
- // success!
- result = true;
-
-z_bail:
- inflateEnd(&zstream); /* free up any allocated structures */
-
-bail:
- delete[] readBuf;
- return result;
-}
-
-/*
- * Utility function that expands zip/gzip "deflate" compressed data
- * into a buffer.
- *
- * (This is a clone of the previous function, but it takes a FILE* instead
- * of an fd. We could pass fileno(fd) to the above, but we can run into
- * trouble when "fp" has a different notion of what fd's file position is.)
- *
- * "fp" is an open file positioned at the start of the "deflate" data
- * "buf" must hold at least "uncompressedLen" bytes.
- */
-/*static*/ bool ZipUtils::inflateToBuffer(FILE* fp, void* buf,
- long uncompressedLen, long compressedLen)
-{
- bool result = false;
- const unsigned long kReadBufSize = 32768;
- unsigned char* readBuf = NULL;
- z_stream zstream;
- int zerr;
- unsigned long compRemaining;
-
- assert(uncompressedLen >= 0);
- assert(compressedLen >= 0);
-
- readBuf = new unsigned char[kReadBufSize];
- if (readBuf == NULL)
- goto bail;
- compRemaining = compressedLen;
-
- /*
- * Initialize the zlib stream.
- */
- memset(&zstream, 0, sizeof(zstream));
- zstream.zalloc = Z_NULL;
- zstream.zfree = Z_NULL;
- zstream.opaque = Z_NULL;
- zstream.next_in = NULL;
- zstream.avail_in = 0;
- zstream.next_out = (Bytef*) buf;
- zstream.avail_out = uncompressedLen;
- zstream.data_type = Z_UNKNOWN;
-
- /*
- * Use the undocumented "negative window bits" feature to tell zlib
- * that there's no zlib header waiting for it.
- */
- zerr = inflateInit2(&zstream, -MAX_WBITS);
- if (zerr != Z_OK) {
- if (zerr == Z_VERSION_ERROR) {
- LOGE("Installed zlib is not compatible with linked version (%s)\n",
- ZLIB_VERSION);
- } else {
- LOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
- }
- goto bail;
- }
-
- /*
- * Loop while we have data.
- */
- do {
- unsigned long getSize;
-
- /* read as much as we can */
- if (zstream.avail_in == 0) {
- getSize = (compRemaining > kReadBufSize) ?
- kReadBufSize : compRemaining;
- LOGV("+++ reading %ld bytes (%ld left)\n",
- getSize, compRemaining);
-
- int cc = fread(readBuf, getSize, 1, fp);
- if (cc != (int) getSize) {
- LOGD("inflate read failed (%d vs %ld)\n",
- cc, getSize);
- goto z_bail;
- }
-
- compRemaining -= getSize;
-
- zstream.next_in = readBuf;
- zstream.avail_in = getSize;
- }
-
- /* uncompress the data */
- zerr = inflate(&zstream, Z_NO_FLUSH);
- if (zerr != Z_OK && zerr != Z_STREAM_END) {
- LOGD("zlib inflate call failed (zerr=%d)\n", zerr);
- goto z_bail;
- }
-
- /* output buffer holds all, so no need to write the output */
- } while (zerr == Z_OK);
-
- assert(zerr == Z_STREAM_END); /* other errors should've been caught */
-
- if ((long) zstream.total_out != uncompressedLen) {
- LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
- zstream.total_out, uncompressedLen);
- goto z_bail;
- }
-
- // success!
- result = true;
-
-z_bail:
- inflateEnd(&zstream); /* free up any allocated structures */
-
-bail:
- delete[] readBuf;
- return result;
-}
-
-/*
- * Look at the contents of a gzip archive. We want to know where the
- * data starts, and how long it will be after it is uncompressed.
- *
- * We expect to find the CRC and length as the last 8 bytes on the file.
- * This is a pretty reasonable thing to expect for locally-compressed
- * files, but there's a small chance that some extra padding got thrown
- * on (the man page talks about compressed data written to tape). We
- * don't currently deal with that here. If "gzip -l" whines, we're going
- * to fail too.
- *
- * On exit, "fp" is pointing at the start of the compressed data.
- */
-/*static*/ bool ZipUtils::examineGzip(FILE* fp, int* pCompressionMethod,
- long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32)
-{
- enum { // flags
- FTEXT = 0x01,
- FHCRC = 0x02,
- FEXTRA = 0x04,
- FNAME = 0x08,
- FCOMMENT = 0x10,
- };
- int ic;
- int method, flags;
- int i;
-
- ic = getc(fp);
- if (ic != 0x1f || getc(fp) != 0x8b)
- return false; // not gzip
- method = getc(fp);
- flags = getc(fp);
-
- /* quick sanity checks */
- if (method == EOF || flags == EOF)
- return false;
- if (method != ZipFileRO::kCompressDeflated)
- return false;
-
- /* skip over 4 bytes of mod time, 1 byte XFL, 1 byte OS */
- for (i = 0; i < 6; i++)
- (void) getc(fp);
- /* consume "extra" field, if present */
- if ((flags & FEXTRA) != 0) {
- int len;
-
- len = getc(fp);
- len |= getc(fp) << 8;
- while (len-- && getc(fp) != EOF)
- ;
- }
- /* consume filename, if present */
- if ((flags & FNAME) != 0) {
- do {
- ic = getc(fp);
- } while (ic != 0 && ic != EOF);
- }
- /* consume comment, if present */
- if ((flags & FCOMMENT) != 0) {
- do {
- ic = getc(fp);
- } while (ic != 0 && ic != EOF);
- }
- /* consume 16-bit header CRC, if present */
- if ((flags & FHCRC) != 0) {
- (void) getc(fp);
- (void) getc(fp);
- }
-
- if (feof(fp) || ferror(fp))
- return false;
-
- /* seek to the end; CRC and length are in the last 8 bytes */
- long curPosn = ftell(fp);
- unsigned char buf[8];
- fseek(fp, -8, SEEK_END);
- *pCompressedLen = ftell(fp) - curPosn;
-
- if (fread(buf, 1, 8, fp) != 8)
- return false;
- /* seek back to start of compressed data */
- fseek(fp, curPosn, SEEK_SET);
-
- *pCompressionMethod = method;
- *pCRC32 = ZipFileRO::get4LE(&buf[0]);
- *pUncompressedLen = ZipFileRO::get4LE(&buf[4]);
-
- return true;
-}
-
diff --git a/libs/utils/characterData.h b/libs/utils/characterData.h
deleted file mode 100644
index e931d99..0000000
--- a/libs/utils/characterData.h
+++ /dev/null
@@ -1,730 +0,0 @@
-/*
- * 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.
- */
-
-// Automatically generated on 07-11-2006 by make-CharacterDataC
-// DO NOT EDIT DIRECTLY
-namespace CharacterData {
-
- // Structure containing an array of ranges
- struct Range {
- int length;
- const uint32_t* array;
- };
-
- // For Latin1 characters just index into this array to get the index and decomposition
- static const uint16_t LATIN1_DATA[] = {
- 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
- 0x0001, 0x0002, 0x0003, 0x0002, 0x0004, 0x0003, 0x0001, 0x0001,
- 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
- 0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0003, 0x0003, 0x0002,
- 0x0005, 0x0006, 0x0006, 0x0007, 0x0008, 0x0007, 0x0006, 0x0006,
- 0x0009, 0x000A, 0x0006, 0x000B, 0x000C, 0x000D, 0x000C, 0x000C,
- 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015,
- 0x0016, 0x0017, 0x000C, 0x0006, 0x0018, 0x0019, 0x001A, 0x0006,
- 0x0006, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021,
- 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029,
- 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031,
- 0x0032, 0x0033, 0x0034, 0x0035, 0x0006, 0x0036, 0x0037, 0x0038,
- 0x0037, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
- 0x0050, 0x0051, 0x0052, 0x0035, 0x0019, 0x0036, 0x0019, 0x0001,
- 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0001, 0x0001,
- 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
- 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
- 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
- 0x5853, 0x0006, 0x0008, 0x0008, 0x0008, 0x0008, 0x0054, 0x0054,
- 0x1037, 0x0054, 0x7855, 0x0056, 0x0019, 0x0057, 0x0054, 0x1037,
- 0x0058, 0x0059, 0x785A, 0x785B, 0x1037, 0x105C, 0x0054, 0x0006,
- 0x1037, 0x785D, 0x7855, 0x005E, 0x305F, 0x305F, 0x305F, 0x0006,
- 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0060, 0x0860,
- 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860,
- 0x0060, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0019,
- 0x0060, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0060, 0x0055,
- 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0061, 0x0861,
- 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861,
- 0x0061, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0019,
- 0x0061, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0061, 0x0862
- };
-
- // Each of these arrays is stripped into ranges. In order to build the arrays, each
- // codepoint was bit-shifted so that even and odd characters were separated into different
- // arrays. The identifier of each array is the top byte after bit-shifting.
- // The numbers stored in the array are the bit-shifted codepoint, the decomposition, and an
- // index into another array of all possible packed data values. The top 16 bits are the
- // codepoint and the bottom 16 are the decomposition and index. The top 5 bits for the decomposition
- // and the rest for the index.
- static const uint32_t a0[] = {
- 0x00800863, 0x00880063, 0x00890863, 0x00930063, 0x00940863, 0x00980864, 0x00991063, 0x009A0863,
- 0x009C0055, 0x009D0865, 0x00A01065, 0x00A10065, 0x00A20865, 0x00A50063, 0x00A60863, 0x00A90063,
- 0x00AA0863, 0x00B30063, 0x00B40863, 0x00BC0866, 0x00BD0865, 0x00C00055, 0x00C10063, 0x00C30067,
- 0x00C40065, 0x00C50068, 0x00C60065, 0x00C70069, 0x00C8006A, 0x00C90065, 0x00CA006B, 0x00CB006C,
- 0x00CC0063, 0x00CD006D, 0x00CE006C, 0x00CF006E, 0x00D00863, 0x00D10063, 0x00D3006F, 0x00D40065,
- 0x00D50055, 0x00D60063, 0x00D7006F, 0x00D80865, 0x00D90070, 0x00DA0065, 0x00DC0063, 0x00DD0055,
- 0x00DE0063, 0x00DF0055, 0x00E00071, 0x00E21072, 0x00E31073, 0x00E41074, 0x00E51072, 0x00E61073,
- 0x00E70865, 0x00EF0863, 0x00F20063, 0x00F30863, 0x00F80855, 0x00F91074, 0x00FA0863, 0x00FB0075,
- 0x00FC0863, 0x010E0063, 0x010F0863, 0x01100076, 0x01110063, 0x01130863, 0x011A0055, 0x011D0077,
- 0x011E0065, 0x011F0077, 0x01200055, 0x01210078, 0x01280055, 0x012A0079, 0x012B007A, 0x012C0055,
- 0x0130007A, 0x01310055, 0x0134007B, 0x01350055, 0x0139007C, 0x013A0055, 0x0140007D, 0x01410055,
- 0x0144007D, 0x0145007E, 0x01460055, 0x0149007F, 0x014A0080, 0x014B0055, 0x01587881, 0x015D0082,
- 0x015E0081, 0x01610037, 0x01630082, 0x01680081, 0x01690037, 0x016C1037, 0x016F0037, 0x01707881,
- 0x01730037, 0x01770081, 0x01780037, 0x01800083, 0x01A00883, 0x01A10083, 0x01A20883, 0x01A30083,
- 0x01B80078, 0x01BA0837, 0x01BB0078, 0x01BD1081, 0x01BE0078, 0x01BF0806, 0x01C00078, 0x01C21037,
- 0x01C30884, 0x01C40885, 0x01C60886, 0x01C70887, 0x01C80855, 0x01C90060, 0x01D10078, 0x01D20060,
- 0x01D50860, 0x01D60888, 0x01D70889, 0x01D80855, 0x01D90061, 0x01E1008A, 0x01E20061, 0x01E50861,
- 0x01E6088B, 0x01E7088C, 0x01E8108D, 0x01E91077, 0x01EA0877, 0x01EB108E, 0x01EC0063, 0x01F8108F,
- 0x01F91090, 0x01FA1091, 0x01FB0019, 0x01FC0065, 0x01FD0063, 0x01FE0055, 0x01FF0077, 0x02000892,
- 0x02010092, 0x02060892, 0x02080060, 0x02180061, 0x02280893, 0x02290093, 0x022E0893, 0x02300063,
- 0x023B0863, 0x023C0063, 0x02410094, 0x02420083, 0x02440095, 0x02450063, 0x02600077, 0x02610865,
- 0x02620065, 0x02680863, 0x026A0063, 0x026B0863, 0x026C0063, 0x026D0863, 0x02700063, 0x02710863,
- 0x02740063, 0x02750863, 0x027B0063, 0x027C0863, 0x027D0078, 0x02800063, 0x02880078, 0x02990096,
- 0x02AC0078, 0x02AD0097, 0x02B00078, 0x02B10098, 0x02C40078, 0x02C50099, 0x02C60078, 0x02C90083,
- 0x02DD0078, 0x02DE0083, 0x02DF009A, 0x02E10083, 0x02E3009A, 0x02E40078, 0x02E8009B, 0x02F60078,
- 0x02F8009B, 0x02FA009A, 0x02FB0078, 0x0300009C, 0x03020078, 0x0306000C, 0x03070054, 0x03080083,
- 0x030B0078, 0x030F009D, 0x03100078, 0x0311089E, 0x0314009E, 0x031E0078, 0x0320009F, 0x0321009E,
- 0x03260083, 0x033000A0, 0x033100A1, 0x033200A2, 0x033300A3, 0x033400A4, 0x03350007, 0x033600A5,
- 0x0337009E, 0x03380083, 0x0339009E, 0x033B109E, 0x033D009E, 0x0360089E, 0x0362009E, 0x036A009D,
- 0x036B0083, 0x036F0095, 0x03700083, 0x0373009F, 0x03740083, 0x0377009E, 0x0378000E, 0x03790010,
- 0x037A0012, 0x037B0014, 0x037C0016, 0x037D009E, 0x037F00A6, 0x0380009D, 0x03870078, 0x0388009E,
- 0x03980083, 0x03A60078, 0x03A7009E, 0x03B70078, 0x03C0009E, 0x03D30083, 0x03D90078, 0x04810083,
- 0x04820071, 0x049A0871, 0x049B0071, 0x049D0078, 0x049E0083, 0x049F00A7, 0x04A10083, 0x04A500A7,
- 0x04A70078, 0x04A80071, 0x04A90083, 0x04AB0078, 0x04AC0871, 0x04B00071, 0x04B10083, 0x04B20097,
- 0x04B300A8, 0x04B400A9, 0x04B500AA, 0x04B600AB, 0x04B700AC, 0x04B80097, 0x04B90078, 0x04C100A7,
- 0x04C20078, 0x04C30071, 0x04C70078, 0x04C80071, 0x04C90078, 0x04CA0071, 0x04DA0078, 0x04DB0071,
- 0x04DD0078, 0x04DE0083, 0x04DF00A7, 0x04E10083, 0x04E30078, 0x04E400A7, 0x04E50078, 0x04E608A7,
- 0x04E70071, 0x04E80078, 0x04EE0871, 0x04EF0078, 0x04F00071, 0x04F10083, 0x04F20078, 0x04F300A8,
- 0x04F400A9, 0x04F500AA, 0x04F600AB, 0x04F700AC, 0x04F80071, 0x04F90008, 0x04FA00AD, 0x04FB00AE,
- 0x04FC00AF, 0x04FD0094, 0x04FE0078, 0x05010083, 0x05020078, 0x05030071, 0x05060078, 0x05080071,
- 0x05090078, 0x050A0071, 0x051A0078, 0x051B0871, 0x051C0071, 0x051D0078, 0x051E0083, 0x051F00A7,
- 0x05210083, 0x05220078, 0x05240083, 0x05250078, 0x05260083, 0x05270078, 0x052D0871, 0x052E0071,
- 0x052F0871, 0x05300078, 0x053300A8, 0x053400A9, 0x053500AA, 0x053600AB, 0x053700AC, 0x05380083,
- 0x05390071, 0x053B0078, 0x05410083, 0x05420078, 0x05430071, 0x05470078, 0x05480071, 0x05490078,
- 0x054A0071, 0x055A0078, 0x055B0071, 0x055D0078, 0x055E0083, 0x055F00A7, 0x05610083, 0x05630078,
- 0x05640083, 0x05650078, 0x056600A7, 0x05670078, 0x05680071, 0x05690078, 0x05700071, 0x05710083,
- 0x05720078, 0x057300A8, 0x057400A9, 0x057500AA, 0x057600AB, 0x057700AC, 0x05780078, 0x058100A7,
- 0x05820078, 0x05830071, 0x05870078, 0x05880071, 0x05890078, 0x058A0071, 0x059A0078, 0x059B0071,
- 0x059D0078, 0x059E0083, 0x059F00A7, 0x05A10083, 0x05A20078, 0x05A408A7, 0x05A50078, 0x05A608A7,
- 0x05A70078, 0x05AB0083, 0x05AC0078, 0x05AE0871, 0x05AF0078, 0x05B00071, 0x05B10078, 0x05B300A8,
- 0x05B400A9, 0x05B500AA, 0x05B600AB, 0x05B700AC, 0x05B80094, 0x05B90078, 0x05C10083, 0x05C20078,
- 0x05C30071, 0x05C60078, 0x05C70071, 0x05CA0871, 0x05CB0078, 0x05CD0071, 0x05D00078, 0x05D20071,
- 0x05D30078, 0x05D40071, 0x05D60078, 0x05D70071, 0x05DD0078, 0x05DF00A7, 0x05E00083, 0x05E100A7,
- 0x05E20078, 0x05E300A7, 0x05E508A7, 0x05E70078, 0x05F300A8, 0x05F400A9, 0x05F500AA, 0x05F600AB,
- 0x05F700AC, 0x05F800B0, 0x05F900B1, 0x05FA0054, 0x05FE0078, 0x060100A7, 0x06020078, 0x06030071,
- 0x061A0078, 0x061B0071, 0x061D0078, 0x061F0083, 0x062100A7, 0x06230083, 0x06240883, 0x06250083,
- 0x06270078, 0x062B0083, 0x062C0078, 0x06300071, 0x06310078, 0x063300A8, 0x063400A9, 0x063500AA,
- 0x063600AB, 0x063700AC, 0x06380078, 0x064100A7, 0x06420078, 0x06430071, 0x065A0078, 0x065B0071,
- 0x065D0078, 0x065E0083, 0x065F00A7, 0x066008A7, 0x066100A7, 0x066300B2, 0x066408A7, 0x06660083,
- 0x06670078, 0x066B00A7, 0x066C0078, 0x066F0071, 0x06710078, 0x067300A8, 0x067400A9, 0x067500AA,
- 0x067600AB, 0x067700AC, 0x06780078, 0x068100A7, 0x06820078, 0x06830071, 0x069D0078, 0x069F00A7,
- 0x06A10083, 0x06A20078, 0x06A300A7, 0x06A508A7, 0x06A70078, 0x06B00071, 0x06B10078, 0x06B300A8,
- 0x06B400A9, 0x06B500AA, 0x06B600AB, 0x06B700AC, 0x06B80078, 0x06C100A7, 0x06C20078, 0x06C30071,
- 0x06CC0078, 0x06CD0071, 0x06D90078, 0x06DA0071, 0x06DE0078, 0x06E00071, 0x06E40078, 0x06E50083,
- 0x06E60078, 0x06E800A7, 0x06E90083, 0x06EC00A7, 0x06ED08A7, 0x06F00078, 0x06F900A7, 0x06FA0097,
- 0x06FB0078, 0x07010071, 0x071A0083, 0x071E0078, 0x07200071, 0x07230081, 0x07240083, 0x072800A8,
- 0x072900A9, 0x072A00AA, 0x072B00AB, 0x072C00AC, 0x072D0097, 0x072E0078, 0x07410071, 0x07430078,
- 0x07440071, 0x07460078, 0x074A0071, 0x074C0078, 0x074D0071, 0x07500078, 0x07510071, 0x07520078,
- 0x07550071, 0x07560078, 0x07570071, 0x075A0083, 0x075D0078, 0x075E0083, 0x075F0078, 0x07600071,
- 0x07630081, 0x07640083, 0x07670078, 0x076800A8, 0x076900A9, 0x076A00AA, 0x076B00AB, 0x076C00AC,
- 0x076D0078, 0x076E1071, 0x076F0078, 0x07800071, 0x07810094, 0x07820097, 0x07865897, 0x07870097,
- 0x078A0094, 0x078C0083, 0x078D0094, 0x079000A8, 0x079100A9, 0x079200AA, 0x079300AB, 0x079400AC,
- 0x079500B3, 0x079A0094, 0x079D00B4, 0x079F00A7, 0x07A00071, 0x07A40078, 0x07A50071, 0x07A90871,
- 0x07AA0071, 0x07AE0871, 0x07AF0071, 0x07B60078, 0x07B90083, 0x07BB0883, 0x07BD0083, 0x07C40071,
- 0x07C60078, 0x07C80083, 0x07CC0078, 0x07CD0083, 0x07D10883, 0x07D20083, 0x07D60883, 0x07D70083,
- 0x07DF0094, 0x07E30083, 0x07E40094, 0x07E70078, 0x07E80097, 0x07E90078, 0x08000071, 0x08110078,
- 0x08120071, 0x08130871, 0x08140078, 0x08150071, 0x081600A7, 0x08170083, 0x081A0078, 0x081B0083,
- 0x081C00A7, 0x081D0078, 0x082000A8, 0x082100A9, 0x082200AA, 0x082300AB, 0x082400AC, 0x08250097,
- 0x08280071, 0x082B00A7, 0x082C0083, 0x082D0078, 0x085000B5, 0x08630078, 0x08680071, 0x087E7881,
- 0x087F0078, 0x08800071, 0x08AD0078, 0x08B00071, 0x08D20078, 0x08D40071, 0x08FD0078, 0x09000071,
- 0x09270078, 0x09280071, 0x092F0078, 0x09300071, 0x09470078, 0x09480071, 0x095B0078, 0x095C0071,
- 0x09630078, 0x09640071, 0x098B0078, 0x098C0071, 0x09AE0078, 0x09B00094, 0x09B10097, 0x09B500B6,
- 0x09B600B7, 0x09B700B8, 0x09B800B9, 0x09B900B0, 0x09BA00BA, 0x09BB00BB, 0x09BC00BC, 0x09BD00BD,
- 0x09BE00BE, 0x09BF0078, 0x09C00071, 0x09C80054, 0x09CD0078, 0x09D00071, 0x09FB0078, 0x0A010071,
- 0x0B370097, 0x0B380071, 0x0B3C0078, 0x0B400005, 0x0B410071, 0x0B4E00BF, 0x0B4F0078, 0x0B500071,
- 0x0B760097, 0x0B7700C0, 0x0B7800C1, 0x0B790078, 0x0B800071, 0x0B890083, 0x0B8B0078, 0x0B900071,
- 0x0B990083, 0x0B9B0097, 0x0B9C0078, 0x0BA00071, 0x0BA90083, 0x0BAA0078, 0x0BB00071, 0x0BB90083,
- 0x0BBA0078, 0x0BC00071, 0x0BDA00C2, 0x0BDB00A7, 0x0BDC0083, 0x0BDF00A7, 0x0BE30083, 0x0BE400A7,
- 0x0BE50083, 0x0BEA0097, 0x0BEE0071, 0x0BEF0078, 0x0BF000A8, 0x0BF100A9, 0x0BF200AA, 0x0BF300AB,
- 0x0BF400AC, 0x0BF50078, 0x0BF800C3, 0x0BF900C4, 0x0BFA00C5, 0x0BFB00C6, 0x0BFC00C7, 0x0BFD0078,
- 0x0C000006, 0x0C030099, 0x0C040006, 0x0C060083, 0x0C070005, 0x0C0800A8, 0x0C0900A9, 0x0C0A00AA,
- 0x0C0B00AB, 0x0C0C00AC, 0x0C0D0078, 0x0C100071, 0x0C3C0078, 0x0C400071, 0x0C550078, 0x0C800071,
- 0x0C8F0078, 0x0C900083, 0x0C9200A7, 0x0C940083, 0x0C9500C8, 0x0C960078, 0x0C9800A7, 0x0C990083,
- 0x0C9A00A7, 0x0C9D0083, 0x0C9E0078, 0x0CA00054, 0x0CA10078, 0x0CA20006, 0x0CA300A8, 0x0CA400A9,
- 0x0CA500AA, 0x0CA600AB, 0x0CA700AC, 0x0CA80071, 0x0CB70078, 0x0CB80071, 0x0CBB0078, 0x0CC00071,
- 0x0CD50078, 0x0CD800A7, 0x0CE10071, 0x0CE400A7, 0x0CE50078, 0x0CE800A8, 0x0CE900A9, 0x0CEA00AA,
- 0x0CEB00AB, 0x0CEC00AC, 0x0CED0078, 0x0CEF0006, 0x0CF00054, 0x0D000071, 0x0D0C0083, 0x0D0D00A7,
- 0x0D0E0078, 0x0D0F0097, 0x0D100078, 0x0E800055, 0x0E967881, 0x0EA70081, 0x0EA87881, 0x0EB17055,
- 0x0EB60055, 0x0EBC7881, 0x0EBD0055, 0x0ECE7881, 0x0EE00083, 0x0EE20078, 0x0F000863, 0x0F4B0855,
- 0x0F4D1055, 0x0F4E0078, 0x0F500863, 0x0F7D0078, 0x0F8008C9, 0x0F8408CA, 0x0F8808C9, 0x0F8B0078,
- 0x0F8C08CA, 0x0F8F0078, 0x0F9008C9, 0x0F9408CA, 0x0F9808C9, 0x0F9C08CA, 0x0FA008C9, 0x0FA30078,
- 0x0FA408CA, 0x0FA70078, 0x0FA80855, 0x0FAC0078, 0x0FB008C9, 0x0FB408CA, 0x0FB808CB, 0x0FB908CC,
- 0x0FBB08CD, 0x0FBC08CE, 0x0FBD08CF, 0x0FBE08D0, 0x0FBF0078, 0x0FC008C9, 0x0FC408D1, 0x0FC808C9,
- 0x0FCC08D1, 0x0FD008C9, 0x0FD408D1, 0x0FD808C9, 0x0FD90855, 0x0FDC08CA, 0x0FDD08D2, 0x0FDE08D3,
- 0x0FDF08D4, 0x0FE01037, 0x0FE10855, 0x0FE408D5, 0x0FE608D3, 0x0FE70837, 0x0FE808C9, 0x0FE90855,
- 0x0FEA0078, 0x0FEB0855, 0x0FEC08CA, 0x0FED08D6, 0x0FEE0078, 0x0FEF0837, 0x0FF008C9, 0x0FF10855,
- 0x0FF408CA, 0x0FF508D7, 0x0FF608D8, 0x0FF70837, 0x0FF80078, 0x0FF90855, 0x0FFC08D9, 0x0FFD08DA,
- 0x0FFE08D3, 0x0FFF1037, 0x10000805, 0x10011005, 0x10060057, 0x100700C2, 0x10080099, 0x100B0006,
- 0x100C00DB, 0x100D00B4, 0x100E00DB, 0x100F00B4, 0x10100006, 0x10121006, 0x101400DC, 0x101500DD,
- 0x101600DE, 0x101700DF, 0x10180007, 0x101A1007, 0x101B1006, 0x101C0006, 0x101D00E0, 0x101E1006,
- 0x10200038, 0x10210006, 0x102200E1, 0x1023000A, 0x10241006, 0x10250006, 0x10290019, 0x102A0038,
- 0x102B0006, 0x10300057, 0x10320078, 0x10350057, 0x103878E2, 0x10390078, 0x103A78E3, 0x103B78E4,
- 0x103C78E5, 0x103D780B, 0x103E7819, 0x103F780A, 0x104070E2, 0x1041705A, 0x104270E3, 0x104370E4,
- 0x104470E5, 0x1045700B, 0x10467019, 0x1047700A, 0x10487081, 0x104B0078, 0x10500008, 0x10541008,
- 0x10550008, 0x105B0078, 0x10680083, 0x106F0095, 0x10730083, 0x10760078, 0x10801054, 0x10812877,
- 0x10820054, 0x10831054, 0x10840054, 0x10852855, 0x10862877, 0x10872855, 0x10882877, 0x108A0054,
- 0x108B1054, 0x108C0054, 0x108D2877, 0x108F0054, 0x10907854, 0x10922877, 0x109308E6, 0x10942877,
- 0x109508E7, 0x10962877, 0x10970058, 0x10982877, 0x10990054, 0x109A2855, 0x109B1071, 0x109D0054,
- 0x109E2855, 0x109F2877, 0x10A028E8, 0x10A10019, 0x10A32855, 0x10A50054, 0x10A70078, 0x10AA305F,
- 0x10B010E9, 0x10B110EA, 0x10B210EB, 0x10B310EC, 0x10B410ED, 0x10B510EE, 0x10B610EF, 0x10B710F0,
- 0x10B810F1, 0x10B910F2, 0x10BA10F3, 0x10BB10F4, 0x10BC10F5, 0x10BD10F6, 0x10BE10F7, 0x10BF10F8,
- 0x10C000F9, 0x10C100FA, 0x10C20078, 0x10C80019, 0x10CB0054, 0x10CD0819, 0x10CE0054, 0x10D00019,
- 0x10D10054, 0x10D30019, 0x10D40054, 0x10D70819, 0x10D80054, 0x10E70819, 0x10E80054, 0x10E90019,
- 0x10EB0054, 0x10FA0019, 0x110100E8, 0x110208E8, 0x11030019, 0x110400FB, 0x110608FC, 0x11070019,
- 0x1109000B, 0x110A0019, 0x110B00E8, 0x110C0019, 0x110D00E8, 0x110F0019, 0x111000E8, 0x111208E8,
- 0x11140019, 0x111610E8, 0x111700E8, 0x111810E8, 0x111900E8, 0x111A0019, 0x111E00FD, 0x111F00E8,
- 0x112208E8, 0x112300E8, 0x11270019, 0x112900FD, 0x112B0019, 0x113008E8, 0x113200FD, 0x11360019,
- 0x113708FD, 0x113900FD, 0x113A08FD, 0x113B00FD, 0x113C08FD, 0x113D00FD, 0x114008FD, 0x114100FD,
- 0x114208FD, 0x114300FD, 0x114408FD, 0x114500FD, 0x114600E8, 0x11470019, 0x114800FE, 0x114A0019,
- 0x114C00FF, 0x114D0019, 0x115100FD, 0x11520019, 0x11530100, 0x11540101, 0x115500E8, 0x115608E8,
- 0x115800FD, 0x115C00E8, 0x115D0019, 0x115F00E8, 0x11600019, 0x116500FE, 0x11670019, 0x116800FD,
- 0x11690019, 0x116B00FD, 0x117008FD, 0x117200FD, 0x117508FD, 0x11770019, 0x117800FD, 0x11790102,
- 0x117B0103, 0x117C00E8, 0x117D0104, 0x117F0105, 0x11800054, 0x118400FD, 0x11860054, 0x119000E8,
- 0x11910054, 0x1195080A, 0x11960054, 0x119B0094, 0x11BE0019, 0x11BF0054, 0x11CE0019, 0x11DA00B4,
- 0x11DB0006, 0x11DC0054, 0x11EE0078, 0x12000054, 0x12140078, 0x12200054, 0x12260078, 0x12301906,
- 0x12311907, 0x12321908, 0x12331909, 0x1234190A, 0x1235190B, 0x1236190C, 0x1237190D, 0x1238190E,
- 0x1239190F, 0x123A1106, 0x123B1107, 0x123C1108, 0x123D1109, 0x123E110A, 0x123F110B, 0x1240110C,
- 0x1241110D, 0x1242110E, 0x1243110F, 0x1244105D, 0x1245105B, 0x12461110, 0x12471111, 0x12481112,
- 0x12491113, 0x124A1114, 0x124B1115, 0x124C1116, 0x124D1117, 0x124E1094, 0x125B1918, 0x12681919,
- 0x127518C3, 0x1276011A, 0x1277011B, 0x1278011C, 0x1279011D, 0x127A011E, 0x127B00C4, 0x127C00C5,
- 0x127D00C6, 0x127E00C7, 0x127F011F, 0x12800054, 0x12FC0019, 0x13000054, 0x134F0078, 0x13500054,
- 0x13560094, 0x13570054, 0x13590078, 0x13810054, 0x13850078, 0x13860054, 0x13940078, 0x13950054,
- 0x13A60078, 0x13A80054, 0x13AA0078, 0x13AB0054, 0x13B00078, 0x13B10054, 0x13B40009, 0x13BB0106,
- 0x13BC0107, 0x13BD0108, 0x13BE0109, 0x13BF010A, 0x13C00106, 0x13C10107, 0x13C20108, 0x13C30109,
- 0x13C4010A, 0x13C50106, 0x13C60107, 0x13C70108, 0x13C80109, 0x13C9010A, 0x13CA0054, 0x13CB0078,
- 0x13CC0054, 0x13D80078, 0x13D90054, 0x13E000E8, 0x13E10019, 0x13E200FE, 0x13E3000A, 0x13E40078,
- 0x13E80019, 0x13EA00E8, 0x13EB00FE, 0x13EC0019, 0x13EE00E8, 0x13EF00FE, 0x13F00019, 0x13F100FD,
- 0x13F30009, 0x13F60078, 0x13F80019, 0x14000094, 0x14800019, 0x14C2000A, 0x14C70120, 0x14C80121,
- 0x14C9000A, 0x14CD0019, 0x14CE00E8, 0x14D80019, 0x14DC0122, 0x14DD0019, 0x14E000FD, 0x14E100E8,
- 0x14E200FD, 0x14E30019, 0x14E700E8, 0x14E800FE, 0x14EA00FD, 0x14EB0019, 0x14EC0009, 0x14EE00E8,
- 0x14EF0019, 0x14F200E8, 0x14F30019, 0x14F400E8, 0x14F50019, 0x14FA00E8, 0x14FC00FD, 0x14FD0019,
- 0x14FE0009, 0x14FF0019, 0x150500E8, 0x150610E8, 0x150700E8, 0x15110019, 0x151200E8, 0x15140019,
- 0x151600FE, 0x15180019, 0x151A00FD, 0x151B0019, 0x151E00FD, 0x151F00E8, 0x15200019, 0x152C00E8,
- 0x152D0019, 0x153200FD, 0x15330019, 0x153500E8, 0x15370019, 0x153800E8, 0x15390019, 0x153A10E8,
- 0x153B1019, 0x153C0019, 0x153D00FE, 0x153E00E8, 0x153F00FE, 0x154300E8, 0x154600FE, 0x154700E8,
- 0x154900FE, 0x154F00E8, 0x155100FE, 0x15520019, 0x155300FD, 0x15570019, 0x155800FE, 0x155900E8,
- 0x155A00FE, 0x155B00E8, 0x155E00FE, 0x156400E8, 0x156700FE, 0x156C0019, 0x156E08E8, 0x156F0123,
- 0x15700019, 0x157100E8, 0x15720124, 0x157300E8, 0x15740019, 0x157600FD, 0x157700E8, 0x15780019,
- 0x157C00FE, 0x157E0019, 0x15800054, 0x158A0078, 0x16000096, 0x16180098, 0x16300078, 0x16400063,
- 0x16720055, 0x16730054, 0x16760078, 0x167D0006, 0x16800125, 0x16930078, 0x16980071, 0x16B30078,
- 0x16C00071, 0x16CC0078, 0x16D00071, 0x16F00078, 0x17000006, 0x17010126, 0x17030006, 0x170500E0,
- 0x17060126, 0x17070006, 0x170C0078, 0x170E0126, 0x170F0078, 0x17400054, 0x174D0078, 0x174E0054,
- 0x177A0078, 0x17801054, 0x17EB0078, 0x17F80054, 0x17FE0078, 0x18008805, 0x18010006, 0x18020054,
- 0x18030071, 0x18040009, 0x18090054, 0x180A0009, 0x180E0099, 0x180F00BF, 0x18100054, 0x18110127,
- 0x18120128, 0x18130129, 0x1814012A, 0x18150083, 0x18180099, 0x18190081, 0x181B1054, 0x181C112B,
- 0x181D112C, 0x181E0071, 0x181F0054, 0x18200078, 0x18210071, 0x18260871, 0x18320071, 0x18380871,
- 0x18390071, 0x183A0871, 0x183C0071, 0x183D0871, 0x183F0071, 0x184A0871, 0x184B0071, 0x184C0078,
- 0x184D0083, 0x184E1037, 0x184F0881, 0x18500099, 0x18510071, 0x18560871, 0x18620071, 0x18680871,
- 0x18690071, 0x186A0871, 0x186C0071, 0x186D0871, 0x186F0071, 0x187A0871, 0x187B0071, 0x187C0871,
- 0x187E0081, 0x187F0881, 0x18800078, 0x18830071, 0x18970078, 0x18991071, 0x18C80094, 0x18C978AD,
- 0x18CA78AE, 0x18CB7894, 0x18D00071, 0x18DC0078, 0x18E00054, 0x18E80078, 0x18F80071, 0x19001094,
- 0x190F1054, 0x191010AD, 0x191110AE, 0x1912112D, 0x1913112E, 0x1914112F, 0x19151094, 0x19220078,
- 0x19286854, 0x19291930, 0x192A1931, 0x192B1932, 0x192C1933, 0x192D1934, 0x192E1935, 0x192F1936,
- 0x19301894, 0x193E1854, 0x194018AD, 0x194118AE, 0x1942192D, 0x1943192E, 0x1944192F, 0x19451894,
- 0x19591937, 0x195A1938, 0x195B1939, 0x195C193A, 0x195D193B, 0x195E193C, 0x195F193D, 0x19601094,
- 0x19666854, 0x19681894, 0x19806894, 0x19AC1094, 0x19B96894, 0x19BC6854, 0x19BE6894, 0x19EF6854,
- 0x19F01094, 0x1A000071, 0x26DB0078, 0x26E00054, 0x27000071, 0x4FDE0078, 0x50000071, 0x52470078,
- 0x52480054, 0x52640078, 0x53800037, 0x538C0078, 0x54000071, 0x540100C8, 0x54020071, 0x54030083,
- 0x54040071, 0x541200A7, 0x54130083, 0x54140054, 0x54160078, 0x56000071, 0x6BD20078, 0x6C00013E,
- 0x7000013F, 0x7C800871, 0x7D070071, 0x7D080871, 0x7D0A0071, 0x7D0B0871, 0x7D120071, 0x7D130871,
- 0x7D140071, 0x7D150871, 0x7D170078, 0x7D180871, 0x7D360078, 0x7D380871, 0x7D6D0078, 0x7D801055,
- 0x7D840078, 0x7D8A1055, 0x7D8C0078, 0x7D8F0083, 0x7D90289B, 0x7D95089B, 0x7DA10078, 0x7DA2089B,
- 0x7DA8409E, 0x7DAA389E, 0x7DAB409E, 0x7DAC389E, 0x7DAD409E, 0x7DAE389E, 0x7DAF409E, 0x7DB0389E,
- 0x7DB1409E, 0x7DB2389E, 0x7DB3409E, 0x7DB4389E, 0x7DB5409E, 0x7DB6389E, 0x7DB7409E, 0x7DB8389E,
- 0x7DB9409E, 0x7DBA389E, 0x7DBB409E, 0x7DBC389E, 0x7DBD409E, 0x7DBE389E, 0x7DBF409E, 0x7DC0389E,
- 0x7DC1409E, 0x7DC8389E, 0x7DC9409E, 0x7DCA389E, 0x7DCB409E, 0x7DCC389E, 0x7DCD409E, 0x7DCE389E,
- 0x7DCF409E, 0x7DD1389E, 0x7DD2409E, 0x7DD4389E, 0x7DD5409E, 0x7DD6389E, 0x7DD7409E, 0x7DD90078,
- 0x7DEA209E, 0x7DEB489E, 0x7DEC209E, 0x7DEF409E, 0x7DF3389E, 0x7DF5409E, 0x7DFC389E, 0x7DFD209E,
- 0x7DFE409E, 0x7DFF389E, 0x7E00409E, 0x7E32209E, 0x7E4C389E, 0x7E70489E, 0x7E7B409E, 0x7E89209E,
- 0x7E97389E, 0x7E9A489E, 0x7E9E209E, 0x7E9F00B4, 0x7EA00078, 0x7EA8389E, 0x7EAC209E, 0x7EAE389E,
- 0x7EAF209E, 0x7EB0389E, 0x7EB1209E, 0x7EB4389E, 0x7EB5209E, 0x7EB8389E, 0x7EBA209E, 0x7EC3389E,
- 0x7EC80078, 0x7EC9389E, 0x7ECB209E, 0x7ECC389E, 0x7ECD209E, 0x7EDA389E, 0x7EDB209E, 0x7EDC389E,
- 0x7EDE209E, 0x7EE2389E, 0x7EE3209E, 0x7EE40078, 0x7EF8409E, 0x7EFE4140, 0x7EFF0078, 0x7F000083,
- 0x7F088006, 0x7F0C80BF, 0x7F0D0078, 0x7F100083, 0x7F120078, 0x7F188006, 0x7F198099, 0x7F1A8038,
- 0x7F1B80BF, 0x7F230006, 0x7F2480BF, 0x7F251006, 0x7F271038, 0x7F28600C, 0x7F2A6006, 0x7F2C6099,
- 0x7F2D60BF, 0x7F306006, 0x7F31600B, 0x7F326019, 0x7F346006, 0x7F356007, 0x7F360078, 0x7F38409E,
- 0x7F41209E, 0x7F46489E, 0x7F47209E, 0x7F49489E, 0x7F4A209E, 0x7F4C489E, 0x7F4D209E, 0x7F4E489E,
- 0x7F4F209E, 0x7F50489E, 0x7F51209E, 0x7F52489E, 0x7F53209E, 0x7F54489E, 0x7F55209E, 0x7F5A489E,
- 0x7F5B209E, 0x7F5C489E, 0x7F5D209E, 0x7F5E489E, 0x7F5F209E, 0x7F60489E, 0x7F61209E, 0x7F62489E,
- 0x7F63209E, 0x7F64489E, 0x7F65209E, 0x7F66489E, 0x7F67209E, 0x7F68489E, 0x7F69209E, 0x7F6A489E,
- 0x7F6B209E, 0x7F6C489E, 0x7F6D209E, 0x7F6E489E, 0x7F6F209E, 0x7F70489E, 0x7F71209E, 0x7F72489E,
- 0x7F73209E, 0x7F74489E, 0x7F75209E, 0x7F76489E, 0x7F77209E, 0x7F7A489E, 0x7F7B209E, 0x7F7F0078,
- 0x7F818806, 0x7F828808, 0x7F838806, 0x7F848809, 0x7F858806, 0x7F86880C, 0x7F88880E, 0x7F898810,
- 0x7F8A8812, 0x7F8B8814, 0x7F8C8816, 0x7F8D880C, 0x7F8E8818, 0x7F8F881A, 0x7F908806, 0x7F918860,
- 0x7F9E8806, 0x7F9F8837, 0x7FA18861, 0x7FAE8819, 0x7FB0880A, 0x7FB15009, 0x7FB25006, 0x7FB35071,
- 0x7FB85081, 0x7FB95071, 0x7FCF5081, 0x7FD05071, 0x7FE00078, 0x7FE15071, 0x7FE40078, 0x7FE55071,
- 0x7FE80078, 0x7FE95071, 0x7FEC0078, 0x7FED5071, 0x7FEF0078, 0x7FF08808, 0x7FF18819, 0x7FF28854,
- 0x7FF38808, 0x7FF45054, 0x7FF55019, 0x7FF75054, 0x7FF80078, 0x7FFD0141, 0x7FFE0054, 0x7FFF0078,
- 0x80000071, 0x80060078, 0x80070071, 0x801F0078, 0x80200071, 0x80270078, 0x80280071, 0x802F0078,
- 0x80400071, 0x807E0078, 0x80800097, 0x80810094, 0x80820078, 0x808400B6, 0x808500B7, 0x808600B8,
- 0x808700B9, 0x808800B0, 0x808900BA, 0x808A00BB, 0x808B00BC, 0x808C00BD, 0x808D0142, 0x808E0143,
- 0x808F0144, 0x80900145, 0x809100B1, 0x80920146, 0x80930147, 0x80940148, 0x80950149, 0x8096014A,
- 0x8097014B, 0x8098014C, 0x8099014D, 0x809A0078, 0x809C0094, 0x80A0014E, 0x80A1014F, 0x80A20150,
- 0x80A30151, 0x80A40152, 0x80A50150, 0x80A60153, 0x80A70151, 0x80A80154, 0x80A90155, 0x80AA0156,
- 0x80AB0157, 0x80AC014F, 0x80AE0158, 0x80B00154, 0x80B30150, 0x80B50155, 0x80B60153, 0x80B90151,
- 0x80BA0150, 0x80BB005F, 0x80BD0054, 0x80C500C3, 0x80C60078, 0x81800071, 0x819000AD, 0x819100B0,
- 0x81920078, 0x81980071, 0x81A50159, 0x81A60078, 0x81C00071, 0x81CF0078, 0x81D00071, 0x81E20078,
- 0x81E40071, 0x81E80094, 0x81E90158, 0x81EA015A, 0x81EB0078, 0x8200015B, 0x8214015C, 0x82280071,
- 0x824F0078, 0x825000A8, 0x825100A9, 0x825200AA, 0x825300AB, 0x825400AC, 0x82550078, 0x8400009B,
- 0x84030078, 0x8404009B, 0x841B0078, 0x841C009B, 0x841D0078, 0x841E009B, 0x841F0078, 0x8500009B,
- 0x85010083, 0x85020078, 0x85030083, 0x85040078, 0x85060083, 0x8508009B, 0x850A0078, 0x850B009B,
- 0x850C0078, 0x850D009B, 0x851A0078, 0x851C0083, 0x851E0078, 0x8520015D, 0x8521015E, 0x8522015F,
- 0x85230160, 0x85240078, 0x8528009A, 0x852D0078, 0xE8000094, 0xE87B0078, 0xE8800094, 0xE8940078,
- 0xE8950094, 0xE8AF0894, 0xE8B300A7, 0xE8B40083, 0xE8B50094, 0xE8B700A7, 0xE8BA0057, 0xE8BE0083,
- 0xE8C20094, 0xE8C30083, 0xE8C60094, 0xE8D50083, 0xE8D70094, 0xE8DE0894, 0xE8E10094, 0xE8EF0078,
- 0xE9000054, 0xE9210083, 0xE9230078, 0xE9800054, 0xE9AC0078, 0xEA002877, 0xEA0D2855, 0xEA1A2877,
- 0xEA272855, 0xEA342877, 0xEA412855, 0xEA4E2877, 0xEA500078, 0xEA512877, 0xEA520078, 0xEA532877,
- 0xEA540078, 0xEA552877, 0xEA5B2855, 0xEA5D0078, 0xEA5F2855, 0xEA620078, 0xEA632855, 0xEA682877,
- 0xEA752855, 0xEA822877, 0xEA830078, 0xEA842877, 0xEA860078, 0xEA872877, 0xEA8F2855, 0xEA9C2877,
- 0xEA9D0078, 0xEA9E2877, 0xEAA40078, 0xEAA52877, 0xEAA92855, 0xEAB62877, 0xEAC32855, 0xEAD02877,
- 0xEADD2855, 0xEAEA2877, 0xEAF72855, 0xEB042877, 0xEB112855, 0xEB1E2877, 0xEB2B2855, 0xEB382877,
- 0xEB452855, 0xEB530078, 0xEB542877, 0xEB612855, 0xEB712877, 0xEB7E2855, 0xEB8E2877, 0xEB9B2855,
- 0xEBAB2877, 0xEBB82855, 0xEBC82877, 0xEBD52855, 0xEBE50078, 0xEBE7280E, 0xEBE82810, 0xEBE92812,
- 0xEBEA2814, 0xEBEB2816, 0xEBEC280E, 0xEBED2810, 0xEBEE2812, 0xEBEF2814, 0xEBF02816, 0xEBF1280E,
- 0xEBF22810, 0xEBF32812, 0xEBF42814, 0xEBF52816, 0xEBF6280E, 0xEBF72810, 0xEBF82812, 0xEBF92814,
- 0xEBFA2816, 0xEBFB280E, 0xEBFC2810, 0xEBFD2812, 0xEBFE2814, 0xEBFF2816, 0xEC000078
- };
-
- static const uint32_t a1[] = {
- 0x00000071, 0x536C0078, 0x7C000871, 0x7D0F0078
- };
-
- static const uint32_t a7[] = {
- 0x00100057, 0x00400078, 0x00800083, 0x00F80078, 0x8000013F, 0xFFFF0078
- };
-
- static const uint32_t a8[] = {
- 0x0000013F, 0x7FFF0078
- };
-
- static const uint32_t a16[] = {
- 0x00800865, 0x00880065, 0x00890865, 0x00930065, 0x00940865, 0x00980161, 0x00991065, 0x009A0865,
- 0x009C0863, 0x009F1063, 0x00A00063, 0x00A10863, 0x00A41055, 0x00A50065, 0x00A60865, 0x00A90065,
- 0x00AA0865, 0x00B30065, 0x00B40865, 0x00BC0863, 0x00BF1162, 0x00C00163, 0x00C10065, 0x00C30063,
- 0x00C40068, 0x00C50063, 0x00C60055, 0x00C70164, 0x00C80063, 0x00C90068, 0x00CA0165, 0x00CB0166,
- 0x00CC0065, 0x00CD0055, 0x00CE0167, 0x00CF0168, 0x00D00865, 0x00D10065, 0x00D30063, 0x00D4006F,
- 0x00D50055, 0x00D60065, 0x00D70863, 0x00D80070, 0x00D90063, 0x00DB0169, 0x00DC0065, 0x00DD0071,
- 0x00DE0065, 0x00DF016A, 0x00E00071, 0x00E21074, 0x00E31072, 0x00E41073, 0x00E51074, 0x00E60863,
- 0x00EE016B, 0x00EF0865, 0x00F20065, 0x00F30865, 0x00F81072, 0x00F91073, 0x00FA0865, 0x00FB016C,
- 0x00FC0865, 0x010E0065, 0x010F0865, 0x01100055, 0x01110065, 0x01130865, 0x011A0055, 0x011D0063,
- 0x011E016D, 0x011F0055, 0x0120016E, 0x01210078, 0x01280055, 0x0129016F, 0x012A0055, 0x012B007A,
- 0x012C0170, 0x012D0171, 0x012E0055, 0x01310172, 0x01320055, 0x01340173, 0x01350055, 0x01370173,
- 0x01380055, 0x013A0174, 0x013B0055, 0x0141007D, 0x01420055, 0x0145007E, 0x01460055, 0x01587881,
- 0x015C0082, 0x015D0081, 0x01610037, 0x01630082, 0x01680081, 0x01690037, 0x016C1037, 0x016F0037,
- 0x01707881, 0x01720037, 0x01800083, 0x01A00883, 0x01A20175, 0x01A30083, 0x01B80078, 0x01BA0037,
- 0x01BB0078, 0x01C20837, 0x01C30806, 0x01C40885, 0x01C50078, 0x01C70887, 0x01C80060, 0x01D50860,
- 0x01D60889, 0x01D80061, 0x01E50861, 0x01E6088C, 0x01E70078, 0x01E81176, 0x01E90877, 0x01EA1177,
- 0x01EB0055, 0x01EC0065, 0x01F81093, 0x01F90055, 0x01FA1178, 0x01FB0063, 0x01FC10D8, 0x01FD0065,
- 0x01FE0077, 0x02000892, 0x02020092, 0x02030892, 0x02040092, 0x02060892, 0x02070092, 0x02080060,
- 0x020C0860, 0x020D0060, 0x02180061, 0x021C0861, 0x021D0061, 0x02280893, 0x022A0093, 0x022B0893,
- 0x022C0093, 0x022E0893, 0x022F0093, 0x02300065, 0x023B0865, 0x023C0065, 0x02410083, 0x02430078,
- 0x02440095, 0x02450065, 0x02600863, 0x02610063, 0x02670078, 0x02680865, 0x026A0065, 0x026B0865,
- 0x026C0065, 0x026D0865, 0x02700065, 0x02710865, 0x02740065, 0x02750865, 0x027B0065, 0x027C0865,
- 0x027D0078, 0x02800065, 0x02880078, 0x02980096, 0x02AB0078, 0x02AC0081, 0x02AD0097, 0x02B00098,
- 0x02C31055, 0x02C40097, 0x02C50078, 0x02C80083, 0x02E1009A, 0x02E20083, 0x02E40078, 0x02E8009B,
- 0x02F50078, 0x02F8009B, 0x02F9009A, 0x02FA0078, 0x0300009C, 0x03020078, 0x03050140, 0x0306009D,
- 0x03070054, 0x03080083, 0x030B0078, 0x030D009D, 0x030E0078, 0x030F009D, 0x0310009E, 0x0311089E,
- 0x0313009E, 0x031D0078, 0x0320009E, 0x03250083, 0x032F0078, 0x03300179, 0x0331017A, 0x0332017B,
- 0x0333017C, 0x0334017D, 0x033500A5, 0x0336009D, 0x0337009E, 0x033A109E, 0x033C009E, 0x0369089E,
- 0x036A009E, 0x036B0083, 0x036E009C, 0x036F0083, 0x0372009F, 0x03730083, 0x03740054, 0x03750083,
- 0x0377009E, 0x0378000F, 0x03790011, 0x037A0013, 0x037B0015, 0x037C0017, 0x037D009E, 0x037E00A6,
- 0x037F009E, 0x0380009D, 0x03870057, 0x03880083, 0x0389009E, 0x03980083, 0x03A50078, 0x03A6009E,
- 0x03B70078, 0x03C0009E, 0x03D30083, 0x03D8009E, 0x03D90078, 0x04800083, 0x048100A7, 0x04820071,
- 0x04940871, 0x04950071, 0x04980871, 0x04990071, 0x049D0078, 0x049E0071, 0x049F00A7, 0x04A00083,
- 0x04A400A7, 0x04A60083, 0x04A70078, 0x04A80083, 0x04AA0078, 0x04AC0871, 0x04B00071, 0x04B10083,
- 0x04B20097, 0x04B3017E, 0x04B4017F, 0x04B50180, 0x04B60181, 0x04B70182, 0x04B80078, 0x04BE0071,
- 0x04BF0078, 0x04C00083, 0x04C100A7, 0x04C20071, 0x04C60078, 0x04C70071, 0x04C80078, 0x04C90071,
- 0x04D40078, 0x04D50071, 0x04D80078, 0x04DB0071, 0x04DD0078, 0x04DE0071, 0x04DF00A7, 0x04E00083,
- 0x04E20078, 0x04E300A7, 0x04E40078, 0x04E508A7, 0x04E60083, 0x04E70078, 0x04EB00A7, 0x04EC0078,
- 0x04EE0871, 0x04F00071, 0x04F10083, 0x04F20078, 0x04F3017E, 0x04F4017F, 0x04F50180, 0x04F60181,
- 0x04F70182, 0x04F80071, 0x04F90008, 0x04FA00B6, 0x04FB00B7, 0x04FC0183, 0x04FD0078, 0x05000083,
- 0x050100A7, 0x05020071, 0x05050078, 0x05070071, 0x05080078, 0x05090071, 0x05140078, 0x05150071,
- 0x05180078, 0x05190871, 0x051A0071, 0x051B0078, 0x051C0071, 0x051D0078, 0x051F00A7, 0x05200083,
- 0x05210078, 0x05230083, 0x05240078, 0x05250083, 0x05270078, 0x052C0871, 0x052E0078, 0x0533017E,
- 0x0534017F, 0x05350180, 0x05360181, 0x05370182, 0x05380083, 0x05390071, 0x053A0078, 0x05400083,
- 0x054100A7, 0x05420071, 0x05540078, 0x05550071, 0x05580078, 0x05590071, 0x055D0078, 0x055E0071,
- 0x055F00A7, 0x05600083, 0x056400A7, 0x05660083, 0x05670078, 0x05700071, 0x05710083, 0x05720078,
- 0x0573017E, 0x0574017F, 0x05750180, 0x05760181, 0x05770182, 0x05780008, 0x05790078, 0x05800083,
- 0x058100A7, 0x05820071, 0x05860078, 0x05870071, 0x05880078, 0x05890071, 0x05940078, 0x05950071,
- 0x05980078, 0x05990071, 0x059D0078, 0x059E0071, 0x059F0083, 0x05A20078, 0x05A300A7, 0x05A40078,
- 0x05A508A7, 0x05A60083, 0x05A70078, 0x05AB00A7, 0x05AC0078, 0x05AE0871, 0x05AF0071, 0x05B10078,
- 0x05B3017E, 0x05B4017F, 0x05B50180, 0x05B60181, 0x05B70182, 0x05B80071, 0x05B90078, 0x05C10071,
- 0x05C50078, 0x05C70071, 0x05C80078, 0x05C90071, 0x05CB0078, 0x05CC0071, 0x05CD0078, 0x05CF0071,
- 0x05D00078, 0x05D10071, 0x05D20078, 0x05D40071, 0x05D50078, 0x05D70071, 0x05DD0078, 0x05DF00A7,
- 0x05E10078, 0x05E300A7, 0x05E40078, 0x05E508A7, 0x05E60083, 0x05E70078, 0x05EB00A7, 0x05EC0078,
- 0x05F3017E, 0x05F4017F, 0x05F50180, 0x05F60181, 0x05F70182, 0x05F80184, 0x05F90054, 0x05FC0008,
- 0x05FD0078, 0x060000A7, 0x06020071, 0x06060078, 0x06070071, 0x06080078, 0x06090071, 0x06140078,
- 0x06150071, 0x061D0078, 0x061F0083, 0x062000A7, 0x06220078, 0x06230083, 0x06240078, 0x06250083,
- 0x06270078, 0x062A0083, 0x062B0078, 0x06300071, 0x06310078, 0x0633017E, 0x0634017F, 0x06350180,
- 0x06360181, 0x06370182, 0x06380078, 0x064100A7, 0x06420071, 0x06460078, 0x06470071, 0x06480078,
- 0x06490071, 0x06540078, 0x06550071, 0x065D0078, 0x065E0071, 0x065F00B2, 0x066000A7, 0x06620078,
- 0x066308A7, 0x06640078, 0x066508A7, 0x06660083, 0x06670078, 0x066A00A7, 0x066B0078, 0x06700071,
- 0x06710078, 0x0673017E, 0x0674017F, 0x06750180, 0x06760181, 0x06770182, 0x06780078, 0x068100A7,
- 0x06820071, 0x06860078, 0x06870071, 0x06880078, 0x06890071, 0x06940078, 0x06950071, 0x069D0078,
- 0x069F00A7, 0x06A00083, 0x06A20078, 0x06A300A7, 0x06A40078, 0x06A508A7, 0x06A60083, 0x06A70078,
- 0x06AB00A7, 0x06AC0078, 0x06B00071, 0x06B10078, 0x06B3017E, 0x06B4017F, 0x06B50180, 0x06B60181,
- 0x06B70182, 0x06B80078, 0x06C100A7, 0x06C20071, 0x06CB0078, 0x06CD0071, 0x06DF0078, 0x06E00071,
- 0x06E30078, 0x06E700A7, 0x06E90083, 0x06EA0078, 0x06EC00A7, 0x06EE08A7, 0x06EF00A7, 0x06F00078,
- 0x06F900A7, 0x06FA0078, 0x07000071, 0x07180083, 0x07191071, 0x071A0083, 0x071D0078, 0x071F0008,
- 0x07200071, 0x07230083, 0x07270097, 0x0728017E, 0x0729017F, 0x072A0180, 0x072B0181, 0x072C0182,
- 0x072D0097, 0x072E0078, 0x07400071, 0x07410078, 0x07430071, 0x07440078, 0x07460071, 0x07470078,
- 0x074A0071, 0x07540078, 0x07550071, 0x07580083, 0x07591071, 0x075A0083, 0x075E0071, 0x075F0078,
- 0x07600071, 0x07620078, 0x07640083, 0x07670078, 0x0768017E, 0x0769017F, 0x076A0180, 0x076B0181,
- 0x076C0182, 0x076D0078, 0x076E1071, 0x076F0078, 0x07800094, 0x07820097, 0x07890094, 0x078C0083,
- 0x078D0094, 0x0790017E, 0x0791017F, 0x07920180, 0x07930181, 0x07940182, 0x079500B3, 0x079A0083,
- 0x079D00BF, 0x079F00A7, 0x07A00071, 0x07A10871, 0x07A20071, 0x07A60871, 0x07A70071, 0x07AB0871,
- 0x07AC0071, 0x07B40871, 0x07B50078, 0x07B80083, 0x07B90883, 0x07BB1083, 0x07BD0083, 0x07BF00A7,
- 0x07C00883, 0x07C10083, 0x07C20097, 0x07C30083, 0x07C40071, 0x07C60078, 0x07C80083, 0x07C90883,
- 0x07CA0083, 0x07CE0883, 0x07CF0083, 0x07D30883, 0x07D40083, 0x07DC0883, 0x07DD0083, 0x07DE0078,
- 0x07DF0094, 0x07E60078, 0x07E70094, 0x07E80097, 0x07E90078, 0x08000071, 0x08150078, 0x08160083,
- 0x081800A7, 0x08190078, 0x081B0083, 0x081D0078, 0x0820017E, 0x0821017F, 0x08220180, 0x08230181,
- 0x08240182, 0x08250097, 0x08280071, 0x082B00A7, 0x082C0083, 0x082D0078, 0x085000B5, 0x08630078,
- 0x08680071, 0x087D0097, 0x087E0078, 0x08800071, 0x08AD0078, 0x08AF0071, 0x08D10078, 0x08D40071,
- 0x08FD0078, 0x09000071, 0x09240078, 0x09250071, 0x09270078, 0x09280071, 0x092B0078, 0x092D0071,
- 0x092F0078, 0x09300071, 0x09440078, 0x09450071, 0x09470078, 0x09480071, 0x09580078, 0x09590071,
- 0x095B0078, 0x095C0071, 0x095F0078, 0x09610071, 0x09630078, 0x09640071, 0x096B0078, 0x096C0071,
- 0x09880078, 0x09890071, 0x098B0078, 0x098C0071, 0x09AD0078, 0x09AF0083, 0x09B00097, 0x09B400AD,
- 0x09B500AE, 0x09B6012D, 0x09B7012E, 0x09B8012F, 0x09B90185, 0x09BA0186, 0x09BB0187, 0x09BC0188,
- 0x09BD0184, 0x09BE0078, 0x09C00071, 0x09C80054, 0x09CD0078, 0x09D00071, 0x09FA0078, 0x0A000071,
- 0x0B360097, 0x0B370071, 0x0B3B0078, 0x0B400071, 0x0B4D00B4, 0x0B4E0078, 0x0B500071, 0x0B750097,
- 0x0B770189, 0x0B780078, 0x0B800071, 0x0B860078, 0x0B870071, 0x0B890083, 0x0B8A0078, 0x0B900071,
- 0x0B990083, 0x0B9A0097, 0x0B9B0078, 0x0BA00071, 0x0BA90083, 0x0BAA0078, 0x0BB00071, 0x0BB60078,
- 0x0BB70071, 0x0BB80078, 0x0BB90083, 0x0BBA0078, 0x0BC00071, 0x0BDA00C2, 0x0BDB0083, 0x0BDF00A7,
- 0x0BE40083, 0x0BEA0097, 0x0BEB0081, 0x0BEC0097, 0x0BED0008, 0x0BEE0083, 0x0BEF0078, 0x0BF0017E,
- 0x0BF1017F, 0x0BF20180, 0x0BF30181, 0x0BF40182, 0x0BF50078, 0x0BF80106, 0x0BF90107, 0x0BFA0108,
- 0x0BFB0109, 0x0BFC010A, 0x0BFD0078, 0x0C000006, 0x0C050083, 0x0C070078, 0x0C08017E, 0x0C09017F,
- 0x0C0A0180, 0x0C0B0181, 0x0C0C0182, 0x0C0D0078, 0x0C100071, 0x0C210081, 0x0C220071, 0x0C3C0078,
- 0x0C400071, 0x0C540083, 0x0C550078, 0x0C800071, 0x0C8E0078, 0x0C900083, 0x0C9100A7, 0x0C930083,
- 0x0C9400C8, 0x0C960078, 0x0C9800A7, 0x0C9C0083, 0x0C9E0078, 0x0CA20006, 0x0CA3017E, 0x0CA4017F,
- 0x0CA50180, 0x0CA60181, 0x0CA70182, 0x0CA80071, 0x0CB70078, 0x0CB80071, 0x0CBA0078, 0x0CC00071,
- 0x0CD50078, 0x0CD800A7, 0x0CE00071, 0x0CE400A7, 0x0CE50078, 0x0CE8017E, 0x0CE9017F, 0x0CEA0180,
- 0x0CEB0181, 0x0CEC0182, 0x0CED0078, 0x0CEF0006, 0x0CF00054, 0x0D000071, 0x0D0B0083, 0x0D0C00A7,
- 0x0D0E0078, 0x0D0F0097, 0x0D100078, 0x0E800055, 0x0E967881, 0x0E970081, 0x0E987881, 0x0E9D0081,
- 0x0E9E7881, 0x0EB17055, 0x0EB50055, 0x0ECD7881, 0x0EE00083, 0x0EE20078, 0x0F000865, 0x0F4B0855,
- 0x0F4D098A, 0x0F4E0078, 0x0F500865, 0x0F7D0078, 0x0F8008C9, 0x0F8408CA, 0x0F8808C9, 0x0F8B0078,
- 0x0F8C08CA, 0x0F8F0078, 0x0F9008C9, 0x0F9408CA, 0x0F9808C9, 0x0F9C08CA, 0x0FA008C9, 0x0FA30078,
- 0x0FA408CA, 0x0FA70078, 0x0FA808C9, 0x0FAC08CA, 0x0FB008C9, 0x0FB408CA, 0x0FB808CB, 0x0FB908CC,
- 0x0FBB08CD, 0x0FBC08CE, 0x0FBD08CF, 0x0FBE08D0, 0x0FBF0078, 0x0FC008C9, 0x0FC408D1, 0x0FC808C9,
- 0x0FCC08D1, 0x0FD008C9, 0x0FD408D1, 0x0FD808C9, 0x0FD9098B, 0x0FDA0078, 0x0FDB0855, 0x0FDC08CA,
- 0x0FDD08D2, 0x0FDE1037, 0x0FE00837, 0x0FE1098B, 0x0FE20078, 0x0FE30855, 0x0FE408D5, 0x0FE60837,
- 0x0FE808C9, 0x0FE90855, 0x0FEA0078, 0x0FEB0855, 0x0FEC08CA, 0x0FED08D6, 0x0FEE0837, 0x0FF008C9,
- 0x0FF10855, 0x0FF20890, 0x0FF30855, 0x0FF408CA, 0x0FF508D7, 0x0FF60837, 0x0FF80078, 0x0FF9098B,
- 0x0FFA0078, 0x0FFB0855, 0x0FFC08D9, 0x0FFD08DA, 0x0FFE0837, 0x0FFF0078, 0x10000805, 0x10011005,
- 0x10035805, 0x10041005, 0x10050057, 0x1007018C, 0x10085899, 0x10090099, 0x100B1006, 0x100C018D,
- 0x100D00DB, 0x100E018D, 0x100F00DB, 0x10100006, 0x10121006, 0x10130006, 0x1014018E, 0x1015018F,
- 0x10160190, 0x10175853, 0x10180007, 0x10191007, 0x101A0006, 0x101B1006, 0x101C0126, 0x101D0006,
- 0x101F0038, 0x10200006, 0x10220009, 0x10231006, 0x10250006, 0x102B1006, 0x102C0006, 0x102F1005,
- 0x10300057, 0x10320078, 0x10350057, 0x10387855, 0x10390078, 0x103A7910, 0x103B7911, 0x103C7912,
- 0x103D780B, 0x103E7809, 0x103F7855, 0x1040705D, 0x1041705B, 0x10427110, 0x10437111, 0x10447112,
- 0x1045700B, 0x10467009, 0x10470078, 0x10487081, 0x104A0078, 0x10500008, 0x105B0078, 0x10680083,
- 0x106E0095, 0x10700083, 0x10710095, 0x10720083, 0x10760078, 0x10801054, 0x10831077, 0x10841054,
- 0x10852877, 0x10872855, 0x10882877, 0x10892855, 0x108A2877, 0x108B0054, 0x108C2877, 0x108F0054,
- 0x10901054, 0x10910054, 0x10950991, 0x10962877, 0x10972855, 0x10982877, 0x109A1071, 0x109C2855,
- 0x109D1054, 0x109E2855, 0x109F2877, 0x10A00019, 0x10A22877, 0x10A32855, 0x10A50019, 0x10A60078,
- 0x10A9305F, 0x10AF3106, 0x10B01192, 0x10B11193, 0x10B21194, 0x10B31195, 0x10B41196, 0x10B51197,
- 0x10B61198, 0x10B71199, 0x10B8119A, 0x10B9119B, 0x10BA119C, 0x10BB119D, 0x10BC119E, 0x10BD119F,
- 0x10BE11A0, 0x10BF11A1, 0x10C001A2, 0x10C101A3, 0x10C20078, 0x10C80019, 0x10CA0054, 0x10CD0819,
- 0x10CE0054, 0x10D10019, 0x10D20054, 0x10E60854, 0x10E70819, 0x10E80054, 0x10FA0019, 0x110000E8,
- 0x11020019, 0x110408FB, 0x110500FC, 0x11070019, 0x110800E8, 0x11090059, 0x110A01A4, 0x110B0019,
- 0x110D00E8, 0x11110019, 0x111500E8, 0x111610E8, 0x111800E8, 0x111A0019, 0x111C00E8, 0x111E00FE,
- 0x111F00E8, 0x112008E8, 0x112101A5, 0x112200E8, 0x112308E8, 0x112500E8, 0x11260019, 0x112900FE,
- 0x112B0019, 0x112F00E8, 0x11300019, 0x113200FE, 0x11360819, 0x113708FE, 0x113900FE, 0x113A08FE,
- 0x113B00FE, 0x113C08FE, 0x113D00FE, 0x114008FE, 0x114100FE, 0x114208FE, 0x114300FE, 0x114408FE,
- 0x114500FE, 0x11460019, 0x114700FD, 0x11490019, 0x115100FE, 0x11520019, 0x115300E8, 0x115401A6,
- 0x115608E8, 0x115800FE, 0x115C0019, 0x115F00E8, 0x11600019, 0x116400FD, 0x116601A7, 0x11670019,
- 0x116800FE, 0x11690019, 0x116B00FE, 0x117008FE, 0x117200FE, 0x117508FE, 0x11770019, 0x117800FE,
- 0x11790102, 0x117A00E8, 0x117B0103, 0x117C00E8, 0x117D0104, 0x117E0105, 0x117F00E8, 0x11800054,
- 0x118400FE, 0x11860054, 0x119000E8, 0x11910054, 0x11940809, 0x11950054, 0x119B0094, 0x11BD0054,
- 0x11CA0094, 0x11CB0054, 0x11CD0019, 0x11DA00BF, 0x11DB0054, 0x11EE0078, 0x12000054, 0x12130078,
- 0x12200054, 0x12250078, 0x123018C4, 0x123118C5, 0x123218C6, 0x123318C7, 0x1234191F, 0x1235191A,
- 0x1236191B, 0x1237191C, 0x1238191D, 0x1239191E, 0x123A10C4, 0x123B10C5, 0x123C10C6, 0x123D10C7,
- 0x123E111F, 0x123F111A, 0x1240111B, 0x1241111C, 0x1242111D, 0x1243111E, 0x1244105A, 0x124510E3,
- 0x124610E4, 0x124710E5, 0x124811A8, 0x124911A9, 0x124A11AA, 0x124B11AB, 0x124C11AC, 0x124D11AD,
- 0x124E1094, 0x125B1918, 0x12681919, 0x1275010B, 0x1276010C, 0x1277010D, 0x1278010E, 0x1279010F,
- 0x127A0106, 0x127B0107, 0x127C0108, 0x127D0109, 0x127E010A, 0x127F00C3, 0x12800054, 0x12DB0019,
- 0x12DC0054, 0x12E00019, 0x12E10054, 0x12FC0019, 0x13000054, 0x13370019, 0x13380054, 0x134E0078,
- 0x13500054, 0x13590078, 0x13800054, 0x13820078, 0x13830054, 0x13850078, 0x13860054, 0x13A90078,
- 0x13AC0054, 0x13AF0078, 0x13B00054, 0x13B4000A, 0x13BB00C4, 0x13BC00C5, 0x13BD00C6, 0x13BE00C7,
- 0x13BF011F, 0x13C000C4, 0x13C100C5, 0x13C200C6, 0x13C300C7, 0x13C4011F, 0x13C500C4, 0x13C600C5,
- 0x13C700C6, 0x13C800C7, 0x13C9011F, 0x13CA0078, 0x13CC0054, 0x13DF0078, 0x13E00019, 0x13E100FD,
- 0x13E20009, 0x13E30078, 0x13E80019, 0x13E900E8, 0x13EA00FD, 0x13EB0019, 0x13EE00FD, 0x13EF0019,
- 0x13F100FE, 0x13F3000A, 0x13F60078, 0x13F80019, 0x14000094, 0x14800019, 0x14C10009, 0x14C601AE,
- 0x14C701AF, 0x14C80009, 0x14CC0019, 0x14CD00E8, 0x14D80019, 0x14E000FE, 0x14E100E8, 0x14E200FE,
- 0x14E30019, 0x14E400E8, 0x14E50019, 0x14E700FD, 0x14E90019, 0x14EA00FE, 0x14EB0019, 0x14EC000A,
- 0x14EE0019, 0x14F000E8, 0x14F30019, 0x14F400E8, 0x14F50019, 0x14FA01B0, 0x14FB00E8, 0x14FC00FE,
- 0x14FD0019, 0x14FE000A, 0x14FF0019, 0x150500E8, 0x150E0019, 0x150F00E8, 0x15110019, 0x151400E8,
- 0x151500FD, 0x15170019, 0x151A00FE, 0x151B0019, 0x151E00FE, 0x151F0019, 0x152B00E8, 0x152C0019,
- 0x153200FE, 0x15330019, 0x153500E8, 0x15380019, 0x153900E8, 0x153A1019, 0x153B0019, 0x153C00FD,
- 0x153D00E8, 0x153E00FD, 0x154200E8, 0x154500FD, 0x154600E8, 0x154800FD, 0x154E00E8, 0x155000FD,
- 0x155100E8, 0x15520019, 0x155300FE, 0x155700FD, 0x155800E8, 0x155900FD, 0x155A00E8, 0x155D00FD,
- 0x156300E8, 0x156600FD, 0x156B0019, 0x157101B1, 0x15730019, 0x157600FE, 0x15770019, 0x157900E8,
- 0x157A0019, 0x157B00FD, 0x157D00E8, 0x157F0019, 0x15800054, 0x158A0078, 0x16000096, 0x16170078,
- 0x16180098, 0x162F0078, 0x16400065, 0x16720054, 0x16750078, 0x167C0006, 0x167E005F, 0x167F0006,
- 0x16800125, 0x16930078, 0x16980071, 0x16B30078, 0x16B77881, 0x16B80078, 0x16C00071, 0x16CB0078,
- 0x16D00071, 0x16D30078, 0x16D40071, 0x16D70078, 0x16D80071, 0x16DB0078, 0x16DC0071, 0x16DF0078,
- 0x16E00071, 0x16E30078, 0x16E40071, 0x16E70078, 0x16E80071, 0x16EB0078, 0x16EC0071, 0x16EF0078,
- 0x17000006, 0x170100E0, 0x17030006, 0x17040126, 0x17050006, 0x170600E0, 0x17070006, 0x170B0099,
- 0x170C0078, 0x170E00E0, 0x170F0078, 0x17400054, 0x174F1054, 0x17500054, 0x17791054, 0x177A0078,
- 0x17801054, 0x17EB0078, 0x17F80054, 0x17FE0078, 0x18000006, 0x18020081, 0x180301B2, 0x1804000A,
- 0x18090054, 0x180A000A, 0x180E00B4, 0x180F00BF, 0x181001B3, 0x181101B4, 0x181201B5, 0x181301B6,
- 0x181401B7, 0x18150083, 0x18180081, 0x181B0054, 0x181C11B8, 0x181D0081, 0x181E0006, 0x181F0054,
- 0x18200071, 0x18320871, 0x18350071, 0x18380871, 0x183A0071, 0x183B0871, 0x183D0071, 0x183E0871,
- 0x183F0071, 0x184B0078, 0x184C0083, 0x184D1037, 0x184E0081, 0x184F8071, 0x18500071, 0x18620871,
- 0x18650071, 0x18680871, 0x186A0071, 0x186B0871, 0x186D0071, 0x186E0871, 0x186F0071, 0x187B0871,
- 0x187D0006, 0x187E0081, 0x187F8071, 0x18800078, 0x18820071, 0x18960078, 0x18981071, 0x18C70078,
- 0x18C80094, 0x18C978B6, 0x18CA78B7, 0x18CB7894, 0x18D00071, 0x18DC0078, 0x18E00054, 0x18E80078,
- 0x18F80071, 0x19001094, 0x190E1054, 0x190F0078, 0x191010B6, 0x191110B7, 0x191210B8, 0x191310B9,
- 0x191410B0, 0x19151094, 0x19220078, 0x192819B9, 0x192919BA, 0x192A19BB, 0x192B19BC, 0x192C19BD,
- 0x192D19BE, 0x192E19BF, 0x192F19C0, 0x19301894, 0x193E1854, 0x193F0094, 0x194018B6, 0x194118B7,
- 0x194218B8, 0x194318B9, 0x194418B0, 0x19451894, 0x195819C1, 0x195919C2, 0x195A19C3, 0x195B19C4,
- 0x195C19C5, 0x195D19C6, 0x195E19C7, 0x195F19C8, 0x19601094, 0x19666854, 0x19681894, 0x197F0078,
- 0x19806894, 0x19AC1094, 0x19B86894, 0x19BB6854, 0x19BD6894, 0x19EF6854, 0x19F01094, 0x19FF6854,
- 0x1A000071, 0x26DB0078, 0x26E00054, 0x27000071, 0x4FDE0078, 0x50000071, 0x500A0081, 0x500B0071,
- 0x52460078, 0x52480054, 0x52630078, 0x53800037, 0x538B0078, 0x54000071, 0x54050083, 0x54060071,
- 0x541100A7, 0x54120083, 0x541300A7, 0x54140054, 0x54160078, 0x56000071, 0x6BD20078, 0x6C00013E,
- 0x7000013F, 0x7C800871, 0x7D070071, 0x7D0A0871, 0x7D0F0071, 0x7D120871, 0x7D130071, 0x7D150871,
- 0x7D170078, 0x7D180871, 0x7D350078, 0x7D380871, 0x7D6D0078, 0x7D801055, 0x7D830078, 0x7D891055,
- 0x7D8C0078, 0x7D8E089B, 0x7D90289B, 0x7D94280B, 0x7D95089B, 0x7D9B0078, 0x7D9C089B, 0x7D9E0078,
- 0x7DA0089B, 0x7DA20078, 0x7DA3089B, 0x7DA7109B, 0x7DA8209E, 0x7DAA489E, 0x7DAB209E, 0x7DAC489E,
- 0x7DAD209E, 0x7DAE489E, 0x7DAF209E, 0x7DB0489E, 0x7DB1209E, 0x7DB2489E, 0x7DB3209E, 0x7DB4489E,
- 0x7DB5209E, 0x7DB6489E, 0x7DB7209E, 0x7DB8489E, 0x7DB9209E, 0x7DBA489E, 0x7DBB209E, 0x7DBC489E,
- 0x7DBD209E, 0x7DBE489E, 0x7DBF209E, 0x7DC0489E, 0x7DC1209E, 0x7DC8489E, 0x7DC9209E, 0x7DCA489E,
- 0x7DCB209E, 0x7DCC489E, 0x7DCD209E, 0x7DCE489E, 0x7DCF209E, 0x7DD1489E, 0x7DD2209E, 0x7DD4489E,
- 0x7DD5209E, 0x7DD6489E, 0x7DD7209E, 0x7DD90078, 0x7DE9409E, 0x7DEA389E, 0x7DEB409E, 0x7DEF209E,
- 0x7DF3489E, 0x7DF5209E, 0x7DFC409E, 0x7DFD389E, 0x7DFE209E, 0x7DFF489E, 0x7E00409E, 0x7E32209E,
- 0x7E4B389E, 0x7E6F489E, 0x7E7A409E, 0x7E88209E, 0x7E96389E, 0x7E9A489E, 0x7E9E409E, 0x7E9F00BF,
- 0x7EA00078, 0x7EA8209E, 0x7EA9389E, 0x7EAD209E, 0x7EAE389E, 0x7EAF209E, 0x7EB0389E, 0x7EB3209E,
- 0x7EB5389E, 0x7EB7209E, 0x7EB9389E, 0x7EBA209E, 0x7EBB389E, 0x7EBC209E, 0x7EBE389E, 0x7EBF209E,
- 0x7EC1389E, 0x7EC2209E, 0x7EC4389E, 0x7EC5209E, 0x7EC6389E, 0x7EC80078, 0x7EC9389E, 0x7ECB209E,
- 0x7ECE389E, 0x7ECF209E, 0x7EDA389E, 0x7EDB209E, 0x7EE1389E, 0x7EE3209E, 0x7EE40078, 0x7EF8409E,
- 0x7EFE0054, 0x7EFF0078, 0x7F000083, 0x7F088006, 0x7F0B80B4, 0x7F0C8006, 0x7F0D0078, 0x7F100083,
- 0x7F120078, 0x7F188099, 0x7F198038, 0x7F1A80B4, 0x7F220006, 0x7F2380B4, 0x7F241006, 0x7F261038,
- 0x7F286006, 0x7F290078, 0x7F2A600C, 0x7F2B6006, 0x7F2C60B4, 0x7F2F6007, 0x7F306006, 0x7F31600D,
- 0x7F326019, 0x7F330078, 0x7F346008, 0x7F356006, 0x7F360078, 0x7F38489E, 0x7F39009E, 0x7F3A0078,
- 0x7F3B489E, 0x7F40409E, 0x7F45389E, 0x7F46409E, 0x7F48389E, 0x7F49409E, 0x7F4B389E, 0x7F4C409E,
- 0x7F4D389E, 0x7F4E409E, 0x7F4F389E, 0x7F50409E, 0x7F51389E, 0x7F52409E, 0x7F53389E, 0x7F54409E,
- 0x7F59389E, 0x7F5A409E, 0x7F5B389E, 0x7F5C409E, 0x7F5D389E, 0x7F5E409E, 0x7F5F389E, 0x7F60409E,
- 0x7F61389E, 0x7F62409E, 0x7F63389E, 0x7F64409E, 0x7F65389E, 0x7F66409E, 0x7F67389E, 0x7F68409E,
- 0x7F69389E, 0x7F6A409E, 0x7F6B389E, 0x7F6C409E, 0x7F6D389E, 0x7F6E409E, 0x7F6F389E, 0x7F70409E,
- 0x7F71389E, 0x7F72409E, 0x7F73389E, 0x7F74409E, 0x7F75389E, 0x7F76409E, 0x7F79389E, 0x7F7A409E,
- 0x7F7E0078, 0x7F7F0057, 0x7F808806, 0x7F818807, 0x7F838806, 0x7F84880A, 0x7F85880B, 0x7F86880D,
- 0x7F87880C, 0x7F88880F, 0x7F898811, 0x7F8A8813, 0x7F8B8815, 0x7F8C8817, 0x7F8D8806, 0x7F8E8819,
- 0x7F8F8806, 0x7F908860, 0x7F9D8835, 0x7F9E8836, 0x7F9F8838, 0x7FA08861, 0x7FAD8835, 0x7FAE8836,
- 0x7FAF8809, 0x7FB05006, 0x7FB1500A, 0x7FB25006, 0x7FB35071, 0x7FCF5081, 0x7FD05071, 0x7FDF0078,
- 0x7FE15071, 0x7FE40078, 0x7FE55071, 0x7FE80078, 0x7FE95071, 0x7FEC0078, 0x7FED5071, 0x7FEE0078,
- 0x7FF08808, 0x7FF18837, 0x7FF28808, 0x7FF30078, 0x7FF45019, 0x7FF65054, 0x7FF70078, 0x7FFC0141,
- 0x7FFE0054, 0x7FFF0078, 0x80000071, 0x80130078, 0x80140071, 0x801D0078, 0x801E0071, 0x80270078,
- 0x80280071, 0x802F0078, 0x80400071, 0x807D0078, 0x80800006, 0x80810078, 0x808300AD, 0x808400AE,
- 0x8085012D, 0x8086012E, 0x8087012F, 0x80880185, 0x80890186, 0x808A0187, 0x808B0188, 0x808C0184,
- 0x808D01C9, 0x808E01CA, 0x808F01CB, 0x809001CC, 0x809101CD, 0x809201CE, 0x809301CF, 0x809401D0,
- 0x809500BE, 0x809601D1, 0x809701D2, 0x809801D3, 0x809901D4, 0x809A0078, 0x809B0094, 0x80A0014E,
- 0x80A10152, 0x80A20153, 0x80A30157, 0x80A40154, 0x80A50155, 0x80A60156, 0x80A70152, 0x80A80150,
- 0x80A90153, 0x80AA01D5, 0x80AB0154, 0x80AC014F, 0x80AD0158, 0x80AF0152, 0x80B00154, 0x80B201D6,
- 0x80B30150, 0x80B501D7, 0x80B60153, 0x80B80156, 0x80B90152, 0x80BA005F, 0x80BC0054, 0x80C50078,
- 0x81800071, 0x818F0078, 0x8190012D, 0x819100BB, 0x81920078, 0x81980071, 0x81A50078, 0x81C00071,
- 0x81CF0097, 0x81D00071, 0x81E20078, 0x81E40071, 0x81E8014F, 0x81E90154, 0x81EA0155, 0x81EB0078,
- 0x8200015B, 0x8214015C, 0x82280071, 0x824F0078, 0x8250017E, 0x8251017F, 0x82520180, 0x82530181,
- 0x82540182, 0x82550078, 0x8400009B, 0x84030078, 0x8405009B, 0x841C0078, 0x841F009B, 0x84200078,
- 0x85000083, 0x85030078, 0x85060083, 0x8508009B, 0x851A0078, 0x851C0083, 0x851D0078, 0x851F0083,
- 0x852001D8, 0x852101D9, 0x852201DA, 0x852301DB, 0x85240078, 0x8528009A, 0x852C0078, 0xE8000094,
- 0xE87B0078, 0xE8800094, 0xE8930078, 0xE8950094, 0xE8AF0894, 0xE8B200A7, 0xE8B30083, 0xE8B50094,
- 0xE8B600A7, 0xE8B90057, 0xE8BD0083, 0xE8C10094, 0xE8C20083, 0xE8C60094, 0xE8D50083, 0xE8D70094,
- 0xE8DD0894, 0xE8E00094, 0xE8EF0078, 0xE9000054, 0xE9210083, 0xE9220054, 0xE9230078, 0xE9800054,
- 0xE9AB0078, 0xEA002877, 0xEA0D2855, 0xEA1A2877, 0xEA272855, 0xEA2A0078, 0xEA2B2855, 0xEA342877,
- 0xEA412855, 0xEA4E0078, 0xEA4F2877, 0xEA500078, 0xEA522877, 0xEA530078, 0xEA542877, 0xEA560078,
- 0xEA572877, 0xEA5B2855, 0xEA682877, 0xEA752855, 0xEA822877, 0xEA850078, 0xEA862877, 0xEA8A0078,
- 0xEA8B2877, 0xEA8E0078, 0xEA8F2855, 0xEA9C2877, 0xEA9F0078, 0xEAA02877, 0xEAA20078, 0xEAA52877,
- 0xEAA80078, 0xEAA92855, 0xEAB62877, 0xEAC32855, 0xEAD02877, 0xEADD2855, 0xEAEA2877, 0xEAF72855,
- 0xEB042877, 0xEB112855, 0xEB1E2877, 0xEB2B2855, 0xEB382877, 0xEB452855, 0xEB530078, 0xEB542877,
- 0xEB6029DC, 0xEB612855, 0xEB6D29DC, 0xEB6E2855, 0xEB712877, 0xEB7D29DC, 0xEB7E2855, 0xEB8A29DC,
- 0xEB8B2855, 0xEB8E2877, 0xEB9A29DC, 0xEB9B2855, 0xEBA729DC, 0xEBA82855, 0xEBAB2877, 0xEBB729DC,
- 0xEBB82855, 0xEBC429DC, 0xEBC52855, 0xEBC82877, 0xEBD429DC, 0xEBD52855, 0xEBE129DC, 0xEBE22855,
- 0xEBE50078, 0xEBE7280F, 0xEBE82811, 0xEBE92813, 0xEBEA2815, 0xEBEB2817, 0xEBEC280F, 0xEBED2811,
- 0xEBEE2813, 0xEBEF2815, 0xEBF02817, 0xEBF1280F, 0xEBF22811, 0xEBF32813, 0xEBF42815, 0xEBF52817,
- 0xEBF6280F, 0xEBF72811, 0xEBF82813, 0xEBF92815, 0xEBFA2817, 0xEBFB280F, 0xEBFC2811, 0xEBFD2813,
- 0xEBFE2815, 0xEBFF2817, 0xEC000078
- };
-
- static const uint32_t a17[] = {
- 0x00000071, 0x536B0078, 0x7C000871, 0x7D0F0078
- };
-
- static const uint32_t a23[] = {
- 0x00000057, 0x00010078, 0x00100057, 0x00400078, 0x00800083, 0x00F80078, 0x8000013F, 0xFFFF0078
- };
-
- static const uint32_t a24[] = {
- 0x0000013F, 0x7FFF0078
- };
-
-
- // The full set of all arrays to be searched.
- static const Range FULL_DATA[] = {
- {sizeof(a0)/sizeof(uint32_t), a0},
- {sizeof(a1)/sizeof(uint32_t), a1},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {sizeof(a7)/sizeof(uint32_t), a7},
- {sizeof(a8)/sizeof(uint32_t), a8},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {sizeof(a16)/sizeof(uint32_t), a16},
- {sizeof(a17)/sizeof(uint32_t), a17},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {sizeof(a23)/sizeof(uint32_t), a23},
- {sizeof(a24)/sizeof(uint32_t), a24},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0}
- };
-
- // Array of uppercase differences
- static const short UCDIFF[] = {
- 0, -32, 743, 121, -1, -232, -300, 97,
- 163, 130, 56, -2, -79, -210, -206, -205,
- -202, -203, -207, -209, -211, -213, -214, -218,
- -217, -219, -83, 84, -38, -37, -31, -64,
- -63, -62, -57, -47, -54, -86, -80, 7,
- -96, -48, -59, 8, 74, 86, 100, 128,
- 112, 126, 9, -7205, -16, -26, -7264, -40
- };
-
- // Array of lowercase differences
- static const short LCDIFF[] = {
- 0, 32, 1, -199, -121, 210, 206, 205,
- 79, 202, 203, 207, 211, 209, 213, 214,
- 218, 217, 219, 2, -97, -56, -130, -163,
- 83, 38, 37, 64, 63, -60, -7, 80,
- 48, 7264, -8, -74, -9, -86, -100, -112,
- -128, -126, -7517, -8383, -8262, 16, 26, 40
- };
-
- // Array of titlecase differences
- static const short TCDIFF[] = {
- 3, 1, 0, -1
- };
-
- // Array of mirrored character differences
- static const short MIRROR_DIFF[] = {
- 0, 1, -1, 2, -2, 16, -16, 3,
- -3, 2016, 138, 1824, 2104, 2108, 2106, -138,
- 8, 7, -8, -7, -1824, -2016, -2104, -2106,
- -2108
- };
-
- // Array of all possible numeric values
- static const int NUMERICS[] = {
- -1, 0, 1, 2, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 27, 28, 29, 30,
- 31, 32, 33, 34, 35, -2, 100, 1000,
- 40, 50, 60, 70, 80, 90, 10000, 500,
- 5000, 36, 37, 38, 39, 41, 42, 43,
- 44, 45, 46, 47, 48, 49, 200, 300,
- 400, 600, 700, 800, 900, 2000, 3000, 4000,
- 6000, 7000, 8000, 9000, 20000, 30000, 40000, 50000,
- 60000, 70000, 80000, 90000
- };
-
- // All possible packed data values, no duplicates
- static const uint32_t PACKED_DATA[] = {
- 0x00000000, 0x0000012F, 0x0000016F, 0x0000014F, 0x0000018F, 0x0000018C, 0x000001B8, 0x000000B8,
- 0x000000BA, 0x020005B5, 0x040005B6, 0x00000099, 0x000000F8, 0x00000094, 0x02000069, 0x04000069,
- 0x06000069, 0x08000069, 0x0A000069, 0x0C000069, 0x0E000069, 0x10000069, 0x12000069, 0x14000069,
- 0x060005B9, 0x000001B9, 0x080005B9, 0x16020001, 0x18020001, 0x1A020001, 0x1C020001, 0x1E020001,
- 0x20020001, 0x22020001, 0x24020001, 0x26020001, 0x28020001, 0x2A020001, 0x2C020001, 0x2E020001,
- 0x30020001, 0x32020001, 0x34020001, 0x36020001, 0x38020001, 0x3A020001, 0x3C020001, 0x3E020001,
- 0x40020001, 0x42020001, 0x44020001, 0x46020001, 0x48020001, 0x060005B5, 0x080005B6, 0x000001BB,
- 0x000001B7, 0x16000802, 0x18000802, 0x1A000802, 0x1C000802, 0x1E000802, 0x20000802, 0x22000802,
- 0x24000802, 0x26000802, 0x28000802, 0x2A000802, 0x2C000802, 0x2E000802, 0x30000802, 0x32000802,
- 0x34000802, 0x36000802, 0x38000802, 0x3A000802, 0x3C000802, 0x3E000802, 0x40000802, 0x42000802,
- 0x44000802, 0x46000802, 0x48000802, 0x000000EC, 0x000001BC, 0x00000002, 0x0A0005BD, 0x00000130,
- 0x000000BC, 0x000000B9, 0x0600006B, 0x0800006B, 0x00001002, 0x0400006B, 0x0C0005BE, 0x4A0001AB,
- 0x00020001, 0x00000802, 0x00001802, 0x00040001, 0x00060001, 0x00002002, 0x00080001, 0x000C0001,
- 0x000E0001, 0x00100001, 0x00140001, 0x00160001, 0x00180001, 0x00004002, 0x00004802, 0x00200001,
- 0x00220001, 0x00000005, 0x00A60001, 0x01805802, 0x01042003, 0x00280001, 0x002C0001, 0x00000001,
- 0x00000000, 0x00007002, 0x00007802, 0x00009802, 0x0000A802, 0x0000B802, 0x0000C002, 0x0000C802,
- 0x0000D002, 0x00000004, 0x000001A4, 0x00000106, 0x00320001, 0x00340001, 0x00360001, 0x00380001,
- 0x0000E002, 0x0000E802, 0x0000F002, 0x0000F802, 0x00010002, 0x00010802, 0x00012002, 0x00012802,
- 0x00013802, 0x003A0001, 0x003E0001, 0x00013002, 0x0000001C, 0x00000107, 0x00400001, 0x00000018,
- 0x00014802, 0x000001B4, 0x00000038, 0x00000025, 0x00000050, 0x00000058, 0x00000045, 0x00000044,
- 0x020000C9, 0x060000C9, 0x0A0000C9, 0x0E0000C9, 0x120000C9, 0x000000D8, 0x0000005C, 0x00000008,
- 0x02000009, 0x06000009, 0x0A000009, 0x0E000009, 0x12000009, 0x0400000B, 0x0800000B, 0x0000000B,
- 0x1600000B, 0x4E00000B, 0x00000006, 0x4A00000B, 0x000001B5, 0x00420001, 0x0600000B, 0x0A00000B,
- 0x0E00000B, 0x1200000B, 0x3E00000B, 0x5200000B, 0x5600000B, 0x5A00000B, 0x5C00000B, 0x000001B6,
- 0x2400000A, 0x2800000A, 0x00000010, 0x020001AB, 0x060001AB, 0x0A0001AB, 0x0E0001AB, 0x120001AB,
- 0x00000108, 0x00015802, 0x00440001, 0x00016002, 0x00016802, 0x00017002, 0x00017802, 0x00018002,
- 0x00018802, 0x00440003, 0x00460001, 0x00480003, 0x00019802, 0x004A0001, 0x004C0001, 0x004E0001,
- 0x003C0001, 0x00500001, 0x00520001, 0x000001BD, 0x0000018D, 0x000001D0, 0x00000250, 0x00000230,
- 0x040005BE, 0x000000F9, 0x0200006B, 0x0A00006B, 0x0E00006B, 0x1200006B, 0x00540001, 0x00560001,
- 0x000005B9, 0x045A000A, 0x085A000A, 0x0C5A000A, 0x105A000A, 0x145A000A, 0x185A000A, 0x525A000A,
- 0x5E5A000A, 0x0401A00A, 0x0801A00A, 0x0C01A00A, 0x1001A00A, 0x1401A00A, 0x1801A00A, 0x5201A00A,
- 0x5E01A00A, 0x4E00000A, 0x5C00000A, 0x0E0005B9, 0x100005B9, 0x020005B9, 0x040005B9, 0x160005B9,
- 0x180005B9, 0x1A0005B9, 0x200005B9, 0x220005B9, 0x240005B9, 0x260005B9, 0x040001AB, 0x080001AB,
- 0x0C0001AB, 0x100001AB, 0x140001AB, 0x180001AB, 0x1C0001AB, 0x200001AB, 0x240001AB, 0x280001AB,
- 0x0C00006B, 0x1000006B, 0x1400006B, 0x1800006B, 0x1C00006B, 0x2000006B, 0x2400006B, 0x2800006B,
- 0x005C001C, 0x0001A81C, 0x1A0001AB, 0x1E0001AB, 0x220001AB, 0x260001AB, 0x2A0001AB, 0x160001AB,
- 0x020005B6, 0x100005B6, 0x280005B9, 0x2C0005B9, 0x300005B9, 0x0001B002, 0x020005BD, 0x0600000A,
- 0x0A00000A, 0x0E00000A, 0x1200000A, 0x1600000A, 0x3E00000A, 0x0C00000B, 0x1000000B, 0x1400000B,
- 0x2E0001AB, 0x320001AB, 0x360001AB, 0x3A0001AB, 0x3E0001AB, 0x420001AB, 0x460001AB, 0x640001AB,
- 0x680001AB, 0x6A0001AB, 0x6E0001AB, 0x720001AB, 0x760001AB, 0x7A0001AB, 0x00000013, 0x00000012,
- 0x0000005A, 0x000001B0, 0x7C00000B, 0x8000000B, 0x8200000B, 0x8600000B, 0x8C00000B, 0x6000000B,
- 0x9200000B, 0x9600000B, 0x9800000B, 0x9C00000B, 0xA000000B, 0xA400000B, 0x4A0001AA, 0x040001AA,
- 0x520001AA, 0x600001AA, 0x0C0001AA, 0x5E0001AA, 0x160001AA, 0x4C0001AA, 0x4E0001AA, 0x9E0001AA,
- 0x060001AA, 0x8800000A, 0x2A0001AA, 0x005E0001, 0x0001B802, 0x0400002B, 0x0800002B, 0x1600002B,
- 0x4C00002B, 0x00002802, 0x00003002, 0x000A0001, 0x00120001, 0x00003802, 0x001A0001, 0x001C0001,
- 0x001E0001, 0x00240001, 0x00005002, 0x00006002, 0x002A0001, 0x002E0001, 0x00300001, 0x00006802,
- 0x00008002, 0x00008802, 0x00009002, 0x0000A002, 0x0000B002, 0x0000D906, 0x00011002, 0x00011802,
- 0x00014002, 0x040000C9, 0x080000C9, 0x0C0000C9, 0x100000C9, 0x140000C9, 0x04000009, 0x08000009,
- 0x0C000009, 0x10000009, 0x14000009, 0x2200000B, 0x4C00000B, 0x2A00000B, 0x5000000B, 0x5400000B,
- 0x5800000B, 0x2600000A, 0x00015002, 0x00019002, 0x00000030, 0x000001BE, 0x0000014E, 0x00000210,
- 0x000001F0, 0x00580001, 0x065A000A, 0x0A5A000A, 0x0E5A000A, 0x125A000A, 0x165A000A, 0x1A5A000A,
- 0x4C5A000A, 0x4E5A000A, 0x0601A00A, 0x0A01A00A, 0x0E01A00A, 0x1201A00A, 0x1601A00A, 0x1A01A00A,
- 0x4C01A00A, 0x4E01A00A, 0x6000000A, 0x0000000A, 0x120005B9, 0x140005B9, 0x1C0005B9, 0x1E0005B9,
- 0x1600006B, 0x1A00006B, 0x1E00006B, 0x2200006B, 0x2600006B, 0x2A00006B, 0x0E0005B5, 0x040005B5,
- 0x2A0005B9, 0x2E0005B9, 0x0200000A, 0x0400000A, 0x0800000A, 0x0C00000A, 0x1000000A, 0x1400000A,
- 0x2A00000A, 0x2C0001AB, 0x300001AB, 0x340001AB, 0x380001AB, 0x3C0001AB, 0x400001AB, 0x440001AB,
- 0x480001AB, 0x620001AB, 0x660001AB, 0x500001AB, 0x6C0001AB, 0x700001AB, 0x740001AB, 0x780001AB,
- 0x520001AB, 0x7E00000B, 0x5E00000B, 0x8400000B, 0x8800000B, 0x8A00000B, 0x8E00000B, 0x9000000B,
- 0x9400000B, 0x9A00000B, 0x9E00000B, 0xA200000B, 0xA600000B, 0x5C0001AA, 0x3E0001AA, 0x7E0001AA,
- 0x0600002B, 0x0A00002B, 0x2A00002B, 0x4E00002B, 0x00000019
- };
-}
diff --git a/libs/utils/executablepath_darwin.cpp b/libs/utils/executablepath_darwin.cpp
deleted file mode 100644
index 2e3c3a0..0000000
--- a/libs/utils/executablepath_darwin.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.
- */
-
-#include <utils/executablepath.h>
-#import <Carbon/Carbon.h>
-#include <unistd.h>
-
-void executablepath(char s[PATH_MAX])
-{
- ProcessSerialNumber psn;
- GetCurrentProcess(&psn);
- CFDictionaryRef dict;
- dict = ProcessInformationCopyDictionary(&psn, 0xffffffff);
- CFStringRef value = (CFStringRef)CFDictionaryGetValue(dict,
- CFSTR("CFBundleExecutable"));
- CFStringGetCString(value, s, PATH_MAX+1, kCFStringEncodingUTF8);
-}
-
diff --git a/libs/utils/executablepath_linux.cpp b/libs/utils/executablepath_linux.cpp
deleted file mode 100644
index b8d2a3d..0000000
--- a/libs/utils/executablepath_linux.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-#include <utils/executablepath.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <limits.h>
-#include <stdio.h>
-
-void executablepath(char exe[PATH_MAX])
-{
- char proc[100];
- sprintf(proc, "/proc/%d/exe", getpid());
-
- int err = readlink(proc, exe, PATH_MAX);
-}
-
diff --git a/libs/utils/futex_synchro.c b/libs/utils/futex_synchro.c
deleted file mode 100644
index ba19520..0000000
--- a/libs/utils/futex_synchro.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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.
- */
-
-#include <stdio.h>
-#include <limits.h>
-
-#include <sys/time.h>
-#include <sched.h>
-
-#include <errno.h>
-
-#include <private/utils/futex_synchro.h>
-
-
-// This futex glue code is need on desktop linux, but is already part of bionic.
-#if !defined(HAVE_FUTEX_WRAPPERS)
-
-#include <sys/syscall.h>
-typedef unsigned int u32;
-#define asmlinkage
-#define __user
-#include <linux/futex.h>
-#include <utils/Atomic.h>
-
-
-int futex (int *uaddr, int op, int val, const struct timespec *timeout, int *uaddr2, int val3)
-{
- int err = syscall(SYS_futex, uaddr, op, val, timeout, uaddr2, val3);
- return err == 0 ? 0 : -errno;
-}
-
-int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout)
-{
- return futex((int*)ftx, FUTEX_WAIT, val, timeout, NULL, 0);
-}
-
-int __futex_wake(volatile void *ftx, int count)
-{
- return futex((int*)ftx, FUTEX_WAKE, count, NULL, NULL, 0);
-}
-
-int __atomic_cmpxchg(int old, int _new, volatile int *ptr)
-{
- return android_atomic_cmpxchg(old, _new, ptr);
-}
-
-int __atomic_swap(int _new, volatile int *ptr)
-{
- return android_atomic_swap(_new, ptr);
-}
-
-int __atomic_dec(volatile int *ptr)
-{
- return android_atomic_dec(ptr);
-}
-
-#else // !defined(__arm__)
-
-int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout);
-int __futex_wake(volatile void *ftx, int count);
-
-int __atomic_cmpxchg(int old, int _new, volatile int *ptr);
-int __atomic_swap(int _new, volatile int *ptr);
-int __atomic_dec(volatile int *ptr);
-
-#endif // !defined(HAVE_FUTEX_WRAPPERS)
-
-
-// lock states
-//
-// 0: unlocked
-// 1: locked, no waiters
-// 2: locked, maybe waiters
-
-void futex_mutex_init(futex_mutex_t *m)
-{
- m->value = 0;
-}
-
-int futex_mutex_lock(futex_mutex_t *m, unsigned msec)
-{
- if(__atomic_cmpxchg(0, 1, &m->value) == 0) {
- return 0;
- }
- if(msec == FUTEX_WAIT_INFINITE) {
- while(__atomic_swap(2, &m->value) != 0) {
- __futex_wait(&m->value, 2, 0);
- }
- } else {
- struct timespec ts;
- ts.tv_sec = msec / 1000;
- ts.tv_nsec = (msec % 1000) * 1000000;
- while(__atomic_swap(2, &m->value) != 0) {
- if(__futex_wait(&m->value, 2, &ts) == -ETIMEDOUT) {
- return -1;
- }
- }
- }
- return 0;
-}
-
-int futex_mutex_trylock(futex_mutex_t *m)
-{
- if(__atomic_cmpxchg(0, 1, &m->value) == 0) {
- return 0;
- }
- return -1;
-}
-
-void futex_mutex_unlock(futex_mutex_t *m)
-{
- if(__atomic_dec(&m->value) != 1) {
- m->value = 0;
- __futex_wake(&m->value, 1);
- }
-}
-
-/* XXX *technically* there is a race condition that could allow
- * XXX a signal to be missed. If thread A is preempted in _wait()
- * XXX after unlocking the mutex and before waiting, and if other
- * XXX threads call signal or broadcast UINT_MAX times (exactly),
- * XXX before thread A is scheduled again and calls futex_wait(),
- * XXX then the signal will be lost.
- */
-
-void futex_cond_init(futex_cond_t *c)
-{
- c->value = 0;
-}
-
-int futex_cond_wait(futex_cond_t *c, futex_mutex_t *m, unsigned msec)
-{
- if(msec == FUTEX_WAIT_INFINITE){
- int oldvalue = c->value;
- futex_mutex_unlock(m);
- __futex_wait(&c->value, oldvalue, 0);
- futex_mutex_lock(m, FUTEX_WAIT_INFINITE);
- return 0;
- } else {
- int oldvalue = c->value;
- struct timespec ts;
- ts.tv_sec = msec / 1000;
- ts.tv_nsec = (msec % 1000) * 1000000;
- futex_mutex_unlock(m);
- const int err = __futex_wait(&c->value, oldvalue, &ts);
- futex_mutex_lock(m, FUTEX_WAIT_INFINITE);
- return err;
- }
-}
-
-void futex_cond_signal(futex_cond_t *c)
-{
- __atomic_dec(&c->value);
- __futex_wake(&c->value, 1);
-}
-
-void futex_cond_broadcast(futex_cond_t *c)
-{
- __atomic_dec(&c->value);
- __futex_wake(&c->value, INT_MAX);
-}
-
diff --git a/libs/utils/misc.cpp b/libs/utils/misc.cpp
deleted file mode 100644
index dc89d15..0000000
--- a/libs/utils/misc.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Miscellaneous utility functions.
-//
-#include <utils/misc.h>
-
-#include <sys/stat.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <stdio.h>
-
-using namespace android;
-
-namespace android {
-
-/*
- * Like strdup(), but uses C++ "new" operator instead of malloc.
- */
-char* strdupNew(const char* str)
-{
- char* newStr;
- int len;
-
- if (str == NULL)
- return NULL;
-
- len = strlen(str);
- newStr = new char[len+1];
- memcpy(newStr, str, len+1);
-
- return newStr;
-}
-
-/*
- * Concatenate an argument vector.
- */
-char* concatArgv(int argc, const char* const argv[])
-{
- char* newStr = NULL;
- int len, totalLen, posn, idx;
-
- /*
- * First, figure out the total length.
- */
- totalLen = idx = 0;
- while (1) {
- if (idx == argc || argv[idx] == NULL)
- break;
- if (idx)
- totalLen++; // leave a space between args
- totalLen += strlen(argv[idx]);
- idx++;
- }
-
- /*
- * Alloc the string.
- */
- newStr = new char[totalLen +1];
- if (newStr == NULL)
- return NULL;
-
- /*
- * Finally, allocate the string and copy data over.
- */
- idx = posn = 0;
- while (1) {
- if (idx == argc || argv[idx] == NULL)
- break;
- if (idx)
- newStr[posn++] = ' ';
-
- len = strlen(argv[idx]);
- memcpy(&newStr[posn], argv[idx], len);
- posn += len;
-
- idx++;
- }
-
- assert(posn == totalLen);
- newStr[posn] = '\0';
-
- return newStr;
-}
-
-/*
- * Count the #of args in an argument vector. Don't count the final NULL.
- */
-int countArgv(const char* const argv[])
-{
- int count = 0;
-
- while (argv[count] != NULL)
- count++;
-
- return count;
-}
-
-
-#include <stdio.h>
-/*
- * Get a file's type.
- */
-FileType getFileType(const char* fileName)
-{
- struct stat sb;
-
- if (stat(fileName, &sb) < 0) {
- if (errno == ENOENT || errno == ENOTDIR)
- return kFileTypeNonexistent;
- else {
- fprintf(stderr, "getFileType got errno=%d on '%s'\n",
- errno, fileName);
- return kFileTypeUnknown;
- }
- } else {
- if (S_ISREG(sb.st_mode))
- return kFileTypeRegular;
- else if (S_ISDIR(sb.st_mode))
- return kFileTypeDirectory;
- else if (S_ISCHR(sb.st_mode))
- return kFileTypeCharDev;
- else if (S_ISBLK(sb.st_mode))
- return kFileTypeBlockDev;
- else if (S_ISFIFO(sb.st_mode))
- return kFileTypeFifo;
-#ifdef HAVE_SYMLINKS
- else if (S_ISLNK(sb.st_mode))
- return kFileTypeSymlink;
- else if (S_ISSOCK(sb.st_mode))
- return kFileTypeSocket;
-#endif
- else
- return kFileTypeUnknown;
- }
-}
-
-/*
- * Get a file's modification date.
- */
-time_t getFileModDate(const char* fileName)
-{
- struct stat sb;
-
- if (stat(fileName, &sb) < 0)
- return (time_t) -1;
-
- return sb.st_mtime;
-}
-
-/*
- * Round up to the next highest power of 2.
- *
- * Found on http://graphics.stanford.edu/~seander/bithacks.html.
- */
-unsigned int roundUpPower2(unsigned int val)
-{
- val--;
- val |= val >> 1;
- val |= val >> 2;
- val |= val >> 4;
- val |= val >> 8;
- val |= val >> 16;
- val++;
-
- return val;
-}
-
-}; // namespace android
-
diff --git a/libs/utils/ported.cpp b/libs/utils/ported.cpp
deleted file mode 100644
index 656e46f..0000000
--- a/libs/utils/ported.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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.
- */
-
-//
-// Ports of standard functions that don't exist on a specific platform.
-//
-// Note these are NOT in the "android" namespace.
-//
-#include <utils/ported.h>
-
-#if defined(NEED_GETTIMEOFDAY) || defined(NEED_USLEEP)
-# include <sys/time.h>
-# include <windows.h>
-#endif
-
-
-#if defined(NEED_GETTIMEOFDAY)
-/*
- * Replacement gettimeofday() for Windows environments (primarily MinGW).
- *
- * Ignores "tz".
- */
-int gettimeofday(struct timeval* ptv, struct timezone* tz)
-{
- long long nsTime; // time in 100ns units since Jan 1 1601
- FILETIME ft;
-
- if (tz != NULL) {
- // oh well
- }
-
- ::GetSystemTimeAsFileTime(&ft);
- nsTime = (long long) ft.dwHighDateTime << 32 |
- (long long) ft.dwLowDateTime;
- // convert to time in usec since Jan 1 1970
- ptv->tv_usec = (long) ((nsTime / 10LL) % 1000000LL);
- ptv->tv_sec = (long) ((nsTime - 116444736000000000LL) / 10000000LL);
-
- return 0;
-}
-#endif
-
-#if defined(NEED_USLEEP)
-//
-// Replacement usleep for Windows environments (primarily MinGW).
-//
-void usleep(unsigned long usec)
-{
- // Win32 API function Sleep() takes milliseconds
- ::Sleep((usec + 500) / 1000);
-}
-#endif
-
-#if 0 //defined(NEED_PIPE)
-//
-// Replacement pipe() command for MinGW
-//
-// The _O_NOINHERIT flag sets bInheritHandle to FALSE in the
-// SecurityAttributes argument to CreatePipe(). This means the handles
-// aren't inherited when a new process is created. The examples I've seen
-// use it, possibly because there's a lot of junk going on behind the
-// scenes. (I'm assuming "process" and "thread" are different here, so
-// we should be okay spinning up a thread.) The recommended practice is
-// to dup() the descriptor you want the child to have.
-//
-// It appears that unnamed pipes can't do non-blocking ("overlapped") I/O.
-// You can't use select() either, since that only works on sockets. The
-// Windows API calls that are useful here all operate on a HANDLE, not
-// an integer file descriptor, and I don't think you can get there from
-// here. The "named pipe" stuff is insane.
-//
-int pipe(int filedes[2])
-{
- return _pipe(filedes, 0, _O_BINARY | _O_NOINHERIT);
-}
-#endif
-
-#if defined(NEED_SETENV)
-/*
- * MinGW lacks these. For now, just stub them out so the code compiles.
- */
-int setenv(const char* name, const char* value, int overwrite)
-{
- return 0;
-}
-void unsetenv(const char* name)
-{
-}
-char* getenv(const char* name)
-{
- return NULL;
-}
-#endif