summaryrefslogtreecommitdiff
path: root/cmds
diff options
context:
space:
mode:
Diffstat (limited to 'cmds')
-rw-r--r--cmds/am/src/com/android/commands/am/Am.java82
-rw-r--r--cmds/backup/Android.mk2
-rw-r--r--cmds/backup/backup.cpp2
-rw-r--r--cmds/bootanimation/Android.mk1
-rw-r--r--cmds/bootanimation/BootAnimation.cpp8
-rw-r--r--cmds/bootanimation/BootAnimation.h9
-rw-r--r--cmds/bootanimation/bootanimation_main.cpp2
-rw-r--r--cmds/content/Android.mk33
-rw-r--r--cmds/content/MODULE_LICENSE_APACHE2 (renamed from cmds/dumpsys/MODULE_LICENSE_APACHE2)0
-rw-r--r--cmds/content/NOTICE190
-rwxr-xr-xcmds/content/content5
-rw-r--r--cmds/content/src/com/android/commands/content/Content.java447
-rw-r--r--cmds/dumpstate/Android.mk19
-rw-r--r--cmds/dumpstate/dumpstate.c410
-rw-r--r--cmds/dumpstate/dumpstate.h57
-rw-r--r--cmds/dumpstate/utils.c445
-rw-r--r--cmds/dumpsys/Android.mk19
-rw-r--r--cmds/dumpsys/dumpsys.cpp85
-rwxr-xr-xcmds/input/src/com/android/commands/input/Input.java137
-rw-r--r--cmds/installd/commands.c42
-rw-r--r--cmds/installd/installd.c11
-rw-r--r--cmds/installd/installd.h4
-rw-r--r--cmds/keystore/Android.mk32
-rw-r--r--cmds/keystore/keystore.cpp810
-rw-r--r--cmds/keystore/keystore.h43
-rw-r--r--cmds/keystore/keystore_cli.cpp95
-rw-r--r--cmds/keystore/keystore_get.h80
-rwxr-xr-xcmds/keystore/test-keystore273
-rw-r--r--cmds/pm/src/com/android/commands/pm/Pm.java175
-rw-r--r--cmds/requestsync/Android.mk16
-rw-r--r--cmds/requestsync/MODULE_LICENSE_APACHE20
-rw-r--r--cmds/requestsync/NOTICE (renamed from cmds/dumpsys/NOTICE)0
-rwxr-xr-xcmds/requestsync/requestsync6
-rw-r--r--cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java237
-rw-r--r--cmds/screencap/screencap.cpp3
-rw-r--r--cmds/servicemanager/Android.mk3
-rw-r--r--cmds/servicemanager/binder.c2
-rw-r--r--cmds/servicemanager/service_manager.c28
-rw-r--r--cmds/stagefright/Android.mk150
-rw-r--r--cmds/stagefright/SineSource.cpp102
-rw-r--r--cmds/stagefright/SineSource.h39
-rw-r--r--cmds/stagefright/WaveWriter.h71
-rw-r--r--cmds/stagefright/audioloop.cpp103
-rw-r--r--cmds/stagefright/record.cpp354
-rw-r--r--cmds/stagefright/recordvideo.cpp302
-rw-r--r--cmds/stagefright/sf2.cpp646
-rw-r--r--cmds/stagefright/stagefright.cpp1118
-rw-r--r--cmds/stagefright/stream.cpp376
-rw-r--r--cmds/surfaceflinger/Android.mk17
-rw-r--r--cmds/surfaceflinger/main_surfaceflinger.cpp25
-rw-r--r--cmds/system_server/library/Android.mk9
-rw-r--r--cmds/system_server/library/system_init.cpp4
52 files changed, 1307 insertions, 5822 deletions
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index fddb429d5ae5..53a0186a5e0d 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -31,6 +31,7 @@ import android.content.Intent;
import android.content.pm.IPackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
+import android.os.Binder;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -56,14 +57,14 @@ public class Am {
private int mNextArg;
private String mCurArgData;
- private boolean mDebugOption = false;
+ private int mStartFlags = 0;
private boolean mWaitOption = false;
private boolean mStopOption = false;
private int mRepeat = 0;
+ private int mUserId = 0;
private String mProfileFile;
- private boolean mProfileAutoStop;
// These are magic strings understood by the Eclipse plugin.
private static final String FATAL_ERROR_CODE = "Error type 1";
@@ -135,6 +136,8 @@ public class Am {
runToUri(false);
} else if (op.equals("to-intent-uri")) {
runToUri(true);
+ } else if (op.equals("switch-user")) {
+ runSwitchUser();
} else {
throw new IllegalArgumentException("Unknown command: " + op);
}
@@ -145,11 +148,12 @@ public class Am {
Intent baseIntent = intent;
boolean hasIntentInfo = false;
- mDebugOption = false;
+ mStartFlags = 0;
mWaitOption = false;
mStopOption = false;
mRepeat = 0;
mProfileFile = null;
+ mUserId = 0;
Uri data = null;
String type = null;
@@ -212,6 +216,22 @@ public class Am {
list[i] = Long.valueOf(strings[i]);
}
intent.putExtra(key, list);
+ hasIntentInfo = true;
+ } else if (opt.equals("--ef")) {
+ String key = nextArgRequired();
+ String value = nextArgRequired();
+ intent.putExtra(key, Float.valueOf(value));
+ hasIntentInfo = true;
+ } else if (opt.equals("--efa")) {
+ String key = nextArgRequired();
+ String value = nextArgRequired();
+ String[] strings = value.split(",");
+ float[] list = new float[strings.length];
+ for (int i = 0; i < strings.length; i++) {
+ list[i] = Float.valueOf(strings[i]);
+ }
+ intent.putExtra(key, list);
+ hasIntentInfo = true;
} else if (opt.equals("--ez")) {
String key = nextArgRequired();
String value = nextArgRequired();
@@ -275,19 +295,23 @@ public class Am {
intent.setDataAndType(data, type);
intent = new Intent();
} else if (opt.equals("-D")) {
- mDebugOption = true;
+ mStartFlags |= ActivityManager.START_FLAG_DEBUG;
} else if (opt.equals("-W")) {
mWaitOption = true;
} else if (opt.equals("-P")) {
mProfileFile = nextArgRequired();
- mProfileAutoStop = true;
+ mStartFlags |= ActivityManager.START_FLAG_AUTO_STOP_PROFILER;
} else if (opt.equals("--start-profiler")) {
mProfileFile = nextArgRequired();
- mProfileAutoStop = false;
+ mStartFlags &= ~ActivityManager.START_FLAG_AUTO_STOP_PROFILER;
} else if (opt.equals("-R")) {
mRepeat = Integer.parseInt(nextArgRequired());
} else if (opt.equals("-S")) {
mStopOption = true;
+ } else if (opt.equals("--opengl-trace")) {
+ mStartFlags |= ActivityManager.START_FLAG_OPENGL_TRACES;
+ } else if (opt.equals("--user")) {
+ mUserId = Integer.parseInt(nextArgRequired());
} else {
System.err.println("Error: Unknown option: " + opt);
showUsage();
@@ -387,7 +411,8 @@ public class Am {
System.err.println("Error: Package manager not running; aborting");
return;
}
- List<ResolveInfo> activities = pm.queryIntentActivities(intent, mimeType, 0);
+ List<ResolveInfo> activities = pm.queryIntentActivities(intent, mimeType, 0,
+ mUserId);
if (activities == null || activities.size() <= 0) {
System.err.println("Error: Intent does not match any activities: "
+ intent);
@@ -421,67 +446,65 @@ public class Am {
return;
}
}
-
+
IActivityManager.WaitResult result = null;
int res;
if (mWaitOption) {
result = mAm.startActivityAndWait(null, intent, mimeType,
- null, 0, null, null, 0, false, mDebugOption,
- mProfileFile, fd, mProfileAutoStop);
+ null, null, 0, mStartFlags, mProfileFile, fd, null);
res = result.result;
} else {
res = mAm.startActivity(null, intent, mimeType,
- null, 0, null, null, 0, false, mDebugOption,
- mProfileFile, fd, mProfileAutoStop);
+ null, null, 0, mStartFlags, mProfileFile, fd, null);
}
PrintStream out = mWaitOption ? System.out : System.err;
boolean launched = false;
switch (res) {
- case IActivityManager.START_SUCCESS:
+ case ActivityManager.START_SUCCESS:
launched = true;
break;
- case IActivityManager.START_SWITCHES_CANCELED:
+ case ActivityManager.START_SWITCHES_CANCELED:
launched = true;
out.println(
"Warning: Activity not started because the "
+ " current activity is being kept for the user.");
break;
- case IActivityManager.START_DELIVERED_TO_TOP:
+ case ActivityManager.START_DELIVERED_TO_TOP:
launched = true;
out.println(
"Warning: Activity not started, intent has "
+ "been delivered to currently running "
+ "top-most instance.");
break;
- case IActivityManager.START_RETURN_INTENT_TO_CALLER:
+ case ActivityManager.START_RETURN_INTENT_TO_CALLER:
launched = true;
out.println(
"Warning: Activity not started because intent "
+ "should be handled by the caller");
break;
- case IActivityManager.START_TASK_TO_FRONT:
+ case ActivityManager.START_TASK_TO_FRONT:
launched = true;
out.println(
"Warning: Activity not started, its current "
+ "task has been brought to the front");
break;
- case IActivityManager.START_INTENT_NOT_RESOLVED:
+ case ActivityManager.START_INTENT_NOT_RESOLVED:
out.println(
"Error: Activity not started, unable to "
+ "resolve " + intent.toString());
break;
- case IActivityManager.START_CLASS_NOT_FOUND:
+ case ActivityManager.START_CLASS_NOT_FOUND:
out.println(NO_CLASS_ERROR_CODE);
out.println("Error: Activity class " +
intent.getComponent().toShortString()
+ " does not exist.");
break;
- case IActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
+ case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
out.println(
"Error: Activity not started, you requested to "
+ "both forward and receive its result");
break;
- case IActivityManager.START_PERMISSION_DENIED:
+ case ActivityManager.START_PERMISSION_DENIED:
out.println(
"Error: Activity not started, you do not "
+ "have permission to access it.");
@@ -531,7 +554,8 @@ public class Am {
Intent intent = makeIntent();
IntentReceiver receiver = new IntentReceiver();
System.out.println("Broadcasting: " + intent);
- mAm.broadcastIntent(null, intent, null, receiver, 0, null, null, null, true, false);
+ mAm.broadcastIntent(null, intent, null, receiver, 0, null, null, null, true, false,
+ mUserId);
receiver.waitForFinish();
}
@@ -722,6 +746,14 @@ public class Am {
mAm.setDebugApp(null, false, true);
}
+ private void runSwitchUser() throws Exception {
+ if (android.os.Process.myUid() != 0) {
+ throw new RuntimeException("switchuser can only be run as root");
+ }
+ String user = nextArgRequired();
+ mAm.switchUser(Integer.parseInt(user));
+ }
+
class MyActivityController extends IActivityController.Stub {
final String mGdbPort;
@@ -1249,7 +1281,7 @@ public class Am {
System.err.println(
"usage: am [subcommand] [options]\n" +
"usage: am start [-D] [-W] [-P <FILE>] [--start-profiler <FILE>]\n" +
- " [--R COUNT] [-S] <INTENT>\n" +
+ " [--R COUNT] [-S] [--opengl-trace] <INTENT>\n" +
" am startservice <INTENT>\n" +
" am force-stop <PACKAGE>\n" +
" am kill <PACKAGE>\n" +
@@ -1267,6 +1299,7 @@ public class Am {
" am display-size [reset|MxN]\n" +
" am to-uri [INTENT]\n" +
" am to-intent-uri [INTENT]\n" +
+ " am switch-user <USER_ID>\n" +
"\n" +
"am start: start an Activity. Options are:\n" +
" -D: enable debugging\n" +
@@ -1276,6 +1309,7 @@ public class Am {
" -R: repeat the activity launch <COUNT> times. Prior to each repeat,\n" +
" the top activity will be finished.\n" +
" -S: force stop the target app before starting the activity\n" +
+ " --opengl-trace: enable tracing of OpenGL functions\n" +
"\n" +
"am startservice: start a Service.\n" +
"\n" +
@@ -1330,9 +1364,11 @@ public class Am {
" [--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]\n" +
" [--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]\n" +
" [--el <EXTRA_KEY> <EXTRA_LONG_VALUE> ...]\n" +
+ " [--ef <EXTRA_KEY> <EXTRA_FLOAT_VALUE> ...]\n" +
" [--eu <EXTRA_KEY> <EXTRA_URI_VALUE> ...]\n" +
" [--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]\n" +
" [--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" +
+ " [--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]\n" +
" [-n <COMPONENT>] [-f <FLAGS>]\n" +
" [--grant-read-uri-permission] [--grant-write-uri-permission]\n" +
" [--debug-log-resolution] [--exclude-stopped-packages]\n" +
diff --git a/cmds/backup/Android.mk b/cmds/backup/Android.mk
index 508aec073570..73af0bc0a6ca 100644
--- a/cmds/backup/Android.mk
+++ b/cmds/backup/Android.mk
@@ -5,7 +5,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES:= backup.cpp
-LOCAL_SHARED_LIBRARIES := libcutils libutils
+LOCAL_SHARED_LIBRARIES := libcutils libutils libandroidfw
LOCAL_MODULE:= btool
diff --git a/cmds/backup/backup.cpp b/cmds/backup/backup.cpp
index d4e669b5d9e8..ea1888beea2a 100644
--- a/cmds/backup/backup.cpp
+++ b/cmds/backup/backup.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include <utils/BackupHelpers.h>
+#include <androidfw/BackupHelpers.h>
#include <utils/String8.h>
#include <fcntl.h>
diff --git a/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk
index 7d3991279770..8c46b212814a 100644
--- a/cmds/bootanimation/Android.mk
+++ b/cmds/bootanimation/Android.mk
@@ -9,6 +9,7 @@ LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
LOCAL_SHARED_LIBRARIES := \
libcutils \
+ libandroidfw \
libutils \
libbinder \
libui \
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 0d5b4caa91b4..0ab6aa38a47f 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -25,12 +25,12 @@
#include <cutils/properties.h>
+#include <androidfw/AssetManager.h>
#include <binder/IPCThreadState.h>
-#include <utils/threads.h>
#include <utils/Atomic.h>
#include <utils/Errors.h>
#include <utils/Log.h>
-#include <utils/AssetManager.h>
+#include <utils/threads.h>
#include <ui/PixelFormat.h>
#include <ui/Rect.h>
@@ -38,8 +38,8 @@
#include <ui/DisplayInfo.h>
#include <ui/FramebufferNativeWindow.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/ISurfaceComposerClient.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
#include <core/SkBitmap.h>
#include <core/SkStream.h>
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index 8e28bba2de3c..62da82f134ba 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -20,11 +20,8 @@
#include <stdint.h>
#include <sys/types.h>
+#include <androidfw/AssetManager.h>
#include <utils/threads.h>
-#include <utils/AssetManager.h>
-
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
#include <EGL/egl.h>
#include <GLES/gl.h>
@@ -33,7 +30,9 @@ class SkBitmap;
namespace android {
-class AssetManager;
+class Surface;
+class SurfaceComposerClient;
+class SurfaceControl;
// ---------------------------------------------------------------------------
diff --git a/cmds/bootanimation/bootanimation_main.cpp b/cmds/bootanimation/bootanimation_main.cpp
index ff809d369fb3..417e138b7041 100644
--- a/cmds/bootanimation/bootanimation_main.cpp
+++ b/cmds/bootanimation/bootanimation_main.cpp
@@ -25,8 +25,6 @@
#include <utils/Log.h>
#include <utils/threads.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-
#if defined(HAVE_PTHREADS)
# include <pthread.h>
# include <sys/resource.h>
diff --git a/cmds/content/Android.mk b/cmds/content/Android.mk
new file mode 100644
index 000000000000..88c46f2792d5
--- /dev/null
+++ b/cmds/content/Android.mk
@@ -0,0 +1,33 @@
+# Copyright 2012 The Android Open Source Project
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_MODULE := content
+
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+ALL_PREBUILT += $(TARGET_OUT)/bin/content
+$(TARGET_OUT)/bin/content : $(LOCAL_PATH)/content | $(ACP)
+ $(transform-prebuilt-to-target)
+
+NOTICE_FILE := NOTICE
+files_noticed := bin/content
+
+# Generate rules for a single file. The argument is the file path relative to
+# the installation root
+define make-notice-file
+
+$(TARGET_OUT_NOTICE_FILES)/src/$(1).txt: $(LOCAL_PATH)/$(NOTICE_FILE)
+ @echo Notice file: $$< -- $$@
+ @mkdir -p $$(dir $$@)
+ @cat $$< >> $$@
+
+$(TARGET_OUT_NOTICE_FILES)/hash-timestamp: $(TARGET_OUT_NOTICE_FILES)/src/$(1).txt
+
+endef
+
+$(foreach file,$(files_noticed),$(eval $(call make-notice-file,$(file))))
diff --git a/cmds/dumpsys/MODULE_LICENSE_APACHE2 b/cmds/content/MODULE_LICENSE_APACHE2
index e69de29bb2d1..e69de29bb2d1 100644
--- a/cmds/dumpsys/MODULE_LICENSE_APACHE2
+++ b/cmds/content/MODULE_LICENSE_APACHE2
diff --git a/cmds/content/NOTICE b/cmds/content/NOTICE
new file mode 100644
index 000000000000..33ff96160b77
--- /dev/null
+++ b/cmds/content/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2005-2012, The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+
+ 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/content/content b/cmds/content/content
new file mode 100755
index 000000000000..a8e056d04d69
--- /dev/null
+++ b/cmds/content/content
@@ -0,0 +1,5 @@
+# Script to start "content" on the device, which has a very rudimentary shell.
+base=/system
+export CLASSPATH=$base/framework/content.jar
+exec app_process $base/bin com.android.commands.content.Content "$@"
+
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
new file mode 100644
index 000000000000..bd9eb9a930f9
--- /dev/null
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -0,0 +1,447 @@
+/*
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package com.android.commands.content;
+
+import android.app.ActivityManagerNative;
+import android.app.IActivityManager;
+import android.app.IActivityManager.ContentProviderHolder;
+import android.content.ContentValues;
+import android.content.IContentProvider;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.IBinder;
+import android.text.TextUtils;
+
+/**
+ * This class is a command line utility for manipulating content. A client
+ * can insert, update, and remove records in a content provider. For example,
+ * some settings may be configured before running the CTS tests, etc.
+ * <p>
+ * Examples:
+ * <ul>
+ * <li>
+ * # Add "new_setting" secure setting with value "new_value".</br>
+ * adb shell content insert --uri content://settings/secure --bind name:s:new_setting
+ * --bind value:s:new_value
+ * </li>
+ * <li>
+ * # Change "new_setting" secure setting to "newer_value" (You have to escape single quotes in
+ * the where clause).</br>
+ * adb shell content update --uri content://settings/secure --bind value:s:newer_value
+ * --where "name=\'new_setting\'"
+ * </li>
+ * <li>
+ * # Remove "new_setting" secure setting.</br>
+ * adb shell content delete --uri content://settings/secure --where "name=\'new_setting\'"
+ * </li>
+ * <li>
+ * # Query \"name\" and \"value\" columns from secure settings where \"name\" is equal to"
+ * \"new_setting\" and sort the result by name in ascending order.\n"
+ * adb shell content query --uri content://settings/secure --projection name:value
+ * --where "name=\'new_setting\'" --sort \"name ASC\"
+ * </li>
+ * </ul>
+ * </p>
+ */
+public class Content {
+
+ private static final String USAGE =
+ "usage: adb shell content [subcommand] [options]\n"
+ + "\n"
+ + "usage: adb shell content insert --uri <URI> --bind <BINDING> [--bind <BINDING>...]\n"
+ + " <URI> a content provider URI.\n"
+ + " <BINDING> binds a typed value to a column and is formatted:\n"
+ + " <COLUMN_NAME>:<TYPE>:<COLUMN_VALUE> where:\n"
+ + " <TYPE> specifies data type such as:\n"
+ + " b - boolean, s - string, i - integer, l - long, f - float, d - double\n"
+ + " Note: Omit the value for passing an empty string, e.g column:s:\n"
+ + " Example:\n"
+ + " # Add \"new_setting\" secure setting with value \"new_value\".\n"
+ + " adb shell content insert --uri content://settings/secure --bind name:s:new_setting"
+ + " --bind value:s:new_value\n"
+ + "\n"
+ + "usage: adb shell content update --uri <URI> [--where <WHERE>]\n"
+ + " <WHERE> is a SQL style where clause in quotes (You have to escape single quotes"
+ + " - see example below).\n"
+ + " Example:\n"
+ + " # Change \"new_setting\" secure setting to \"newer_value\".\n"
+ + " adb shell content update --uri content://settings/secure --bind"
+ + " value:s:newer_value --where \"name=\'new_setting\'\"\n"
+ + "\n"
+ + "usage: adb shell content delete --uri <URI> --bind <BINDING>"
+ + " [--bind <BINDING>...] [--where <WHERE>]\n"
+ + " Example:\n"
+ + " # Remove \"new_setting\" secure setting.\n"
+ + " adb shell content delete --uri content://settings/secure "
+ + "--where \"name=\'new_setting\'\"\n"
+ + "\n"
+ + "usage: adb shell content query --uri <URI> [--projection <PROJECTION>]"
+ + " [--where <WHERE>] [--sort <SORT_ORDER>]\n"
+ + " <PROJECTION> is a list of colon separated column names and is formatted:\n"
+ + " <COLUMN_NAME>[:<COLUMN_NAME>...]\n"
+ + " <SORT_OREDER> is the order in which rows in the result should be sorted.\n"
+ + " Example:\n"
+ + " # Select \"name\" and \"value\" columns from secure settings where \"name\" is "
+ + "equal to \"new_setting\" and sort the result by name in ascending order.\n"
+ + " adb shell content query --uri content://settings/secure --projection name:value"
+ + " --where \"name=\'new_setting\'\" --sort \"name ASC\"\n"
+ + "\n";
+
+ private static class Parser {
+ private static final String ARGUMENT_INSERT = "insert";
+ private static final String ARGUMENT_DELETE = "delete";
+ private static final String ARGUMENT_UPDATE = "update";
+ private static final String ARGUMENT_QUERY = "query";
+ private static final String ARGUMENT_WHERE = "--where";
+ private static final String ARGUMENT_BIND = "--bind";
+ private static final String ARGUMENT_URI = "--uri";
+ private static final String ARGUMENT_PROJECTION = "--projection";
+ private static final String ARGUMENT_SORT = "--sort";
+ private static final String TYPE_BOOLEAN = "b";
+ private static final String TYPE_STRING = "s";
+ private static final String TYPE_INTEGER = "i";
+ private static final String TYPE_LONG = "l";
+ private static final String TYPE_FLOAT = "f";
+ private static final String TYPE_DOUBLE = "d";
+ private static final String COLON = ":";
+ private static final String ARGUMENT_PREFIX = "--";
+
+ private final Tokenizer mTokenizer;
+
+ public Parser(String[] args) {
+ mTokenizer = new Tokenizer(args);
+ }
+
+ public Command parseCommand() {
+ try {
+ String operation = mTokenizer.nextArg();
+ if (ARGUMENT_INSERT.equals(operation)) {
+ return parseInsertCommand();
+ } else if (ARGUMENT_DELETE.equals(operation)) {
+ return parseDeleteCommand();
+ } else if (ARGUMENT_UPDATE.equals(operation)) {
+ return parseUpdateCommand();
+ } else if (ARGUMENT_QUERY.equals(operation)) {
+ return parseQueryCommand();
+ } else {
+ throw new IllegalArgumentException("Unsupported operation: " + operation);
+ }
+ } catch (IllegalArgumentException iae) {
+ System.out.println(USAGE);
+ System.out.println("[ERROR] " + iae.getMessage());
+ return null;
+ }
+ }
+
+ private InsertCommand parseInsertCommand() {
+ Uri uri = null;
+ ContentValues values = new ContentValues();
+ for (String argument; (argument = mTokenizer.nextArg()) != null;) {
+ if (ARGUMENT_URI.equals(argument)) {
+ uri = Uri.parse(argumentValueRequired(argument));
+ } else if (ARGUMENT_BIND.equals(argument)) {
+ parseBindValue(values);
+ } else {
+ throw new IllegalArgumentException("Unsupported argument: " + argument);
+ }
+ }
+ if (uri == null) {
+ throw new IllegalArgumentException("Content provider URI not specified."
+ + " Did you specify --uri argument?");
+ }
+ if (values.size() == 0) {
+ throw new IllegalArgumentException("Bindings not specified."
+ + " Did you specify --bind argument(s)?");
+ }
+ return new InsertCommand(uri, values);
+ }
+
+ private DeleteCommand parseDeleteCommand() {
+ Uri uri = null;
+ String where = null;
+ for (String argument; (argument = mTokenizer.nextArg())!= null;) {
+ if (ARGUMENT_URI.equals(argument)) {
+ uri = Uri.parse(argumentValueRequired(argument));
+ } else if (ARGUMENT_WHERE.equals(argument)) {
+ where = argumentValueRequired(argument);
+ } else {
+ throw new IllegalArgumentException("Unsupported argument: " + argument);
+ }
+ }
+ if (uri == null) {
+ throw new IllegalArgumentException("Content provider URI not specified."
+ + " Did you specify --uri argument?");
+ }
+ return new DeleteCommand(uri, where);
+ }
+
+ private UpdateCommand parseUpdateCommand() {
+ Uri uri = null;
+ String where = null;
+ ContentValues values = new ContentValues();
+ for (String argument; (argument = mTokenizer.nextArg())!= null;) {
+ if (ARGUMENT_URI.equals(argument)) {
+ uri = Uri.parse(argumentValueRequired(argument));
+ } else if (ARGUMENT_WHERE.equals(argument)) {
+ where = argumentValueRequired(argument);
+ } else if (ARGUMENT_BIND.equals(argument)) {
+ parseBindValue(values);
+ } else {
+ throw new IllegalArgumentException("Unsupported argument: " + argument);
+ }
+ }
+ if (uri == null) {
+ throw new IllegalArgumentException("Content provider URI not specified."
+ + " Did you specify --uri argument?");
+ }
+ if (values.size() == 0) {
+ throw new IllegalArgumentException("Bindings not specified."
+ + " Did you specify --bind argument(s)?");
+ }
+ return new UpdateCommand(uri, values, where);
+ }
+
+ public QueryCommand parseQueryCommand() {
+ Uri uri = null;
+ String[] projection = null;
+ String sort = null;
+ String where = null;
+ for (String argument; (argument = mTokenizer.nextArg())!= null;) {
+ if (ARGUMENT_URI.equals(argument)) {
+ uri = Uri.parse(argumentValueRequired(argument));
+ } else if (ARGUMENT_WHERE.equals(argument)) {
+ where = argumentValueRequired(argument);
+ } else if (ARGUMENT_SORT.equals(argument)) {
+ sort = argumentValueRequired(argument);
+ } else if (ARGUMENT_PROJECTION.equals(argument)) {
+ projection = argumentValueRequired(argument).split("[\\s]*:[\\s]*");
+ } else {
+ throw new IllegalArgumentException("Unsupported argument: " + argument);
+ }
+ }
+ if (uri == null) {
+ throw new IllegalArgumentException("Content provider URI not specified."
+ + " Did you specify --uri argument?");
+ }
+ return new QueryCommand(uri, projection, where, sort);
+ }
+
+ private void parseBindValue(ContentValues values) {
+ String argument = mTokenizer.nextArg();
+ if (TextUtils.isEmpty(argument)) {
+ throw new IllegalArgumentException("Binding not well formed: " + argument);
+ }
+ final int firstColonIndex = argument.indexOf(COLON);
+ if (firstColonIndex < 0) {
+ throw new IllegalArgumentException("Binding not well formed: " + argument);
+ }
+ final int secondColonIndex = argument.indexOf(COLON, firstColonIndex + 1);
+ if (secondColonIndex < 0) {
+ throw new IllegalArgumentException("Binding not well formed: " + argument);
+ }
+ String column = argument.substring(0, firstColonIndex);
+ String type = argument.substring(firstColonIndex + 1, secondColonIndex);
+ String value = argument.substring(secondColonIndex + 1);
+ if (TYPE_STRING.equals(type)) {
+ values.put(column, value);
+ } else if (TYPE_BOOLEAN.equalsIgnoreCase(type)) {
+ values.put(column, Boolean.parseBoolean(value));
+ } else if (TYPE_INTEGER.equalsIgnoreCase(type) || TYPE_LONG.equalsIgnoreCase(type)) {
+ values.put(column, Long.parseLong(value));
+ } else if (TYPE_FLOAT.equalsIgnoreCase(type) || TYPE_DOUBLE.equalsIgnoreCase(type)) {
+ values.put(column, Double.parseDouble(value));
+ } else {
+ throw new IllegalArgumentException("Unsupported type: " + type);
+ }
+ }
+
+ private String argumentValueRequired(String argument) {
+ String value = mTokenizer.nextArg();
+ if (TextUtils.isEmpty(value) || value.startsWith(ARGUMENT_PREFIX)) {
+ throw new IllegalArgumentException("No value for argument: " + argument);
+ }
+ return value;
+ }
+ }
+
+ private static class Tokenizer {
+ private final String[] mArgs;
+ private int mNextArg;
+
+ public Tokenizer(String[] args) {
+ mArgs = args;
+ }
+
+ private String nextArg() {
+ if (mNextArg < mArgs.length) {
+ return mArgs[mNextArg++];
+ } else {
+ return null;
+ }
+ }
+ }
+
+ private static abstract class Command {
+ final Uri mUri;
+
+ public Command(Uri uri) {
+ mUri = uri;
+ }
+
+ public final void execute() {
+ String providerName = mUri.getAuthority();
+ try {
+ IActivityManager activityManager = ActivityManagerNative.getDefault();
+ IContentProvider provider = null;
+ IBinder token = new Binder();
+ try {
+ ContentProviderHolder holder = activityManager.getContentProviderExternal(
+ providerName, token);
+ if (holder == null) {
+ throw new IllegalStateException("Could not find provider: " + providerName);
+ }
+ provider = holder.provider;
+ onExecute(provider);
+ } finally {
+ if (provider != null) {
+ activityManager.removeContentProviderExternal(providerName, token);
+ }
+ }
+ } catch (Exception e) {
+ System.err.println("Error while accessing provider:" + providerName);
+ e.printStackTrace();
+ }
+ }
+
+ protected abstract void onExecute(IContentProvider provider) throws Exception;
+ }
+
+ private static class InsertCommand extends Command {
+ final ContentValues mContentValues;
+
+ public InsertCommand(Uri uri, ContentValues contentValues) {
+ super(uri);
+ mContentValues = contentValues;
+ }
+
+ @Override
+ public void onExecute(IContentProvider provider) throws Exception {
+ provider.insert(mUri, mContentValues);
+ }
+ }
+
+ private static class DeleteCommand extends Command {
+ final String mWhere;
+
+ public DeleteCommand(Uri uri, String where) {
+ super(uri);
+ mWhere = where;
+ }
+
+ @Override
+ public void onExecute(IContentProvider provider) throws Exception {
+ provider.delete(mUri, mWhere, null);
+ }
+ }
+
+ private static class QueryCommand extends DeleteCommand {
+ final String[] mProjection;
+ final String mSortOrder;
+
+ public QueryCommand(Uri uri, String[] projection, String where, String sortOrder) {
+ super(uri, where);
+ mProjection = projection;
+ mSortOrder = sortOrder;
+ }
+
+ @Override
+ public void onExecute(IContentProvider provider) throws Exception {
+ Cursor cursor = provider.query(mUri, mProjection, mWhere, null, mSortOrder, null);
+ if (cursor == null) {
+ System.out.println("No result found.");
+ return;
+ }
+ try {
+ if (cursor.moveToFirst()) {
+ int rowIndex = 0;
+ StringBuilder builder = new StringBuilder();
+ do {
+ builder.setLength(0);
+ builder.append("Row: ").append(rowIndex).append(" ");
+ rowIndex++;
+ final int columnCount = cursor.getColumnCount();
+ for (int i = 0; i < columnCount; i++) {
+ if (i > 0) {
+ builder.append(", ");
+ }
+ String columnName = cursor.getColumnName(i);
+ String columnValue = null;
+ final int columnIndex = cursor.getColumnIndex(columnName);
+ final int type = cursor.getType(columnIndex);
+ switch (type) {
+ case Cursor.FIELD_TYPE_FLOAT:
+ columnValue = String.valueOf(cursor.getFloat(columnIndex));
+ break;
+ case Cursor.FIELD_TYPE_INTEGER:
+ columnValue = String.valueOf(cursor.getInt(columnIndex));
+ break;
+ case Cursor.FIELD_TYPE_STRING:
+ columnValue = cursor.getString(columnIndex);
+ break;
+ case Cursor.FIELD_TYPE_BLOB:
+ columnValue = "BLOB";
+ break;
+ case Cursor.FIELD_TYPE_NULL:
+ columnValue = "NULL";
+ break;
+ }
+ builder.append(columnName).append("=").append(columnValue);
+ }
+ System.out.println(builder);
+ } while (cursor.moveToNext());
+ } else {
+ System.out.println("No reuslt found.");
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+ }
+
+ private static class UpdateCommand extends InsertCommand {
+ final String mWhere;
+
+ public UpdateCommand(Uri uri, ContentValues contentValues, String where) {
+ super(uri, contentValues);
+ mWhere = where;
+ }
+
+ @Override
+ public void onExecute(IContentProvider provider) throws Exception {
+ provider.update(mUri, mContentValues, mWhere, null);
+ }
+ }
+
+ public static void main(String[] args) {
+ Parser parser = new Parser(args);
+ Command command = parser.parseCommand();
+ if (command != null) {
+ command.execute();
+ }
+ }
+}
diff --git a/cmds/dumpstate/Android.mk b/cmds/dumpstate/Android.mk
deleted file mode 100644
index d6025006bff8..000000000000
--- a/cmds/dumpstate/Android.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-ifdef BOARD_WLAN_DEVICE
-LOCAL_CFLAGS := -DFWDUMP_$(BOARD_WLAN_DEVICE)
-endif
-
-LOCAL_SRC_FILES := dumpstate.c utils.c
-
-LOCAL_MODULE := dumpstate
-
-LOCAL_SHARED_LIBRARIES := libcutils
-
-ifdef BOARD_LIB_DUMPSTATE
-LOCAL_STATIC_LIBRARIES := $(BOARD_LIB_DUMPSTATE)
-LOCAL_CFLAGS += -DBOARD_HAS_DUMPSTATE
-endif
-
-include $(BUILD_EXECUTABLE)
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
deleted file mode 100644
index 3613101e6768..000000000000
--- a/cmds/dumpstate/dumpstate.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/resource.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <cutils/properties.h>
-
-#include "private/android_filesystem_config.h"
-
-#define LOG_TAG "dumpstate"
-#include <utils/Log.h>
-
-#include "dumpstate.h"
-
-/* read before root is shed */
-static char cmdline_buf[16384] = "(unknown)";
-static const char *dump_traces_path = NULL;
-
-static char screenshot_path[PATH_MAX] = "";
-
-/* dumps the current system state to stdout */
-static void dumpstate() {
- time_t now = time(NULL);
- 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)");
- strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&now));
-
- printf("========================================================\n");
- printf("== dumpstate: %s\n", date);
- printf("========================================================\n");
-
- printf("\n");
- printf("Build: %s\n", build);
- printf("Bootloader: %s\n", bootloader);
- printf("Radio: %s\n", radio);
- printf("Network: %s\n", network);
-
- printf("Kernel: ");
- dump_file(NULL, "/proc/version");
- printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
- printf("\n");
-
- run_command("UPTIME", 10, "uptime", NULL);
- dump_file("MEMORY INFO", "/proc/meminfo");
- run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-t", NULL);
- run_command("PROCRANK", 20, "procrank", NULL);
- dump_file("VIRTUAL MEMORY STATS", "/proc/vmstat");
- dump_file("VMALLOC INFO", "/proc/vmallocinfo");
- dump_file("SLAB INFO", "/proc/slabinfo");
- dump_file("ZONEINFO", "/proc/zoneinfo");
- dump_file("PAGETYPEINFO", "/proc/pagetypeinfo");
- dump_file("BUDDYINFO", "/proc/buddyinfo");
-
- if (screenshot_path[0]) {
- ALOGI("taking screenshot\n");
- run_command(NULL, 5, "su", "root", "screenshot", screenshot_path, NULL);
- ALOGI("wrote screenshot: %s\n", screenshot_path);
- }
-
- run_command("SYSTEM LOG", 20, "logcat", "-v", "threadtime", "-d", "*:v", NULL);
-
- /* show the traces we collected in main(), if that was done */
- if (dump_traces_path != NULL) {
- dump_file("VM TRACES JUST NOW", dump_traces_path);
- }
-
- /* only show ANR traces if they're less than 15 minutes old */
- struct stat st;
- char anr_traces_path[PATH_MAX];
- property_get("dalvik.vm.stack-trace-file", anr_traces_path, "");
- if (!anr_traces_path[0]) {
- printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n");
- } else if (stat(anr_traces_path, &st)) {
- printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_path, strerror(errno));
- } else {
- dump_file("VM TRACES AT LAST ANR", anr_traces_path);
- }
-
- /* slow traces for slow operations */
- if (anr_traces_path[0] != 0) {
- int tail = strlen(anr_traces_path)-1;
- while (tail > 0 && anr_traces_path[tail] != '/') {
- tail--;
- }
- int i = 0;
- while (1) {
- sprintf(anr_traces_path+tail+1, "slow%02d.txt", i);
- if (stat(anr_traces_path, &st)) {
- // No traces file at this index, done with the files.
- break;
- }
- dump_file("VM TRACES WHEN SLOW", anr_traces_path);
- i++;
- }
- }
-
- // dump_file("EVENT LOG TAGS", "/etc/event-log-tags");
- run_command("EVENT LOG", 20, "logcat", "-b", "events", "-v", "threadtime", "-d", "*:v", NULL);
- run_command("RADIO LOG", 20, "logcat", "-b", "radio", "-v", "threadtime", "-d", "*:v", NULL);
-
- run_command("NETWORK INTERFACES", 10, "su", "root", "netcfg", NULL);
- dump_file("NETWORK DEV INFO", "/proc/net/dev");
- dump_file("QTAGUID NETWORK INTERFACES INFO", "/proc/net/xt_qtaguid/iface_stat_all");
- dump_file("QTAGUID CTRL INFO", "/proc/net/xt_qtaguid/ctrl");
- run_command("QTAGUID STATS INFO", 10, "su", "root", "cat", "/proc/net/xt_qtaguid/stats", NULL);
-
- dump_file("NETWORK ROUTES", "/proc/net/route");
- dump_file("NETWORK ROUTES IPV6", "/proc/net/ipv6_route");
- run_command("IP RULES", 10, "ip", "rule", "show", NULL);
- run_command("IP RULES v6", 10, "ip", "-6", "rule", "show", NULL);
- run_command("ROUTE TABLE 60", 10, "ip", "route", "show", "table", "60", NULL);
- run_command("ROUTE TABLE 61 v6", 10, "ip", "-6", "route", "show", "table", "60", NULL);
- run_command("ROUTE TABLE 61", 10, "ip", "route", "show", "table", "61", NULL);
- run_command("ROUTE TABLE 61 v6", 10, "ip", "-6", "route", "show", "table", "61", NULL);
- dump_file("ARP CACHE", "/proc/net/arp");
- run_command("IPTABLES", 10, "su", "root", "iptables", "-L", "-nvx", NULL);
- run_command("IP6TABLES", 10, "su", "root", "ip6tables", "-L", "-nvx", NULL);
- run_command("IPTABLE NAT", 10, "su", "root", "iptables", "-t", "nat", "-L", "-n", NULL);
- run_command("IPT6ABLE NAT", 10, "su", "root", "ip6tables", "-t", "nat", "-L", "-n", NULL);
-
- run_command("WIFI NETWORKS", 20,
- "su", "root", "wpa_cli", "list_networks", NULL);
-
- property_get("dhcp.wlan0.gateway", network, "");
- if (network[0])
- run_command("PING GATEWAY", 10, "su", "root", "ping", "-c", "3", "-i", ".5", network, NULL);
- property_get("dhcp.wlan0.dns1", network, "");
- if (network[0])
- run_command("PING DNS1", 10, "su", "root", "ping", "-c", "3", "-i", ".5", network, NULL);
- property_get("dhcp.wlan0.dns2", network, "");
- if (network[0])
- run_command("PING DNS2", 10, "su", "root", "ping", "-c", "3", "-i", ".5", network, NULL);
-#ifdef FWDUMP_bcm4329
- run_command("DUMP WIFI STATUS", 20,
- "su", "root", "dhdutil", "-i", "wlan0", "dump", NULL);
- run_command("DUMP WIFI INTERNAL COUNTERS", 20,
- "su", "root", "wlutil", "counters", NULL);
-#endif
-
- char ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {0};
- property_get("ril.dumpstate.timeout", ril_dumpstate_timeout, "30");
- 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);
- }
- }
-
- print_properties();
-
- run_command("KERNEL LOG", 20, "dmesg", NULL);
-
- dump_file("KERNEL WAKELOCKS", "/proc/wakelocks");
- dump_file("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state");
-
- run_command("VOLD DUMP", 10, "vdc", "dump", NULL);
- run_command("SECURE CONTAINERS", 10, "vdc", "asec", "list", NULL);
-
- run_command("PROCESSES", 10, "ps", "-P", NULL);
- run_command("PROCESSES AND THREADS", 10, "ps", "-t", "-p", "-P", NULL);
- run_command("LIBRANK", 10, "librank", NULL);
-
- dump_file("BINDER FAILED TRANSACTION LOG", "/sys/kernel/debug/binder/failed_transaction_log");
- dump_file("BINDER TRANSACTION LOG", "/sys/kernel/debug/binder/transaction_log");
- dump_file("BINDER TRANSACTIONS", "/sys/kernel/debug/binder/transactions");
- dump_file("BINDER STATS", "/sys/kernel/debug/binder/stats");
- dump_file("BINDER STATE", "/sys/kernel/debug/binder/state");
-
- run_command("FILESYSTEMS & FREE SPACE", 10, "su", "root", "df", NULL);
-
- dump_file("PACKAGE SETTINGS", "/data/system/packages.xml");
- dump_file("PACKAGE UID ERRORS", "/data/system/uiderrors.txt");
-
- dump_file("LAST KMSG", "/proc/last_kmsg");
- run_command("LAST RADIO LOG", 10, "parse_radio_log", "/proc/last_radio_log", NULL);
- dump_file("LAST PANIC CONSOLE", "/data/dontpanic/apanic_console");
- dump_file("LAST PANIC THREADS", "/data/dontpanic/apanic_threads");
-
- for_each_pid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS");
-
- printf("------ BACKLIGHTS ------\n");
- printf("LCD brightness=");
- dump_file(NULL, "/sys/class/leds/lcd-backlight/brightness");
- printf("Button brightness=");
- dump_file(NULL, "/sys/class/leds/button-backlight/brightness");
- printf("Keyboard brightness=");
- dump_file(NULL, "/sys/class/leds/keyboard-backlight/brightness");
- printf("ALS mode=");
- dump_file(NULL, "/sys/class/leds/lcd-backlight/als");
- printf("LCD driver registers:\n");
- dump_file(NULL, "/sys/class/leds/lcd-backlight/registers");
- printf("\n");
-
- run_command("LIST OF OPEN FILES", 10, "su", "root", "lsof", NULL);
-
- for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES");
-
-#ifdef BOARD_HAS_DUMPSTATE
- printf("========================================================\n");
- printf("== Board\n");
- printf("========================================================\n");
-
- dumpstate_board();
- printf("\n");
-#endif
-
- printf("========================================================\n");
- printf("== Android Framework Services\n");
- printf("========================================================\n");
-
- /* the full dumpsys is starting to take a long time, so we need
- to increase its timeout. we really need to do the timeouts in
- dumpsys itself... */
- run_command("DUMPSYS", 60, "dumpsys", NULL);
-
- printf("========================================================\n");
- printf("== Running Application Activities\n");
- printf("========================================================\n");
-
- run_command("APP ACTIVITIES", 30, "dumpsys", "activity", "all", NULL);
-
- printf("========================================================\n");
- printf("== Running Application Services\n");
- printf("========================================================\n");
-
- run_command("APP SERVICES", 30, "dumpsys", "activity", "service", "all", NULL);
-
- printf("========================================================\n");
- printf("== dumpstate: done\n");
- printf("========================================================\n");
-}
-
-static void usage() {
- fprintf(stderr, "usage: dumpstate [-b soundfile] [-e soundfile] [-o file [-d] [-p] [-z]] [-s]\n"
- " -o: write to file (instead of stdout)\n"
- " -d: append date to filename (requires -o)\n"
- " -z: gzip output (requires -o)\n"
- " -p: capture screenshot to filename.png (requires -o)\n"
- " -s: write output to control socket (for init)\n"
- " -b: play sound file instead of vibrate, at beginning of job\n"
- " -e: play sound file instead of vibrate, at end of job\n"
- );
-}
-
-int main(int argc, char *argv[]) {
- int do_add_date = 0;
- int do_compress = 0;
- char* use_outfile = 0;
- char* begin_sound = 0;
- char* end_sound = 0;
- int use_socket = 0;
- int do_fb = 0;
-
- ALOGI("begin\n");
-
- /* set as high priority, and protect from OOM killer */
- setpriority(PRIO_PROCESS, 0, -20);
- FILE *oom_adj = fopen("/proc/self/oom_adj", "w");
- if (oom_adj) {
- fputs("-17", oom_adj);
- fclose(oom_adj);
- }
-
- /* very first thing, collect VM traces from Dalvik (needs root) */
- dump_traces_path = dump_vm_traces();
-
- int c;
- while ((c = getopt(argc, argv, "b:de:ho:svzp")) != -1) {
- switch (c) {
- case 'b': begin_sound = optarg; break;
- case 'd': do_add_date = 1; break;
- case 'e': end_sound = optarg; break;
- case 'o': use_outfile = optarg; break;
- case 's': use_socket = 1; break;
- case 'v': break; // compatibility no-op
- case 'z': do_compress = 6; break;
- case 'p': do_fb = 1; break;
- case '?': printf("\n");
- case 'h':
- usage();
- exit(1);
- }
- }
-
- /* open the vibrator before dropping root */
- FILE *vibrator = fopen("/sys/class/timed_output/vibrator/enable", "w");
- if (vibrator) fcntl(fileno(vibrator), F_SETFD, FD_CLOEXEC);
-
- /* read /proc/cmdline before dropping root */
- FILE *cmdline = fopen("/proc/cmdline", "r");
- if (cmdline != NULL) {
- fgets(cmdline_buf, sizeof(cmdline_buf), cmdline);
- fclose(cmdline);
- }
-
- if (getuid() == 0) {
- /* switch to non-root user and group */
- gid_t groups[] = { AID_LOG, AID_SDCARD_RW, AID_MOUNT, AID_INET };
- if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
- ALOGE("Unable to setgroups, aborting: %s\n", strerror(errno));
- return -1;
- }
- if (setgid(AID_SHELL) != 0) {
- ALOGE("Unable to setgid, aborting: %s\n", strerror(errno));
- return -1;
- }
- if (setuid(AID_SHELL) != 0) {
- ALOGE("Unable to setuid, aborting: %s\n", strerror(errno));
- return -1;
- }
- }
-
- char path[PATH_MAX], tmp_path[PATH_MAX];
- pid_t gzip_pid = -1;
-
- if (use_socket) {
- redirect_to_socket(stdout, "dumpstate");
- } else if (use_outfile) {
- strlcpy(path, use_outfile, sizeof(path));
- if (do_add_date) {
- char date[80];
- time_t now = time(NULL);
- strftime(date, sizeof(date), "-%Y-%m-%d-%H-%M-%S", localtime(&now));
- strlcat(path, date, sizeof(path));
- }
- if (do_fb) {
- strlcpy(screenshot_path, path, sizeof(screenshot_path));
- strlcat(screenshot_path, ".png", sizeof(screenshot_path));
- }
- strlcat(path, ".txt", sizeof(path));
- if (do_compress) strlcat(path, ".gz", sizeof(path));
- strlcpy(tmp_path, path, sizeof(tmp_path));
- strlcat(tmp_path, ".tmp", sizeof(tmp_path));
- gzip_pid = redirect_to_file(stdout, tmp_path, do_compress);
- }
-
- if (begin_sound) {
- play_sound(begin_sound);
- } else if (vibrator) {
- fputs("150", vibrator);
- fflush(vibrator);
- }
-
- dumpstate();
-
- if (end_sound) {
- play_sound(end_sound);
- } else if (vibrator) {
- int i;
- for (i = 0; i < 3; i++) {
- fputs("75\n", vibrator);
- fflush(vibrator);
- usleep((75 + 50) * 1000);
- }
- fclose(vibrator);
- }
-
- /* wait for gzip to finish, otherwise it might get killed when we exit */
- if (gzip_pid > 0) {
- fclose(stdout);
- waitpid(gzip_pid, NULL, 0);
- }
-
- /* rename the (now complete) .tmp file to its final location */
- if (use_outfile && rename(tmp_path, path)) {
- fprintf(stderr, "rename(%s, %s): %s\n", tmp_path, path, strerror(errno));
- }
-
- ALOGI("done\n");
-
- return 0;
-}
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
deleted file mode 100644
index 6d66b1ba6676..000000000000
--- a/cmds/dumpstate/dumpstate.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _DUMPSTATE_H_
-#define _DUMPSTATE_H_
-
-#include <time.h>
-#include <unistd.h>
-#include <stdio.h>
-
-/* prints the contents of a file */
-int dump_file(const char *title, const char* path);
-
-/* forks a command and waits for it to finish -- terminate args with NULL */
-int run_command(const char *title, int timeout_seconds, const char *command, ...);
-
-/* prints all the system properties */
-void print_properties();
-
-/* redirect output to a service control socket */
-void redirect_to_socket(FILE *redirect, const char *service);
-
-/* redirect output to a file, optionally gzipping; returns gzip pid */
-pid_t redirect_to_file(FILE *redirect, char *path, int gzip_level);
-
-/* dump Dalvik stack traces, return the trace file location (NULL if none) */
-const char *dump_vm_traces();
-
-/* for each process in the system, run the specified function */
-void for_each_pid(void (*func)(int, const char *), const char *header);
-
-/* Displays a blocked processes in-kernel wait channel */
-void show_wchan(int pid, const char *name);
-
-/* Runs "showmap" for a process */
-void do_showmap(int pid, const char *name);
-
-/* Play a sound via Stagefright */
-void play_sound(const char* path);
-
-/* Implemented by libdumpstate_board to dump board-specific info */
-void dumpstate_board();
-
-#endif /* _DUMPSTATE_H_ */
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
deleted file mode 100644
index 14984ecf40a9..000000000000
--- a/cmds/dumpstate/utils.c
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <poll.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/inotify.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <cutils/properties.h>
-#include <cutils/sockets.h>
-#include <private/android_filesystem_config.h>
-
-#include "dumpstate.h"
-
-void for_each_pid(void (*func)(int, const char *), const char *header) {
- DIR *d;
- struct dirent *de;
-
- if (!(d = opendir("/proc"))) {
- printf("Failed to open /proc (%s)\n", strerror(errno));
- return;
- }
-
- printf("\n------ %s ------\n", header);
- while ((de = readdir(d))) {
- int pid;
- int fd;
- char cmdpath[255];
- char cmdline[255];
-
- if (!(pid = atoi(de->d_name))) {
- continue;
- }
-
- sprintf(cmdpath,"/proc/%d/cmdline", pid);
- memset(cmdline, 0, sizeof(cmdline));
- if ((fd = open(cmdpath, O_RDONLY)) < 0) {
- strcpy(cmdline, "N/A");
- } else {
- read(fd, cmdline, sizeof(cmdline));
- close(fd);
- }
- func(pid, cmdline);
- }
-
- closedir(d);
-}
-
-void show_wchan(int pid, const char *name) {
- char path[255];
- char buffer[255];
- int fd;
-
- memset(buffer, 0, sizeof(buffer));
-
- sprintf(path, "/proc/%d/wchan", pid);
- if ((fd = open(path, O_RDONLY)) < 0) {
- printf("Failed to open '%s' (%s)\n", path, strerror(errno));
- return;
- }
-
- if (read(fd, buffer, sizeof(buffer)) < 0) {
- printf("Failed to read '%s' (%s)\n", path, strerror(errno));
- goto out_close;
- }
-
- printf("%-7d %-32s %s\n", pid, name, buffer);
-
-out_close:
- close(fd);
- return;
-}
-
-void do_showmap(int pid, const char *name) {
- char title[255];
- char arg[255];
-
- sprintf(title, "SHOW MAP %d (%s)", pid, name);
- sprintf(arg, "%d", pid);
- run_command(title, 10, "su", "root", "showmap", arg, NULL);
-}
-
-/* prints the contents of a file */
-int dump_file(const char *title, const char* path) {
- char buffer[32768];
- int fd = open(path, O_RDONLY);
- if (fd < 0) {
- int err = errno;
- if (title) printf("------ %s (%s) ------\n", title, path);
- printf("*** %s: %s\n", path, strerror(err));
- if (title) printf("\n");
- return -1;
- }
-
- if (title) printf("------ %s (%s", title, path);
-
- if (title) {
- struct stat st;
- if (memcmp(path, "/proc/", 6) && memcmp(path, "/sys/", 5) && !fstat(fd, &st)) {
- char stamp[80];
- time_t mtime = st.st_mtime;
- strftime(stamp, sizeof(stamp), "%Y-%m-%d %H:%M:%S", localtime(&mtime));
- printf(": %s", stamp);
- }
- printf(") ------\n");
- }
-
- int newline = 0;
- for (;;) {
- int ret = read(fd, buffer, sizeof(buffer));
- if (ret > 0) {
- newline = (buffer[ret - 1] == '\n');
- ret = fwrite(buffer, ret, 1, stdout);
- }
- if (ret <= 0) break;
- }
-
- close(fd);
- if (!newline) printf("\n");
- if (title) printf("\n");
- return 0;
-}
-
-/* forks a command and waits for it to finish */
-int run_command(const char *title, int timeout_seconds, const char *command, ...) {
- fflush(stdout);
- clock_t start = clock();
- pid_t pid = fork();
-
- /* handle error case */
- if (pid < 0) {
- printf("*** fork: %s\n", strerror(errno));
- return pid;
- }
-
- /* handle child case */
- if (pid == 0) {
- const char *args[1024] = {command};
- size_t arg;
-
- va_list ap;
- va_start(ap, command);
- if (title) printf("------ %s (%s", title, command);
- for (arg = 1; arg < sizeof(args) / sizeof(args[0]); ++arg) {
- args[arg] = va_arg(ap, const char *);
- if (args[arg] == NULL) break;
- if (title) printf(" %s", args[arg]);
- }
- if (title) printf(") ------\n");
- fflush(stdout);
-
- execvp(command, (char**) args);
- printf("*** exec(%s): %s\n", command, strerror(errno));
- fflush(stdout);
- _exit(-1);
- }
-
- /* handle parent case */
- for (;;) {
- int status;
- pid_t p = waitpid(pid, &status, WNOHANG);
- float elapsed = (float) (clock() - start) / CLOCKS_PER_SEC;
- if (p == pid) {
- if (WIFSIGNALED(status)) {
- printf("*** %s: Killed by signal %d\n", command, WTERMSIG(status));
- } else if (WIFEXITED(status) && WEXITSTATUS(status) > 0) {
- printf("*** %s: Exit code %d\n", command, WEXITSTATUS(status));
- }
- if (title) printf("[%s: %.1fs elapsed]\n\n", command, elapsed);
- return status;
- }
-
- if (timeout_seconds && elapsed > timeout_seconds) {
- printf("*** %s: Timed out after %.1fs (killing pid %d)\n", command, elapsed, pid);
- kill(pid, SIGTERM);
- return -1;
- }
-
- usleep(100000); // poll every 0.1 sec
- }
-}
-
-size_t num_props = 0;
-static char* props[2000];
-
-static void print_prop(const char *key, const char *name, void *user) {
- (void) user;
- if (num_props < sizeof(props) / sizeof(props[0])) {
- char buf[PROPERTY_KEY_MAX + PROPERTY_VALUE_MAX + 10];
- snprintf(buf, sizeof(buf), "[%s]: [%s]\n", key, name);
- props[num_props++] = strdup(buf);
- }
-}
-
-static int compare_prop(const void *a, const void *b) {
- return strcmp(*(char * const *) a, *(char * const *) b);
-}
-
-/* prints all the system properties */
-void print_properties() {
- size_t i;
- num_props = 0;
- property_list(print_prop, NULL);
- qsort(&props, num_props, sizeof(props[0]), compare_prop);
-
- printf("------ SYSTEM PROPERTIES ------\n");
- for (i = 0; i < num_props; ++i) {
- fputs(props[i], stdout);
- free(props[i]);
- }
- printf("\n");
-}
-
-/* redirect output to a service control socket */
-void redirect_to_socket(FILE *redirect, const char *service) {
- int s = android_get_control_socket(service);
- if (s < 0) {
- fprintf(stderr, "android_get_control_socket(%s): %s\n", service, strerror(errno));
- exit(1);
- }
- if (listen(s, 4) < 0) {
- fprintf(stderr, "listen(control socket): %s\n", strerror(errno));
- exit(1);
- }
-
- struct sockaddr addr;
- socklen_t alen = sizeof(addr);
- int fd = accept(s, &addr, &alen);
- if (fd < 0) {
- fprintf(stderr, "accept(control socket): %s\n", strerror(errno));
- exit(1);
- }
-
- fflush(redirect);
- dup2(fd, fileno(redirect));
- close(fd);
-}
-
-/* redirect output to a file, optionally gzipping; returns gzip pid (or -1) */
-pid_t redirect_to_file(FILE *redirect, char *path, int gzip_level) {
- char *chp = path;
-
- /* skip initial slash */
- if (chp[0] == '/')
- chp++;
-
- /* create leading directories, if necessary */
- while (chp && chp[0]) {
- chp = strchr(chp, '/');
- if (chp) {
- *chp = 0;
- mkdir(path, 0775); /* drwxrwxr-x */
- *chp++ = '/';
- }
- }
-
- int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- if (fd < 0) {
- fprintf(stderr, "%s: %s\n", path, strerror(errno));
- exit(1);
- }
-
- pid_t gzip_pid = -1;
- if (gzip_level > 0) {
- int fds[2];
- if (pipe(fds)) {
- fprintf(stderr, "pipe: %s\n", strerror(errno));
- exit(1);
- }
-
- fflush(redirect);
- fflush(stdout);
-
- gzip_pid = fork();
- if (gzip_pid < 0) {
- fprintf(stderr, "fork: %s\n", strerror(errno));
- exit(1);
- }
-
- if (gzip_pid == 0) {
- dup2(fds[0], STDIN_FILENO);
- dup2(fd, STDOUT_FILENO);
-
- close(fd);
- close(fds[0]);
- close(fds[1]);
-
- char level[10];
- snprintf(level, sizeof(level), "-%d", gzip_level);
- execlp("gzip", "gzip", level, NULL);
- fprintf(stderr, "exec(gzip): %s\n", strerror(errno));
- _exit(-1);
- }
-
- close(fd);
- close(fds[0]);
- fd = fds[1];
- }
-
- dup2(fd, fileno(redirect));
- close(fd);
- return gzip_pid;
-}
-
-/* dump Dalvik stack traces, return the trace file location (NULL if none) */
-const char *dump_vm_traces() {
- char traces_path[PROPERTY_VALUE_MAX] = "";
- property_get("dalvik.vm.stack-trace-file", traces_path, "");
- if (!traces_path[0]) return NULL;
-
- /* move the old traces.txt (if any) out of the way temporarily */
- char anr_traces_path[PATH_MAX];
- strlcpy(anr_traces_path, traces_path, sizeof(anr_traces_path));
- strlcat(anr_traces_path, ".anr", sizeof(anr_traces_path));
- if (rename(traces_path, anr_traces_path) && errno != ENOENT) {
- fprintf(stderr, "rename(%s, %s): %s\n", traces_path, anr_traces_path, strerror(errno));
- return NULL; // Can't rename old traces.txt -- no permission? -- leave it alone instead
- }
-
- /* make the directory if necessary */
- char anr_traces_dir[PATH_MAX];
- strlcpy(anr_traces_dir, traces_path, sizeof(anr_traces_dir));
- char *slash = strrchr(anr_traces_dir, '/');
- if (slash != NULL) {
- *slash = '\0';
- if (!mkdir(anr_traces_dir, 0775)) {
- chown(anr_traces_dir, AID_SYSTEM, AID_SYSTEM);
- } else if (errno != EEXIST) {
- fprintf(stderr, "mkdir(%s): %s\n", anr_traces_dir, strerror(errno));
- return NULL;
- }
- }
-
- /* create a new, empty traces.txt file to receive stack dumps */
- int fd = open(traces_path, O_CREAT | O_WRONLY | O_TRUNC, 0666); /* -rw-rw-rw- */
- if (fd < 0) {
- fprintf(stderr, "%s: %s\n", traces_path, strerror(errno));
- return NULL;
- }
- close(fd);
-
- /* walk /proc and kill -QUIT all Dalvik processes */
- DIR *proc = opendir("/proc");
- if (proc == NULL) {
- fprintf(stderr, "/proc: %s\n", strerror(errno));
- return NULL;
- }
-
- /* use inotify to find when processes are done dumping */
- int ifd = inotify_init();
- if (ifd < 0) {
- fprintf(stderr, "inotify_init: %s\n", strerror(errno));
- return NULL;
- }
-
- int wfd = inotify_add_watch(ifd, traces_path, IN_CLOSE_WRITE);
- if (wfd < 0) {
- fprintf(stderr, "inotify_add_watch(%s): %s\n", traces_path, strerror(errno));
- return NULL;
- }
-
- struct dirent *d;
- int dalvik_found = 0;
- while ((d = readdir(proc))) {
- int pid = atoi(d->d_name);
- if (pid <= 0) continue;
-
- /* identify Dalvik: /proc/(pid)/exe = /system/bin/app_process */
- char path[PATH_MAX], data[PATH_MAX];
- snprintf(path, sizeof(path), "/proc/%d/exe", pid);
- size_t len = readlink(path, data, sizeof(data) - 1);
- if (len <= 0 || memcmp(data, "/system/bin/app_process", 23)) continue;
-
- /* skip zygote -- it won't dump its stack anyway */
- snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
- int fd = open(path, O_RDONLY);
- len = read(fd, data, sizeof(data) - 1);
- close(fd);
- if (len <= 0 || !memcmp(data, "zygote", 6)) continue;
-
- ++dalvik_found;
- if (kill(pid, SIGQUIT)) {
- fprintf(stderr, "kill(%d, SIGQUIT): %s\n", pid, strerror(errno));
- continue;
- }
-
- /* wait for the writable-close notification from inotify */
- struct pollfd pfd = { ifd, POLLIN, 0 };
- int ret = poll(&pfd, 1, 200); /* 200 msec timeout */
- if (ret < 0) {
- fprintf(stderr, "poll: %s\n", strerror(errno));
- } else if (ret == 0) {
- fprintf(stderr, "warning: timed out dumping pid %d\n", pid);
- } else {
- struct inotify_event ie;
- read(ifd, &ie, sizeof(ie));
- }
- }
-
- close(ifd);
- if (dalvik_found == 0) {
- fprintf(stderr, "Warning: no Dalvik processes found to dump stacks\n");
- }
-
- static char dump_traces_path[PATH_MAX];
- strlcpy(dump_traces_path, traces_path, sizeof(dump_traces_path));
- strlcat(dump_traces_path, ".bugreport", sizeof(dump_traces_path));
- if (rename(traces_path, dump_traces_path)) {
- fprintf(stderr, "rename(%s, %s): %s\n", traces_path, dump_traces_path, strerror(errno));
- return NULL;
- }
-
- /* replace the saved [ANR] traces.txt file */
- rename(anr_traces_path, traces_path);
- return dump_traces_path;
-}
-
-void play_sound(const char* path) {
- run_command(NULL, 5, "/system/bin/stagefright", "-o", "-a", path, NULL);
-}
diff --git a/cmds/dumpsys/Android.mk b/cmds/dumpsys/Android.mk
deleted file mode 100644
index 42b1b7365b1b..000000000000
--- a/cmds/dumpsys/Android.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- dumpsys.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libutils \
- libbinder
-
-
-ifeq ($(TARGET_OS),linux)
- LOCAL_CFLAGS += -DXP_UNIX
- #LOCAL_SHARED_LIBRARIES += librt
-endif
-
-LOCAL_MODULE:= dumpsys
-
-include $(BUILD_EXECUTABLE)
diff --git a/cmds/dumpsys/dumpsys.cpp b/cmds/dumpsys/dumpsys.cpp
deleted file mode 100644
index 7dad6b625b6a..000000000000
--- a/cmds/dumpsys/dumpsys.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Command that dumps interesting system state to the log.
- *
- */
-
-#define LOG_TAG "dumpsys"
-
-#include <utils/Log.h>
-#include <binder/Parcel.h>
-#include <binder/ProcessState.h>
-#include <binder/IServiceManager.h>
-#include <utils/TextOutput.h>
-#include <utils/Vector.h>
-
-#include <getopt.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/time.h>
-
-using namespace android;
-
-static int sort_func(const String16* lhs, const String16* rhs)
-{
- return lhs->compare(*rhs);
-}
-
-int main(int argc, char* const argv[])
-{
- sp<IServiceManager> sm = defaultServiceManager();
- fflush(stdout);
- if (sm == NULL) {
- ALOGE("Unable to get default service manager!");
- aerr << "dumpsys: Unable to get default service manager!" << endl;
- return 20;
- }
-
- Vector<String16> services;
- Vector<String16> args;
- if (argc == 1) {
- services = sm->listServices();
- services.sort(sort_func);
- args.add(String16("-a"));
- } else {
- services.add(String16(argv[1]));
- for (int i=2; i<argc; i++) {
- args.add(String16(argv[i]));
- }
- }
-
- const size_t N = services.size();
-
- if (N > 1) {
- // first print a list of the current services
- aout << "Currently running services:" << endl;
-
- for (size_t i=0; i<N; i++) {
- sp<IBinder> service = sm->checkService(services[i]);
- if (service != NULL) {
- aout << " " << services[i] << endl;
- }
- }
- }
-
- for (size_t i=0; i<N; i++) {
- sp<IBinder> service = sm->checkService(services[i]);
- if (service != NULL) {
- if (N > 1) {
- aout << "------------------------------------------------------------"
- "-------------------" << endl;
- aout << "DUMP OF SERVICE " << services[i] << ":" << endl;
- }
- int err = service->dump(STDOUT_FILENO, args);
- if (err != 0) {
- aerr << "Error dumping service info: (" << strerror(err)
- << ") " << services[i] << endl;
- }
- } else {
- aerr << "Can't find service: " << services[i] << endl;
- }
- }
-
- return 0;
-}
diff --git a/cmds/input/src/com/android/commands/input/Input.java b/cmds/input/src/com/android/commands/input/Input.java
index df1d0bf98a62..c4c3b8a9bcac 100755
--- a/cmds/input/src/com/android/commands/input/Input.java
+++ b/cmds/input/src/com/android/commands/input/Input.java
@@ -23,6 +23,7 @@ import android.util.Log;
import android.view.IWindowManager;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
+import android.view.MotionEvent;
/**
* Command that sends key events to the device, either by their keycode, or by
@@ -30,6 +31,9 @@ import android.view.KeyEvent;
*/
public class Input {
+ private static final String TAG = "Input";
+
+ private IWindowManager mWindowManager;
/**
* Command-line entry point.
@@ -40,6 +44,13 @@ public class Input {
(new Input()).run(args);
}
+ private IWindowManager getWindowManager() {
+ if (mWindowManager == null) {
+ mWindowManager = (IWindowManager.Stub.asInterface(ServiceManager.getService("window")));
+ }
+ return mWindowManager;
+ }
+
private void run(String[] args) {
if (args.length < 1) {
showUsage();
@@ -48,19 +59,37 @@ public class Input {
String command = args[0];
- if (command.equals("text")) {
- sendText(args[1]);
- } else if (command.equals("keyevent")) {
- sendKeyEvent(args[1]);
- } else if (command.equals("motionevent")) {
- System.err.println("Error: motionevent not yet supported.");
- return;
- }
- else {
- System.err.println("Error: Unknown command: " + command);
- showUsage();
- return;
+ try {
+ if (command.equals("text")) {
+ if (args.length == 2) {
+ sendText(args[1]);
+ return;
+ }
+ } else if (command.equals("keyevent")) {
+ if (args.length == 2) {
+ sendKeyEvent(Integer.parseInt(args[1]));
+ return;
+ }
+ } else if (command.equals("tap")) {
+ if (args.length == 3) {
+ sendTap(Float.parseFloat(args[1]), Float.parseFloat(args[2]));
+ return;
+ }
+ } else if (command.equals("swipe")) {
+ if (args.length == 5) {
+ sendSwipe(Float.parseFloat(args[1]), Float.parseFloat(args[2]),
+ Float.parseFloat(args[3]), Float.parseFloat(args[4]));
+ return;
+ }
+ } else {
+ System.err.println("Error: Unknown command: " + command);
+ showUsage();
+ return;
+ }
+ } catch (NumberFormatException ex) {
}
+ System.err.println("Error: Invalid arguments for command: " + command);
+ showUsage();
}
/**
@@ -69,7 +98,6 @@ public class Input {
*
* @param text is a string of characters you want to input to the device.
*/
-
private void sendText(String text) {
StringBuffer buff = new StringBuffer(text);
@@ -90,55 +118,66 @@ public class Input {
char[] chars = buff.toString().toCharArray();
- KeyCharacterMap mKeyCharacterMap = KeyCharacterMap.
- load(KeyCharacterMap.VIRTUAL_KEYBOARD);
-
- KeyEvent[] events = mKeyCharacterMap.getEvents(chars);
-
+ KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
+ KeyEvent[] events = kcm.getEvents(chars);
for(int i = 0; i < events.length; i++) {
- KeyEvent event = events[i];
- Log.i("SendKeyEvent", Integer.toString(event.getKeyCode()));
- try {
- (IWindowManager.Stub
- .asInterface(ServiceManager.getService("window")))
- .injectKeyEvent(event, true);
- } catch (RemoteException e) {
- Log.i("Input", "DeadOjbectException");
- }
+ injectKeyEvent(events[i]);
}
}
- /**
- * Send a single key event.
- *
- * @param event is a string representing the keycode of the key event you
- * want to execute.
- */
- private void sendKeyEvent(String event) {
- int eventCode = Integer.parseInt(event);
+ private void sendKeyEvent(int keyCode) {
long now = SystemClock.uptimeMillis();
- Log.i("SendKeyEvent", event);
+ injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 0));
+ injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP, keyCode, 0));
+ }
+
+ private void sendTap(float x, float y) {
+ long now = SystemClock.uptimeMillis();
+ injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, x, y, 0));
+ injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_UP, x, y, 0));
+ }
+
+ private void sendSwipe(float x1, float y1, float x2, float y2) {
+ final int NUM_STEPS = 11;
+ long now = SystemClock.uptimeMillis();
+ injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, x1, y1, 0));
+ for (int i = 1; i < NUM_STEPS; i++) {
+ float alpha = (float)i / NUM_STEPS;
+ injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_MOVE,
+ lerp(x1, x2, alpha), lerp(y1, y2, alpha), 0));
+ }
+ injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_UP, x2, y2, 0));
+ }
+
+ private void injectKeyEvent(KeyEvent event) {
+ try {
+ Log.i(TAG, "InjectKeyEvent: " + event);
+ getWindowManager().injectKeyEvent(event, true);
+ } catch (RemoteException ex) {
+ Log.i(TAG, "RemoteException", ex);
+ }
+ }
+
+ private void injectPointerEvent(MotionEvent event) {
try {
- KeyEvent down = new KeyEvent(now, now, KeyEvent.ACTION_DOWN, eventCode, 0);
- KeyEvent up = new KeyEvent(now, now, KeyEvent.ACTION_UP, eventCode, 0);
- (IWindowManager.Stub
- .asInterface(ServiceManager.getService("window")))
- .injectKeyEvent(down, true);
- (IWindowManager.Stub
- .asInterface(ServiceManager.getService("window")))
- .injectKeyEvent(up, true);
- } catch (RemoteException e) {
- Log.i("Input", "DeadOjbectException");
+ Log.i("Input", "InjectPointerEvent: " + event);
+ getWindowManager().injectPointerEvent(event, true);
+ } catch (RemoteException ex) {
+ Log.i(TAG, "RemoteException", ex);
+ } finally {
+ event.recycle();
}
}
- private void sendMotionEvent(long downTime, int action, float x, float y,
- float pressure, float size) {
+ private static final float lerp(float a, float b, float alpha) {
+ return (b - a) * alpha + a;
}
private void showUsage() {
System.err.println("usage: input [text|keyevent]");
System.err.println(" input text <string>");
- System.err.println(" input keyevent <event_code>");
+ System.err.println(" input keyevent <key code>");
+ System.err.println(" input tap <x> <y>");
+ System.err.println(" input swipe <x1> <y1> <x2> <y2>");
}
}
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index dd92bbe499bc..203d180a6439 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -148,6 +148,48 @@ int delete_persona(uid_t persona)
return delete_dir_contents(pkgdir, 1, NULL);
}
+int clone_persona_data(uid_t src_persona, uid_t target_persona, int copy)
+{
+ char src_data_dir[PKG_PATH_MAX];
+ char pkg_path[PKG_PATH_MAX];
+ DIR *d;
+ struct dirent *de;
+ struct stat s;
+ uid_t uid;
+
+ if (create_persona_path(src_data_dir, src_persona)) {
+ return -1;
+ }
+
+ d = opendir(src_data_dir);
+ if (d != NULL) {
+ while ((de = readdir(d))) {
+ const char *name = de->d_name;
+
+ if (de->d_type == DT_DIR) {
+ int subfd;
+ /* always skip "." and ".." */
+ if (name[0] == '.') {
+ if (name[1] == 0) continue;
+ if ((name[1] == '.') && (name[2] == 0)) continue;
+ }
+ /* Create the full path to the package's data dir */
+ create_pkg_path(pkg_path, name, PKG_DIR_POSTFIX, src_persona);
+ /* Get the file stat */
+ if (stat(pkg_path, &s) < 0) continue;
+ /* Get the uid of the package */
+ ALOGI("Adding datadir for uid = %d\n", s.st_uid);
+ uid = (uid_t) s.st_uid % PER_USER_RANGE;
+ /* Create the directory for the target */
+ make_user_data(name, uid + target_persona * PER_USER_RANGE,
+ target_persona);
+ }
+ }
+ closedir(d);
+ }
+ return 0;
+}
+
int delete_cache(const char *pkgname)
{
char cachedir[PKG_PATH_MAX];
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index 569b491be012..c2c749ace793 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -107,6 +107,11 @@ static int do_rm_user(char **arg, char reply[REPLY_MAX])
return delete_persona(atoi(arg[0])); /* userid */
}
+static int do_clone_user_data(char **arg, char reply[REPLY_MAX])
+{
+ return clone_persona_data(atoi(arg[0]), atoi(arg[1]), atoi(arg[2]));
+}
+
static int do_movefiles(char **arg, char reply[REPLY_MAX])
{
return movefiles();
@@ -146,6 +151,7 @@ struct cmdinfo cmds[] = {
{ "unlinklib", 1, do_unlinklib },
{ "mkuserdata", 3, do_mk_user_data },
{ "rmuser", 1, do_rm_user },
+ { "cloneuserdata", 3, do_clone_user_data },
};
static int readx(int s, void *_buf, int count)
@@ -326,12 +332,15 @@ int initialize_directories() {
ret = 0;
// Make the /data/user directory if necessary
if (access(user_data_dir, R_OK) < 0) {
- if (mkdir(user_data_dir, 0755) < 0) {
+ if (mkdir(user_data_dir, 0711) < 0) {
return -1;
}
if (chown(user_data_dir, AID_SYSTEM, AID_SYSTEM) < 0) {
return -1;
}
+ if (chmod(user_data_dir, 0711) < 0) {
+ return -1;
+ }
}
// Make the /data/user/0 symlink to /data/data if necessary
if (access(primary_data_dir, R_OK) < 0) {
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index 173cabfb77a7..78342bb6ac09 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -72,6 +72,9 @@
#define PKG_NAME_MAX 128 /* largest allowed package name */
#define PKG_PATH_MAX 256 /* max size of any path we use */
+#define PER_USER_RANGE ((uid_t)100000) /* range of uids per user
+ uid = persona * PER_USER_RANGE + appid */
+
/* data structures */
typedef struct {
@@ -143,6 +146,7 @@ int renamepkg(const char *oldpkgname, const char *newpkgname);
int delete_user_data(const char *pkgname, uid_t persona);
int make_user_data(const char *pkgname, uid_t uid, uid_t persona);
int delete_persona(uid_t persona);
+int clone_persona_data(uid_t src_persona, uid_t target_persona, int copy);
int delete_cache(const char *pkgname);
int move_dex(const char *src, const char *dst);
int rm_dex(const char *path);
diff --git a/cmds/keystore/Android.mk b/cmds/keystore/Android.mk
deleted file mode 100644
index 5a9b979c6406..000000000000
--- a/cmds/keystore/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := keystore.cpp
-LOCAL_C_INCLUDES := external/openssl/include
-LOCAL_SHARED_LIBRARIES := libcutils libcrypto
-LOCAL_MODULE:= keystore
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := keystore_cli.cpp
-LOCAL_C_INCLUDES := external/openssl/include
-LOCAL_SHARED_LIBRARIES := libcutils libcrypto
-LOCAL_MODULE:= keystore_cli
-LOCAL_MODULE_TAGS := debug
-include $(BUILD_EXECUTABLE)
diff --git a/cmds/keystore/keystore.cpp b/cmds/keystore/keystore.cpp
deleted file mode 100644
index 05f77e5326d9..000000000000
--- a/cmds/keystore/keystore.cpp
+++ /dev/null
@@ -1,810 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <arpa/inet.h>
-
-#include <openssl/aes.h>
-#include <openssl/evp.h>
-#include <openssl/md5.h>
-
-#define LOG_TAG "keystore"
-#include <cutils/log.h>
-#include <cutils/sockets.h>
-#include <private/android_filesystem_config.h>
-
-#include "keystore.h"
-
-/* KeyStore is a secured storage for key-value pairs. In this implementation,
- * each file stores one key-value pair. Keys are encoded in file names, and
- * values are encrypted with checksums. The encryption key is protected by a
- * user-defined password. To keep things simple, buffers are always larger than
- * the maximum space we needed, so boundary checks on buffers are omitted. */
-
-#define KEY_SIZE ((NAME_MAX - 15) / 2)
-#define VALUE_SIZE 32768
-#define PASSWORD_SIZE VALUE_SIZE
-
-struct Value {
- int length;
- uint8_t value[VALUE_SIZE];
-};
-
-/* Here is the encoding of keys. This is necessary in order to allow arbitrary
- * characters in keys. Characters in [0-~] are not encoded. Others are encoded
- * into two bytes. The first byte is one of [+-.] which represents the first
- * two bits of the character. The second byte encodes the rest of the bits into
- * [0-o]. Therefore in the worst case the length of a key gets doubled. Note
- * that Base64 cannot be used here due to the need of prefix match on keys. */
-
-static int encode_key(char* out, uid_t uid, const Value* key) {
- int n = snprintf(out, NAME_MAX, "%u_", uid);
- out += n;
- const uint8_t* in = key->value;
- int length = key->length;
- for (int i = length; i > 0; --i, ++in, ++out) {
- if (*in >= '0' && *in <= '~') {
- *out = *in;
- } else {
- *out = '+' + (*in >> 6);
- *++out = '0' + (*in & 0x3F);
- ++length;
- }
- }
- *out = '\0';
- return n + length;
-}
-
-static int decode_key(uint8_t* out, char* in, int length) {
- for (int i = 0; i < length; ++i, ++in, ++out) {
- if (*in >= '0' && *in <= '~') {
- *out = *in;
- } else {
- *out = (*in - '+') << 6;
- *out |= (*++in - '0') & 0x3F;
- --length;
- }
- }
- *out = '\0';
- return length;
-}
-
-static size_t readFully(int fd, uint8_t* data, size_t size) {
- size_t remaining = size;
- while (remaining > 0) {
- ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, size));
- if (n == -1 || n == 0) {
- return size-remaining;
- }
- data += n;
- remaining -= n;
- }
- return size;
-}
-
-static size_t writeFully(int fd, uint8_t* data, size_t size) {
- size_t remaining = size;
- while (remaining > 0) {
- ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, size));
- if (n == -1 || n == 0) {
- return size-remaining;
- }
- data += n;
- remaining -= n;
- }
- return size;
-}
-
-class Entropy {
-public:
- Entropy() : mRandom(-1) {}
- ~Entropy() {
- if (mRandom != -1) {
- close(mRandom);
- }
- }
-
- bool open() {
- const char* randomDevice = "/dev/urandom";
- mRandom = ::open(randomDevice, O_RDONLY);
- if (mRandom == -1) {
- ALOGE("open: %s: %s", randomDevice, strerror(errno));
- return false;
- }
- return true;
- }
-
- bool generate_random_data(uint8_t* data, size_t size) {
- return (readFully(mRandom, data, size) == size);
- }
-
-private:
- int mRandom;
-};
-
-/* Here is the file format. There are two parts in blob.value, the secret and
- * the description. The secret is stored in ciphertext, and its original size
- * can be found in blob.length. The description is stored after the secret in
- * plaintext, and its size is specified in blob.info. The total size of the two
- * parts must be no more than VALUE_SIZE bytes. The first three bytes of the
- * file are reserved for future use and are always set to zero. Fields other
- * than blob.info, blob.length, and blob.value are modified by encryptBlob()
- * and decryptBlob(). Thus they should not be accessed from outside. */
-
-struct __attribute__((packed)) blob {
- uint8_t reserved[3];
- uint8_t info;
- uint8_t vector[AES_BLOCK_SIZE];
- uint8_t encrypted[0];
- uint8_t digest[MD5_DIGEST_LENGTH];
- uint8_t digested[0];
- int32_t length; // in network byte order when encrypted
- uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE];
-};
-
-class Blob {
-public:
- Blob(uint8_t* value, int32_t valueLength, uint8_t* info, uint8_t infoLength) {
- mBlob.length = valueLength;
- memcpy(mBlob.value, value, valueLength);
-
- mBlob.info = infoLength;
- memcpy(mBlob.value + valueLength, info, infoLength);
- }
-
- Blob(blob b) {
- mBlob = b;
- }
-
- Blob() {}
-
- uint8_t* getValue() {
- return mBlob.value;
- }
-
- int32_t getLength() {
- return mBlob.length;
- }
-
- uint8_t getInfo() {
- return mBlob.info;
- }
-
- ResponseCode encryptBlob(const char* filename, AES_KEY *aes_key, Entropy* entropy) {
- if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) {
- return SYSTEM_ERROR;
- }
-
- // data includes the value and the value's length
- size_t dataLength = mBlob.length + sizeof(mBlob.length);
- // pad data to the AES_BLOCK_SIZE
- size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1)
- / AES_BLOCK_SIZE * AES_BLOCK_SIZE);
- // encrypted data includes the digest value
- size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH;
- // move info after space for padding
- memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info);
- // zero padding area
- memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength);
-
- mBlob.length = htonl(mBlob.length);
- MD5(mBlob.digested, digestedLength, mBlob.digest);
-
- uint8_t vector[AES_BLOCK_SIZE];
- memcpy(vector, mBlob.vector, AES_BLOCK_SIZE);
- AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength,
- aes_key, vector, AES_ENCRYPT);
-
- memset(mBlob.reserved, 0, sizeof(mBlob.reserved));
- size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
- size_t fileLength = encryptedLength + headerLength + mBlob.info;
-
- const char* tmpFileName = ".tmp";
- int out = open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
- if (out == -1) {
- return SYSTEM_ERROR;
- }
- size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength);
- if (close(out) != 0) {
- return SYSTEM_ERROR;
- }
- if (writtenBytes != fileLength) {
- unlink(tmpFileName);
- return SYSTEM_ERROR;
- }
- return (rename(tmpFileName, filename) == 0) ? NO_ERROR : SYSTEM_ERROR;
- }
-
- ResponseCode decryptBlob(const char* filename, AES_KEY *aes_key) {
- int in = open(filename, O_RDONLY);
- if (in == -1) {
- return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR;
- }
- // fileLength may be less than sizeof(mBlob) since the in
- // memory version has extra padding to tolerate rounding up to
- // the AES_BLOCK_SIZE
- size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob));
- if (close(in) != 0) {
- return SYSTEM_ERROR;
- }
- size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
- if (fileLength < headerLength) {
- return VALUE_CORRUPTED;
- }
-
- ssize_t encryptedLength = fileLength - (headerLength + mBlob.info);
- if (encryptedLength < 0 || encryptedLength % AES_BLOCK_SIZE != 0) {
- return VALUE_CORRUPTED;
- }
- AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key,
- mBlob.vector, AES_DECRYPT);
- size_t digestedLength = encryptedLength - MD5_DIGEST_LENGTH;
- uint8_t computedDigest[MD5_DIGEST_LENGTH];
- MD5(mBlob.digested, digestedLength, computedDigest);
- if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) {
- return VALUE_CORRUPTED;
- }
-
- ssize_t maxValueLength = digestedLength - sizeof(mBlob.length);
- mBlob.length = ntohl(mBlob.length);
- if (mBlob.length < 0 || mBlob.length > maxValueLength) {
- return VALUE_CORRUPTED;
- }
- if (mBlob.info != 0) {
- // move info from after padding to after data
- memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info);
- }
- return NO_ERROR;
- }
-
-private:
- struct blob mBlob;
-};
-
-class KeyStore {
-public:
- KeyStore(Entropy* entropy) : mEntropy(entropy), mRetry(MAX_RETRY) {
- if (access(MASTER_KEY_FILE, R_OK) == 0) {
- setState(STATE_LOCKED);
- } else {
- setState(STATE_UNINITIALIZED);
- }
- }
-
- State getState() {
- return mState;
- }
-
- int8_t getRetry() {
- return mRetry;
- }
-
- ResponseCode initialize(Value* pw) {
- if (!generateMasterKey()) {
- return SYSTEM_ERROR;
- }
- ResponseCode response = writeMasterKey(pw);
- if (response != NO_ERROR) {
- return response;
- }
- setupMasterKeys();
- return NO_ERROR;
- }
-
- ResponseCode writeMasterKey(Value* pw) {
- uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
- generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt);
- AES_KEY passwordAesKey;
- AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
- Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt));
- return masterKeyBlob.encryptBlob(MASTER_KEY_FILE, &passwordAesKey, mEntropy);
- }
-
- ResponseCode readMasterKey(Value* pw) {
- int in = open(MASTER_KEY_FILE, O_RDONLY);
- if (in == -1) {
- return SYSTEM_ERROR;
- }
-
- // we read the raw blob to just to get the salt to generate
- // the AES key, then we create the Blob to use with decryptBlob
- blob rawBlob;
- size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob));
- if (close(in) != 0) {
- return SYSTEM_ERROR;
- }
- // find salt at EOF if present, otherwise we have an old file
- uint8_t* salt;
- if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) {
- salt = (uint8_t*) &rawBlob + length - SALT_SIZE;
- } else {
- salt = NULL;
- }
- uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
- generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt);
- AES_KEY passwordAesKey;
- AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
- Blob masterKeyBlob(rawBlob);
- ResponseCode response = masterKeyBlob.decryptBlob(MASTER_KEY_FILE, &passwordAesKey);
- if (response == SYSTEM_ERROR) {
- return SYSTEM_ERROR;
- }
- if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) {
- // if salt was missing, generate one and write a new master key file with the salt.
- if (salt == NULL) {
- if (!generateSalt()) {
- return SYSTEM_ERROR;
- }
- response = writeMasterKey(pw);
- }
- if (response == NO_ERROR) {
- memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES);
- setupMasterKeys();
- }
- return response;
- }
- if (mRetry <= 0) {
- reset();
- return UNINITIALIZED;
- }
- --mRetry;
- switch (mRetry) {
- case 0: return WRONG_PASSWORD_0;
- case 1: return WRONG_PASSWORD_1;
- case 2: return WRONG_PASSWORD_2;
- case 3: return WRONG_PASSWORD_3;
- default: return WRONG_PASSWORD_3;
- }
- }
-
- bool reset() {
- clearMasterKeys();
- setState(STATE_UNINITIALIZED);
-
- DIR* dir = opendir(".");
- struct dirent* file;
-
- if (!dir) {
- return false;
- }
- while ((file = readdir(dir)) != NULL) {
- unlink(file->d_name);
- }
- closedir(dir);
- return true;
- }
-
- bool isEmpty() {
- DIR* dir = opendir(".");
- struct dirent* file;
- if (!dir) {
- return true;
- }
- bool result = true;
- while ((file = readdir(dir)) != NULL) {
- if (isKeyFile(file->d_name)) {
- result = false;
- break;
- }
- }
- closedir(dir);
- return result;
- }
-
- void lock() {
- clearMasterKeys();
- setState(STATE_LOCKED);
- }
-
- ResponseCode get(const char* filename, Blob* keyBlob) {
- return keyBlob->decryptBlob(filename, &mMasterKeyDecryption);
- }
-
- ResponseCode put(const char* filename, Blob* keyBlob) {
- return keyBlob->encryptBlob(filename, &mMasterKeyEncryption, mEntropy);
- }
-
-private:
- static const char* MASTER_KEY_FILE;
- static const int MASTER_KEY_SIZE_BYTES = 16;
- static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8;
-
- static const int MAX_RETRY = 4;
- static const size_t SALT_SIZE = 16;
-
- Entropy* mEntropy;
-
- State mState;
- int8_t mRetry;
-
- uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES];
- uint8_t mSalt[SALT_SIZE];
-
- AES_KEY mMasterKeyEncryption;
- AES_KEY mMasterKeyDecryption;
-
- void setState(State state) {
- mState = state;
- if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) {
- mRetry = MAX_RETRY;
- }
- }
-
- bool generateSalt() {
- return mEntropy->generate_random_data(mSalt, sizeof(mSalt));
- }
-
- bool generateMasterKey() {
- if (!mEntropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) {
- return false;
- }
- if (!generateSalt()) {
- return false;
- }
- return true;
- }
-
- void setupMasterKeys() {
- AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption);
- AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption);
- setState(STATE_NO_ERROR);
- }
-
- void clearMasterKeys() {
- memset(mMasterKey, 0, sizeof(mMasterKey));
- memset(mSalt, 0, sizeof(mSalt));
- memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption));
- memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption));
- }
-
- static void generateKeyFromPassword(uint8_t* key, ssize_t keySize, Value* pw, uint8_t* salt) {
- size_t saltSize;
- if (salt != NULL) {
- saltSize = SALT_SIZE;
- } else {
- // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found
- salt = (uint8_t*) "keystore";
- // sizeof = 9, not strlen = 8
- saltSize = sizeof("keystore");
- }
- PKCS5_PBKDF2_HMAC_SHA1((char*) pw->value, pw->length, salt, saltSize, 8192, keySize, key);
- }
-
- static bool isKeyFile(const char* filename) {
- return ((strcmp(filename, MASTER_KEY_FILE) != 0)
- && (strcmp(filename, ".") != 0)
- && (strcmp(filename, "..") != 0));
- }
-};
-
-const char* KeyStore::MASTER_KEY_FILE = ".masterkey";
-
-/* Here is the protocol used in both requests and responses:
- * code [length_1 message_1 ... length_n message_n] end-of-file
- * where code is one byte long and lengths are unsigned 16-bit integers in
- * network order. Thus the maximum length of a message is 65535 bytes. */
-
-static int recv_code(int sock, int8_t* code) {
- return recv(sock, code, 1, 0) == 1;
-}
-
-static int recv_message(int sock, uint8_t* message, int length) {
- uint8_t bytes[2];
- if (recv(sock, &bytes[0], 1, 0) != 1 ||
- recv(sock, &bytes[1], 1, 0) != 1) {
- return -1;
- } else {
- int offset = bytes[0] << 8 | bytes[1];
- if (length < offset) {
- return -1;
- }
- length = offset;
- offset = 0;
- while (offset < length) {
- int n = recv(sock, &message[offset], length - offset, 0);
- if (n <= 0) {
- return -1;
- }
- offset += n;
- }
- }
- return length;
-}
-
-static int recv_end_of_file(int sock) {
- uint8_t byte;
- return recv(sock, &byte, 1, 0) == 0;
-}
-
-static void send_code(int sock, int8_t code) {
- send(sock, &code, 1, 0);
-}
-
-static void send_message(int sock, uint8_t* message, int length) {
- uint16_t bytes = htons(length);
- send(sock, &bytes, 2, 0);
- send(sock, message, length, 0);
-}
-
-/* Here are the actions. Each of them is a function without arguments. All
- * information is defined in global variables, which are set properly before
- * performing an action. The number of parameters required by each action is
- * fixed and defined in a table. If the return value of an action is positive,
- * it will be treated as a response code and transmitted to the client. Note
- * that the lengths of parameters are checked when they are received, so
- * boundary checks on parameters are omitted. */
-
-static const ResponseCode NO_ERROR_RESPONSE_CODE_SENT = (ResponseCode) 0;
-
-static ResponseCode test(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*) {
- return (ResponseCode) keyStore->getState();
-}
-
-static ResponseCode get(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*) {
- char filename[NAME_MAX];
- encode_key(filename, uid, keyName);
- Blob keyBlob;
- ResponseCode responseCode = keyStore->get(filename, &keyBlob);
- if (responseCode != NO_ERROR) {
- return responseCode;
- }
- send_code(sock, NO_ERROR);
- send_message(sock, keyBlob.getValue(), keyBlob.getLength());
- return NO_ERROR_RESPONSE_CODE_SENT;
-}
-
-static ResponseCode insert(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* val) {
- char filename[NAME_MAX];
- encode_key(filename, uid, keyName);
- Blob keyBlob(val->value, val->length, 0, NULL);
- return keyStore->put(filename, &keyBlob);
-}
-
-static ResponseCode del(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*) {
- char filename[NAME_MAX];
- encode_key(filename, uid, keyName);
- return (unlink(filename) && errno != ENOENT) ? SYSTEM_ERROR : NO_ERROR;
-}
-
-static ResponseCode exist(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*) {
- char filename[NAME_MAX];
- encode_key(filename, uid, keyName);
- if (access(filename, R_OK) == -1) {
- return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND;
- }
- return NO_ERROR;
-}
-
-static ResponseCode saw(KeyStore* keyStore, int sock, uid_t uid, Value* keyPrefix, Value*) {
- DIR* dir = opendir(".");
- if (!dir) {
- return SYSTEM_ERROR;
- }
- char filename[NAME_MAX];
- int n = encode_key(filename, uid, keyPrefix);
- send_code(sock, NO_ERROR);
-
- struct dirent* file;
- while ((file = readdir(dir)) != NULL) {
- if (!strncmp(filename, file->d_name, n)) {
- char* p = &file->d_name[n];
- keyPrefix->length = decode_key(keyPrefix->value, p, strlen(p));
- send_message(sock, keyPrefix->value, keyPrefix->length);
- }
- }
- closedir(dir);
- return NO_ERROR_RESPONSE_CODE_SENT;
-}
-
-static ResponseCode reset(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*) {
- return keyStore->reset() ? NO_ERROR : SYSTEM_ERROR;
-}
-
-/* Here is the history. To improve the security, the parameters to generate the
- * master key has been changed. To make a seamless transition, we update the
- * file using the same password when the user unlock it for the first time. If
- * any thing goes wrong during the transition, the new file will not overwrite
- * the old one. This avoids permanent damages of the existing data. */
-
-static ResponseCode password(KeyStore* keyStore, int sock, uid_t uid, Value* pw, Value*) {
- switch (keyStore->getState()) {
- case STATE_UNINITIALIZED: {
- // generate master key, encrypt with password, write to file, initialize mMasterKey*.
- return keyStore->initialize(pw);
- }
- case STATE_NO_ERROR: {
- // rewrite master key with new password.
- return keyStore->writeMasterKey(pw);
- }
- case STATE_LOCKED: {
- // read master key, decrypt with password, initialize mMasterKey*.
- return keyStore->readMasterKey(pw);
- }
- }
- return SYSTEM_ERROR;
-}
-
-static ResponseCode lock(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*) {
- keyStore->lock();
- return NO_ERROR;
-}
-
-static ResponseCode unlock(KeyStore* keyStore, int sock, uid_t uid, Value* pw, Value* unused) {
- return password(keyStore, sock, uid, pw, unused);
-}
-
-static ResponseCode zero(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*) {
- return keyStore->isEmpty() ? KEY_NOT_FOUND : NO_ERROR;
-}
-
-/* Here are the permissions, actions, users, and the main function. */
-
-enum perm {
- TEST = 1,
- GET = 2,
- INSERT = 4,
- DELETE = 8,
- EXIST = 16,
- SAW = 32,
- RESET = 64,
- PASSWORD = 128,
- LOCK = 256,
- UNLOCK = 512,
- ZERO = 1024,
-};
-
-static const int MAX_PARAM = 2;
-
-static const State STATE_ANY = (State) 0;
-
-static struct action {
- ResponseCode (*run)(KeyStore* keyStore, int sock, uid_t uid, Value* param1, Value* param2);
- int8_t code;
- State state;
- uint32_t perm;
- int lengths[MAX_PARAM];
-} actions[] = {
- {test, 't', STATE_ANY, TEST, {0, 0}},
- {get, 'g', STATE_NO_ERROR, GET, {KEY_SIZE, 0}},
- {insert, 'i', STATE_NO_ERROR, INSERT, {KEY_SIZE, VALUE_SIZE}},
- {del, 'd', STATE_ANY, DELETE, {KEY_SIZE, 0}},
- {exist, 'e', STATE_ANY, EXIST, {KEY_SIZE, 0}},
- {saw, 's', STATE_ANY, SAW, {KEY_SIZE, 0}},
- {reset, 'r', STATE_ANY, RESET, {0, 0}},
- {password, 'p', STATE_ANY, PASSWORD, {PASSWORD_SIZE, 0}},
- {lock, 'l', STATE_NO_ERROR, LOCK, {0, 0}},
- {unlock, 'u', STATE_LOCKED, UNLOCK, {PASSWORD_SIZE, 0}},
- {zero, 'z', STATE_ANY, ZERO, {0, 0}},
- {NULL, 0 , STATE_ANY, 0, {0, 0}},
-};
-
-static struct user {
- uid_t uid;
- uid_t euid;
- uint32_t perms;
-} users[] = {
- {AID_SYSTEM, ~0, ~0},
- {AID_VPN, AID_SYSTEM, GET},
- {AID_WIFI, AID_SYSTEM, GET},
- {AID_ROOT, AID_SYSTEM, GET},
- {~0, ~0, TEST | GET | INSERT | DELETE | EXIST | SAW},
-};
-
-static ResponseCode process(KeyStore* keyStore, int sock, uid_t uid, int8_t code) {
- struct user* user = users;
- struct action* action = actions;
- int i;
-
- while (~user->uid && user->uid != uid) {
- ++user;
- }
- while (action->code && action->code != code) {
- ++action;
- }
- if (!action->code) {
- return UNDEFINED_ACTION;
- }
- if (!(action->perm & user->perms)) {
- return PERMISSION_DENIED;
- }
- if (action->state != STATE_ANY && action->state != keyStore->getState()) {
- return (ResponseCode) keyStore->getState();
- }
- if (~user->euid) {
- uid = user->euid;
- }
- Value params[MAX_PARAM];
- for (i = 0; i < MAX_PARAM && action->lengths[i] != 0; ++i) {
- params[i].length = recv_message(sock, params[i].value, action->lengths[i]);
- if (params[i].length < 0) {
- return PROTOCOL_ERROR;
- }
- }
- if (!recv_end_of_file(sock)) {
- return PROTOCOL_ERROR;
- }
- return action->run(keyStore, sock, uid, &params[0], &params[1]);
-}
-
-int main(int argc, char* argv[]) {
- int controlSocket = android_get_control_socket("keystore");
- if (argc < 2) {
- ALOGE("A directory must be specified!");
- return 1;
- }
- if (chdir(argv[1]) == -1) {
- ALOGE("chdir: %s: %s", argv[1], strerror(errno));
- return 1;
- }
-
- Entropy entropy;
- if (!entropy.open()) {
- return 1;
- }
- if (listen(controlSocket, 3) == -1) {
- ALOGE("listen: %s", strerror(errno));
- return 1;
- }
-
- signal(SIGPIPE, SIG_IGN);
-
- KeyStore keyStore(&entropy);
- int sock;
- while ((sock = accept(controlSocket, NULL, 0)) != -1) {
- struct timeval tv;
- tv.tv_sec = 3;
- setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
- setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
-
- struct ucred cred;
- socklen_t size = sizeof(cred);
- int credResult = getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cred, &size);
- if (credResult != 0) {
- ALOGW("getsockopt: %s", strerror(errno));
- } else {
- int8_t request;
- if (recv_code(sock, &request)) {
- State old_state = keyStore.getState();
- ResponseCode response = process(&keyStore, sock, cred.uid, request);
- if (response == NO_ERROR_RESPONSE_CODE_SENT) {
- response = NO_ERROR;
- } else {
- send_code(sock, response);
- }
- ALOGI("uid: %d action: %c -> %d state: %d -> %d retry: %d",
- cred.uid,
- request, response,
- old_state, keyStore.getState(),
- keyStore.getRetry());
- }
- }
- close(sock);
- }
- ALOGE("accept: %s", strerror(errno));
- return 1;
-}
diff --git a/cmds/keystore/keystore.h b/cmds/keystore/keystore.h
deleted file mode 100644
index 5ae3d24acee0..000000000000
--- a/cmds/keystore/keystore.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __KEYSTORE_H__
-#define __KEYSTORE_H__
-
-// note state values overlap with ResponseCode for the purposes of the state() API
-enum State {
- STATE_NO_ERROR = 1,
- STATE_LOCKED = 2,
- STATE_UNINITIALIZED = 3,
-};
-
-enum ResponseCode {
- NO_ERROR = STATE_NO_ERROR, // 1
- LOCKED = STATE_LOCKED, // 2
- UNINITIALIZED = STATE_UNINITIALIZED, // 3
- SYSTEM_ERROR = 4,
- PROTOCOL_ERROR = 5,
- PERMISSION_DENIED = 6,
- KEY_NOT_FOUND = 7,
- VALUE_CORRUPTED = 8,
- UNDEFINED_ACTION = 9,
- WRONG_PASSWORD_0 = 10,
- WRONG_PASSWORD_1 = 11,
- WRONG_PASSWORD_2 = 12,
- WRONG_PASSWORD_3 = 13, // MAX_RETRY = 4
-};
-
-#endif
diff --git a/cmds/keystore/keystore_cli.cpp b/cmds/keystore/keystore_cli.cpp
deleted file mode 100644
index dcd3bcb8fc01..000000000000
--- a/cmds/keystore/keystore_cli.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <cutils/sockets.h>
-
-#include "keystore.h"
-
-static const char* responses[] = {
- NULL,
- /* [NO_ERROR] = */ "No error",
- /* [LOCKED] = */ "Locked",
- /* [UNINITIALIZED] = */ "Uninitialized",
- /* [SYSTEM_ERROR] = */ "System error",
- /* [PROTOCOL_ERROR] = */ "Protocol error",
- /* [PERMISSION_DENIED] = */ "Permission denied",
- /* [KEY_NOT_FOUND] = */ "Key not found",
- /* [VALUE_CORRUPTED] = */ "Value corrupted",
- /* [UNDEFINED_ACTION] = */ "Undefined action",
- /* [WRONG_PASSWORD] = */ "Wrong password (last chance)",
- /* [WRONG_PASSWORD + 1] = */ "Wrong password (2 tries left)",
- /* [WRONG_PASSWORD + 2] = */ "Wrong password (3 tries left)",
- /* [WRONG_PASSWORD + 3] = */ "Wrong password (4 tries left)",
-};
-
-int main(int argc, char* argv[])
-{
- if (argc < 2) {
- printf("Usage: %s action [parameter ...]\n", argv[0]);
- return 0;
- }
-
- int sock = socket_local_client("keystore", ANDROID_SOCKET_NAMESPACE_RESERVED,
- SOCK_STREAM);
- if (sock == -1) {
- puts("Failed to connect");
- return 1;
- }
-
- send(sock, argv[1], 1, 0);
- uint8_t bytes[65536];
- for (int i = 2; i < argc; ++i) {
- uint16_t length = strlen(argv[i]);
- bytes[0] = length >> 8;
- bytes[1] = length;
- send(sock, &bytes, 2, 0);
- send(sock, argv[i], length, 0);
- }
- shutdown(sock, SHUT_WR);
-
- uint8_t code;
- if (recv(sock, &code, 1, 0) != 1) {
- puts("Failed to receive");
- return 1;
- }
- printf("%d %s\n", code , responses[code] ? responses[code] : "Unknown");
- int i;
- while ((i = recv(sock, &bytes[0], 1, 0)) == 1) {
- int length;
- int offset;
- if ((i = recv(sock, &bytes[1], 1, 0)) != 1) {
- puts("Failed to receive");
- return 1;
- }
- length = bytes[0] << 8 | bytes[1];
- for (offset = 0; offset < length; offset += i) {
- i = recv(sock, &bytes[offset], length - offset, 0);
- if (i <= 0) {
- puts("Failed to receive");
- return 1;
- }
- }
- fwrite(bytes, 1, length, stdout);
- puts("");
- }
- return 0;
-}
diff --git a/cmds/keystore/keystore_get.h b/cmds/keystore/keystore_get.h
deleted file mode 100644
index 4b4923e5c736..000000000000
--- a/cmds/keystore/keystore_get.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __KEYSTORE_GET_H__
-#define __KEYSTORE_GET_H__
-
-#include <stdio.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <cutils/sockets.h>
-
-#define KEYSTORE_MESSAGE_SIZE 65535
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* This function is provided for native components to get values from keystore.
- * Users are required to link against libcutils. Keys and values are 8-bit safe.
- * The first two arguments are the key and its length. The third argument
- * specifies the buffer to store the retrieved value, which must be an array of
- * KEYSTORE_MESSAGE_SIZE bytes. This function returns the length of the value or
- * -1 if an error happens. */
-static int keystore_get(const char *key, int length, char *value)
-{
- uint8_t bytes[2] = {length >> 8, length};
- uint8_t code = 'g';
- int sock;
-
- if (length < 0 || length > KEYSTORE_MESSAGE_SIZE) {
- return -1;
- }
- sock = socket_local_client("keystore", ANDROID_SOCKET_NAMESPACE_RESERVED,
- SOCK_STREAM);
- if (sock == -1) {
- return -1;
- }
- if (send(sock, &code, 1, 0) == 1 && send(sock, bytes, 2, 0) == 2 &&
- send(sock, key, length, 0) == length && shutdown(sock, SHUT_WR) == 0 &&
- recv(sock, &code, 1, 0) == 1 && code == /* NO_ERROR */ 1 &&
- recv(sock, &bytes[0], 1, 0) == 1 && recv(sock, &bytes[1], 1, 0) == 1) {
- int offset = 0;
- length = bytes[0] << 8 | bytes[1];
- while (offset < length) {
- int n = recv(sock, &value[offset], length - offset, 0);
- if (n <= 0) {
- length = -1;
- break;
- }
- offset += n;
- }
- } else {
- length = -1;
- }
-
- close(sock);
- return length;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/cmds/keystore/test-keystore b/cmds/keystore/test-keystore
deleted file mode 100755
index 3be51b3e7bfb..000000000000
--- a/cmds/keystore/test-keystore
+++ /dev/null
@@ -1,273 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2011, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -e
-
-prefix=$0
-log_file=$prefix.log
-baseline_file=$prefix.baseline
-
-function cleanup_output() {
- rm -f $log_file
- rm -f $baseline_file
-}
-
-function log() {
- echo "$@"
- append $log_file \# "$@"
- append $baseline_file \# "$@"
-}
-
-function expect() {
- append $baseline_file "$@"
-}
-
-function append() {
- declare -r file=$1
- shift
- echo "$@" >> $file
-}
-
-function run() {
- # strip out carriage returns from adb
- # strip out date/time from ls -l
- "$@" | tr --delete '\r' | sed -E 's/[0-9]{4}-[0-9]{2}-[0-9]{2} +[0-9]{1,2}:[0-9]{2} //' >> $log_file
-}
-
-function keystore() {
- declare -r user=$1
- shift
- run adb shell su $user keystore_cli "$@"
-}
-
-function list_keystore_directory() {
- run adb shell ls -al /data/misc/keystore
-}
-
-function compare() {
- log "comparing $baseline_file and $log_file"
- diff $baseline_file $log_file || (log $tag FAILED && exit 1)
-}
-
-function test_basic() {
-
- #
- # reset
- #
- log "reset keystore as system user"
- keystore system r
- expect "1 No error"
- list_keystore_directory
-
- #
- # basic tests as system/root
- #
- log "root does not have permission to run test"
- keystore root t
- expect "6 Permission denied"
-
- log "but system user does"
- keystore system t
- expect "3 Uninitialized"
- list_keystore_directory
-
- log "password is now bar"
- keystore system p bar
- expect "1 No error"
- list_keystore_directory
- expect "-rw------- keystore keystore 84 .masterkey"
-
- log "no error implies initialized and unlocked"
- keystore system t
- expect "1 No error"
-
- log "saw with no argument"
- keystore system s
- expect "5 Protocol error"
-
- log "saw nothing"
- keystore system s ""
- expect "1 No error"
-
- log "add key baz"
- keystore system i baz quux
- expect "1 No error"
-
- log "1000 is uid of system"
- list_keystore_directory
- expect "-rw------- keystore keystore 84 .masterkey"
- expect "-rw------- keystore keystore 52 1000_baz"
-
- log "saw baz"
- keystore system s ""
- expect "1 No error"
- expect "baz"
-
- log "get baz"
- keystore system g baz
- 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"
-
- #
- # app user tests
- #
-
- # app_0 has uid 10000, as seen below
- log "other uses cannot see the system keys"
- keystore app_0 g baz
- expect "7 Key not found"
-
- log "app user cannot use reset, password, lock, unlock"
- keystore app_0 r
- expect "6 Permission denied"
- keystore app_0 p
- expect "6 Permission denied"
- keystore app_0 l
- expect "6 Permission denied"
- keystore app_0 u
- expect "6 Permission denied"
-
- log "install app_0 key"
- keystore app_0 i 0x deadbeef
- expect 1 No error
- list_keystore_directory
- expect "-rw------- keystore keystore 84 .masterkey"
- expect "-rw------- keystore keystore 52 10000_0x"
- expect "-rw------- keystore keystore 52 1000_baz"
-
- log "get with no argument"
- keystore app_0 g
- expect "5 Protocol error"
-
- keystore app_0 g 0x
- expect "1 No error"
- expect "deadbeef"
-
- keystore app_0 i fred barney
- expect "1 No error"
-
- keystore app_0 s ""
- expect "1 No error"
- expect "0x"
- expect "fred"
-
- log "note that saw returns the suffix of prefix matches"
- keystore app_0 s fr # fred
- expect "1 No error"
- expect "ed" # fred
-
- #
- # lock tests
- #
- log "lock the store as system"
- keystore system l
- expect "1 No error"
- keystore system t
- expect "2 Locked"
-
- log "saw works while locked"
- keystore app_0 s ""
- expect "1 No error"
- expect "0x"
- expect "fred"
-
- log "...but cannot read keys..."
- keystore app_0 g 0x
- expect "2 Locked"
-
- log "...but they can be deleted."
- keystore app_0 e 0x
- expect "1 No error"
- keystore app_0 d 0x
- expect "1 No error"
- keystore app_0 e 0x
- expect "7 Key not found"
-
- #
- # password
- #
- log "wrong password"
- keystore system u foo
- expect "13 Wrong password (4 tries left)"
- log "right password"
- keystore system u bar
- expect "1 No error"
-
- log "make the password foo"
- keystore system p foo
- expect "1 No error"
-
- #
- # final reset
- #
- log "reset wipes everything for all users"
- keystore system r
- expect "1 No error"
- list_keystore_directory
-
- keystore system t
- expect "3 Uninitialized"
-
-}
-
-function test_4599735() {
- # http://b/4599735
- log "start regression test for b/4599735"
- keystore system r
- expect "1 No error"
-
- keystore system p foo
- expect "1 No error"
-
- keystore system i baz quux
- expect "1 No error"
-
- keystore root g baz
- expect "1 No error"
- expect "quux"
-
- keystore system l
- expect "1 No error"
-
- keystore system p foo
- expect "1 No error"
-
- log "after unlock, regression led to result of '8 Value corrupted'"
- keystore root g baz
- expect "1 No error"
- expect "quux"
-
- keystore system r
- expect "1 No error"
- log "end regression test for b/4599735"
-}
-
-function main() {
- cleanup_output
- log $tag START
- test_basic
- test_4599735
- compare
- log $tag PASSED
- cleanup_output
-}
-
-main
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 0ec007cf9daa..4d638d00f025 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -16,8 +16,6 @@
package com.android.commands.pm;
-import com.android.internal.content.PackageHelper;
-
import android.app.ActivityManagerNative;
import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
@@ -33,14 +31,17 @@ import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
+import android.content.pm.UserInfo;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.net.Uri;
-import android.os.Parcel;
+import android.os.Binder;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
+import com.android.internal.content.PackageHelper;
+
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
@@ -125,6 +126,16 @@ public final class Pm {
return;
}
+ if ("grant".equals(op)) {
+ runGrantRevokePermission(true);
+ return;
+ }
+
+ if ("revoke".equals(op)) {
+ runGrantRevokePermission(false);
+ return;
+ }
+
if ("set-install-location".equals(op)) {
runSetInstallLocation();
return;
@@ -135,16 +146,21 @@ public final class Pm {
return;
}
- if ("createUser".equals(op)) {
+ if ("create-user".equals(op)) {
runCreateUser();
return;
}
- if ("removeUser".equals(op)) {
+ if ("remove-user".equals(op)) {
runRemoveUser();
return;
}
+ if ("list-users".equals(op)) {
+ runListUsers();
+ return;
+ }
+
try {
if (args.length == 1) {
if (args[0].equalsIgnoreCase("-l")) {
@@ -199,6 +215,8 @@ public final class Pm {
runListLibraries();
} else if ("instrumentation".equals(type)) {
runListInstrumentation();
+ } else if ("users".equals(type)) {
+ runListUsers();
} else {
System.err.println("Error: unknown list type '" + type + "'");
showUsage();
@@ -212,6 +230,7 @@ public final class Pm {
int getFlags = 0;
boolean listDisabled = false, listEnabled = false;
boolean listSystem = false, listThirdParty = false;
+ boolean listInstaller = false;
try {
String opt;
while ((opt=nextOption()) != null) {
@@ -229,6 +248,8 @@ public final class Pm {
listSystem = true;
} else if (opt.equals("-3")) {
listThirdParty = true;
+ } else if (opt.equals("-i")) {
+ listInstaller = true;
} else if (opt.equals("-u")) {
getFlags |= PackageManager.GET_UNINSTALLED_PACKAGES;
} else {
@@ -265,7 +286,12 @@ public final class Pm {
System.out.print(info.applicationInfo.sourceDir);
System.out.print("=");
}
- System.out.println(info.packageName);
+ System.out.print(info.packageName);
+ if (listInstaller) {
+ System.out.print(" installer=");
+ System.out.print(mPm.getInstallerPackageName(info.packageName));
+ }
+ System.out.println();
}
}
} catch (RemoteException e) {
@@ -582,8 +608,9 @@ public final class Pm {
if (groups && groupName == null && pi.group != null) {
continue;
}
- if (pi.protectionLevel < startProtectionLevel
- || pi.protectionLevel > endProtectionLevel) {
+ final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
+ if (base < startProtectionLevel
+ || base > endProtectionLevel) {
continue;
}
if (summary) {
@@ -613,22 +640,8 @@ public final class Pm {
+ loadText(pi, pi.descriptionRes,
pi.nonLocalizedDescription));
}
- String protLevel = "unknown";
- switch(pi.protectionLevel) {
- case PermissionInfo.PROTECTION_DANGEROUS:
- protLevel = "dangerous";
- break;
- case PermissionInfo.PROTECTION_NORMAL:
- protLevel = "normal";
- break;
- case PermissionInfo.PROTECTION_SIGNATURE:
- protLevel = "signature";
- break;
- case PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM:
- protLevel = "signatureOrSystem";
- break;
- }
- System.out.println(prefix + " protectionLevel:" + protLevel);
+ System.out.println(prefix + " protectionLevel:"
+ + PermissionInfo.protectionToString(pi.protectionLevel));
}
}
}
@@ -824,7 +837,7 @@ public final class Pm {
public void runCreateUser() {
// Need to be run as root
if (Process.myUid() != ROOT_UID) {
- System.err.println("Error: createUser must be run as root");
+ System.err.println("Error: create-user must be run as root");
return;
}
String name;
@@ -837,7 +850,7 @@ public final class Pm {
name = arg;
try {
if (mPm.createUser(name, 0) == null) {
- System.err.println("Error: couldn't create user.");
+ System.err.println("Error: couldn't create User.");
showUsage();
}
} catch (RemoteException e) {
@@ -850,7 +863,7 @@ public final class Pm {
public void runRemoveUser() {
// Need to be run as root
if (Process.myUid() != ROOT_UID) {
- System.err.println("Error: removeUser must be run as root");
+ System.err.println("Error: remove-user must be run as root");
return;
}
int userId;
@@ -878,6 +891,27 @@ public final class Pm {
}
}
+ public void runListUsers() {
+ // Need to be run as root
+ if (Process.myUid() != ROOT_UID) {
+ System.err.println("Error: list-users must be run as root");
+ return;
+ }
+ try {
+ List<UserInfo> users = mPm.getUsers();
+ if (users == null) {
+ System.err.println("Error: couldn't get users");
+ } else {
+ System.out.println("Users:");
+ for (int i = 0; i < users.size(); i++) {
+ System.out.println("\t" + users.get(i).toString());
+ }
+ }
+ } catch (RemoteException e) {
+ System.err.println(e.toString());
+ System.err.println(PM_NOT_RUNNING_ERR);
+ }
+ }
class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
boolean finished;
boolean result;
@@ -958,7 +992,8 @@ public final class Pm {
ClearDataObserver obs = new ClearDataObserver();
try {
- if (!ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs)) {
+ if (!ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs,
+ Binder.getOrigCallingUser())) {
System.err.println("Failed");
}
@@ -996,7 +1031,29 @@ public final class Pm {
return "unknown";
}
+ private boolean isNumber(String s) {
+ try {
+ Integer.parseInt(s);
+ } catch (NumberFormatException nfe) {
+ return false;
+ }
+ return true;
+ }
+
private void runSetEnabledSetting(int state) {
+ int userId = 0;
+ String option = nextOption();
+ if (option != null && option.equals("--user")) {
+ String optionData = nextOptionData();
+ if (optionData == null || !isNumber(optionData)) {
+ System.err.println("Error: no USER_ID specified");
+ showUsage();
+ return;
+ } else {
+ userId = Integer.parseInt(optionData);
+ }
+ }
+
String pkg = nextArg();
if (pkg == null) {
System.err.println("Error: no package or component specified");
@@ -1006,20 +1063,20 @@ public final class Pm {
ComponentName cn = ComponentName.unflattenFromString(pkg);
if (cn == null) {
try {
- mPm.setApplicationEnabledSetting(pkg, state, 0);
+ mPm.setApplicationEnabledSetting(pkg, state, 0, userId);
System.err.println("Package " + pkg + " new state: "
+ enabledSettingToString(
- mPm.getApplicationEnabledSetting(pkg)));
+ mPm.getApplicationEnabledSetting(pkg, userId)));
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
}
} else {
try {
- mPm.setComponentEnabledSetting(cn, state, 0);
+ mPm.setComponentEnabledSetting(cn, state, 0, userId);
System.err.println("Component " + cn.toShortString() + " new state: "
+ enabledSettingToString(
- mPm.getComponentEnabledSetting(cn)));
+ mPm.getComponentEnabledSetting(cn, userId)));
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
@@ -1027,13 +1084,43 @@ public final class Pm {
}
}
+ private void runGrantRevokePermission(boolean grant) {
+ String pkg = nextArg();
+ if (pkg == null) {
+ System.err.println("Error: no package specified");
+ showUsage();
+ return;
+ }
+ String perm = nextArg();
+ if (perm == null) {
+ System.err.println("Error: no permission specified");
+ showUsage();
+ return;
+ }
+ try {
+ if (grant) {
+ mPm.grantPermission(pkg, perm);
+ } else {
+ mPm.revokePermission(pkg, perm);
+ }
+ } catch (RemoteException e) {
+ System.err.println(e.toString());
+ System.err.println(PM_NOT_RUNNING_ERR);
+ } catch (IllegalArgumentException e) {
+ System.err.println("Bad argument: " + e.toString());
+ showUsage();
+ } catch (SecurityException e) {
+ System.err.println("Operation not allowed: " + e.toString());
+ }
+ }
+
/**
* Displays the package file for a package.
* @param pckg
*/
private void displayPackageFilePath(String pckg) {
try {
- PackageInfo info = mPm.getPackageInfo(pckg, 0);
+ PackageInfo info = mPm.getPackageInfo(pckg, 0, 0);
if (info != null && info.applicationInfo != null) {
System.out.print("package:");
System.out.println(info.applicationInfo.sourceDir);
@@ -1049,7 +1136,7 @@ public final class Pm {
if (res != null) return res;
try {
- ApplicationInfo ai = mPm.getApplicationInfo(pii.packageName, 0);
+ ApplicationInfo ai = mPm.getApplicationInfo(pii.packageName, 0, 0);
AssetManager am = new AssetManager();
am.addAssetPath(ai.publicSourceDir);
res = new Resources(am, null, null);
@@ -1109,23 +1196,26 @@ public final class Pm {
}
private static void showUsage() {
- System.err.println("usage: pm list packages [-f] [-d] [-e] [-s] [-e] [-u] [FILTER]");
+ System.err.println("usage: pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [FILTER]");
System.err.println(" pm list permission-groups");
System.err.println(" pm list permissions [-g] [-f] [-d] [-u] [GROUP]");
System.err.println(" pm list instrumentation [-f] [TARGET-PACKAGE]");
System.err.println(" pm list features");
System.err.println(" pm list libraries");
+ System.err.println(" pm list users");
System.err.println(" pm path PACKAGE");
System.err.println(" pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f] PATH");
System.err.println(" pm uninstall [-k] PACKAGE");
System.err.println(" pm clear PACKAGE");
- System.err.println(" pm enable PACKAGE_OR_COMPONENT");
- System.err.println(" pm disable PACKAGE_OR_COMPONENT");
- System.err.println(" pm disable-user PACKAGE_OR_COMPONENT");
+ System.err.println(" pm enable [--user USER_ID] PACKAGE_OR_COMPONENT");
+ System.err.println(" pm disable [--user USER_ID] PACKAGE_OR_COMPONENT");
+ System.err.println(" pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
+ System.err.println(" pm grant PACKAGE PERMISSION");
+ System.err.println(" pm revoke PACKAGE PERMISSION");
System.err.println(" pm set-install-location [0/auto] [1/internal] [2/external]");
System.err.println(" pm get-install-location");
- System.err.println(" pm createUser USER_NAME");
- System.err.println(" pm removeUser USER_ID");
+ System.err.println(" pm create-user USER_NAME");
+ System.err.println(" pm remove-user USER_ID");
System.err.println("");
System.err.println("pm list packages: prints all packages, optionally only");
System.err.println(" those whose package name contains the text in FILTER. Options:");
@@ -1134,6 +1224,7 @@ public final class Pm {
System.err.println(" -e: filter to only show enabled packages.");
System.err.println(" -s: filter to only show system packages.");
System.err.println(" -3: filter to only show third party packages.");
+ System.err.println(" -i: see the installer for the packages.");
System.err.println(" -u: also include uninstalled packages.");
System.err.println("");
System.err.println("pm list permission-groups: prints all known permission groups.");
@@ -1171,6 +1262,10 @@ public final class Pm {
System.err.println("pm enable, disable, disable-user: these commands change the enabled state");
System.err.println(" of a given package or component (written as \"package/class\").");
System.err.println("");
+ System.err.println("pm grant, revoke: these commands either grant or revoke permissions");
+ System.err.println(" to applications. Only optional permissions the application has");
+ System.err.println(" declared can be granted or revoked.");
+ System.err.println("");
System.err.println("pm get-install-location: returns the current install location.");
System.err.println(" 0 [auto]: Let system decide the best location");
System.err.println(" 1 [internal]: Install on internal device storage");
diff --git a/cmds/requestsync/Android.mk b/cmds/requestsync/Android.mk
new file mode 100644
index 000000000000..fe2ffd8de4dc
--- /dev/null
+++ b/cmds/requestsync/Android.mk
@@ -0,0 +1,16 @@
+# Copyright 2012 The Android Open Source Project
+#
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_MODULE := requestsync
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := requestsync
+LOCAL_SRC_FILES := requestsync
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_PREBUILT)
diff --git a/cmds/requestsync/MODULE_LICENSE_APACHE2 b/cmds/requestsync/MODULE_LICENSE_APACHE2
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/cmds/requestsync/MODULE_LICENSE_APACHE2
diff --git a/cmds/dumpsys/NOTICE b/cmds/requestsync/NOTICE
index c5b1efa7aac7..c5b1efa7aac7 100644
--- a/cmds/dumpsys/NOTICE
+++ b/cmds/requestsync/NOTICE
diff --git a/cmds/requestsync/requestsync b/cmds/requestsync/requestsync
new file mode 100755
index 000000000000..931567583e90
--- /dev/null
+++ b/cmds/requestsync/requestsync
@@ -0,0 +1,6 @@
+# Script to start "requestsync" on the device
+#
+base=/system
+export CLASSPATH=$base/framework/requestsync.jar
+exec app_process $base/bin com.android.commands.requestsync.RequestSync "$@"
+
diff --git a/cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java b/cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java
new file mode 100644
index 000000000000..808618f28666
--- /dev/null
+++ b/cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java
@@ -0,0 +1,237 @@
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package com.android.commands.requestsync;
+
+import android.accounts.Account;
+import android.content.ContentResolver;
+import android.os.Bundle;
+
+import java.net.URISyntaxException;
+
+public class RequestSync {
+ // agr parsing fields
+ private String[] mArgs;
+ private int mNextArg;
+ private String mCurArgData;
+
+ // account & authority
+ private String mAccountName = null;
+ private String mAccountType = null;
+ private String mAuthority = null;
+
+ // extras
+ private Bundle mExtras = new Bundle();
+
+ /**
+ * Command-line entry point.
+ *
+ * @param args The command-line arguments
+ */
+ public static void main(String[] args) {
+ try {
+ (new RequestSync()).run(args);
+ } catch (IllegalArgumentException e) {
+ showUsage();
+ System.err.println("Error: " + e);
+ e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ System.exit(1);
+ }
+ }
+
+ private void run(String[] args) throws Exception {
+ mArgs = args;
+ mNextArg = 0;
+
+ final boolean ok = parseArgs();
+ if (ok) {
+ final Account account = mAccountName != null && mAccountType != null
+ ? new Account(mAccountName, mAccountType) : null;
+
+ System.out.printf("Requesting sync for: \n");
+ if (account != null) {
+ System.out.printf(" Account: %s (%s)\n", account.name, account.type);
+ } else {
+ System.out.printf(" Account: all\n");
+ }
+
+ System.out.printf(" Authority: %s\n", mAuthority != null ? mAuthority : "All");
+
+ if (mExtras.size() > 0) {
+ System.out.printf(" Extras:\n");
+ for (String key : mExtras.keySet()) {
+ System.out.printf(" %s: %s\n", key, mExtras.get(key));
+ }
+ }
+
+ ContentResolver.requestSync(account, mAuthority, mExtras);
+ }
+ }
+
+ private boolean parseArgs() throws URISyntaxException {
+ String opt;
+ while ((opt=nextOption()) != null) {
+ if (opt.equals("-h") || opt.equals("--help")) {
+ showUsage();
+ return false;
+ } else if (opt.equals("-n") || opt.equals("--account-name")) {
+ mAccountName = nextArgRequired();
+ } else if (opt.equals("-t") || opt.equals("--account-type")) {
+ mAccountType = nextArgRequired();
+ } else if (opt.equals("-a") || opt.equals("--authority")) {
+ mAuthority = nextArgRequired();
+ } else if (opt.equals("--is") || opt.equals("--ignore-settings")) {
+ mExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true);
+ } else if (opt.equals("--ib") || opt.equals("--ignore-backoff")) {
+ mExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true);
+ } else if (opt.equals("--dd") || opt.equals("--discard-deletions")) {
+ mExtras.putBoolean(ContentResolver.SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS, true);
+ } else if (opt.equals("--nr") || opt.equals("--no-retry")) {
+ mExtras.putBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, true);
+ } else if (opt.equals("--ex") || opt.equals("--expedited")) {
+ mExtras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
+ } else if (opt.equals("-i") || opt.equals("--initialize")) {
+ mExtras.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true);
+ } else if (opt.equals("-m") || opt.equals("--manual")) {
+ mExtras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+ } else if (opt.equals("--od") || opt.equals("--override-deletions")) {
+ mExtras.putBoolean(ContentResolver.SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS, true);
+ } else if (opt.equals("-u") || opt.equals("--upload-only")) {
+ mExtras.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, true);
+ } else if (opt.equals("-e") || opt.equals("--es") || opt.equals("--extra-string")) {
+ final String key = nextArgRequired();
+ final String value = nextArgRequired();
+ mExtras.putString(key, value);
+ } else if (opt.equals("--esn") || opt.equals("--extra-string-null")) {
+ final String key = nextArgRequired();
+ mExtras.putString(key, null);
+ } else if (opt.equals("--ei") || opt.equals("--extra-int")) {
+ final String key = nextArgRequired();
+ final String value = nextArgRequired();
+ mExtras.putInt(key, Integer.valueOf(value));
+ } else if (opt.equals("--el") || opt.equals("--extra-long")) {
+ final String key = nextArgRequired();
+ final String value = nextArgRequired();
+ mExtras.putLong(key, Long.valueOf(value));
+ } else if (opt.equals("--ef") || opt.equals("--extra-float")) {
+ final String key = nextArgRequired();
+ final String value = nextArgRequired();
+ mExtras.putFloat(key, Long.valueOf(value));
+ } else if (opt.equals("--ed") || opt.equals("--extra-double")) {
+ final String key = nextArgRequired();
+ final String value = nextArgRequired();
+ mExtras.putFloat(key, Long.valueOf(value));
+ } else if (opt.equals("--ez") || opt.equals("--extra-bool")) {
+ final String key = nextArgRequired();
+ final String value = nextArgRequired();
+ mExtras.putBoolean(key, Boolean.valueOf(value));
+ } else {
+ System.err.println("Error: Unknown option: " + opt);
+ showUsage();
+ return false;
+ }
+ }
+
+ if (mNextArg < mArgs.length) {
+ showUsage();
+ return false;
+ }
+ return true;
+ }
+
+ private String nextOption() {
+ if (mCurArgData != null) {
+ String prev = mArgs[mNextArg - 1];
+ throw new IllegalArgumentException("No argument expected after \"" + prev + "\"");
+ }
+ if (mNextArg >= mArgs.length) {
+ return null;
+ }
+ String arg = mArgs[mNextArg];
+ if (!arg.startsWith("-")) {
+ return null;
+ }
+ mNextArg++;
+ if (arg.equals("--")) {
+ return null;
+ }
+ if (arg.length() > 1 && arg.charAt(1) != '-') {
+ if (arg.length() > 2) {
+ mCurArgData = arg.substring(2);
+ return arg.substring(0, 2);
+ } else {
+ mCurArgData = null;
+ return arg;
+ }
+ }
+ mCurArgData = null;
+ return arg;
+ }
+
+ private String nextArg() {
+ if (mCurArgData != null) {
+ String arg = mCurArgData;
+ mCurArgData = null;
+ return arg;
+ } else if (mNextArg < mArgs.length) {
+ return mArgs[mNextArg++];
+ } else {
+ return null;
+ }
+ }
+
+ private String nextArgRequired() {
+ String arg = nextArg();
+ if (arg == null) {
+ String prev = mArgs[mNextArg - 1];
+ throw new IllegalArgumentException("Argument expected after \"" + prev + "\"");
+ }
+ return arg;
+ }
+
+ private static void showUsage() {
+ System.err.println(
+ "usage: requestsync [options]\n" +
+ "With no options, a sync will be requested for all account and all sync\n" +
+ "authorities with no extras. Options can be:\n" +
+ " -h|--help: Display this message\n" +
+ " -n|--account-name <ACCOUNT-NAME>\n" +
+ " -t|--account-type <ACCOUNT-TYPE>\n" +
+ " -a|--authority <AUTHORITY>\n" +
+ " Add ContentResolver extras:\n" +
+ " --is|--ignore-settings: Add SYNC_EXTRAS_IGNORE_SETTINGS\n" +
+ " --ib|--ignore-backoff: Add SYNC_EXTRAS_IGNORE_BACKOFF\n" +
+ " --dd|--discard-deletions: Add SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS\n" +
+ " --nr|--no-retry: Add SYNC_EXTRAS_DO_NOT_RETRY\n" +
+ " --ex|--expedited: Add SYNC_EXTRAS_EXPEDITED\n" +
+ " --i|--initialize: Add SYNC_EXTRAS_INITIALIZE\n" +
+ " --m|--manual: Add SYNC_EXTRAS_MANUAL\n" +
+ " --od|--override-deletions: Add SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS\n" +
+ " --u|--upload-only: Add SYNC_EXTRAS_UPLOAD\n" +
+ " Add custom extras:\n" +
+ " -e|--es|--extra-string <KEY> <VALUE>\n" +
+ " --esn|--extra-string-null <KEY>\n" +
+ " --ei|--extra-int <KEY> <VALUE>\n" +
+ " --el|--extra-long <KEY> <VALUE>\n" +
+ " --ef|--extra-float <KEY> <VALUE>\n" +
+ " --ed|--extra-double <KEY> <VALUE>\n" +
+ " --ez|--extra-bool <KEY> <VALUE>\n"
+ );
+ }
+}
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index bee5880ac4cc..46e41e3d476e 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -24,7 +24,7 @@
#include <sys/mman.h>
#include <binder/IMemory.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/SurfaceComposerClient.h>
#include <SkImageEncoder.h>
#include <SkBitmap.h>
@@ -49,7 +49,6 @@ static SkBitmap::Config flinger2skia(PixelFormat f)
{
switch (f) {
case PIXEL_FORMAT_A_8:
- case PIXEL_FORMAT_L_8:
return SkBitmap::kA8_Config;
case PIXEL_FORMAT_RGB_565:
return SkBitmap::kRGB_565_Config;
diff --git a/cmds/servicemanager/Android.mk b/cmds/servicemanager/Android.mk
index ea80c7d85dc8..8840867a9dfa 100644
--- a/cmds/servicemanager/Android.mk
+++ b/cmds/servicemanager/Android.mk
@@ -9,7 +9,4 @@ include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_SRC_FILES := service_manager.c binder.c
LOCAL_MODULE := servicemanager
-ifeq ($(BOARD_USE_LVMX),true)
- LOCAL_CFLAGS += -DLVMX
-endif
include $(BUILD_EXECUTABLE)
diff --git a/cmds/servicemanager/binder.c b/cmds/servicemanager/binder.c
index 918d4d4e9633..1985756a669f 100644
--- a/cmds/servicemanager/binder.c
+++ b/cmds/servicemanager/binder.c
@@ -412,7 +412,7 @@ void bio_init(struct binder_io *bio, void *data,
return;
}
- bio->data = bio->data0 = data + n;
+ bio->data = bio->data0 = (char *) data + n;
bio->offs = bio->offs0 = data;
bio->data_avail = maxdata - n;
bio->offs_avail = maxoffs;
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index 42d8977339ee..71c5622ec382 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -27,9 +27,6 @@ static struct {
unsigned uid;
const char *name;
} allowed[] = {
-#ifdef LVMX
- { AID_MEDIA, "com.lifevibes.mx.ipc" },
-#endif
{ AID_MEDIA, "media.audio_flinger" },
{ AID_MEDIA, "media.player" },
{ AID_MEDIA, "media.camera" },
@@ -46,6 +43,8 @@ static struct {
{ AID_RADIO, "isms" },
{ AID_RADIO, "iphonesubinfo" },
{ AID_RADIO, "simphonebook" },
+ { AID_MEDIA, "common_time.clock" },
+ { AID_MEDIA, "common_time.config" },
};
void *svcmgr_handle;
@@ -93,6 +92,7 @@ struct svcinfo
struct svcinfo *next;
void *ptr;
struct binder_death death;
+ int allow_isolated;
unsigned len;
uint16_t name[0];
};
@@ -128,13 +128,21 @@ uint16_t svcmgr_id[] = {
};
-void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len)
+void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len, unsigned uid)
{
struct svcinfo *si;
si = find_svc(s, len);
// ALOGI("check_service('%s') ptr = %p\n", str8(s), si ? si->ptr : 0);
if (si && si->ptr) {
+ if (!si->allow_isolated) {
+ // If this service doesn't allow access from isolated processes,
+ // then check the uid to see if it is isolated.
+ unsigned appid = uid % AID_USER;
+ if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) {
+ return 0;
+ }
+ }
return si->ptr;
} else {
return 0;
@@ -143,10 +151,11 @@ void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len)
int do_add_service(struct binder_state *bs,
uint16_t *s, unsigned len,
- void *ptr, unsigned uid)
+ void *ptr, unsigned uid, int allow_isolated)
{
struct svcinfo *si;
-// ALOGI("add_service('%s',%p) uid=%d\n", str8(s), ptr, uid);
+ //ALOGI("add_service('%s',%p,%s) uid=%d\n", str8(s), ptr,
+ // allow_isolated ? "allow_isolated" : "!allow_isolated", uid);
if (!ptr || (len == 0) || (len > 127))
return -1;
@@ -178,6 +187,7 @@ int do_add_service(struct binder_state *bs,
si->name[len] = '\0';
si->death.func = svcinfo_death;
si->death.ptr = si;
+ si->allow_isolated = allow_isolated;
si->next = svclist;
svclist = si;
}
@@ -197,6 +207,7 @@ int svcmgr_handler(struct binder_state *bs,
unsigned len;
void *ptr;
uint32_t strict_policy;
+ int allow_isolated;
// ALOGI("target=%p code=%d pid=%d uid=%d\n",
// txn->target, txn->code, txn->sender_pid, txn->sender_euid);
@@ -220,7 +231,7 @@ int svcmgr_handler(struct binder_state *bs,
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE:
s = bio_get_string16(msg, &len);
- ptr = do_find_service(bs, s, len);
+ ptr = do_find_service(bs, s, len, txn->sender_euid);
if (!ptr)
break;
bio_put_ref(reply, ptr);
@@ -229,7 +240,8 @@ int svcmgr_handler(struct binder_state *bs,
case SVC_MGR_ADD_SERVICE:
s = bio_get_string16(msg, &len);
ptr = bio_get_ref(msg);
- if (do_add_service(bs, s, len, ptr, txn->sender_euid))
+ allow_isolated = bio_get_uint32(msg) ? 1 : 0;
+ if (do_add_service(bs, s, len, ptr, txn->sender_euid, allow_isolated))
return -1;
break;
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
deleted file mode 100644
index e9642f7cc8c5..000000000000
--- a/cmds/stagefright/Android.mk
+++ /dev/null
@@ -1,150 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- stagefright.cpp \
- SineSource.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libstagefright libmedia libutils libbinder libstagefright_foundation \
- libskia libgui
-
-LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
- frameworks/base/media/libstagefright \
- frameworks/base/media/libstagefright/include \
- $(TOP)/frameworks/base/include/media/stagefright/openmax \
- external/skia/include/core \
- external/skia/include/images \
-
-LOCAL_CFLAGS += -Wno-multichar
-
-LOCAL_MODULE_TAGS := debug
-
-LOCAL_MODULE:= stagefright
-
-include $(BUILD_EXECUTABLE)
-
-################################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- SineSource.cpp \
- record.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libstagefright liblog libutils libbinder
-
-LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
- frameworks/base/media/libstagefright \
- $(TOP)/frameworks/base/include/media/stagefright/openmax
-
-LOCAL_CFLAGS += -Wno-multichar
-
-LOCAL_MODULE_TAGS := debug
-
-LOCAL_MODULE:= record
-
-include $(BUILD_EXECUTABLE)
-
-################################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- SineSource.cpp \
- recordvideo.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libstagefright liblog libutils libbinder
-
-LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
- frameworks/base/media/libstagefright \
- $(TOP)/frameworks/base/include/media/stagefright/openmax
-
-LOCAL_CFLAGS += -Wno-multichar
-
-LOCAL_MODULE_TAGS := debug
-
-LOCAL_MODULE:= recordvideo
-
-include $(BUILD_EXECUTABLE)
-
-
-################################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- SineSource.cpp \
- audioloop.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libstagefright liblog libutils libbinder
-
-LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
- frameworks/base/media/libstagefright \
- $(TOP)/frameworks/base/include/media/stagefright/openmax
-
-LOCAL_CFLAGS += -Wno-multichar
-
-LOCAL_MODULE_TAGS := debug
-
-LOCAL_MODULE:= audioloop
-
-include $(BUILD_EXECUTABLE)
-
-################################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- stream.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
- libstagefright liblog libutils libbinder libgui \
- libstagefright_foundation libmedia
-
-LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
- frameworks/base/media/libstagefright \
- $(TOP)/frameworks/base/include/media/stagefright/openmax
-
-LOCAL_CFLAGS += -Wno-multichar
-
-LOCAL_MODULE_TAGS := debug
-
-LOCAL_MODULE:= stream
-
-include $(BUILD_EXECUTABLE)
-
-################################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- sf2.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
- libstagefright liblog libutils libbinder libstagefright_foundation \
- libmedia libgui libcutils libui
-
-LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
- frameworks/base/media/libstagefright \
- $(TOP)/frameworks/base/include/media/stagefright/openmax
-
-LOCAL_CFLAGS += -Wno-multichar
-
-LOCAL_MODULE_TAGS := debug
-
-LOCAL_MODULE:= sf2
-
-include $(BUILD_EXECUTABLE)
-
-
diff --git a/cmds/stagefright/SineSource.cpp b/cmds/stagefright/SineSource.cpp
deleted file mode 100644
index 021f636e2eb0..000000000000
--- a/cmds/stagefright/SineSource.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-#include "SineSource.h"
-
-#include <math.h>
-
-#include <media/stagefright/MediaBufferGroup.h>
-#include <media/stagefright/MediaDebug.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
-
-namespace android {
-
-SineSource::SineSource(int32_t sampleRate, int32_t numChannels)
- : mStarted(false),
- mSampleRate(sampleRate),
- mNumChannels(numChannels),
- mPhase(0),
- mGroup(NULL) {
- CHECK(numChannels == 1 || numChannels == 2);
-}
-
-SineSource::~SineSource() {
- if (mStarted) {
- stop();
- }
-}
-
-status_t SineSource::start(MetaData *params) {
- CHECK(!mStarted);
-
- mGroup = new MediaBufferGroup;
- mGroup->add_buffer(new MediaBuffer(kBufferSize));
-
- mPhase = 0;
- mStarted = true;
-
- return OK;
-}
-
-status_t SineSource::stop() {
- CHECK(mStarted);
-
- delete mGroup;
- mGroup = NULL;
-
- mStarted = false;
-
- return OK;
-}
-
-sp<MetaData> SineSource::getFormat() {
- sp<MetaData> meta = new MetaData;
- meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
- meta->setInt32(kKeyChannelCount, mNumChannels);
- meta->setInt32(kKeySampleRate, mSampleRate);
- meta->setInt32(kKeyMaxInputSize, kBufferSize);
-
- return meta;
-}
-
-status_t SineSource::read(
- MediaBuffer **out, const ReadOptions *options) {
- *out = NULL;
-
- MediaBuffer *buffer;
- status_t err = mGroup->acquire_buffer(&buffer);
-
- if (err != OK) {
- return err;
- }
-
- size_t frameSize = mNumChannels * sizeof(int16_t);
- size_t numFramesPerBuffer = buffer->size() / frameSize;
-
- int16_t *ptr = (int16_t *)buffer->data();
-
- const double k = kFrequency / mSampleRate * (2.0 * M_PI);
-
- double x = mPhase * k;
- for (size_t i = 0; i < numFramesPerBuffer; ++i) {
- int16_t amplitude = (int16_t)(32767.0 * sin(x));
-
- *ptr++ = amplitude;
- if (mNumChannels == 2) {
- *ptr++ = amplitude;
- }
-
- x += k;
- }
-
- buffer->meta_data()->setInt64(
- kKeyTime, ((int64_t)mPhase * 1000000) / mSampleRate);
-
- mPhase += numFramesPerBuffer;
-
- buffer->set_range(0, numFramesPerBuffer * frameSize);
-
- *out = buffer;
-
- return OK;
-}
-
-} // namespace android
diff --git a/cmds/stagefright/SineSource.h b/cmds/stagefright/SineSource.h
deleted file mode 100644
index 76ab669fbfc6..000000000000
--- a/cmds/stagefright/SineSource.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef SINE_SOURCE_H_
-
-#define SINE_SOURCE_H_
-
-#include <media/stagefright/MediaSource.h>
-
-namespace android {
-
-struct MediaBufferGroup;
-
-struct SineSource : public MediaSource {
- SineSource(int32_t sampleRate, int32_t numChannels);
-
- virtual status_t start(MetaData *params);
- virtual status_t stop();
-
- virtual sp<MetaData> getFormat();
-
- virtual status_t read(
- MediaBuffer **out, const ReadOptions *options = NULL);
-
-protected:
- virtual ~SineSource();
-
-private:
- enum { kBufferSize = 8192 };
- static const double kFrequency = 500.0;
-
- bool mStarted;
- int32_t mSampleRate;
- int32_t mNumChannels;
- size_t mPhase;
-
- MediaBufferGroup *mGroup;
-};
-
-} // namespace android
-
-#endif // SINE_SOURCE_H_
diff --git a/cmds/stagefright/WaveWriter.h b/cmds/stagefright/WaveWriter.h
deleted file mode 100644
index a0eb66e2b9bc..000000000000
--- a/cmds/stagefright/WaveWriter.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_WAVEWRITER_H_
-
-#define ANDROID_WAVEWRITER_H_
-
-namespace android {
-
-class WaveWriter {
-public:
- WaveWriter(const char *filename,
- uint16_t num_channels, uint32_t sampling_rate)
- : mFile(fopen(filename, "wb")),
- mTotalBytes(0) {
- fwrite("RIFFxxxxWAVEfmt \x10\x00\x00\x00\x01\x00", 1, 22, mFile);
- write_u16(num_channels);
- write_u32(sampling_rate);
- write_u32(sampling_rate * num_channels * 2);
- write_u16(num_channels * 2);
- write_u16(16);
- fwrite("dataxxxx", 1, 8, mFile);
- }
-
- ~WaveWriter() {
- fseek(mFile, 40, SEEK_SET);
- write_u32(mTotalBytes);
-
- fseek(mFile, 4, SEEK_SET);
- write_u32(36 + mTotalBytes);
-
- fclose(mFile);
- mFile = NULL;
- }
-
- void Append(const void *data, size_t size) {
- fwrite(data, 1, size, mFile);
- mTotalBytes += size;
- }
-
-private:
- void write_u16(uint16_t x) {
- fputc(x & 0xff, mFile);
- fputc(x >> 8, mFile);
- }
-
- void write_u32(uint32_t x) {
- write_u16(x & 0xffff);
- write_u16(x >> 16);
- }
-
- FILE *mFile;
- size_t mTotalBytes;
-};
-
-} // namespace android
-
-#endif // ANDROID_WAVEWRITER_H_
diff --git a/cmds/stagefright/audioloop.cpp b/cmds/stagefright/audioloop.cpp
deleted file mode 100644
index 858681f6ce45..000000000000
--- a/cmds/stagefright/audioloop.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-#include "SineSource.h"
-
-#include <binder/ProcessState.h>
-#include <media/mediarecorder.h>
-#include <media/stagefright/AMRWriter.h>
-#include <media/stagefright/AudioPlayer.h>
-#include <media/stagefright/AudioSource.h>
-#include <media/stagefright/MediaDebug.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/OMXClient.h>
-#include <media/stagefright/OMXCodec.h>
-
-#include <system/audio.h>
-
-using namespace android;
-
-int main() {
- // We only have an AMR-WB encoder on sholes...
- static bool outputWBAMR = false;
- static const int32_t kSampleRate = outputWBAMR ? 16000 : 8000;
- static const int32_t kNumChannels = 1;
-
- android::ProcessState::self()->startThreadPool();
-
- OMXClient client;
- CHECK_EQ(client.connect(), OK);
-
-#if 0
- sp<MediaSource> source = new SineSource(kSampleRate, kNumChannels);
-#else
- sp<MediaSource> source = new AudioSource(
- AUDIO_SOURCE_DEFAULT,
- kSampleRate,
- kNumChannels == 1
- ? AUDIO_CHANNEL_IN_MONO
- : AUDIO_CHANNEL_IN_STEREO);
-#endif
-
- sp<MetaData> meta = new MetaData;
-
- meta->setCString(
- kKeyMIMEType,
- outputWBAMR ? MEDIA_MIMETYPE_AUDIO_AMR_WB
- : MEDIA_MIMETYPE_AUDIO_AMR_NB);
-
- meta->setInt32(kKeyChannelCount, kNumChannels);
- meta->setInt32(kKeySampleRate, kSampleRate);
-
- int32_t maxInputSize;
- if (source->getFormat()->findInt32(kKeyMaxInputSize, &maxInputSize)) {
- meta->setInt32(kKeyMaxInputSize, maxInputSize);
- }
-
- sp<MediaSource> encoder = OMXCodec::Create(
- client.interface(),
- meta, true /* createEncoder */,
- source);
-
-#if 1
- sp<AMRWriter> writer = new AMRWriter("/sdcard/out.amr");
- writer->addSource(encoder);
- writer->start();
- sleep(10);
- writer->stop();
-#else
- sp<MediaSource> decoder = OMXCodec::Create(
- client.interface(),
- meta, false /* createEncoder */,
- encoder);
-
-#if 0
- AudioPlayer *player = new AudioPlayer(NULL);
- player->setSource(decoder);
-
- player->start();
-
- sleep(10);
-
- player->stop();
-
- delete player;
- player = NULL;
-#elif 0
- CHECK_EQ(decoder->start(), OK);
-
- MediaBuffer *buffer;
- while (decoder->read(&buffer) == OK) {
- // do something with buffer
-
- putchar('.');
- fflush(stdout);
-
- buffer->release();
- buffer = NULL;
- }
-
- CHECK_EQ(decoder->stop(), OK);
-#endif
-#endif
-
- return 0;
-}
diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp
deleted file mode 100644
index 613435df15e8..000000000000
--- a/cmds/stagefright/record.cpp
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "SineSource.h"
-
-#include <binder/ProcessState.h>
-#include <media/stagefright/AudioPlayer.h>
-#include <media/stagefright/CameraSource.h>
-#include <media/stagefright/FileSource.h>
-#include <media/stagefright/MediaBufferGroup.h>
-#include <media/stagefright/MediaDebug.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/MediaExtractor.h>
-#include <media/stagefright/MPEG4Writer.h>
-#include <media/stagefright/OMXClient.h>
-#include <media/stagefright/OMXCodec.h>
-#include <media/MediaPlayerInterface.h>
-
-using namespace android;
-
-static const int32_t kFramerate = 24; // fps
-static const int32_t kIFramesIntervalSec = 1;
-static const int32_t kVideoBitRate = 512 * 1024;
-static const int32_t kAudioBitRate = 12200;
-static const int64_t kDurationUs = 10000000LL; // 10 seconds
-
-#if 1
-class DummySource : public MediaSource {
-
-public:
- DummySource(int width, int height, int colorFormat)
- : mWidth(width),
- mHeight(height),
- mColorFormat(colorFormat),
- 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() {
- sp<MetaData> meta = new MetaData;
- meta->setInt32(kKeyWidth, mWidth);
- meta->setInt32(kKeyHeight, mHeight);
- meta->setInt32(kKeyColorFormat, mColorFormat);
- meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
-
- return meta;
- }
-
- virtual status_t start(MetaData *params) {
- mNumFramesOutput = 0;
- return OK;
- }
-
- virtual status_t stop() {
- return OK;
- }
-
- virtual status_t read(
- MediaBuffer **buffer, const MediaSource::ReadOptions *options) {
- if (mNumFramesOutput == kFramerate * 10) {
- // Stop returning data after 10 secs.
- return ERROR_END_OF_STREAM;
- }
-
- // printf("DummySource::read\n");
- status_t err = mGroup.acquire_buffer(buffer);
- if (err != OK) {
- return err;
- }
-
- char x = (char)((double)rand() / RAND_MAX * 255);
- memset((*buffer)->data(), x, mSize);
- (*buffer)->set_range(0, mSize);
- (*buffer)->meta_data()->clear();
- (*buffer)->meta_data()->setInt64(
- kKeyTime, (mNumFramesOutput * 1000000) / kFramerate);
- ++mNumFramesOutput;
-
- // printf("DummySource::read - returning buffer\n");
- // ALOGI("DummySource::read - returning buffer");
- return OK;
- }
-
-protected:
- virtual ~DummySource() {}
-
-private:
- MediaBufferGroup mGroup;
- int mWidth, mHeight;
- int mColorFormat;
- size_t mSize;
- int64_t mNumFramesOutput;;
-
- DummySource(const DummySource &);
- DummySource &operator=(const DummySource &);
-};
-
-sp<MediaSource> createSource(const char *filename) {
- sp<MediaSource> source;
-
- sp<MediaExtractor> extractor =
- MediaExtractor::Create(new FileSource(filename));
- if (extractor == NULL) {
- return NULL;
- }
-
- size_t num_tracks = extractor->countTracks();
-
- sp<MetaData> meta;
- for (size_t i = 0; i < num_tracks; ++i) {
- meta = extractor->getTrackMetaData(i);
- CHECK(meta.get() != NULL);
-
- const char *mime;
- if (!meta->findCString(kKeyMIMEType, &mime)) {
- continue;
- }
-
- if (strncasecmp(mime, "video/", 6)) {
- continue;
- }
-
- source = extractor->getTrack(i);
- break;
- }
-
- return source;
-}
-
-enum {
- kYUV420SP = 0,
- kYUV420P = 1,
-};
-
-// returns -1 if mapping of the given color is unsuccessful
-// returns an omx color enum value otherwise
-static int translateColorToOmxEnumValue(int color) {
- switch (color) {
- case kYUV420SP:
- return OMX_COLOR_FormatYUV420SemiPlanar;
- case kYUV420P:
- return OMX_COLOR_FormatYUV420Planar;
- default:
- fprintf(stderr, "Unsupported color: %d\n", color);
- return -1;
- }
-}
-
-int main(int argc, char **argv) {
- android::ProcessState::self()->startThreadPool();
-
- DataSource::RegisterDefaultSniffers();
-
-#if 1
- if (argc != 3) {
- fprintf(stderr, "usage: %s <filename> <input_color_format>\n", argv[0]);
- fprintf(stderr, " <input_color_format>: 0 (YUV420SP) or 1 (YUV420P)\n");
- return 1;
- }
-
- int colorFormat = translateColorToOmxEnumValue(atoi(argv[2]));
- if (colorFormat == -1) {
- fprintf(stderr, "input color format must be 0 (YUV420SP) or 1 (YUV420P)\n");
- return 1;
- }
- OMXClient client;
- CHECK_EQ(client.connect(), OK);
-
- status_t err = OK;
-
-#if 0
- sp<MediaSource> source = createSource(argv[1]);
-
- if (source == NULL) {
- fprintf(stderr, "Unable to find a suitable video track.\n");
- return 1;
- }
-
- sp<MetaData> meta = source->getFormat();
-
- sp<MediaSource> decoder = OMXCodec::Create(
- client.interface(), meta, false /* createEncoder */, source);
-
- int width, height;
- bool success = meta->findInt32(kKeyWidth, &width);
- success = success && meta->findInt32(kKeyHeight, &height);
- CHECK(success);
-#else
- int width = 720;
- int height = 480;
- sp<MediaSource> decoder = new DummySource(width, height, colorFormat);
-#endif
-
- sp<MetaData> enc_meta = new MetaData;
- // enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
- // enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
- enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
- enc_meta->setInt32(kKeyWidth, width);
- enc_meta->setInt32(kKeyHeight, height);
- enc_meta->setInt32(kKeySampleRate, kFramerate);
- enc_meta->setInt32(kKeyBitRate, kVideoBitRate);
- enc_meta->setInt32(kKeyStride, width);
- enc_meta->setInt32(kKeySliceHeight, height);
- enc_meta->setInt32(kKeyIFramesInterval, kIFramesIntervalSec);
- enc_meta->setInt32(kKeyColorFormat, colorFormat);
-
- sp<MediaSource> encoder =
- OMXCodec::Create(
- client.interface(), enc_meta, true /* createEncoder */, decoder);
-
-#if 1
- sp<MPEG4Writer> writer = new MPEG4Writer("/sdcard/output.mp4");
- writer->addSource(encoder);
- writer->setMaxFileDuration(kDurationUs);
- CHECK_EQ(OK, writer->start());
- while (!writer->reachedEOS()) {
- fprintf(stderr, ".");
- usleep(100000);
- }
- err = writer->stop();
-#else
- CHECK_EQ(OK, encoder->start());
-
- MediaBuffer *buffer;
- while (encoder->read(&buffer) == OK) {
- printf(".");
- fflush(stdout);
- int32_t isSync;
- if (!buffer->meta_data()->findInt32(kKeyIsSyncFrame, &isSync)) {
- isSync = false;
- }
-
- printf("got an output frame of size %d%s\n", buffer->range_length(),
- isSync ? " (SYNC)" : "");
-
- buffer->release();
- buffer = NULL;
- }
-
- err = encoder->stop();
-#endif
-
- printf("$\n");
- client.disconnect();
-#endif
-
-#if 0
- CameraSource *source = CameraSource::Create();
- source->start();
-
- printf("source = %p\n", source);
-
- for (int i = 0; i < 100; ++i) {
- MediaBuffer *buffer;
- status_t err = source->read(&buffer);
- CHECK_EQ(err, OK);
-
- printf("got a frame, data=%p, size=%d\n",
- buffer->data(), buffer->range_length());
-
- buffer->release();
- buffer = NULL;
- }
-
- err = source->stop();
-
- delete source;
- source = NULL;
-#endif
-
- if (err != OK && err != ERROR_END_OF_STREAM) {
- fprintf(stderr, "record failed: %d\n", err);
- return 1;
- }
- return 0;
-}
-#else
-
-int main(int argc, char **argv) {
- android::ProcessState::self()->startThreadPool();
-
- OMXClient client;
- CHECK_EQ(client.connect(), OK);
-
- const int32_t kSampleRate = 22050;
- const int32_t kNumChannels = 2;
- sp<MediaSource> audioSource = new SineSource(kSampleRate, kNumChannels);
-
-#if 0
- sp<MediaPlayerBase::AudioSink> audioSink;
- AudioPlayer *player = new AudioPlayer(audioSink);
- player->setSource(audioSource);
- player->start();
-
- sleep(10);
-
- player->stop();
-#endif
-
- sp<MetaData> encMeta = new MetaData;
- encMeta->setCString(kKeyMIMEType,
- 1 ? MEDIA_MIMETYPE_AUDIO_AMR_WB : MEDIA_MIMETYPE_AUDIO_AAC);
- encMeta->setInt32(kKeySampleRate, kSampleRate);
- encMeta->setInt32(kKeyChannelCount, kNumChannels);
- encMeta->setInt32(kKeyMaxInputSize, 8192);
- encMeta->setInt32(kKeyBitRate, kAudioBitRate);
-
- sp<MediaSource> encoder =
- OMXCodec::Create(client.interface(), encMeta, true, audioSource);
-
- encoder->start();
-
- int32_t n = 0;
- status_t err;
- MediaBuffer *buffer;
- while ((err = encoder->read(&buffer)) == OK) {
- printf(".");
- fflush(stdout);
-
- buffer->release();
- buffer = NULL;
-
- if (++n == 100) {
- break;
- }
- }
- printf("$\n");
-
- encoder->stop();
-
- client.disconnect();
-
- return 0;
-}
-#endif
diff --git a/cmds/stagefright/recordvideo.cpp b/cmds/stagefright/recordvideo.cpp
deleted file mode 100644
index c40228631ae2..000000000000
--- a/cmds/stagefright/recordvideo.cpp
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "SineSource.h"
-
-#include <binder/ProcessState.h>
-#include <media/stagefright/AudioPlayer.h>
-#include <media/stagefright/MediaBufferGroup.h>
-#include <media/stagefright/MediaDebug.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/MPEG4Writer.h>
-#include <media/stagefright/OMXClient.h>
-#include <media/stagefright/OMXCodec.h>
-#include <media/MediaPlayerInterface.h>
-
-using namespace android;
-
-// Print usage showing how to use this utility to record videos
-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 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");
- fprintf(stderr, " -w width in pixels (default: 176)\n");
- fprintf(stderr, " -t height in pixels (default: 144)\n");
- fprintf(stderr, " -l encoder level. see omx il header (default: encoder specific)\n");
- fprintf(stderr, " -p encoder profile. see omx il header (default: encoder specific)\n");
- fprintf(stderr, " -v video codec: [0] AVC [1] M4V [2] H263 (default: 0)\n");
- fprintf(stderr, "The output file is /sdcard/output.mp4\n");
- exit(1);
-}
-
-class DummySource : public MediaSource {
-
-public:
- DummySource(int width, int height, int nFrames, int fps, int colorFormat)
- : mWidth(width),
- mHeight(height),
- mMaxNumFrames(nFrames),
- mFrameRate(fps),
- mColorFormat(colorFormat),
- mSize((width * height * 3) / 2) {
-
- mGroup.add_buffer(new MediaBuffer(mSize));
- }
-
- virtual sp<MetaData> getFormat() {
- sp<MetaData> meta = new MetaData;
- meta->setInt32(kKeyWidth, mWidth);
- meta->setInt32(kKeyHeight, mHeight);
- meta->setInt32(kKeyColorFormat, mColorFormat);
- meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
-
- return meta;
- }
-
- virtual status_t start(MetaData *params) {
- mNumFramesOutput = 0;
- return OK;
- }
-
- virtual status_t stop() {
- return OK;
- }
-
- virtual status_t read(
- MediaBuffer **buffer, const MediaSource::ReadOptions *options) {
-
- if (mNumFramesOutput % 10 == 0) {
- fprintf(stderr, ".");
- }
- if (mNumFramesOutput == mMaxNumFrames) {
- return ERROR_END_OF_STREAM;
- }
-
- status_t err = mGroup.acquire_buffer(buffer);
- if (err != OK) {
- return err;
- }
-
- // We don't care about the contents. we just test video encoder
- // Also, by skipping the content generation, we can return from
- // read() much faster.
- //char x = (char)((double)rand() / RAND_MAX * 255);
- //memset((*buffer)->data(), x, mSize);
- (*buffer)->set_range(0, mSize);
- (*buffer)->meta_data()->clear();
- (*buffer)->meta_data()->setInt64(
- kKeyTime, (mNumFramesOutput * 1000000) / mFrameRate);
- ++mNumFramesOutput;
-
- return OK;
- }
-
-protected:
- virtual ~DummySource() {}
-
-private:
- MediaBufferGroup mGroup;
- int mWidth, mHeight;
- int mMaxNumFrames;
- int mFrameRate;
- int mColorFormat;
- size_t mSize;
- int64_t mNumFramesOutput;;
-
- DummySource(const DummySource &);
- DummySource &operator=(const DummySource &);
-};
-
-enum {
- kYUV420SP = 0,
- kYUV420P = 1,
-};
-
-// returns -1 if mapping of the given color is unsuccessful
-// returns an omx color enum value otherwise
-static int translateColorToOmxEnumValue(int color) {
- switch (color) {
- case kYUV420SP:
- return OMX_COLOR_FormatYUV420SemiPlanar;
- case kYUV420P:
- return OMX_COLOR_FormatYUV420Planar;
- default:
- 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) {
-
- // Default values for the program if not overwritten
- int frameRateFps = 30;
- int width = 176;
- int height = 144;
- int bitRateBps = 300000;
- int iFramesIntervalSeconds = 1;
- int colorFormat = OMX_COLOR_FormatYUV420Planar;
- int nFrames = 300;
- int level = -1; // Encoder specific default
- int profile = -1; // Encoder specific default
- int codec = 0;
- const char *fileName = "/sdcard/output.mp4";
-
- android::ProcessState::self()->startThreadPool();
- int res;
- while ((res = getopt(argc, argv, "b:c:f:i:n:w:t:l:p:v:h")) >= 0) {
- switch (res) {
- case 'b':
- {
- bitRateBps = atoi(optarg);
- break;
- }
-
- case 'c':
- {
- colorFormat = translateColorToOmxEnumValue(atoi(optarg));
- if (colorFormat == -1) {
- usage(argv[0]);
- }
- break;
- }
-
- case 'f':
- {
- frameRateFps = atoi(optarg);
- break;
- }
-
- case 'i':
- {
- iFramesIntervalSeconds = atoi(optarg);
- break;
- }
-
- case 'n':
- {
- nFrames = atoi(optarg);
- break;
- }
-
- case 'w':
- {
- width = atoi(optarg);
- break;
- }
-
- case 't':
- {
- height = atoi(optarg);
- break;
- }
-
- case 'l':
- {
- level = atoi(optarg);
- break;
- }
-
- case 'p':
- {
- profile = atoi(optarg);
- break;
- }
-
- case 'v':
- {
- codec = atoi(optarg);
- if (codec < 0 || codec > 2) {
- usage(argv[0]);
- }
- break;
- }
-
- case 'h':
- default:
- {
- usage(argv[0]);
- break;
- }
- }
- }
-
- OMXClient client;
- CHECK_EQ(client.connect(), OK);
-
- status_t err = OK;
- sp<MediaSource> source =
- new DummySource(width, height, nFrames, frameRateFps, colorFormat);
-
- sp<MetaData> enc_meta = new MetaData;
- switch (codec) {
- case 1:
- enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
- break;
- case 2:
- enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
- break;
- default:
- enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
- break;
- }
- enc_meta->setInt32(kKeyWidth, width);
- enc_meta->setInt32(kKeyHeight, height);
- enc_meta->setInt32(kKeyFrameRate, frameRateFps);
- enc_meta->setInt32(kKeyBitRate, bitRateBps);
- enc_meta->setInt32(kKeyStride, width);
- enc_meta->setInt32(kKeySliceHeight, height);
- enc_meta->setInt32(kKeyIFramesInterval, iFramesIntervalSeconds);
- enc_meta->setInt32(kKeyColorFormat, colorFormat);
- if (level != -1) {
- enc_meta->setInt32(kKeyVideoLevel, level);
- }
- if (profile != -1) {
- enc_meta->setInt32(kKeyVideoProfile, profile);
- }
-
- sp<MediaSource> encoder =
- OMXCodec::Create(
- client.interface(), enc_meta, true /* createEncoder */, source);
-
- sp<MPEG4Writer> writer = new MPEG4Writer(fileName);
- writer->addSource(encoder);
- int64_t start = systemTime();
- CHECK_EQ(OK, writer->start());
- while (!writer->reachedEOS()) {
- }
- err = writer->stop();
- int64_t end = systemTime();
-
- fprintf(stderr, "$\n");
- client.disconnect();
-
- if (err != OK && err != ERROR_END_OF_STREAM) {
- fprintf(stderr, "record failed: %d\n", err);
- return 1;
- }
- fprintf(stderr, "encoding %d frames in %lld us\n", nFrames, (end-start)/1000);
- fprintf(stderr, "encoding speed is: %.2f fps\n", (nFrames * 1E9) / (end-start));
- return 0;
-}
diff --git a/cmds/stagefright/sf2.cpp b/cmds/stagefright/sf2.cpp
deleted file mode 100644
index ae80f8804992..000000000000
--- a/cmds/stagefright/sf2.cpp
+++ /dev/null
@@ -1,646 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <binder/ProcessState.h>
-
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/foundation/AMessage.h>
-
-#include <media/stagefright/ACodec.h>
-#include <media/stagefright/DataSource.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaDefs.h>
-#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>
-#include <surfaceflinger/SurfaceComposerClient.h>
-
-#include "include/ESDS.h"
-
-using namespace android;
-
-struct Controller : public AHandler {
- Controller(const char *uri, bool decodeAudio,
- const sp<Surface> &surface, bool renderToSurface)
- : mURI(uri),
- mDecodeAudio(decodeAudio),
- mSurface(surface),
- mRenderToSurface(renderToSurface),
- mCodec(new ACodec),
- mIsVorbis(false) {
- CHECK(!mDecodeAudio || mSurface == NULL);
- }
-
- void startAsync() {
- (new AMessage(kWhatStart, id()))->post();
- }
-
-protected:
- virtual ~Controller() {
- }
-
- virtual void onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatStart:
- {
-#if 1
- mDecodeLooper = looper();
-#else
- mDecodeLooper = new ALooper;
- mDecodeLooper->setName("sf2 decode looper");
- mDecodeLooper->start();
-#endif
-
- sp<DataSource> dataSource =
- DataSource::CreateFromURI(mURI.c_str());
-
- sp<MediaExtractor> extractor =
- MediaExtractor::Create(dataSource);
-
- for (size_t i = 0; i < extractor->countTracks(); ++i) {
- sp<MetaData> meta = extractor->getTrackMetaData(i);
-
- const char *mime;
- CHECK(meta->findCString(kKeyMIMEType, &mime));
-
- if (!strncasecmp(mDecodeAudio ? "audio/" : "video/",
- mime, 6)) {
- mSource = extractor->getTrack(i);
-
- if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
- mIsVorbis = true;
- } else {
- mIsVorbis = false;
- }
- break;
- }
- }
- CHECK(mSource != NULL);
-
- CHECK_EQ(mSource->start(), (status_t)OK);
-
- mDecodeLooper->registerHandler(mCodec);
-
- mCodec->setNotificationMessage(
- new AMessage(kWhatCodecNotify, id()));
-
- sp<AMessage> format = makeFormat(mSource->getFormat());
-
- if (mSurface != NULL) {
- format->setObject(
- "native-window", new NativeWindowWrapper(mSurface));
- }
-
- mCodec->initiateSetup(format);
-
- mCSDIndex = 0;
- mStartTimeUs = ALooper::GetNowUs();
- mNumOutputBuffersReceived = 0;
- mTotalBytesReceived = 0;
- mLeftOverBuffer = NULL;
- mFinalResult = OK;
- mSeekState = SEEK_NONE;
-
- // (new AMessage(kWhatSeek, id()))->post(5000000ll);
- break;
- }
-
- case kWhatSeek:
- {
- printf("+");
- fflush(stdout);
-
- CHECK(mSeekState == SEEK_NONE
- || mSeekState == SEEK_FLUSH_COMPLETED);
-
- if (mLeftOverBuffer != NULL) {
- mLeftOverBuffer->release();
- mLeftOverBuffer = NULL;
- }
-
- mSeekState = SEEK_FLUSHING;
- mSeekTimeUs = 30000000ll;
-
- mCodec->signalFlush();
- break;
- }
-
- case kWhatStop:
- {
- if (mLeftOverBuffer != NULL) {
- mLeftOverBuffer->release();
- mLeftOverBuffer = NULL;
- }
-
- CHECK_EQ(mSource->stop(), (status_t)OK);
- mSource.clear();
-
- mCodec->initiateShutdown();
- break;
- }
-
- case kWhatCodecNotify:
- {
- int32_t what;
- CHECK(msg->findInt32("what", &what));
-
- if (what == ACodec::kWhatFillThisBuffer) {
- onFillThisBuffer(msg);
- } else if (what == ACodec::kWhatDrainThisBuffer) {
- if ((mNumOutputBuffersReceived++ % 16) == 0) {
- printf(".");
- fflush(stdout);
- }
-
- onDrainThisBuffer(msg);
- } else if (what == ACodec::kWhatEOS) {
- printf("$\n");
-
- int64_t delayUs = ALooper::GetNowUs() - mStartTimeUs;
-
- if (mDecodeAudio) {
- printf("%lld bytes received. %.2f KB/sec\n",
- mTotalBytesReceived,
- mTotalBytesReceived * 1E6 / 1024 / delayUs);
- } else {
- printf("%d frames decoded, %.2f fps. %lld bytes "
- "received. %.2f KB/sec\n",
- mNumOutputBuffersReceived,
- mNumOutputBuffersReceived * 1E6 / delayUs,
- mTotalBytesReceived,
- mTotalBytesReceived * 1E6 / 1024 / delayUs);
- }
-
- (new AMessage(kWhatStop, id()))->post();
- } else if (what == ACodec::kWhatFlushCompleted) {
- mSeekState = SEEK_FLUSH_COMPLETED;
- mCodec->signalResume();
-
- (new AMessage(kWhatSeek, id()))->post(5000000ll);
- } else if (what == ACodec::kWhatOutputFormatChanged) {
- } else {
- CHECK_EQ(what, (int32_t)ACodec::kWhatShutdownCompleted);
-
- mDecodeLooper->unregisterHandler(mCodec->id());
-
- if (mDecodeLooper != looper()) {
- mDecodeLooper->stop();
- }
-
- looper()->stop();
- }
- break;
- }
-
- default:
- TRESPASS();
- break;
- }
- }
-
-private:
- enum {
- kWhatStart = 'strt',
- kWhatStop = 'stop',
- kWhatCodecNotify = 'noti',
- kWhatSeek = 'seek',
- };
-
- sp<ALooper> mDecodeLooper;
-
- AString mURI;
- bool mDecodeAudio;
- sp<Surface> mSurface;
- bool mRenderToSurface;
- sp<ACodec> mCodec;
- sp<MediaSource> mSource;
- bool mIsVorbis;
-
- Vector<sp<ABuffer> > mCSD;
- size_t mCSDIndex;
-
- MediaBuffer *mLeftOverBuffer;
- status_t mFinalResult;
-
- int64_t mStartTimeUs;
- int32_t mNumOutputBuffersReceived;
- int64_t mTotalBytesReceived;
-
- enum SeekState {
- SEEK_NONE,
- SEEK_FLUSHING,
- SEEK_FLUSH_COMPLETED,
- };
- SeekState mSeekState;
- int64_t mSeekTimeUs;
-
- sp<AMessage> makeFormat(const sp<MetaData> &meta) {
- CHECK(mCSD.isEmpty());
-
- const char *mime;
- CHECK(meta->findCString(kKeyMIMEType, &mime));
-
- sp<AMessage> msg = new AMessage;
- msg->setString("mime", mime);
-
- if (!strncasecmp("video/", mime, 6)) {
- int32_t width, height;
- CHECK(meta->findInt32(kKeyWidth, &width));
- CHECK(meta->findInt32(kKeyHeight, &height));
-
- msg->setInt32("width", width);
- msg->setInt32("height", height);
- } else {
- CHECK(!strncasecmp("audio/", mime, 6));
-
- int32_t numChannels, sampleRate;
- CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
- CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
-
- msg->setInt32("channel-count", numChannels);
- msg->setInt32("sample-rate", sampleRate);
- }
-
- uint32_t type;
- const void *data;
- size_t size;
- if (meta->findData(kKeyAVCC, &type, &data, &size)) {
- // Parse the AVCDecoderConfigurationRecord
-
- const uint8_t *ptr = (const uint8_t *)data;
-
- CHECK(size >= 7);
- CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1
- uint8_t profile = ptr[1];
- uint8_t level = ptr[3];
-
- // There is decodable content out there that fails the following
- // assertion, let's be lenient for now...
- // CHECK((ptr[4] >> 2) == 0x3f); // reserved
-
- size_t lengthSize = 1 + (ptr[4] & 3);
-
- // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
- // violates it...
- // CHECK((ptr[5] >> 5) == 7); // reserved
-
- size_t numSeqParameterSets = ptr[5] & 31;
-
- ptr += 6;
- size -= 6;
-
- sp<ABuffer> buffer = new ABuffer(1024);
- buffer->setRange(0, 0);
-
- for (size_t i = 0; i < numSeqParameterSets; ++i) {
- CHECK(size >= 2);
- size_t length = U16_AT(ptr);
-
- ptr += 2;
- size -= 2;
-
- CHECK(size >= length);
-
- memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
- memcpy(buffer->data() + buffer->size() + 4, ptr, length);
- buffer->setRange(0, buffer->size() + 4 + length);
-
- ptr += length;
- size -= length;
- }
-
- buffer->meta()->setInt32("csd", true);
- mCSD.push(buffer);
-
- buffer = new ABuffer(1024);
- buffer->setRange(0, 0);
-
- CHECK(size >= 1);
- size_t numPictureParameterSets = *ptr;
- ++ptr;
- --size;
-
- for (size_t i = 0; i < numPictureParameterSets; ++i) {
- CHECK(size >= 2);
- size_t length = U16_AT(ptr);
-
- ptr += 2;
- size -= 2;
-
- CHECK(size >= length);
-
- memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
- memcpy(buffer->data() + buffer->size() + 4, ptr, length);
- buffer->setRange(0, buffer->size() + 4 + length);
-
- ptr += length;
- size -= length;
- }
-
- buffer->meta()->setInt32("csd", true);
- mCSD.push(buffer);
-
- msg->setObject("csd", buffer);
- } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
- ESDS esds((const char *)data, size);
- CHECK_EQ(esds.InitCheck(), (status_t)OK);
-
- const void *codec_specific_data;
- size_t codec_specific_data_size;
- esds.getCodecSpecificInfo(
- &codec_specific_data, &codec_specific_data_size);
-
- sp<ABuffer> buffer = new ABuffer(codec_specific_data_size);
-
- memcpy(buffer->data(), codec_specific_data,
- codec_specific_data_size);
-
- buffer->meta()->setInt32("csd", true);
- mCSD.push(buffer);
- } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
- sp<ABuffer> buffer = new ABuffer(size);
- memcpy(buffer->data(), data, size);
-
- buffer->meta()->setInt32("csd", true);
- mCSD.push(buffer);
-
- CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size));
-
- buffer = new ABuffer(size);
- memcpy(buffer->data(), data, size);
-
- buffer->meta()->setInt32("csd", true);
- mCSD.push(buffer);
- }
-
- int32_t maxInputSize;
- if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
- msg->setInt32("max-input-size", maxInputSize);
- }
-
- return msg;
- }
-
- void onFillThisBuffer(const sp<AMessage> &msg) {
- sp<AMessage> reply;
- CHECK(msg->findMessage("reply", &reply));
-
- if (mSeekState == SEEK_FLUSHING) {
- reply->post();
- return;
- }
-
- sp<RefBase> obj;
- CHECK(msg->findObject("buffer", &obj));
- sp<ABuffer> outBuffer = static_cast<ABuffer *>(obj.get());
-
- if (mCSDIndex < mCSD.size()) {
- outBuffer = mCSD.editItemAt(mCSDIndex++);
- outBuffer->meta()->setInt64("timeUs", 0);
- } else {
- size_t sizeLeft = outBuffer->capacity();
- outBuffer->setRange(0, 0);
-
- int32_t n = 0;
-
- for (;;) {
- MediaBuffer *inBuffer;
-
- if (mLeftOverBuffer != NULL) {
- inBuffer = mLeftOverBuffer;
- mLeftOverBuffer = NULL;
- } else if (mFinalResult != OK) {
- break;
- } else {
- MediaSource::ReadOptions options;
- if (mSeekState == SEEK_FLUSH_COMPLETED) {
- options.setSeekTo(mSeekTimeUs);
- mSeekState = SEEK_NONE;
- }
- status_t err = mSource->read(&inBuffer, &options);
-
- if (err != OK) {
- mFinalResult = err;
- break;
- }
- }
-
- size_t sizeNeeded = inBuffer->range_length();
- if (mIsVorbis) {
- // Vorbis data is suffixed with the number of
- // valid samples on the page.
- sizeNeeded += sizeof(int32_t);
- }
-
- if (sizeNeeded > sizeLeft) {
- if (outBuffer->size() == 0) {
- ALOGE("Unable to fit even a single input buffer of size %d.",
- sizeNeeded);
- }
- CHECK_GT(outBuffer->size(), 0u);
-
- mLeftOverBuffer = inBuffer;
- break;
- }
-
- ++n;
-
- if (outBuffer->size() == 0) {
- int64_t timeUs;
- CHECK(inBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
-
- outBuffer->meta()->setInt64("timeUs", timeUs);
- }
-
- memcpy(outBuffer->data() + outBuffer->size(),
- (const uint8_t *)inBuffer->data()
- + inBuffer->range_offset(),
- inBuffer->range_length());
-
- if (mIsVorbis) {
- int32_t numPageSamples;
- if (!inBuffer->meta_data()->findInt32(
- kKeyValidSamples, &numPageSamples)) {
- numPageSamples = -1;
- }
-
- memcpy(outBuffer->data()
- + outBuffer->size() + inBuffer->range_length(),
- &numPageSamples, sizeof(numPageSamples));
- }
-
- outBuffer->setRange(
- 0, outBuffer->size() + sizeNeeded);
-
- sizeLeft -= sizeNeeded;
-
- inBuffer->release();
- inBuffer = NULL;
-
- break; // Don't coalesce
- }
-
- ALOGV("coalesced %d input buffers", n);
-
- if (outBuffer->size() == 0) {
- CHECK_NE(mFinalResult, (status_t)OK);
-
- reply->setInt32("err", mFinalResult);
- reply->post();
- return;
- }
- }
-
- reply->setObject("buffer", outBuffer);
- reply->post();
- }
-
- void onDrainThisBuffer(const sp<AMessage> &msg) {
- sp<RefBase> obj;
- CHECK(msg->findObject("buffer", &obj));
-
- sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
- mTotalBytesReceived += buffer->size();
-
- sp<AMessage> reply;
- CHECK(msg->findMessage("reply", &reply));
-
- if (mRenderToSurface) {
- reply->setInt32("render", 1);
- }
-
- reply->post();
- }
-
- DISALLOW_EVIL_CONSTRUCTORS(Controller);
-};
-
-static void usage(const char *me) {
- fprintf(stderr, "usage: %s\n", me);
- fprintf(stderr, " -h(elp)\n");
- fprintf(stderr, " -a(udio)\n");
-
- fprintf(stderr,
- " -S(urface) Allocate output buffers on a surface.\n"
- " -R(ender) Render surface-allocated buffers.\n");
-}
-
-int main(int argc, char **argv) {
- android::ProcessState::self()->startThreadPool();
-
- bool decodeAudio = false;
- bool useSurface = false;
- bool renderToSurface = false;
-
- int res;
- while ((res = getopt(argc, argv, "haSR")) >= 0) {
- switch (res) {
- case 'a':
- decodeAudio = true;
- break;
-
- case 'S':
- useSurface = true;
- break;
-
- case 'R':
- renderToSurface = true;
- break;
-
- case '?':
- case 'h':
- default:
- {
- usage(argv[0]);
- return 1;
- }
- }
- }
-
- argc -= optind;
- argv += optind;
-
- if (argc != 1) {
- usage(argv[-optind]);
- return 1;
- }
-
- DataSource::RegisterDefaultSniffers();
-
- sp<ALooper> looper = new ALooper;
- looper->setName("sf2");
-
- sp<SurfaceComposerClient> composerClient;
- sp<SurfaceControl> control;
- sp<Surface> surface;
-
- if (!decodeAudio && useSurface) {
- 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(INT_MAX), (status_t)OK);
- CHECK_EQ(control->show(), (status_t)OK);
- SurfaceComposerClient::closeGlobalTransaction();
-
- surface = control->getSurface();
- CHECK(surface != NULL);
-
- CHECK_EQ((status_t)OK,
- native_window_api_connect(
- surface.get(), NATIVE_WINDOW_API_MEDIA));
- }
-
- sp<Controller> controller =
- new Controller(argv[0], decodeAudio, surface, renderToSurface);
-
- looper->registerHandler(controller);
-
- controller->startAsync();
-
- CHECK_EQ(looper->start(true /* runOnCallingThread */), (status_t)OK);
-
- looper->unregisterHandler(controller->id());
-
- if (!decodeAudio && useSurface) {
- CHECK_EQ((status_t)OK,
- native_window_api_disconnect(
- surface.get(), NATIVE_WINDOW_API_MEDIA));
-
- composerClient->dispose();
- }
-
- return 0;
-}
-
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
deleted file mode 100644
index 7cb8f62e62f3..000000000000
--- a/cmds/stagefright/stagefright.cpp
+++ /dev/null
@@ -1,1118 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "stagefright"
-#include <media/stagefright/foundation/ADebug.h>
-
-#include <sys/time.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "SineSource.h"
-
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
-#include <media/IMediaPlayerService.h>
-#include <media/stagefright/foundation/ALooper.h>
-#include "include/LiveSession.h"
-#include "include/NuCachedSource2.h"
-#include <media/stagefright/AudioPlayer.h>
-#include <media/stagefright/DataSource.h>
-#include <media/stagefright/JPEGSource.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MediaExtractor.h>
-#include <media/stagefright/MediaSource.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/OMXClient.h>
-#include <media/stagefright/OMXCodec.h>
-#include <media/mediametadataretriever.h>
-
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/MPEG2TSWriter.h>
-#include <media/stagefright/MPEG4Writer.h>
-
-#include <private/media/VideoFrame.h>
-#include <SkBitmap.h>
-#include <SkImageEncoder.h>
-
-#include <fcntl.h>
-
-#include <gui/SurfaceTextureClient.h>
-
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-
-using namespace android;
-
-static long gNumRepetitions;
-static long gMaxNumFrames; // 0 means decode all available.
-static long gReproduceBug; // if not -1.
-static bool gPreferSoftwareCodec;
-static bool gForceToUseHardwareCodec;
-static bool gPlaybackAudio;
-static bool gWriteMP4;
-static bool gDisplayHistogram;
-static String8 gWriteMP4Filename;
-
-static sp<ANativeWindow> gSurface;
-
-static int64_t getNowUs() {
- struct timeval tv;
- gettimeofday(&tv, NULL);
-
- return (int64_t)tv.tv_usec + tv.tv_sec * 1000000ll;
-}
-
-static int CompareIncreasing(const int64_t *a, const int64_t *b) {
- return (*a) < (*b) ? -1 : (*a) > (*b) ? 1 : 0;
-}
-
-static void displayDecodeHistogram(Vector<int64_t> *decodeTimesUs) {
- printf("decode times:\n");
-
- decodeTimesUs->sort(CompareIncreasing);
-
- size_t n = decodeTimesUs->size();
- int64_t minUs = decodeTimesUs->itemAt(0);
- int64_t maxUs = decodeTimesUs->itemAt(n - 1);
-
- printf("min decode time %lld us (%.2f secs)\n", minUs, minUs / 1E6);
- printf("max decode time %lld us (%.2f secs)\n", maxUs, maxUs / 1E6);
-
- size_t counts[100];
- for (size_t i = 0; i < 100; ++i) {
- counts[i] = 0;
- }
-
- for (size_t i = 0; i < n; ++i) {
- int64_t x = decodeTimesUs->itemAt(i);
-
- size_t slot = ((x - minUs) * 100) / (maxUs - minUs);
- if (slot == 100) { slot = 99; }
-
- ++counts[slot];
- }
-
- for (size_t i = 0; i < 100; ++i) {
- int64_t slotUs = minUs + (i * (maxUs - minUs) / 100);
-
- double fps = 1E6 / slotUs;
- printf("[%.2f fps]: %d\n", fps, counts[i]);
- }
-}
-
-static void displayAVCProfileLevelIfPossible(const sp<MetaData>& meta) {
- uint32_t type;
- const void *data;
- size_t size;
- if (meta->findData(kKeyAVCC, &type, &data, &size)) {
- const uint8_t *ptr = (const uint8_t *)data;
- CHECK(size >= 7);
- CHECK(ptr[0] == 1); // configurationVersion == 1
- uint8_t profile = ptr[1];
- uint8_t level = ptr[3];
- fprintf(stderr, "AVC video profile %d and level %d\n", profile, level);
- }
-}
-
-static void dumpSource(const sp<MediaSource> &source, const String8 &filename) {
- FILE *out = fopen(filename.string(), "wb");
-
- CHECK_EQ((status_t)OK, source->start());
-
- status_t err;
- for (;;) {
- MediaBuffer *mbuf;
- err = source->read(&mbuf);
-
- if (err == INFO_FORMAT_CHANGED) {
- continue;
- } else if (err != OK) {
- break;
- }
-
- CHECK_EQ(
- fwrite((const uint8_t *)mbuf->data() + mbuf->range_offset(),
- 1,
- mbuf->range_length(),
- out),
- (ssize_t)mbuf->range_length());
-
- mbuf->release();
- mbuf = NULL;
- }
-
- CHECK_EQ((status_t)OK, source->stop());
-
- fclose(out);
- out = NULL;
-}
-
-static void playSource(OMXClient *client, sp<MediaSource> &source) {
- sp<MetaData> meta = source->getFormat();
-
- const char *mime;
- CHECK(meta->findCString(kKeyMIMEType, &mime));
-
- sp<MediaSource> rawSource;
- if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mime)) {
- rawSource = source;
- } else {
- int flags = 0;
- if (gPreferSoftwareCodec) {
- flags |= OMXCodec::kPreferSoftwareCodecs;
- }
- if (gForceToUseHardwareCodec) {
- CHECK(!gPreferSoftwareCodec);
- flags |= OMXCodec::kHardwareCodecsOnly;
- }
- rawSource = OMXCodec::Create(
- client->interface(), meta, false /* createEncoder */, source,
- NULL /* matchComponentName */,
- flags,
- gSurface);
-
- if (rawSource == NULL) {
- fprintf(stderr, "Failed to instantiate decoder for '%s'.\n", mime);
- return;
- }
- displayAVCProfileLevelIfPossible(meta);
- }
-
- source.clear();
-
- status_t err = rawSource->start();
-
- if (err != OK) {
- fprintf(stderr, "rawSource returned error %d (0x%08x)\n", err, err);
- return;
- }
-
- if (gPlaybackAudio) {
- AudioPlayer *player = new AudioPlayer(NULL);
- player->setSource(rawSource);
- rawSource.clear();
-
- player->start(true /* sourceAlreadyStarted */);
-
- status_t finalStatus;
- while (!player->reachedEOS(&finalStatus)) {
- usleep(100000ll);
- }
-
- delete player;
- player = NULL;
-
- return;
- } else if (gReproduceBug >= 3 && gReproduceBug <= 5) {
- int64_t durationUs;
- CHECK(meta->findInt64(kKeyDuration, &durationUs));
-
- status_t err;
- MediaBuffer *buffer;
- MediaSource::ReadOptions options;
- int64_t seekTimeUs = -1;
- for (;;) {
- err = rawSource->read(&buffer, &options);
- options.clearSeekTo();
-
- bool shouldSeek = false;
- if (err == INFO_FORMAT_CHANGED) {
- CHECK(buffer == NULL);
-
- printf("format changed.\n");
- continue;
- } else if (err != OK) {
- printf("reached EOF.\n");
-
- shouldSeek = true;
- } else {
- int64_t timestampUs;
- CHECK(buffer->meta_data()->findInt64(kKeyTime, &timestampUs));
-
- bool failed = false;
-
- if (seekTimeUs >= 0) {
- int64_t diff = timestampUs - seekTimeUs;
-
- if (diff < 0) {
- diff = -diff;
- }
-
- if ((gReproduceBug == 4 && diff > 500000)
- || (gReproduceBug == 5 && timestampUs < 0)) {
- printf("wanted: %.2f secs, got: %.2f secs\n",
- seekTimeUs / 1E6, timestampUs / 1E6);
-
- printf("ERROR: ");
- failed = true;
- }
- }
-
- printf("buffer has timestamp %lld us (%.2f secs)\n",
- timestampUs, timestampUs / 1E6);
-
- buffer->release();
- buffer = NULL;
-
- if (failed) {
- break;
- }
-
- shouldSeek = ((double)rand() / RAND_MAX) < 0.1;
-
- if (gReproduceBug == 3) {
- shouldSeek = false;
- }
- }
-
- seekTimeUs = -1;
-
- if (shouldSeek) {
- seekTimeUs = (rand() * (float)durationUs) / RAND_MAX;
- options.setSeekTo(seekTimeUs);
-
- printf("seeking to %lld us (%.2f secs)\n",
- seekTimeUs, seekTimeUs / 1E6);
- }
- }
-
- rawSource->stop();
-
- return;
- }
-
- int n = 0;
- int64_t startTime = getNowUs();
-
- long numIterationsLeft = gNumRepetitions;
- MediaSource::ReadOptions options;
-
- int64_t sumDecodeUs = 0;
- int64_t totalBytes = 0;
-
- Vector<int64_t> decodeTimesUs;
-
- while (numIterationsLeft-- > 0) {
- long numFrames = 0;
-
- MediaBuffer *buffer;
-
- for (;;) {
- int64_t startDecodeUs = getNowUs();
- status_t err = rawSource->read(&buffer, &options);
- int64_t delayDecodeUs = getNowUs() - startDecodeUs;
-
- options.clearSeekTo();
-
- if (err != OK) {
- CHECK(buffer == NULL);
-
- if (err == INFO_FORMAT_CHANGED) {
- printf("format changed.\n");
- continue;
- }
-
- break;
- }
-
- if (buffer->range_length() > 0) {
- if (gDisplayHistogram && n > 0) {
- // Ignore the first time since it includes some setup
- // cost.
- decodeTimesUs.push(delayDecodeUs);
- }
-
- if ((n++ % 16) == 0) {
- printf(".");
- fflush(stdout);
- }
- }
-
- sumDecodeUs += delayDecodeUs;
- totalBytes += buffer->range_length();
-
- buffer->release();
- buffer = NULL;
-
- ++numFrames;
- if (gMaxNumFrames > 0 && numFrames == gMaxNumFrames) {
- break;
- }
-
- if (gReproduceBug == 1 && numFrames == 40) {
- printf("seeking past the end now.");
- options.setSeekTo(0x7fffffffL);
- } else if (gReproduceBug == 2 && numFrames == 40) {
- printf("seeking to 5 secs.");
- options.setSeekTo(5000000);
- }
- }
-
- printf("$");
- fflush(stdout);
-
- options.setSeekTo(0);
- }
-
- rawSource->stop();
- printf("\n");
-
- int64_t delay = getNowUs() - startTime;
- if (!strncasecmp("video/", mime, 6)) {
- printf("avg. %.2f fps\n", n * 1E6 / delay);
-
- printf("avg. time to decode one buffer %.2f usecs\n",
- (double)sumDecodeUs / n);
-
- printf("decoded a total of %d frame(s).\n", n);
-
- if (gDisplayHistogram) {
- displayDecodeHistogram(&decodeTimesUs);
- }
- } else if (!strncasecmp("audio/", mime, 6)) {
- // Frame count makes less sense for audio, as the output buffer
- // sizes may be different across decoders.
- printf("avg. %.2f KB/sec\n", totalBytes / 1024 * 1E6 / delay);
-
- printf("decoded a total of %lld bytes\n", totalBytes);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct DetectSyncSource : public MediaSource {
- DetectSyncSource(const sp<MediaSource> &source);
-
- virtual status_t start(MetaData *params = NULL);
- virtual status_t stop();
- virtual sp<MetaData> getFormat();
-
- virtual status_t read(
- MediaBuffer **buffer, const ReadOptions *options);
-
-private:
- enum StreamType {
- AVC,
- MPEG4,
- H263,
- OTHER,
- };
-
- sp<MediaSource> mSource;
- StreamType mStreamType;
- bool mSawFirstIDRFrame;
-
- DISALLOW_EVIL_CONSTRUCTORS(DetectSyncSource);
-};
-
-DetectSyncSource::DetectSyncSource(const sp<MediaSource> &source)
- : mSource(source),
- mStreamType(OTHER),
- mSawFirstIDRFrame(false) {
- const char *mime;
- CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime));
-
- if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
- mStreamType = AVC;
- } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)) {
- mStreamType = MPEG4;
- CHECK(!"sync frame detection not implemented yet for MPEG4");
- } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_H263)) {
- mStreamType = H263;
- CHECK(!"sync frame detection not implemented yet for H.263");
- }
-}
-
-status_t DetectSyncSource::start(MetaData *params) {
- mSawFirstIDRFrame = false;
-
- return mSource->start(params);
-}
-
-status_t DetectSyncSource::stop() {
- return mSource->stop();
-}
-
-sp<MetaData> DetectSyncSource::getFormat() {
- return mSource->getFormat();
-}
-
-static bool isIDRFrame(MediaBuffer *buffer) {
- const uint8_t *data =
- (const uint8_t *)buffer->data() + buffer->range_offset();
- size_t size = buffer->range_length();
- for (size_t i = 0; i + 3 < size; ++i) {
- if (!memcmp("\x00\x00\x01", &data[i], 3)) {
- uint8_t nalType = data[i + 3] & 0x1f;
- if (nalType == 5) {
- return true;
- }
- }
- }
-
- return false;
-}
-
-status_t DetectSyncSource::read(
- MediaBuffer **buffer, const ReadOptions *options) {
- for (;;) {
- status_t err = mSource->read(buffer, options);
-
- if (err != OK) {
- return err;
- }
-
- if (mStreamType == AVC) {
- bool isIDR = isIDRFrame(*buffer);
- (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame, isIDR);
- if (isIDR) {
- mSawFirstIDRFrame = true;
- }
- } else {
- (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame, true);
- }
-
- if (mStreamType != AVC || mSawFirstIDRFrame) {
- break;
- }
-
- // Ignore everything up to the first IDR frame.
- (*buffer)->release();
- *buffer = NULL;
- }
-
- return OK;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-static void writeSourcesToMP4(
- Vector<sp<MediaSource> > &sources, bool syncInfoPresent) {
-#if 0
- sp<MPEG4Writer> writer =
- new MPEG4Writer(gWriteMP4Filename.string());
-#else
- sp<MPEG2TSWriter> writer =
- new MPEG2TSWriter(gWriteMP4Filename.string());
-#endif
-
- // at most one minute.
- writer->setMaxFileDuration(60000000ll);
-
- for (size_t i = 0; i < sources.size(); ++i) {
- sp<MediaSource> source = sources.editItemAt(i);
-
- CHECK_EQ(writer->addSource(
- syncInfoPresent ? source : new DetectSyncSource(source)),
- (status_t)OK);
- }
-
- sp<MetaData> params = new MetaData;
- params->setInt32(kKeyNotRealTime, true);
- CHECK_EQ(writer->start(params.get()), (status_t)OK);
-
- while (!writer->reachedEOS()) {
- usleep(100000);
- }
- writer->stop();
-}
-
-static void performSeekTest(const sp<MediaSource> &source) {
- CHECK_EQ((status_t)OK, source->start());
-
- int64_t durationUs;
- CHECK(source->getFormat()->findInt64(kKeyDuration, &durationUs));
-
- for (int64_t seekTimeUs = 0; seekTimeUs <= durationUs;
- seekTimeUs += 60000ll) {
- MediaSource::ReadOptions options;
- options.setSeekTo(
- seekTimeUs, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
-
- MediaBuffer *buffer;
- status_t err;
- for (;;) {
- err = source->read(&buffer, &options);
-
- options.clearSeekTo();
-
- if (err == INFO_FORMAT_CHANGED) {
- CHECK(buffer == NULL);
- continue;
- }
-
- if (err != OK) {
- CHECK(buffer == NULL);
- break;
- }
-
- if (buffer->range_length() > 0) {
- break;
- }
-
- CHECK(buffer != NULL);
-
- buffer->release();
- buffer = NULL;
- }
-
- if (err == OK) {
- int64_t timeUs;
- CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
-
- printf("%lld\t%lld\t%lld\n", seekTimeUs, timeUs, seekTimeUs - timeUs);
-
- buffer->release();
- buffer = NULL;
- } else {
- printf("ERROR\n");
- break;
- }
- }
-
- CHECK_EQ((status_t)OK, source->stop());
-}
-
-static void usage(const char *me) {
- fprintf(stderr, "usage: %s\n", me);
- fprintf(stderr, " -h(elp)\n");
- fprintf(stderr, " -a(udio)\n");
- fprintf(stderr, " -n repetitions\n");
- fprintf(stderr, " -l(ist) components\n");
- fprintf(stderr, " -m max-number-of-frames-to-decode in each pass\n");
- fprintf(stderr, " -b bug to reproduce\n");
- fprintf(stderr, " -p(rofiles) dump decoder profiles supported\n");
- fprintf(stderr, " -t(humbnail) extract video thumbnail or album art\n");
- fprintf(stderr, " -s(oftware) prefer software codec\n");
- fprintf(stderr, " -r(hardware) force to use hardware codec\n");
- fprintf(stderr, " -o playback audio\n");
- fprintf(stderr, " -w(rite) filename (write to .mp4 file)\n");
- fprintf(stderr, " -k seek test\n");
- 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");
- fprintf(stderr, " -d(ump) filename (raw stream data to a file)\n");
-}
-
-int main(int argc, char **argv) {
- android::ProcessState::self()->startThreadPool();
-
- bool audioOnly = false;
- bool listComponents = false;
- bool dumpProfiles = false;
- bool extractThumbnail = false;
- bool seekTest = false;
- bool useSurfaceAlloc = false;
- bool useSurfaceTexAlloc = false;
- bool dumpStream = false;
- String8 dumpStreamFilename;
- gNumRepetitions = 1;
- gMaxNumFrames = 0;
- gReproduceBug = -1;
- gPreferSoftwareCodec = false;
- gForceToUseHardwareCodec = false;
- gPlaybackAudio = false;
- gWriteMP4 = false;
- gDisplayHistogram = false;
-
- sp<ALooper> looper;
- sp<LiveSession> liveSession;
-
- int res;
- while ((res = getopt(argc, argv, "han:lm:b:ptsrow:kxSTd:")) >= 0) {
- switch (res) {
- case 'a':
- {
- audioOnly = true;
- break;
- }
-
- case 'd':
- {
- dumpStream = true;
- dumpStreamFilename.setTo(optarg);
- break;
- }
-
- case 'l':
- {
- listComponents = true;
- break;
- }
-
- case 'm':
- case 'n':
- case 'b':
- {
- char *end;
- long x = strtol(optarg, &end, 10);
-
- if (*end != '\0' || end == optarg || x <= 0) {
- x = 1;
- }
-
- if (res == 'n') {
- gNumRepetitions = x;
- } else if (res == 'm') {
- gMaxNumFrames = x;
- } else {
- CHECK_EQ(res, 'b');
- gReproduceBug = x;
- }
- break;
- }
-
- case 'w':
- {
- gWriteMP4 = true;
- gWriteMP4Filename.setTo(optarg);
- break;
- }
-
- case 'p':
- {
- dumpProfiles = true;
- break;
- }
-
- case 't':
- {
- extractThumbnail = true;
- break;
- }
-
- case 's':
- {
- gPreferSoftwareCodec = true;
- break;
- }
-
- case 'r':
- {
- gForceToUseHardwareCodec = true;
- break;
- }
-
- case 'o':
- {
- gPlaybackAudio = true;
- break;
- }
-
- case 'k':
- {
- seekTest = true;
- break;
- }
-
- case 'x':
- {
- gDisplayHistogram = true;
- break;
- }
-
- case 'S':
- {
- useSurfaceAlloc = true;
- break;
- }
-
- case 'T':
- {
- useSurfaceTexAlloc = true;
- break;
- }
-
- case '?':
- case 'h':
- default:
- {
- usage(argv[0]);
- exit(1);
- break;
- }
- }
- }
-
- if (gPlaybackAudio && !audioOnly) {
- // This doesn't make any sense if we're decoding the video track.
- gPlaybackAudio = false;
- }
-
- argc -= optind;
- argv += optind;
-
- if (extractThumbnail) {
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->getService(String16("media.player"));
- sp<IMediaPlayerService> service =
- interface_cast<IMediaPlayerService>(binder);
-
- CHECK(service.get() != NULL);
-
- sp<IMediaMetadataRetriever> retriever =
- service->createMetadataRetriever(getpid());
-
- CHECK(retriever != NULL);
-
- for (int k = 0; k < argc; ++k) {
- const char *filename = argv[k];
-
- bool failed = true;
- CHECK_EQ(retriever->setDataSource(filename), (status_t)OK);
- sp<IMemory> mem =
- retriever->getFrameAtTime(-1,
- MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
-
- if (mem != NULL) {
- failed = false;
- printf("getFrameAtTime(%s) => OK\n", filename);
-
- VideoFrame *frame = (VideoFrame *)mem->pointer();
-
- SkBitmap bitmap;
- bitmap.setConfig(
- SkBitmap::kRGB_565_Config, frame->mWidth, frame->mHeight);
-
- bitmap.setPixels((uint8_t *)frame + sizeof(VideoFrame));
-
- CHECK(SkImageEncoder::EncodeFile(
- "/sdcard/out.jpg", bitmap,
- SkImageEncoder::kJPEG_Type,
- SkImageEncoder::kDefaultQuality));
- }
-
- {
- mem = retriever->extractAlbumArt();
-
- if (mem != NULL) {
- failed = false;
- printf("extractAlbumArt(%s) => OK\n", filename);
- }
- }
-
- if (failed) {
- printf("both getFrameAtTime and extractAlbumArt "
- "failed on file '%s'.\n", filename);
- }
- }
-
- return 0;
- }
-
- if (dumpProfiles) {
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->getService(String16("media.player"));
- sp<IMediaPlayerService> service =
- interface_cast<IMediaPlayerService>(binder);
-
- CHECK(service.get() != NULL);
-
- sp<IOMX> omx = service->getOMX();
- CHECK(omx.get() != NULL);
-
- const char *kMimeTypes[] = {
- MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_MPEG4,
- MEDIA_MIMETYPE_VIDEO_H263, MEDIA_MIMETYPE_AUDIO_AAC,
- MEDIA_MIMETYPE_AUDIO_AMR_NB, MEDIA_MIMETYPE_AUDIO_AMR_WB,
- MEDIA_MIMETYPE_AUDIO_MPEG, MEDIA_MIMETYPE_AUDIO_G711_MLAW,
- MEDIA_MIMETYPE_AUDIO_G711_ALAW, MEDIA_MIMETYPE_AUDIO_VORBIS,
- MEDIA_MIMETYPE_VIDEO_VPX
- };
-
- for (size_t k = 0; k < sizeof(kMimeTypes) / sizeof(kMimeTypes[0]);
- ++k) {
- printf("type '%s':\n", kMimeTypes[k]);
-
- Vector<CodecCapabilities> results;
- // will retrieve hardware and software codecs
- CHECK_EQ(QueryCodecs(omx, kMimeTypes[k],
- true, // queryDecoders
- &results), (status_t)OK);
-
- for (size_t i = 0; i < results.size(); ++i) {
- printf(" decoder '%s' supports ",
- results[i].mComponentName.string());
-
- if (results[i].mProfileLevels.size() == 0) {
- printf("NOTHING.\n");
- continue;
- }
-
- for (size_t j = 0; j < results[i].mProfileLevels.size(); ++j) {
- const CodecProfileLevel &profileLevel =
- results[i].mProfileLevels[j];
-
- printf("%s%ld/%ld", j > 0 ? ", " : "",
- profileLevel.mProfile, profileLevel.mLevel);
- }
-
- printf("\n");
- }
- }
- }
-
- if (listComponents) {
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->getService(String16("media.player"));
- sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
-
- CHECK(service.get() != NULL);
-
- sp<IOMX> omx = service->getOMX();
- CHECK(omx.get() != NULL);
-
- List<IOMX::ComponentInfo> list;
- omx->listNodes(&list);
-
- for (List<IOMX::ComponentInfo>::iterator it = list.begin();
- it != list.end(); ++it) {
- printf("%s\t Roles: ", (*it).mName.string());
- for (List<String8>::iterator itRoles = (*it).mRoles.begin() ;
- itRoles != (*it).mRoles.end() ; ++itRoles) {
- printf("%s\t", (*itRoles).string());
- }
- printf("\n");
- }
- }
-
- sp<SurfaceComposerClient> composerClient;
- sp<SurfaceControl> control;
-
- 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(INT_MAX), (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);
- }
-
- CHECK_EQ((status_t)OK,
- native_window_api_connect(
- gSurface.get(), NATIVE_WINDOW_API_MEDIA));
- }
-
- DataSource::RegisterDefaultSniffers();
-
- OMXClient client;
- status_t err = client.connect();
-
- for (int k = 0; k < argc; ++k) {
- bool syncInfoPresent = true;
-
- const char *filename = argv[k];
-
- sp<DataSource> dataSource = DataSource::CreateFromURI(filename);
-
- if (strncasecmp(filename, "sine:", 5)
- && strncasecmp(filename, "httplive://", 11)
- && dataSource == NULL) {
- fprintf(stderr, "Unable to create data source.\n");
- return 1;
- }
-
- bool isJPEG = false;
-
- size_t len = strlen(filename);
- if (len >= 4 && !strcasecmp(filename + len - 4, ".jpg")) {
- isJPEG = true;
- }
-
- Vector<sp<MediaSource> > mediaSources;
- sp<MediaSource> mediaSource;
-
- if (isJPEG) {
- mediaSource = new JPEGSource(dataSource);
- if (gWriteMP4) {
- mediaSources.push(mediaSource);
- }
- } else if (!strncasecmp("sine:", filename, 5)) {
- char *end;
- long sampleRate = strtol(filename + 5, &end, 10);
-
- if (end == filename + 5) {
- sampleRate = 44100;
- }
- mediaSource = new SineSource(sampleRate, 1);
- if (gWriteMP4) {
- mediaSources.push(mediaSource);
- }
- } else {
- sp<MediaExtractor> extractor;
-
- if (!strncasecmp("httplive://", filename, 11)) {
- String8 uri("http://");
- uri.append(filename + 11);
-
- if (looper == NULL) {
- looper = new ALooper;
- looper->start();
- }
- liveSession = new LiveSession;
- looper->registerHandler(liveSession);
-
- liveSession->connect(uri.string());
- dataSource = liveSession->getDataSource();
-
- extractor =
- MediaExtractor::Create(
- dataSource, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
-
- syncInfoPresent = false;
- } else {
- extractor = MediaExtractor::Create(dataSource);
-
- if (extractor == NULL) {
- fprintf(stderr, "could not create extractor.\n");
- return -1;
- }
-
- sp<MetaData> meta = extractor->getMetaData();
-
- if (meta != NULL) {
- const char *mime;
- CHECK(meta->findCString(kKeyMIMEType, &mime));
-
- if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
- syncInfoPresent = false;
- }
- }
- }
-
- size_t numTracks = extractor->countTracks();
-
- if (gWriteMP4) {
- bool haveAudio = false;
- bool haveVideo = false;
- for (size_t i = 0; i < numTracks; ++i) {
- sp<MediaSource> source = extractor->getTrack(i);
-
- const char *mime;
- CHECK(source->getFormat()->findCString(
- kKeyMIMEType, &mime));
-
- bool useTrack = false;
- if (!haveAudio && !strncasecmp("audio/", mime, 6)) {
- haveAudio = true;
- useTrack = true;
- } else if (!haveVideo && !strncasecmp("video/", mime, 6)) {
- haveVideo = true;
- useTrack = true;
- }
-
- if (useTrack) {
- mediaSources.push(source);
-
- if (haveAudio && haveVideo) {
- break;
- }
- }
- }
- } else {
- sp<MetaData> meta;
- size_t i;
- for (i = 0; i < numTracks; ++i) {
- meta = extractor->getTrackMetaData(
- i, MediaExtractor::kIncludeExtensiveMetaData);
-
- const char *mime;
- meta->findCString(kKeyMIMEType, &mime);
-
- if (audioOnly && !strncasecmp(mime, "audio/", 6)) {
- break;
- }
-
- if (!audioOnly && !strncasecmp(mime, "video/", 6)) {
- break;
- }
-
- meta = NULL;
- }
-
- if (meta == NULL) {
- fprintf(stderr,
- "No suitable %s track found. The '-a' option will "
- "target audio tracks only, the default is to target "
- "video tracks only.\n",
- audioOnly ? "audio" : "video");
- return -1;
- }
-
- int64_t thumbTimeUs;
- if (meta->findInt64(kKeyThumbnailTime, &thumbTimeUs)) {
- printf("thumbnailTime: %lld us (%.2f secs)\n",
- thumbTimeUs, thumbTimeUs / 1E6);
- }
-
- mediaSource = extractor->getTrack(i);
- }
- }
-
- if (gWriteMP4) {
- writeSourcesToMP4(mediaSources, syncInfoPresent);
- } else if (dumpStream) {
- dumpSource(mediaSource, dumpStreamFilename);
- } else if (seekTest) {
- performSeekTest(mediaSource);
- } else {
- playSource(&client, mediaSource);
- }
- }
-
- if ((useSurfaceAlloc || useSurfaceTexAlloc) && !audioOnly) {
- CHECK_EQ((status_t)OK,
- native_window_api_disconnect(
- gSurface.get(), NATIVE_WINDOW_API_MEDIA));
-
- gSurface.clear();
-
- if (useSurfaceAlloc) {
- composerClient->dispose();
- }
- }
-
- client.disconnect();
-
- return 0;
-}
diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp
deleted file mode 100644
index 0d6c738292da..000000000000
--- a/cmds/stagefright/stream.cpp
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "stream"
-#include "utils/Log.h"
-
-#include <binder/ProcessState.h>
-
-#include <media/IStreamSource.h>
-#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>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-
-#include <fcntl.h>
-
-using namespace android;
-
-struct MyStreamSource : public BnStreamSource {
- // Object assumes ownership of fd.
- MyStreamSource(int fd);
-
- virtual void setListener(const sp<IStreamListener> &listener);
- virtual void setBuffers(const Vector<sp<IMemory> > &buffers);
-
- virtual void onBufferAvailable(size_t index);
-
-protected:
- virtual ~MyStreamSource();
-
-private:
- int mFd;
- off64_t mFileSize;
- uint64_t mNumPacketsSent;
-
- sp<IStreamListener> mListener;
- Vector<sp<IMemory> > mBuffers;
-
- DISALLOW_EVIL_CONSTRUCTORS(MyStreamSource);
-};
-
-MyStreamSource::MyStreamSource(int fd)
- : mFd(fd),
- mFileSize(0),
- mNumPacketsSent(0) {
- CHECK_GE(fd, 0);
-
- mFileSize = lseek64(fd, 0, SEEK_END);
- lseek64(fd, 0, SEEK_SET);
-}
-
-MyStreamSource::~MyStreamSource() {
- close(mFd);
- mFd = -1;
-}
-
-void MyStreamSource::setListener(const sp<IStreamListener> &listener) {
- mListener = listener;
-}
-
-void MyStreamSource::setBuffers(const Vector<sp<IMemory> > &buffers) {
- mBuffers = buffers;
-}
-
-void MyStreamSource::onBufferAvailable(size_t index) {
- CHECK_LT(index, mBuffers.size());
-
-#if 0
- if (mNumPacketsSent >= 20000) {
- ALOGI("signalling discontinuity now");
-
- off64_t offset = 0;
- CHECK((offset % 188) == 0);
-
- lseek(mFd, offset, SEEK_SET);
-
- sp<AMessage> extra = new AMessage;
- extra->setInt32(IStreamListener::kKeyFormatChange, 0);
-
- mListener->issueCommand(
- IStreamListener::DISCONTINUITY, false /* synchronous */, extra);
-
- mNumPacketsSent = 0;
- }
-#endif
-
- sp<IMemory> mem = mBuffers.itemAt(index);
-
- ssize_t n = read(mFd, mem->pointer(), mem->size());
- if (n <= 0) {
- mListener->issueCommand(IStreamListener::EOS, false /* synchronous */);
- } else {
- mListener->queueBuffer(index, n);
-
- mNumPacketsSent += n / 188;
- }
-}
-////////////////////////////////////////////////////////////////////////////////
-
-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 */);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct MyClient : public BnMediaPlayerClient {
- MyClient()
- : mEOS(false) {
- }
-
- virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) {
- Mutex::Autolock autoLock(mLock);
-
- if (msg == MEDIA_ERROR || msg == MEDIA_PLAYBACK_COMPLETE) {
- mEOS = true;
- mCondition.signal();
- }
- }
-
- void waitForEOS() {
- Mutex::Autolock autoLock(mLock);
- while (!mEOS) {
- mCondition.wait(mLock);
- }
- }
-
-protected:
- virtual ~MyClient() {
- }
-
-private:
- Mutex mLock;
- Condition mCondition;
-
- bool mEOS;
-
- DISALLOW_EVIL_CONSTRUCTORS(MyClient);
-};
-
-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;
- }
-
- sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
- CHECK_EQ(composerClient->initCheck(), (status_t)OK);
-
- ssize_t displayWidth = composerClient->getDisplayWidth(0);
- ssize_t displayHeight = composerClient->getDisplayHeight(0);
-
- ALOGV("display is %d x %d\n", displayWidth, displayHeight);
-
- sp<SurfaceControl> control =
- composerClient->createSurface(
- String8("A Surface"),
- 0,
- displayWidth,
- displayHeight,
- PIXEL_FORMAT_RGB_565,
- 0);
-
- CHECK(control != NULL);
- CHECK(control->isValid());
-
- SurfaceComposerClient::openGlobalTransaction();
- CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK);
- CHECK_EQ(control->show(), (status_t)OK);
- SurfaceComposerClient::closeGlobalTransaction();
-
- sp<Surface> surface = control->getSurface();
- CHECK(surface != NULL);
-
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->getService(String16("media.player"));
- sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
-
- CHECK(service.get() != NULL);
-
- sp<MyClient> client = new MyClient;
-
- sp<IStreamSource> source;
-
- size_t len = strlen(argv[1]);
- if (len >= 3 && !strcasecmp(".ts", &argv[1][len - 3])) {
- int fd = open(argv[1], O_RDONLY);
-
- 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, 0);
-
- if (player != NULL && player->setDataSource(source) == NO_ERROR) {
- player->setVideoSurfaceTexture(surface->getSurfaceTexture());
- player->start();
-
- client->waitForEOS();
-
- player->stop();
- } else {
- fprintf(stderr, "failed to instantiate player.\n");
- }
-
- composerClient->dispose();
-
- return 0;
-}
diff --git a/cmds/surfaceflinger/Android.mk b/cmds/surfaceflinger/Android.mk
deleted file mode 100644
index 1df32bbc272d..000000000000
--- a/cmds/surfaceflinger/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- main_surfaceflinger.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libsurfaceflinger \
- libbinder \
- libutils
-
-LOCAL_C_INCLUDES := \
- $(LOCAL_PATH)/../../services/surfaceflinger
-
-LOCAL_MODULE:= surfaceflinger
-
-include $(BUILD_EXECUTABLE)
diff --git a/cmds/surfaceflinger/main_surfaceflinger.cpp b/cmds/surfaceflinger/main_surfaceflinger.cpp
deleted file mode 100644
index 78b1007f5e3c..000000000000
--- a/cmds/surfaceflinger/main_surfaceflinger.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <binder/BinderService.h>
-#include <SurfaceFlinger.h>
-
-using namespace android;
-
-int main(int argc, char** argv) {
- SurfaceFlinger::publishAndJoinThreadPool();
- return 0;
-}
diff --git a/cmds/system_server/library/Android.mk b/cmds/system_server/library/Android.mk
index e8afce39f5f1..9f92330aec84 100644
--- a/cmds/system_server/library/Android.mk
+++ b/cmds/system_server/library/Android.mk
@@ -5,22 +5,17 @@ LOCAL_SRC_FILES:= \
system_init.cpp
base = $(LOCAL_PATH)/../../..
+native = $(LOCAL_PATH)/../../../../native
LOCAL_C_INCLUDES := \
- $(base)/services/camera/libcameraservice \
- $(base)/services/audioflinger \
- $(base)/services/surfaceflinger \
$(base)/services/sensorservice \
- $(base)/media/libmediaplayerservice \
+ $(native)/services/surfaceflinger \
$(JNI_H_INCLUDE)
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \
libsensorservice \
libsurfaceflinger \
- libaudioflinger \
- libcameraservice \
- libmediaplayerservice \
libinput \
libutils \
libbinder \
diff --git a/cmds/system_server/library/system_init.cpp b/cmds/system_server/library/system_init.cpp
index bfbc13870717..745c34a0478c 100644
--- a/cmds/system_server/library/system_init.cpp
+++ b/cmds/system_server/library/system_init.cpp
@@ -15,10 +15,6 @@
#include <utils/Log.h>
#include <SurfaceFlinger.h>
-#include <AudioFlinger.h>
-#include <CameraService.h>
-#include <AudioPolicyService.h>
-#include <MediaPlayerService.h>
#include <SensorService.h>
#include <android_runtime/AndroidRuntime.h>