Merge "Remove more simulator support code. Bug: 5010576"
This commit is contained in:
commit
716c2e5ce9
|
@ -1,30 +0,0 @@
|
|||
ifeq ($(TARGET_SIMULATOR),true)
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES:= \
|
||||
ServiceManager.cpp \
|
||||
SignalHandler.cpp \
|
||||
main_runtime.cpp
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libutils \
|
||||
libbinder \
|
||||
libandroid_runtime \
|
||||
libcutils \
|
||||
libui \
|
||||
libsystem_server \
|
||||
libhardware_legacy
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
$(JNI_H_INCLUDE)
|
||||
|
||||
ifeq ($(TARGET_OS),linux)
|
||||
LOCAL_CFLAGS += -DXP_UNIX
|
||||
endif
|
||||
|
||||
LOCAL_MODULE:= runtime
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
endif
|
|
@ -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
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
//
|
||||
// Copyright 2005 The Android Open Source Project
|
||||
//
|
||||
|
||||
#define LOG_TAG "ServiceManager"
|
||||
|
||||
#include "ServiceManager.h"
|
||||
#include "SignalHandler.h"
|
||||
|
||||
#include <utils/Debug.h>
|
||||
#include <utils/Log.h>
|
||||
#include <binder/Parcel.h>
|
||||
#include <utils/String8.h>
|
||||
#include <binder/ProcessState.h>
|
||||
|
||||
#include <private/utils/Static.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
BServiceManager::BServiceManager()
|
||||
{
|
||||
}
|
||||
|
||||
sp<IBinder> BServiceManager::getService(const String16& name) const
|
||||
{
|
||||
AutoMutex _l(mLock);
|
||||
ssize_t i = mServices.indexOfKey(name);
|
||||
LOGV("ServiceManager: getService(%s) -> %d\n", String8(name).string(), i);
|
||||
if (i >= 0) return mServices.valueAt(i);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sp<IBinder> BServiceManager::checkService(const String16& name) const
|
||||
{
|
||||
AutoMutex _l(mLock);
|
||||
ssize_t i = mServices.indexOfKey(name);
|
||||
LOGV("ServiceManager: getService(%s) -> %d\n", String8(name).string(), i);
|
||||
if (i >= 0) return mServices.valueAt(i);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
status_t BServiceManager::addService(const String16& name, const sp<IBinder>& service)
|
||||
{
|
||||
AutoMutex _l(mLock);
|
||||
LOGI("ServiceManager: addService(%s, %p)\n", String8(name).string(), service.get());
|
||||
const ssize_t res = mServices.add(name, service);
|
||||
if (res >= NO_ERROR) {
|
||||
mChanged.broadcast();
|
||||
return NO_ERROR;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
Vector<String16> BServiceManager::listServices()
|
||||
{
|
||||
Vector<String16> res;
|
||||
|
||||
AutoMutex _l(mLock);
|
||||
const size_t N = mServices.size();
|
||||
for (size_t i=0; i<N; i++) {
|
||||
res.add(mServices.keyAt(i));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
}; // namespace android
|
|
@ -1,38 +0,0 @@
|
|||
//
|
||||
// Copyright 2005 The Android Open Source Project
|
||||
//
|
||||
#ifndef ANDROID_SERVICE_MANAGER_H
|
||||
#define ANDROID_SERVICE_MANAGER_H
|
||||
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
#include <utils/threads.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
class BServiceManager : public BnServiceManager
|
||||
{
|
||||
public:
|
||||
BServiceManager();
|
||||
|
||||
virtual sp<IBinder> getService( const String16& name) const;
|
||||
virtual sp<IBinder> checkService( const String16& name) const;
|
||||
virtual status_t addService( const String16& name,
|
||||
const sp<IBinder>& service);
|
||||
virtual Vector<String16> listServices();
|
||||
|
||||
|
||||
private:
|
||||
mutable Mutex mLock;
|
||||
mutable Condition mChanged;
|
||||
sp<IPermissionController> mPermissionController;
|
||||
KeyedVector<String16, sp<IBinder> > mServices;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#endif // ANDROID_SERVICE_MANAGER_H
|
|
@ -1,249 +0,0 @@
|
|||
//
|
||||
// Copyright 2005 The Android Open Source Project
|
||||
//
|
||||
|
||||
#define LOG_TAG "SignalHandler"
|
||||
|
||||
#include "SignalHandler.h"
|
||||
|
||||
#include <utils/Atomic.h>
|
||||
#include <utils/Debug.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
class SignalHandler::ProcessThread : public Thread
|
||||
{
|
||||
public:
|
||||
ProcessThread(SignalHandler& sh)
|
||||
: Thread(false)
|
||||
, mOwner(sh)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool threadLoop()
|
||||
{
|
||||
char buffer[32];
|
||||
read(mOwner.mAvailMsg[0], buffer, sizeof(buffer));
|
||||
|
||||
LOGV("Signal command processing thread woke up!");
|
||||
|
||||
if (mOwner.mLostCommands) {
|
||||
LOGE("Lost %d signals!", mOwner.mLostCommands);
|
||||
mOwner.mLostCommands = 0;
|
||||
}
|
||||
|
||||
int cur;
|
||||
while ((cur=mOwner.mCommandBottom) != mOwner.mCommandTop) {
|
||||
if (mOwner.mCommands[cur].filled == 0) {
|
||||
LOGV("Command at %d is not yet filled", cur);
|
||||
break;
|
||||
}
|
||||
|
||||
LOGV("Processing command at %d, top is %d",
|
||||
cur, mOwner.mCommandTop);
|
||||
processCommand(mOwner.mCommands[cur]);
|
||||
mOwner.mCommands[cur].filled = 0;
|
||||
|
||||
int next = mOwner.mCommandBottom+1;
|
||||
if (next >= COMMAND_QUEUE_SIZE) {
|
||||
next = 0;
|
||||
}
|
||||
|
||||
mOwner.mCommandBottom = next;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void processCommand(const CommandEntry& entry)
|
||||
{
|
||||
switch (entry.signum) {
|
||||
case SIGCHLD: {
|
||||
mOwner.mLock.lock();
|
||||
ssize_t i = mOwner.mChildHandlers.indexOfKey(entry.info.si_pid);
|
||||
ChildHandler ch;
|
||||
if (i >= 0) {
|
||||
ch = mOwner.mChildHandlers.valueAt(i);
|
||||
mOwner.mChildHandlers.removeItemsAt(i);
|
||||
}
|
||||
mOwner.mLock.unlock();
|
||||
|
||||
LOGD("SIGCHLD: pid=%d, handle index=%d", entry.info.si_pid, i);
|
||||
|
||||
if (i >= 0) {
|
||||
int res = waitpid(entry.info.si_pid, NULL, WNOHANG);
|
||||
LOGW_IF(res == 0,
|
||||
"Received SIGCHLD, but pid %d is not yet stopped",
|
||||
entry.info.si_pid);
|
||||
if (ch.handler) {
|
||||
ch.handler(entry.info.si_pid, ch.userData);
|
||||
}
|
||||
} else {
|
||||
LOGW("Unhandled SIGCHLD for pid %d", entry.info.si_pid);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
SignalHandler& mOwner;
|
||||
};
|
||||
|
||||
|
||||
Mutex SignalHandler::mInstanceLock;
|
||||
SignalHandler* SignalHandler::mInstance = NULL;
|
||||
|
||||
status_t SignalHandler::setChildHandler(pid_t childPid,
|
||||
int tag,
|
||||
child_callback_t handler,
|
||||
void* userData)
|
||||
{
|
||||
SignalHandler* const self = getInstance();
|
||||
|
||||
self->mLock.lock();
|
||||
|
||||
// First make sure this child hasn't already exited.
|
||||
pid_t res = waitpid(childPid, NULL, WNOHANG);
|
||||
if (res != 0) {
|
||||
if (res < 0) {
|
||||
LOGW("setChildHandler waitpid of %d failed: %d (%s)",
|
||||
childPid, res, strerror(errno));
|
||||
} else {
|
||||
LOGW("setChildHandler waitpid of %d said %d already dead",
|
||||
childPid, res);
|
||||
}
|
||||
|
||||
// Some kind of error... just handle the exit now.
|
||||
self->mLock.unlock();
|
||||
|
||||
if (handler) {
|
||||
handler(childPid, userData);
|
||||
}
|
||||
|
||||
// Return an error code -- 0 means it already exited.
|
||||
return (status_t)res;
|
||||
}
|
||||
|
||||
ChildHandler entry;
|
||||
entry.childPid = childPid;
|
||||
entry.tag = tag;
|
||||
entry.handler = handler;
|
||||
entry.userData = userData;
|
||||
|
||||
// Note: this replaces an existing entry for this pid, if there already
|
||||
// is one. This is the required behavior.
|
||||
LOGD("setChildHandler adding pid %d, tag %d, handler %p, data %p",
|
||||
childPid, tag, handler, userData);
|
||||
self->mChildHandlers.add(childPid, entry);
|
||||
|
||||
self->mLock.unlock();
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
void SignalHandler::killAllChildren(int tag)
|
||||
{
|
||||
SignalHandler* const self = getInstance();
|
||||
|
||||
AutoMutex _l (self->mLock);
|
||||
const size_t N = self->mChildHandlers.size();
|
||||
for (size_t i=0; i<N; i++) {
|
||||
const ChildHandler& ch(self->mChildHandlers.valueAt(i));
|
||||
if (tag == 0 || ch.tag == tag) {
|
||||
const pid_t pid = ch.childPid;
|
||||
LOGI("Killing child %d (tag %d)\n", pid, ch.tag);
|
||||
kill(pid, SIGKILL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SignalHandler::SignalHandler()
|
||||
: mCommandTop(0)
|
||||
, mCommandBottom(0)
|
||||
, mLostCommands(0)
|
||||
{
|
||||
memset(mCommands, 0, sizeof(mCommands));
|
||||
|
||||
int res = pipe(mAvailMsg);
|
||||
LOGE_IF(res != 0, "Unable to create signal handler pipe: %s", strerror(errno));
|
||||
|
||||
mProcessThread = new ProcessThread(*this);
|
||||
mProcessThread->run("SignalHandler", PRIORITY_HIGHEST);
|
||||
|
||||
struct sigaction sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_sigaction = sigAction;
|
||||
sa.sa_flags = SA_NOCLDSTOP|SA_SIGINFO;
|
||||
sigaction(SIGCHLD, &sa, NULL);
|
||||
}
|
||||
|
||||
SignalHandler::~SignalHandler()
|
||||
{
|
||||
}
|
||||
|
||||
SignalHandler* SignalHandler::getInstance()
|
||||
{
|
||||
AutoMutex _l(mInstanceLock);
|
||||
if (mInstance == NULL) {
|
||||
mInstance = new SignalHandler();
|
||||
}
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
void SignalHandler::sigAction(int signum, siginfo_t* info, void*)
|
||||
{
|
||||
static const char wakeupMsg[1] = { 0xff };
|
||||
|
||||
// If our signal handler is being called, then we know we have
|
||||
// already initialized the SignalHandler class and thus mInstance
|
||||
// is valid.
|
||||
SignalHandler* const self = mInstance;
|
||||
|
||||
// XXX This is not safe!
|
||||
#if 0
|
||||
LOGV("Signal %d: signo=%d, errno=%d, code=%d, pid=%d\n",
|
||||
signum,
|
||||
info->si_signo, info->si_errno, info->si_code,
|
||||
info->si_pid);
|
||||
#endif
|
||||
|
||||
int32_t oldTop, newTop;
|
||||
|
||||
// Find the next command slot...
|
||||
do {
|
||||
oldTop = self->mCommandTop;
|
||||
|
||||
newTop = oldTop + 1;
|
||||
if (newTop >= COMMAND_QUEUE_SIZE) {
|
||||
newTop = 0;
|
||||
}
|
||||
|
||||
if (newTop == self->mCommandBottom) {
|
||||
// The buffer is filled up! Ouch!
|
||||
// XXX This is not safe!
|
||||
#if 0
|
||||
LOGE("Command buffer overflow! newTop=%d\n", newTop);
|
||||
#endif
|
||||
android_atomic_add(1, &self->mLostCommands);
|
||||
write(self->mAvailMsg[1], wakeupMsg, sizeof(wakeupMsg));
|
||||
return;
|
||||
}
|
||||
} while(android_atomic_cmpxchg(oldTop, newTop, &(self->mCommandTop)));
|
||||
|
||||
// Fill in the command data...
|
||||
self->mCommands[oldTop].signum = signum;
|
||||
self->mCommands[oldTop].info = *info;
|
||||
|
||||
// And now make this command available.
|
||||
self->mCommands[oldTop].filled = 1;
|
||||
|
||||
// Wake up the processing thread.
|
||||
write(self->mAvailMsg[1], wakeupMsg, sizeof(wakeupMsg));
|
||||
}
|
||||
|
||||
}; // namespace android
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
//
|
||||
// Copyright 2005 The Android Open Source Project
|
||||
//
|
||||
#ifndef ANDROID_SIGNAL_HANDLER_H
|
||||
#define ANDROID_SIGNAL_HANDLER_H
|
||||
|
||||
#include <utils/KeyedVector.h>
|
||||
#include <utils/threads.h>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
enum {
|
||||
DEFAULT_PROCESS_TAG = 1
|
||||
};
|
||||
|
||||
class SignalHandler
|
||||
{
|
||||
public:
|
||||
typedef void (*child_callback_t)(pid_t child, void* userData);
|
||||
|
||||
/**
|
||||
* Set a handler for when a child process exits. By calling
|
||||
* this, a waitpid() will be done when the child exits to remove
|
||||
* it from the zombie state. You can also optionally specify a
|
||||
* handler to be called when the child exits.
|
||||
*
|
||||
* If there is already a handler for this child process, it is
|
||||
* replaced by this new handler. In this case the old handler's
|
||||
* function is not called.
|
||||
*
|
||||
* @param childPid Process ID of child to watch.
|
||||
* @param childTag User-defined tag for this child. Must be
|
||||
* greater than zero.
|
||||
* @param handler If non-NULL, this will be called when the
|
||||
* child exits. It may be called in either a
|
||||
* separate signal handling thread, or
|
||||
* immediately if the child has already exited.
|
||||
* @param userData Propageted as-is to handler.
|
||||
*
|
||||
* @return status_t NO_ERROR if all is well.
|
||||
*/
|
||||
static status_t setChildHandler(pid_t childPid,
|
||||
int childTag = DEFAULT_PROCESS_TAG,
|
||||
child_callback_t handler = NULL,
|
||||
void* userData = NULL);
|
||||
|
||||
/**
|
||||
* Kill all of the child processes for which we have a waiting
|
||||
* handler, whose tag is the given value. If tag is 0, all
|
||||
* children are killed.
|
||||
*
|
||||
* @param tag
|
||||
*/
|
||||
static void killAllChildren(int tag = 0);
|
||||
|
||||
private:
|
||||
SignalHandler();
|
||||
~SignalHandler();
|
||||
|
||||
static SignalHandler* getInstance();
|
||||
|
||||
static void sigAction(int, siginfo_t*, void*);
|
||||
|
||||
// --------------------------------------------------
|
||||
// Shared state... all of this is protected by mLock.
|
||||
// --------------------------------------------------
|
||||
|
||||
mutable Mutex mLock;
|
||||
|
||||
struct ChildHandler
|
||||
{
|
||||
pid_t childPid;
|
||||
int tag;
|
||||
child_callback_t handler;
|
||||
void* userData;
|
||||
};
|
||||
KeyedVector<pid_t, ChildHandler> mChildHandlers;
|
||||
|
||||
// --------------------------------------------------
|
||||
// Commmand queue... data is inserted by the signal
|
||||
// handler using atomic ops, and retrieved by the
|
||||
// signal processing thread. Because these are touched
|
||||
// by the signal handler, no lock is used.
|
||||
// --------------------------------------------------
|
||||
|
||||
enum {
|
||||
COMMAND_QUEUE_SIZE = 64
|
||||
};
|
||||
struct CommandEntry
|
||||
{
|
||||
int filled;
|
||||
int signum;
|
||||
siginfo_t info;
|
||||
};
|
||||
|
||||
// The top of the queue. This is incremented atomically by the
|
||||
// signal handler before placing a command in the queue.
|
||||
volatile int32_t mCommandTop;
|
||||
|
||||
// The bottom of the queue. Only modified by the processing
|
||||
// thread; the signal handler reads it only to determine if the
|
||||
// queue is full.
|
||||
int32_t mCommandBottom;
|
||||
|
||||
// Incremented each time we receive a signal and don't have room
|
||||
// for it on the command queue.
|
||||
volatile int32_t mLostCommands;
|
||||
|
||||
// The command processing thread.
|
||||
class ProcessThread;
|
||||
sp<Thread> mProcessThread;
|
||||
|
||||
// Pipe used to tell command processing thread when new commands.
|
||||
// are available. The thread blocks on the read end, the signal
|
||||
// handler writes when it enqueues new commands.
|
||||
int mAvailMsg[2];
|
||||
|
||||
// The commands.
|
||||
CommandEntry mCommands[COMMAND_QUEUE_SIZE];
|
||||
|
||||
// --------------------------------------------------
|
||||
// Singleton.
|
||||
// --------------------------------------------------
|
||||
|
||||
static Mutex mInstanceLock;
|
||||
static SignalHandler* mInstance;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#endif // ANDROID_SIGNAL_HANDLER_H
|
|
@ -1,472 +0,0 @@
|
|||
//
|
||||
// Copyright 2005 The Android Open Source Project
|
||||
//
|
||||
// Main entry point for runtime.
|
||||
//
|
||||
|
||||
#include "ServiceManager.h"
|
||||
#include "SignalHandler.h"
|
||||
|
||||
#include <utils/threads.h>
|
||||
#include <utils/Errors.h>
|
||||
|
||||
#include <binder/IPCThreadState.h>
|
||||
#include <binder/ProcessState.h>
|
||||
#include <utils/Log.h>
|
||||
#include <cutils/zygote.h>
|
||||
|
||||
#include <cutils/properties.h>
|
||||
|
||||
#include <private/utils/Static.h>
|
||||
|
||||
#include <surfaceflinger/ISurfaceComposer.h>
|
||||
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <linux/capability.h>
|
||||
#include <linux/ioctl.h>
|
||||
#ifdef HAVE_ANDROID_OS
|
||||
# include <linux/android_alarm.h>
|
||||
#endif
|
||||
|
||||
#undef LOG_TAG
|
||||
#define LOG_TAG "runtime"
|
||||
|
||||
static const char* ZYGOTE_ARGV[] = {
|
||||
"--setuid=1000",
|
||||
"--setgid=1000",
|
||||
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",
|
||||
/* CAP_SYS_TTY_CONFIG & CAP_SYS_RESOURCE & CAP_NET_BROADCAST &
|
||||
* CAP_NET_ADMIN & CAP_NET_RAW & CAP_NET_BIND_SERVICE & CAP_KILL &
|
||||
* CAP_SYS_BOOT CAP_SYS_NICE
|
||||
*/
|
||||
"--capabilities=96549920,96549920",
|
||||
"--runtime-init",
|
||||
"--nice-name=system_server",
|
||||
"com.android.server.SystemServer"
|
||||
};
|
||||
|
||||
using namespace android;
|
||||
|
||||
extern "C" status_t system_init();
|
||||
|
||||
enum {
|
||||
SYSTEM_PROCESS_TAG = DEFAULT_PROCESS_TAG+1
|
||||
};
|
||||
|
||||
extern Mutex gEventQMutex;
|
||||
extern Condition gEventQCondition;
|
||||
|
||||
namespace android {
|
||||
|
||||
extern void set_finish_init_func(void (*func)());
|
||||
|
||||
|
||||
/**
|
||||
* This class is used to kill this process (runtime) when the system_server dies.
|
||||
*/
|
||||
class GrimReaper : public IBinder::DeathRecipient {
|
||||
public:
|
||||
GrimReaper() { }
|
||||
|
||||
virtual void binderDied(const wp<IBinder>& who)
|
||||
{
|
||||
LOGI("Grim Reaper killing runtime...");
|
||||
kill(getpid(), SIGKILL);
|
||||
}
|
||||
};
|
||||
|
||||
extern void QuickTests();
|
||||
|
||||
/*
|
||||
* Print usage info.
|
||||
*/
|
||||
static void usage(const char* argv0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: runtime [-g gamma] [-l logfile] [-n]\n"
|
||||
" [-j app-component] [-v app-verb] [-d app-data]\n"
|
||||
"\n"
|
||||
"-l: File to send log messages to\n"
|
||||
"-n: Don't print to stdout/stderr\n"
|
||||
"-j: Custom home app component name\n"
|
||||
"-v: Custom home app intent verb\n"
|
||||
"-d: Custom home app intent data\n"
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Selected application to run.
|
||||
static const char* gInitialApplication = NULL;
|
||||
static const char* gInitialVerb = NULL;
|
||||
static const char* gInitialData = NULL;
|
||||
|
||||
static void writeStringToParcel(Parcel& parcel, const char* str)
|
||||
{
|
||||
if (str) {
|
||||
parcel.writeString16(String16(str));
|
||||
} else {
|
||||
parcel.writeString16(NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Starting point for program logic.
|
||||
*
|
||||
* Returns with an exit status code (0 on success, nonzero on error).
|
||||
*/
|
||||
static int run(sp<ProcessState>& proc)
|
||||
{
|
||||
// Temporary hack to call startRunning() on the activity manager.
|
||||
sp<IServiceManager> sm = defaultServiceManager();
|
||||
sp<IBinder> am;
|
||||
while ((am = sm->getService(String16("activity"))) == NULL) {
|
||||
LOGI("Waiting for activity manager...");
|
||||
}
|
||||
Parcel data, reply;
|
||||
// XXX Need to also supply a package name for this to work again.
|
||||
// IActivityManager::getInterfaceDescriptor() is the token for invoking on this interface;
|
||||
// hardcoding it here avoids having to link with the full Activity Manager library
|
||||
data.writeInterfaceToken(String16("android.app.IActivityManager"));
|
||||
writeStringToParcel(data, NULL);
|
||||
writeStringToParcel(data, gInitialApplication);
|
||||
writeStringToParcel(data, gInitialVerb);
|
||||
writeStringToParcel(data, gInitialData);
|
||||
LOGI("run() sending FIRST_CALL_TRANSACTION to activity manager");
|
||||
am->transact(IBinder::FIRST_CALL_TRANSACTION, data, &reply);
|
||||
|
||||
// Now we link to the Activity Manager waiting for it to die. If it does kill ourself.
|
||||
// initd will restart this process and bring the system back up.
|
||||
sp<GrimReaper> grim = new GrimReaper();
|
||||
am->linkToDeath(grim, grim.get(), 0);
|
||||
|
||||
// Now join the thread pool. Note this is needed so that the message enqueued in the driver
|
||||
// for the linkToDeath gets processed.
|
||||
IPCThreadState::self()->joinThreadPool();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
}; // namespace android
|
||||
|
||||
|
||||
/*
|
||||
* Post-system-process initialization.
|
||||
*
|
||||
* This function continues initialization after the system process
|
||||
* has been initialized. It needs to be separate because the system
|
||||
* initialization needs to care of starting the Android runtime if it is not
|
||||
* running in its own process, which doesn't return until the runtime is
|
||||
* being shut down. So it will call back to here from inside of Dalvik,
|
||||
* to allow us to continue booting up.
|
||||
*/
|
||||
static void finish_system_init(sp<ProcessState>& proc)
|
||||
{
|
||||
proc->startThreadPool();
|
||||
}
|
||||
|
||||
|
||||
// This function can be used to enforce security to different
|
||||
// root contexts. For now, we just give every access.
|
||||
static bool contextChecker(
|
||||
const String16& name, const sp<IBinder>& caller, void* userData)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialization of boot services.
|
||||
*
|
||||
* This is where we perform initialization of all of our low-level
|
||||
* boot services. Most importantly, here we become the context
|
||||
* manager and use that to publish the service manager that will provide
|
||||
* access to all other services.
|
||||
*/
|
||||
static void boot_init()
|
||||
{
|
||||
LOGI("Entered boot_init()!\n");
|
||||
|
||||
sp<ProcessState> proc(ProcessState::self());
|
||||
LOGD("ProcessState: %p\n", proc.get());
|
||||
proc->becomeContextManager(contextChecker, NULL);
|
||||
|
||||
LOGI("Binder driver opened.\n");
|
||||
|
||||
sp<BServiceManager> sm = new BServiceManager;
|
||||
proc->setContextObject(sm);
|
||||
}
|
||||
|
||||
/*
|
||||
* Redirect stdin/stdout/stderr to /dev/null.
|
||||
*/
|
||||
static void redirectStdFds(void)
|
||||
{
|
||||
int fd = open("/dev/null", O_RDWR, 0);
|
||||
if (fd < 0) {
|
||||
LOGW("Unable to open /dev/null: %s\n", strerror(errno));
|
||||
} else {
|
||||
dup2(fd, 0);
|
||||
dup2(fd, 1);
|
||||
dup2(fd, 2);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
static int hasDir(const char* dir)
|
||||
{
|
||||
struct stat s;
|
||||
int res = stat(dir, &s);
|
||||
if (res == 0) {
|
||||
return S_ISDIR(s.st_mode);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void validateTime()
|
||||
{
|
||||
#if HAVE_ANDROID_OS
|
||||
int fd;
|
||||
int res;
|
||||
time_t min_time = 1167652800; // jan 1 2007, type 'date -ud "1/1 12:00" +%s' to get value for current year
|
||||
struct timespec ts;
|
||||
|
||||
fd = open("/dev/alarm", O_RDWR);
|
||||
if(fd < 0) {
|
||||
LOGW("Unable to open alarm driver: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
res = ioctl(fd, ANDROID_ALARM_GET_TIME(ANDROID_ALARM_RTC_WAKEUP), &ts);
|
||||
if(res < 0) {
|
||||
LOGW("Unable to read rtc, %s\n", strerror(errno));
|
||||
}
|
||||
else if(ts.tv_sec >= min_time) {
|
||||
goto done;
|
||||
}
|
||||
LOGW("Invalid time detected, %ld set to %ld\n", ts.tv_sec, min_time);
|
||||
ts.tv_sec = min_time;
|
||||
ts.tv_nsec = 0;
|
||||
res = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
|
||||
if(res < 0) {
|
||||
LOGW("Unable to set rtc to %ld: %s\n", ts.tv_sec, strerror(errno));
|
||||
}
|
||||
done:
|
||||
close(fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef HAVE_ANDROID_OS
|
||||
class QuickRuntime : public AndroidRuntime
|
||||
{
|
||||
public:
|
||||
QuickRuntime() {}
|
||||
|
||||
virtual void onStarted()
|
||||
{
|
||||
printf("QuickRuntime: onStarted\n");
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
static status_t start_process(const char* name);
|
||||
|
||||
static void restart_me(pid_t child, void* userData)
|
||||
{
|
||||
start_process((const char*)userData);
|
||||
}
|
||||
|
||||
static status_t start_process(const char* name)
|
||||
{
|
||||
String8 path(name);
|
||||
Vector<const char*> args;
|
||||
String8 leaf(path.getPathLeaf());
|
||||
String8 parentDir(path.getPathDir());
|
||||
args.insertAt(leaf.string(), 0);
|
||||
args.add(parentDir.string());
|
||||
args.add(NULL);
|
||||
pid_t child = fork();
|
||||
if (child < 0) {
|
||||
status_t err = errno;
|
||||
LOGE("*** fork of child %s failed: %s", leaf.string(), strerror(err));
|
||||
return -errno;
|
||||
} else if (child == 0) {
|
||||
LOGI("Executing: %s", path.string());
|
||||
execv(path.string(), const_cast<char**>(args.array()));
|
||||
int err = errno;
|
||||
LOGE("Exec failed: %s\n", strerror(err));
|
||||
_exit(err);
|
||||
} else {
|
||||
SignalHandler::setChildHandler(child, DEFAULT_PROCESS_TAG,
|
||||
restart_me, (void*)name);
|
||||
}
|
||||
return -errno;
|
||||
}
|
||||
|
||||
/*
|
||||
* Application entry point.
|
||||
*
|
||||
* Parse arguments, set some values, and pass control off to Run().
|
||||
*
|
||||
* This is redefined to "SDL_main" on SDL simulator builds, and
|
||||
* "runtime_main" on wxWidgets builds.
|
||||
*/
|
||||
extern "C"
|
||||
int main(int argc, char* const argv[])
|
||||
{
|
||||
const char* logFile = NULL;
|
||||
int ic;
|
||||
int result = 1;
|
||||
pid_t systemPid;
|
||||
|
||||
sp<ProcessState> proc;
|
||||
|
||||
#ifndef HAVE_ANDROID_OS
|
||||
/* Set stdout/stderr to unbuffered for MinGW/MSYS. */
|
||||
//setvbuf(stdout, NULL, _IONBF, 0);
|
||||
//setvbuf(stderr, NULL, _IONBF, 0);
|
||||
|
||||
LOGI("commandline args:\n");
|
||||
for (int i = 0; i < argc; i++)
|
||||
LOGI(" %2d: '%s'\n", i, argv[i]);
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
ic = getopt(argc, argv, "g:j:v:d:l:n");
|
||||
if (ic < 0)
|
||||
break;
|
||||
|
||||
switch (ic) {
|
||||
case 'g':
|
||||
break;
|
||||
case 'j':
|
||||
gInitialApplication = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
gInitialVerb = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
gInitialData = optarg;
|
||||
break;
|
||||
case 'l':
|
||||
logFile = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
redirectStdFds();
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
LOGE("runtime: unrecognized flag -%c\n", ic);
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (optind < argc) {
|
||||
LOGE("runtime: extra stuff: %s\n", argv[optind]);
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
if (logFile != NULL) {
|
||||
android_logToFile(NULL, logFile);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up ANDROID_* environment variables.
|
||||
*
|
||||
* TODO: the use of $ANDROID_PRODUCT_OUT will go away soon.
|
||||
*/
|
||||
static const char* kSystemDir = "/system";
|
||||
static const char* kDataDir = "/data";
|
||||
static const char* kAppSubdir = "/app";
|
||||
const char* out = NULL;
|
||||
#ifndef HAVE_ANDROID_OS
|
||||
//out = getenv("ANDROID_PRODUCT_OUT");
|
||||
#endif
|
||||
if (out == NULL)
|
||||
out = "";
|
||||
|
||||
char* systemDir = (char*) malloc(strlen(out) + strlen(kSystemDir) +1);
|
||||
char* dataDir = (char*) malloc(strlen(out) + strlen(kDataDir) +1);
|
||||
|
||||
sprintf(systemDir, "%s%s", out, kSystemDir);
|
||||
sprintf(dataDir, "%s%s", out, kDataDir);
|
||||
setenv("ANDROID_ROOT", systemDir, 1);
|
||||
setenv("ANDROID_DATA", dataDir, 1);
|
||||
|
||||
char* assetDir = (char*) malloc(strlen(systemDir) + strlen(kAppSubdir) +1);
|
||||
sprintf(assetDir, "%s%s", systemDir, kAppSubdir);
|
||||
|
||||
LOGI("Startup: sys='%s' asset='%s' data='%s'\n",
|
||||
systemDir, assetDir, dataDir);
|
||||
free(systemDir);
|
||||
free(dataDir);
|
||||
|
||||
#ifdef HAVE_ANDROID_OS
|
||||
/* set up a process group for easier killing on the device */
|
||||
setpgid(0, getpid());
|
||||
#endif
|
||||
|
||||
// Change to asset dir. This is only necessary if we've changed to
|
||||
// a different directory, but there's little harm in doing it regardless.
|
||||
//
|
||||
// Expecting assets to live in the current dir is not a great idea,
|
||||
// because some of our code or one of our libraries could change the
|
||||
// directory out from under us. Preserve the behavior for now.
|
||||
if (chdir(assetDir) != 0) {
|
||||
LOGW("WARNING: could not change dir to '%s': %s\n",
|
||||
assetDir, strerror(errno));
|
||||
}
|
||||
free(assetDir);
|
||||
|
||||
#if 0
|
||||
// Hack to keep libc from beating the filesystem to death. It's
|
||||
// hitting /etc/localtime frequently,
|
||||
//
|
||||
// This statement locks us into Pacific time. We could do better,
|
||||
// but there's not much point until we're sure that the library
|
||||
// can't be changed to do more along the lines of what we want.
|
||||
#ifndef XP_WIN
|
||||
setenv("TZ", "PST+8PDT,M4.1.0/2,M10.5.0/2", true);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* track our progress through the boot sequence */
|
||||
const int LOG_BOOT_PROGRESS_START = 3000;
|
||||
LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,
|
||||
ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
|
||||
|
||||
validateTime();
|
||||
|
||||
proc = ProcessState::self();
|
||||
|
||||
boot_init();
|
||||
|
||||
// Have zygote spawn the system server process and call system_init().
|
||||
// If stdio logging is on, system_server should not inherit our stdio
|
||||
// The dalvikvm instance will copy stdio to the log on its own
|
||||
char propBuf[PROPERTY_VALUE_MAX];
|
||||
bool logStdio = false;
|
||||
property_get("log.redirect-stdio", propBuf, "");
|
||||
logStdio = (strcmp(propBuf, "true") == 0);
|
||||
|
||||
zygote_run_oneshot((int)(!logStdio),
|
||||
sizeof(ZYGOTE_ARGV) / sizeof(ZYGOTE_ARGV[0]),
|
||||
ZYGOTE_ARGV);
|
||||
|
||||
finish_system_init(proc);
|
||||
run(proc);
|
||||
|
||||
bail:
|
||||
if (proc != NULL) {
|
||||
proc->setContextObject(NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue