diff options
Diffstat (limited to 'cmds')
24 files changed, 383 insertions, 1362 deletions
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp index 152a7cb..f2be29f 100644 --- a/cmds/app_process/app_main.cpp +++ b/cmds/app_process/app_main.cpp @@ -82,35 +82,27 @@ public: virtual void onStarted() { sp<ProcessState> proc = ProcessState::self(); - if (proc->supportsProcesses()) { - LOGV("App process: starting thread pool.\n"); - proc->startThreadPool(); - } + LOGV("App process: starting thread pool.\n"); + proc->startThreadPool(); AndroidRuntime* ar = AndroidRuntime::getRuntime(); ar->callMain(mClassName, mClass, mArgC, mArgV); - if (ProcessState::self()->supportsProcesses()) { - IPCThreadState::self()->stopProcess(); - } + IPCThreadState::self()->stopProcess(); } virtual void onZygoteInit() { sp<ProcessState> proc = ProcessState::self(); - if (proc->supportsProcesses()) { - LOGV("App process: starting thread pool.\n"); - proc->startThreadPool(); - } + LOGV("App process: starting thread pool.\n"); + proc->startThreadPool(); } virtual void onExit(int code) { if (mClassName == NULL) { // if zygote - if (ProcessState::self()->supportsProcesses()) { - IPCThreadState::self()->stopProcess(); - } + IPCThreadState::self()->stopProcess(); } AndroidRuntime::onExit(code); diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java index 38d0d2a..2666b41 100644 --- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java +++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java @@ -23,6 +23,8 @@ import android.app.backup.IRestoreSession; import android.os.RemoteException; import android.os.ServiceManager; +import java.util.HashSet; + public final class Bmgr { IBackupManager mBmgr; IRestoreSession mRestore; @@ -45,7 +47,6 @@ public final class Bmgr { } public void run(String[] args) { - boolean validCommand = false; if (args.length < 1) { showUsage(); return; @@ -329,7 +330,13 @@ public final class Bmgr { } else { try { long token = Long.parseLong(arg, 16); - doRestoreAll(token); + HashSet<String> filter = null; + while ((arg = nextArg()) != null) { + if (filter == null) filter = new HashSet<String>(); + filter.add(arg); + } + + doRestoreAll(token, filter); } catch (NumberFormatException e) { showUsage(); return; @@ -364,7 +371,7 @@ public final class Bmgr { } } - private void doRestoreAll(long token) { + private void doRestoreAll(long token, HashSet<String> filter) { RestoreObserver observer = new RestoreObserver(); try { @@ -383,7 +390,13 @@ public final class Bmgr { for (RestoreSet s : sets) { if (s.token == token) { System.out.println("Scheduling restore: " + s.name); - didRestore = (mRestore.restoreAll(token, observer) == 0); + if (filter == null) { + didRestore = (mRestore.restoreAll(token, observer) == 0); + } else { + String[] names = new String[filter.size()]; + filter.toArray(names); + didRestore = (mRestore.restoreSome(token, observer, names) == 0); + } break; } } @@ -430,6 +443,7 @@ public final class Bmgr { System.err.println(" bmgr list sets"); System.err.println(" bmgr transport WHICH"); System.err.println(" bmgr restore TOKEN"); + System.err.println(" bmgr restore TOKEN PACKAGE..."); System.err.println(" bmgr restore PACKAGE"); System.err.println(" bmgr run"); System.err.println(" bmgr wipe PACKAGE"); @@ -457,12 +471,18 @@ public final class Bmgr { System.err.println("The 'transport' command designates the named transport as the currently"); System.err.println("active one. This setting is persistent across reboots."); System.err.println(""); - System.err.println("The 'restore' command when given a restore token initiates a full-system"); + System.err.println("The 'restore' command when given just a restore token initiates a full-system"); System.err.println("restore operation from the currently active transport. It will deliver"); System.err.println("the restore set designated by the TOKEN argument to each application"); System.err.println("that had contributed data to that restore set."); System.err.println(""); - System.err.println("The 'restore' command when given a package name intiates a restore of"); + System.err.println("The 'restore' command when given a token and one or more package names"); + System.err.println("initiates a restore operation of just those given packages from the restore"); + System.err.println("set designated by the TOKEN argument. It is effectively the same as the"); + System.err.println("'restore' operation supplying only a token, but applies a filter to the"); + System.err.println("set of applications to be restored."); + System.err.println(""); + System.err.println("The 'restore' command when given just a package name intiates a restore of"); System.err.println("just that one package according to the restore set selection algorithm"); System.err.println("used by the RestoreSession.restorePackage() method."); System.err.println(""); diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index 0acba8b..ccd668d 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -213,9 +213,10 @@ status_t BootAnimation::readyToRun() { // create the native surface sp<SurfaceControl> control = session()->createSurface( 0, dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565); - session()->openTransaction(); + + SurfaceComposerClient::openGlobalTransaction(); control->setLayer(0x40000000); - session()->closeTransaction(); + SurfaceComposerClient::closeGlobalTransaction(); sp<Surface> s = control->getSurface(); diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c index 21bb62e..42c35af 100644 --- a/cmds/dumpstate/dumpstate.c +++ b/cmds/dumpstate/dumpstate.c @@ -47,9 +47,11 @@ static void dumpstate() { char build[PROPERTY_VALUE_MAX], fingerprint[PROPERTY_VALUE_MAX]; char radio[PROPERTY_VALUE_MAX], bootloader[PROPERTY_VALUE_MAX]; char network[PROPERTY_VALUE_MAX], date[80]; + char build_type[PROPERTY_VALUE_MAX]; property_get("ro.build.display.id", build, "(unknown)"); property_get("ro.build.fingerprint", fingerprint, "(unknown)"); + property_get("ro.build.type", build_type, "(unknown)"); property_get("ro.baseband", radio, "(unknown)"); property_get("ro.bootloader", bootloader, "(unknown)"); property_get("gsm.operator.alpha", network, "(unknown)"); @@ -136,9 +138,17 @@ static void dumpstate() { #ifdef BROKEN_VRIL_IS_FIXED_B_4442803 char ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {0}; property_get("ril.dumpstate.timeout", ril_dumpstate_timeout, "30"); - if (strlen(ril_dumpstate_timeout) > 0) { - run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout), - "su", "root", "vril-dump", NULL); + if (strnlen(ril_dumpstate_timeout, PROPERTY_VALUE_MAX - 1) > 0) { + if (0 == strncmp(build_type, "user", PROPERTY_VALUE_MAX - 1)) { + // su does not exist on user builds, so try running without it. + // This way any implementations of vril-dump that do not require + // root can run on user builds. + run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout), + "vril-dump", NULL); + } else { + run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout), + "su", "root", "vril-dump", NULL); + } } #endif @@ -275,7 +285,7 @@ int main(int argc, char *argv[]) { if (getuid() == 0) { /* switch to non-root user and group */ - gid_t groups[] = { AID_LOG, AID_SDCARD_RW, AID_MOUNT }; + gid_t groups[] = { AID_LOG, AID_SDCARD_RW, AID_MOUNT, AID_INET }; if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) { LOGE("Unable to setgroups, aborting: %s\n", strerror(errno)); return -1; diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c index d45ac19..26b9113 100644 --- a/cmds/installd/commands.c +++ b/cmds/installd/commands.c @@ -288,8 +288,9 @@ int protect(char *pkgname, gid_t gid) } int get_size(const char *pkgname, const char *apkpath, - const char *fwdlock_apkpath, - int64_t *_codesize, int64_t *_datasize, int64_t *_cachesize) + const char *fwdlock_apkpath, const char *asecpath, + int64_t *_codesize, int64_t *_datasize, int64_t *_cachesize, + int64_t* _asecsize) { DIR *d; int dfd; @@ -300,6 +301,7 @@ int get_size(const char *pkgname, const char *apkpath, int64_t codesize = 0; int64_t datasize = 0; int64_t cachesize = 0; + int64_t asecsize = 0; /* count the source apk as code -- but only if it's not * on the /system partition and its not on the sdcard. @@ -324,6 +326,14 @@ int get_size(const char *pkgname, const char *apkpath, } } + /* compute asec size if it is given + */ + if (asecpath != NULL && asecpath[0] != '!') { + if (stat(asecpath, &s) == 0) { + asecsize += stat_size(&s); + } + } + if (create_pkg_path(path, pkgname, PKG_DIR_POSTFIX, 0)) { goto done; } @@ -370,6 +380,7 @@ done: *_codesize = codesize; *_datasize = datasize; *_cachesize = cachesize; + *_asecsize = asecsize; return 0; } diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c index c062d36..feb6b92 100644 --- a/cmds/installd/installd.c +++ b/cmds/installd/installd.c @@ -77,16 +77,18 @@ static int do_get_size(char **arg, char reply[REPLY_MAX]) int64_t codesize = 0; int64_t datasize = 0; int64_t cachesize = 0; + int64_t asecsize = 0; int res = 0; /* pkgdir, apkpath */ - res = get_size(arg[0], arg[1], arg[2], &codesize, &datasize, &cachesize); + res = get_size(arg[0], arg[1], arg[2], arg[3], &codesize, &datasize, &cachesize, &asecsize); /* * Each int64_t can take up 22 characters printed out. Make sure it * doesn't go over REPLY_MAX in the future. */ - snprintf(reply, REPLY_MAX, "%" PRId64 " %" PRId64 " %" PRId64, codesize, datasize, cachesize); + snprintf(reply, REPLY_MAX, "%" PRId64 " %" PRId64 " %" PRId64 " %" PRId64, + codesize, datasize, cachesize, asecsize); return res; } @@ -137,7 +139,7 @@ struct cmdinfo cmds[] = { { "freecache", 1, do_free_cache }, { "rmcache", 1, do_rm_cache }, { "protect", 2, do_protect }, - { "getsize", 3, do_get_size }, + { "getsize", 4, do_get_size }, { "rmuserdata", 2, do_rm_user_data }, { "movefiles", 0, do_movefiles }, { "linklib", 2, do_linklib }, diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h index e5f6739..c5872b8 100644 --- a/cmds/installd/installd.h +++ b/cmds/installd/installd.h @@ -143,7 +143,8 @@ int move_dex(const char *src, const char *dst); int rm_dex(const char *path); int protect(char *pkgname, gid_t gid); int get_size(const char *pkgname, const char *apkpath, const char *fwdlock_apkpath, - int64_t *codesize, int64_t *datasize, int64_t *cachesize); + const char *asecpath, int64_t *codesize, int64_t *datasize, int64_t *cachesize, + int64_t *asecsize); int free_cache(int64_t free_size); int dexopt(const char *apk_path, uid_t uid, int is_public); int movefiles(); diff --git a/cmds/ip-up-vpn/Android.mk b/cmds/ip-up-vpn/Android.mk new file mode 100644 index 0000000..de81889 --- /dev/null +++ b/cmds/ip-up-vpn/Android.mk @@ -0,0 +1,26 @@ +# +# Copyright (C) 2011 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := ip-up-vpn.c +LOCAL_SHARED_LIBRARIES := libcutils +LOCAL_MODULE := ip-up-vpn +LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/ppp +LOCAL_MODULE_TAGS := optional + +include $(BUILD_EXECUTABLE) diff --git a/cmds/ip-up-vpn/ip-up-vpn.c b/cmds/ip-up-vpn/ip-up-vpn.c new file mode 100644 index 0000000..bbf6b14 --- /dev/null +++ b/cmds/ip-up-vpn/ip-up-vpn.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <cutils/properties.h> + +int main(int argc, char **argv) +{ + if (argc > 1 && strlen(argv[1]) > 0) { + char dns[PROPERTY_VALUE_MAX]; + char *dns1 = getenv("DNS1"); + char *dns2 = getenv("DNS2"); + + snprintf(dns, sizeof(dns), "%s %s", dns1 ? dns1 : "", dns2 ? dns2 : ""); + property_set("vpn.dns", dns); + property_set("vpn.via", argv[1]); + } + return 0; +} diff --git a/cmds/keystore/keystore.cpp b/cmds/keystore/keystore.cpp index bbd1a1b..4b4b9b9 100644 --- a/cmds/keystore/keystore.cpp +++ b/cmds/keystore/keystore.cpp @@ -708,11 +708,10 @@ static struct user { uid_t euid; uint32_t perms; } users[] = { - {AID_SYSTEM, ~0, ~GET}, + {AID_SYSTEM, ~0, ~0}, {AID_VPN, AID_SYSTEM, GET}, {AID_WIFI, AID_SYSTEM, GET}, {AID_ROOT, AID_SYSTEM, GET}, - {AID_KEYCHAIN, AID_SYSTEM, TEST | GET | SAW}, {~0, ~0, TEST | GET | INSERT | DELETE | EXIST | SAW}, }; diff --git a/cmds/keystore/test-keystore b/cmds/keystore/test-keystore index 82b276f..3be51b3 100755 --- a/cmds/keystore/test-keystore +++ b/cmds/keystore/test-keystore @@ -116,11 +116,12 @@ function test_basic() { expect "1 No error" expect "baz" - log "system does not have access to read any keys" + log "get baz" keystore system g baz - expect "6 Permission denied" - - log "however, root can read system user keys (as can wifi or vpn users)" + expect "1 No error" + expect "quux" + + log "root can read system user keys (as can wifi or vpn users)" keystore root g baz expect "1 No error" expect "quux" diff --git a/cmds/runtime/Android.mk b/cmds/runtime/Android.mk deleted file mode 100644 index 6a72d10..0000000 --- a/cmds/runtime/Android.mk +++ /dev/null @@ -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 diff --git a/cmds/runtime/MODULE_LICENSE_APACHE2 b/cmds/runtime/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29..0000000 --- a/cmds/runtime/MODULE_LICENSE_APACHE2 +++ /dev/null diff --git a/cmds/runtime/NOTICE b/cmds/runtime/NOTICE deleted file mode 100644 index c5b1efa..0000000 --- a/cmds/runtime/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/cmds/runtime/ServiceManager.cpp b/cmds/runtime/ServiceManager.cpp deleted file mode 100644 index b2bef07..0000000 --- a/cmds/runtime/ServiceManager.cpp +++ /dev/null @@ -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 diff --git a/cmds/runtime/ServiceManager.h b/cmds/runtime/ServiceManager.h deleted file mode 100644 index 090ca6d..0000000 --- a/cmds/runtime/ServiceManager.h +++ /dev/null @@ -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 diff --git a/cmds/runtime/SignalHandler.cpp b/cmds/runtime/SignalHandler.cpp deleted file mode 100644 index cccaabf..0000000 --- a/cmds/runtime/SignalHandler.cpp +++ /dev/null @@ -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 - diff --git a/cmds/runtime/SignalHandler.h b/cmds/runtime/SignalHandler.h deleted file mode 100644 index 7f4ef8e..0000000 --- a/cmds/runtime/SignalHandler.h +++ /dev/null @@ -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 diff --git a/cmds/runtime/main_runtime.cpp b/cmds/runtime/main_runtime.cpp deleted file mode 100644 index dbff095..0000000 --- a/cmds/runtime/main_runtime.cpp +++ /dev/null @@ -1,515 +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] [-s]\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" - "-s: Force single-process mode\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); - - if (proc->supportsProcesses()) { - // 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(); - } else { - // Keep this thread running forever... - while (1) { - usleep(100000); - } - } - 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) -{ - // If we are running multiprocess, we now need to have the - // thread pool started here. We don't do this in boot_init() - // because when running single process we need to start the - // thread pool after the Android runtime has been started (so - // the pool uses Dalvik threads). - if (proc->supportsProcesses()) { - 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); - - if (proc->supportsProcesses()) { - LOGI("Binder driver opened. Multiprocess enabled.\n"); - } else { - LOGI("Binder driver not found. Processes not supported.\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[]) -{ - bool singleProcess = false; - 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:ns"); - 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 's': - singleProcess = true; - 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 (singleProcess) { - ProcessState::setSingleProcess(true); - } - - 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(); - - /* If we are in multiprocess mode, have zygote spawn the system - * server process and call system_init(). If we are running in - * single process mode just call system_init() directly. - */ - if (proc->supportsProcesses()) { - // 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); - - //start_process("/system/bin/mediaserver"); - - } else { -#ifndef HAVE_ANDROID_OS - QuickRuntime* runt = new QuickRuntime(); - runt->start("com/android/server/SystemServer", - "" /* spontaneously fork system server from zygote */); -#endif - } - - //printf("+++ post-zygote\n"); - - finish_system_init(proc); - run(proc); - -bail: - if (proc != NULL) { - proc->setContextObject(NULL); - } - - return 0; -} diff --git a/cmds/stagefright/recordvideo.cpp b/cmds/stagefright/recordvideo.cpp index 1264215..c402286 100644 --- a/cmds/stagefright/recordvideo.cpp +++ b/cmds/stagefright/recordvideo.cpp @@ -34,7 +34,7 @@ static void usage(const char *me) { fprintf(stderr, "usage: %s\n", me); fprintf(stderr, " -h(elp)\n"); fprintf(stderr, " -b bit rate in bits per second (default: 300000)\n"); - fprintf(stderr, " -c YUV420 color format: [0] semi planar or [1] planar (default: 1)\n"); + fprintf(stderr, " -c YUV420 color format: [0] semi planar or [1] planar or other omx YUV420 color format (default: 1)\n"); fprintf(stderr, " -f frame rate in frames per second (default: 30)\n"); fprintf(stderr, " -i I frame interval in seconds (default: 1)\n"); fprintf(stderr, " -n number of frames to be recorded (default: 300)\n"); @@ -59,11 +59,6 @@ public: mSize((width * height * 3) / 2) { mGroup.add_buffer(new MediaBuffer(mSize)); - - // Check the color format to make sure - // that the buffer size mSize it set correctly above. - CHECK(colorFormat == OMX_COLOR_FormatYUV420SemiPlanar || - colorFormat == OMX_COLOR_FormatYUV420Planar); } virtual sp<MetaData> getFormat() { @@ -144,9 +139,13 @@ static int translateColorToOmxEnumValue(int color) { case kYUV420P: return OMX_COLOR_FormatYUV420Planar; default: - fprintf(stderr, "Unsupported color: %d\n", color); - return -1; + fprintf(stderr, "Custom OMX color format: %d\n", color); + if (color == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar || + color == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { + return color; + } } + return -1; } int main(int argc, char **argv) { diff --git a/cmds/stagefright/sf2.cpp b/cmds/stagefright/sf2.cpp index 289665f..6fa66cf 100644 --- a/cmds/stagefright/sf2.cpp +++ b/cmds/stagefright/sf2.cpp @@ -29,6 +29,7 @@ #include <media/stagefright/MediaExtractor.h> #include <media/stagefright/MediaSource.h> #include <media/stagefright/MetaData.h> +#include <media/stagefright/NativeWindowWrapper.h> #include <media/stagefright/Utils.h> #include <surfaceflinger/ISurfaceComposer.h> @@ -39,10 +40,12 @@ using namespace android; struct Controller : public AHandler { - Controller(const char *uri, bool decodeAudio, const sp<Surface> &surface) + Controller(const char *uri, bool decodeAudio, + const sp<Surface> &surface, bool renderToSurface) : mURI(uri), mDecodeAudio(decodeAudio), mSurface(surface), + mRenderToSurface(renderToSurface), mCodec(new ACodec) { CHECK(!mDecodeAudio || mSurface == NULL); } @@ -97,7 +100,8 @@ protected: sp<AMessage> format = makeFormat(mSource->getFormat()); if (mSurface != NULL) { - format->setObject("surface", mSurface); + format->setObject( + "native-window", new NativeWindowWrapper(mSurface)); } mCodec->initiateSetup(format); @@ -220,6 +224,7 @@ private: AString mURI; bool mDecodeAudio; sp<Surface> mSurface; + bool mRenderToSurface; sp<ACodec> mCodec; sp<MediaSource> mSource; @@ -451,7 +456,7 @@ private: inBuffer->release(); inBuffer = NULL; - // break; // Don't coalesce + break; // Don't coalesce } LOGV("coalesced %d input buffers", n); @@ -479,6 +484,10 @@ private: sp<AMessage> reply; CHECK(msg->findMessage("reply", &reply)); + if (mRenderToSurface) { + reply->setInt32("render", 1); + } + reply->post(); } @@ -491,7 +500,8 @@ static void usage(const char *me) { fprintf(stderr, " -a(udio)\n"); fprintf(stderr, - " -s(surface) Allocate output buffers on a surface.\n"); + " -S(urface) Allocate output buffers on a surface.\n" + " -R(ender) Render surface-allocated buffers.\n"); } int main(int argc, char **argv) { @@ -499,18 +509,23 @@ int main(int argc, char **argv) { bool decodeAudio = false; bool useSurface = false; + bool renderToSurface = false; int res; - while ((res = getopt(argc, argv, "has")) >= 0) { + while ((res = getopt(argc, argv, "haSR")) >= 0) { switch (res) { case 'a': decodeAudio = true; break; - case 's': + case 'S': useSurface = true; break; + case 'R': + renderToSurface = true; + break; + case '?': case 'h': default: @@ -553,16 +568,18 @@ int main(int argc, char **argv) { CHECK(control != NULL); CHECK(control->isValid()); - CHECK_EQ(composerClient->openTransaction(), (status_t)OK); + SurfaceComposerClient::openGlobalTransaction(); CHECK_EQ(control->setLayer(30000), (status_t)OK); CHECK_EQ(control->show(), (status_t)OK); - CHECK_EQ(composerClient->closeTransaction(), (status_t)OK); + SurfaceComposerClient::closeGlobalTransaction(); surface = control->getSurface(); CHECK(surface != NULL); } - sp<Controller> controller = new Controller(argv[0], decodeAudio, surface); + sp<Controller> controller = + new Controller(argv[0], decodeAudio, surface, renderToSurface); + looper->registerHandler(controller); controller->startAsync(); diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp index d7b1e71..1a5b7f3 100644 --- a/cmds/stagefright/stagefright.cpp +++ b/cmds/stagefright/stagefright.cpp @@ -74,8 +74,6 @@ static String8 gWriteMP4Filename; static sp<ANativeWindow> gSurface; -#define USE_SURFACE_COMPOSER 0 - static int64_t getNowUs() { struct timeval tv; gettimeofday(&tv, NULL); @@ -579,6 +577,7 @@ static void usage(const char *me) { fprintf(stderr, " -x display a histogram of decoding times/fps " "(video only)\n"); fprintf(stderr, " -S allocate buffers from a surface\n"); + fprintf(stderr, " -T allocate buffers from a surface texture\n"); } int main(int argc, char **argv) { @@ -590,6 +589,7 @@ int main(int argc, char **argv) { bool extractThumbnail = false; bool seekTest = false; bool useSurfaceAlloc = false; + bool useSurfaceTexAlloc = false; gNumRepetitions = 1; gMaxNumFrames = 0; gReproduceBug = -1; @@ -604,7 +604,7 @@ int main(int argc, char **argv) { sp<LiveSession> liveSession; int res; - while ((res = getopt(argc, argv, "han:lm:b:ptsrow:kxS")) >= 0) { + while ((res = getopt(argc, argv, "han:lm:b:ptsrow:kxST")) >= 0) { switch (res) { case 'a': { @@ -695,6 +695,12 @@ int main(int argc, char **argv) { break; } + case 'T': + { + useSurfaceTexAlloc = true; + break; + } + case '?': case 'h': default: @@ -843,34 +849,35 @@ int main(int argc, char **argv) { sp<SurfaceComposerClient> composerClient; sp<SurfaceControl> control; - if (useSurfaceAlloc && !audioOnly) { -#if USE_SURFACE_COMPOSER - composerClient = new SurfaceComposerClient; - CHECK_EQ(composerClient->initCheck(), (status_t)OK); - - control = composerClient->createSurface( - getpid(), - String8("A Surface"), - 0, - 1280, - 800, - PIXEL_FORMAT_RGB_565, - 0); - - CHECK(control != NULL); - CHECK(control->isValid()); - - CHECK_EQ(composerClient->openTransaction(), (status_t)OK); - CHECK_EQ(control->setLayer(30000), (status_t)OK); - CHECK_EQ(control->show(), (status_t)OK); - CHECK_EQ(composerClient->closeTransaction(), (status_t)OK); - - gSurface = control->getSurface(); - CHECK(gSurface != NULL); -#else - sp<SurfaceTexture> texture = new SurfaceTexture(0 /* tex */); - gSurface = new SurfaceTextureClient(texture); -#endif + if ((useSurfaceAlloc || useSurfaceTexAlloc) && !audioOnly) { + if (useSurfaceAlloc) { + composerClient = new SurfaceComposerClient; + CHECK_EQ(composerClient->initCheck(), (status_t)OK); + + control = composerClient->createSurface( + String8("A Surface"), + 0, + 1280, + 800, + PIXEL_FORMAT_RGB_565, + 0); + + CHECK(control != NULL); + CHECK(control->isValid()); + + SurfaceComposerClient::openGlobalTransaction(); + CHECK_EQ(control->setLayer(30000), (status_t)OK); + CHECK_EQ(control->show(), (status_t)OK); + SurfaceComposerClient::closeGlobalTransaction(); + + gSurface = control->getSurface(); + CHECK(gSurface != NULL); + } else { + CHECK(useSurfaceTexAlloc); + + sp<SurfaceTexture> texture = new SurfaceTexture(0 /* tex */); + gSurface = new SurfaceTextureClient(texture); + } } DataSource::RegisterDefaultSniffers(); @@ -1061,12 +1068,12 @@ int main(int argc, char **argv) { } } - if (useSurfaceAlloc && !audioOnly) { + if ((useSurfaceAlloc || useSurfaceTexAlloc) && !audioOnly) { gSurface.clear(); -#if USE_SURFACE_COMPOSER - composerClient->dispose(); -#endif + if (useSurfaceAlloc) { + composerClient->dispose(); + } } client.disconnect(); diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp index f780afb..ee91c29 100644 --- a/cmds/stagefright/stream.cpp +++ b/cmds/stagefright/stream.cpp @@ -20,6 +20,11 @@ #include <media/mediaplayer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> +#include <media/stagefright/DataSource.h> +#include <media/stagefright/MPEG2TSWriter.h> +#include <media/stagefright/MediaExtractor.h> +#include <media/stagefright/MediaSource.h> +#include <media/stagefright/MetaData.h> #include <binder/IServiceManager.h> #include <media/IMediaPlayerService.h> @@ -31,7 +36,7 @@ using namespace android; struct MyStreamSource : public BnStreamSource { - // Caller retains ownership of fd. + // Object assumes ownership of fd. MyStreamSource(int fd); virtual void setListener(const sp<IStreamListener> &listener); @@ -64,6 +69,8 @@ MyStreamSource::MyStreamSource(int fd) } MyStreamSource::~MyStreamSource() { + close(mFd); + mFd = -1; } void MyStreamSource::setListener(const sp<IStreamListener> &listener) { @@ -99,6 +106,143 @@ void MyStreamSource::onBufferAvailable(size_t index) { mListener->queueBuffer(index, n); } } +//////////////////////////////////////////////////////////////////////////////// + +struct MyConvertingStreamSource : public BnStreamSource { + MyConvertingStreamSource(const char *filename); + + virtual void setListener(const sp<IStreamListener> &listener); + virtual void setBuffers(const Vector<sp<IMemory> > &buffers); + + virtual void onBufferAvailable(size_t index); + +protected: + virtual ~MyConvertingStreamSource(); + +private: + Mutex mLock; + Condition mCondition; + + sp<IStreamListener> mListener; + Vector<sp<IMemory> > mBuffers; + + sp<MPEG2TSWriter> mWriter; + + ssize_t mCurrentBufferIndex; + size_t mCurrentBufferOffset; + + List<size_t> mBufferQueue; + + static ssize_t WriteDataWrapper(void *me, const void *data, size_t size); + ssize_t writeData(const void *data, size_t size); + + DISALLOW_EVIL_CONSTRUCTORS(MyConvertingStreamSource); +}; + +//////////////////////////////////////////////////////////////////////////////// + +MyConvertingStreamSource::MyConvertingStreamSource(const char *filename) + : mCurrentBufferIndex(-1), + mCurrentBufferOffset(0) { + sp<DataSource> dataSource = DataSource::CreateFromURI(filename); + CHECK(dataSource != NULL); + + sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource); + CHECK(extractor != NULL); + + mWriter = new MPEG2TSWriter( + this, &MyConvertingStreamSource::WriteDataWrapper); + + for (size_t i = 0; i < extractor->countTracks(); ++i) { + const sp<MetaData> &meta = extractor->getTrackMetaData(i); + + const char *mime; + CHECK(meta->findCString(kKeyMIMEType, &mime)); + + if (strncasecmp("video/", mime, 6) && strncasecmp("audio/", mime, 6)) { + continue; + } + + CHECK_EQ(mWriter->addSource(extractor->getTrack(i)), (status_t)OK); + } + + CHECK_EQ(mWriter->start(), (status_t)OK); +} + +MyConvertingStreamSource::~MyConvertingStreamSource() { +} + +void MyConvertingStreamSource::setListener( + const sp<IStreamListener> &listener) { + mListener = listener; +} + +void MyConvertingStreamSource::setBuffers( + const Vector<sp<IMemory> > &buffers) { + mBuffers = buffers; +} + +ssize_t MyConvertingStreamSource::WriteDataWrapper( + void *me, const void *data, size_t size) { + return static_cast<MyConvertingStreamSource *>(me)->writeData(data, size); +} + +ssize_t MyConvertingStreamSource::writeData(const void *data, size_t size) { + size_t totalWritten = 0; + + while (size > 0) { + Mutex::Autolock autoLock(mLock); + + if (mCurrentBufferIndex < 0) { + while (mBufferQueue.empty()) { + mCondition.wait(mLock); + } + + mCurrentBufferIndex = *mBufferQueue.begin(); + mCurrentBufferOffset = 0; + + mBufferQueue.erase(mBufferQueue.begin()); + } + + sp<IMemory> mem = mBuffers.itemAt(mCurrentBufferIndex); + + size_t copy = size; + if (copy + mCurrentBufferOffset > mem->size()) { + copy = mem->size() - mCurrentBufferOffset; + } + + memcpy((uint8_t *)mem->pointer() + mCurrentBufferOffset, data, copy); + mCurrentBufferOffset += copy; + + if (mCurrentBufferOffset == mem->size()) { + mListener->queueBuffer(mCurrentBufferIndex, mCurrentBufferOffset); + mCurrentBufferIndex = -1; + } + + data = (const uint8_t *)data + copy; + size -= copy; + + totalWritten += copy; + } + + return (ssize_t)totalWritten; +} + +void MyConvertingStreamSource::onBufferAvailable(size_t index) { + Mutex::Autolock autoLock(mLock); + + mBufferQueue.push_back(index); + mCondition.signal(); + + if (mWriter->reachedEOS()) { + if (mCurrentBufferIndex >= 0) { + mListener->queueBuffer(mCurrentBufferIndex, mCurrentBufferOffset); + mCurrentBufferIndex = -1; + } + + mListener->issueCommand(IStreamListener::EOS, false /* synchronous */); + } +} //////////////////////////////////////////////////////////////////////////////// @@ -139,6 +283,8 @@ private: int main(int argc, char **argv) { android::ProcessState::self()->startThreadPool(); + DataSource::RegisterDefaultSniffers(); + if (argc != 2) { fprintf(stderr, "Usage: %s filename\n", argv[0]); return 1; @@ -159,10 +305,10 @@ int main(int argc, char **argv) { CHECK(control != NULL); CHECK(control->isValid()); - CHECK_EQ(composerClient->openTransaction(), (status_t)OK); + SurfaceComposerClient::openGlobalTransaction(); CHECK_EQ(control->setLayer(30000), (status_t)OK); CHECK_EQ(control->show(), (status_t)OK); - CHECK_EQ(composerClient->closeTransaction(), (status_t)OK); + SurfaceComposerClient::closeGlobalTransaction(); sp<Surface> surface = control->getSurface(); CHECK(surface != NULL); @@ -173,17 +319,28 @@ int main(int argc, char **argv) { CHECK(service.get() != NULL); - int fd = open(argv[1], O_RDONLY); + sp<MyClient> client = new MyClient; + + sp<IStreamSource> source; - if (fd < 0) { - fprintf(stderr, "Failed to open file '%s'.", argv[1]); - return 1; - } + size_t len = strlen(argv[1]); + if (len >= 3 && !strcasecmp(".ts", &argv[1][len - 3])) { + int fd = open(argv[1], O_RDONLY); - sp<MyClient> client = new MyClient; + if (fd < 0) { + fprintf(stderr, "Failed to open file '%s'.", argv[1]); + return 1; + } + + source = new MyStreamSource(fd); + } else { + printf("Converting file to transport stream for streaming...\n"); + + source = new MyConvertingStreamSource(argv[1]); + } sp<IMediaPlayer> player = - service->create(getpid(), client, new MyStreamSource(fd), 0); + service->create(getpid(), client, source, 0); if (player != NULL) { player->setVideoSurface(surface); @@ -196,9 +353,6 @@ int main(int argc, char **argv) { fprintf(stderr, "failed to instantiate player.\n"); } - close(fd); - fd = -1; - composerClient->dispose(); return 0; diff --git a/cmds/system_server/library/system_init.cpp b/cmds/system_server/library/system_init.cpp index a19711e..59360d3 100644 --- a/cmds/system_server/library/system_init.cpp +++ b/cmds/system_server/library/system_init.cpp @@ -76,23 +76,6 @@ extern "C" status_t system_init() SensorService::instantiate(); } - // On the simulator, audioflinger et al don't get started the - // same way as on the device, and we need to start them here - if (!proc->supportsProcesses()) { - - // Start the AudioFlinger - AudioFlinger::instantiate(); - - // Start the media playback service - MediaPlayerService::instantiate(); - - // Start the camera service - CameraService::instantiate(); - - // Start the audio policy service - AudioPolicyService::instantiate(); - } - // And now start the Android runtime. We have to do this bit // of nastiness because the Android runtime initialization requires // some of the core system services to already be started. @@ -117,14 +100,10 @@ extern "C" status_t system_init() } env->CallStaticVoidMethod(clazz, methodId); - // If running in our own process, just go into the thread - // pool. Otherwise, call the initialization finished - // func to let this process continue its initilization. - if (proc->supportsProcesses()) { - LOGI("System server: entering thread pool.\n"); - ProcessState::self()->startThreadPool(); - IPCThreadState::self()->joinThreadPool(); - LOGI("System server: exiting thread pool.\n"); - } + LOGI("System server: entering thread pool.\n"); + ProcessState::self()->startThreadPool(); + IPCThreadState::self()->joinThreadPool(); + LOGI("System server: exiting thread pool.\n"); + return NO_ERROR; } |