Added a daemon mode to aapt to receive streams of commands from gradle.

When crunching png, we used to spawn a separate aapt process from java
which is slow and resource intensive.
Introduced a daemon mode to appt which when invoked with -m parameter
will listen from commands on stdin and give report of command execution
on stdout.

One one command is supported so far :
s f1 f2

This command perform a single png crunch, f1 pointing to the input
png file to crunch, and f2 pointing to the path for the resulting
crunced file.

Expected output from the command is "Done" or "Error".

Change-Id: Iaf1d865e8d5ee5d36abe39dea6443715865a98d3
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 9bed899..cb34448 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -40,6 +40,7 @@
     kCommandPackage,
     kCommandCrunch,
     kCommandSingleCrunch,
+    kCommandDaemon
 } Command;
 
 /*
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 41d8502..1e9e3e2 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -23,6 +23,10 @@
 #include <errno.h>
 #include <fcntl.h>
 
+#include <iostream>
+#include <string>
+#include <sstream>
+
 using namespace android;
 
 #ifndef AAPT_VERSION
@@ -2506,6 +2510,37 @@
     return NO_ERROR;
 }
 
+int runInDaemonMode(Bundle* bundle) {
+    std::cout << "Ready" << std::endl;
+    for (std::string line; std::getline(std::cin, line);) {
+        if (line == "quit") {
+            return NO_ERROR;
+        }
+        std::stringstream ss;
+        ss << line;
+        std::string s;
+
+        std::string command, parameterOne, parameterTwo;
+        std::getline(ss, command, ' ');
+        std::getline(ss, parameterOne, ' ');
+        std::getline(ss, parameterTwo, ' ');
+        if (command[0] == 's') {
+            bundle->setSingleCrunchInputFile(parameterOne.c_str());
+            bundle->setSingleCrunchOutputFile(parameterTwo.c_str());
+            std::cout << "Crunching " << parameterOne << std::endl;
+            if (doSingleCrunch(bundle) != NO_ERROR) {
+                std::cout << "Error" << std::endl;
+            }
+            std::cout << "Done" << std::endl;
+        } else {
+            // in case of invalid command, just bail out.
+            std::cerr << "Unknown command" << std::endl;
+            return -1;
+        }
+    }
+    return -1;
+}
+
 char CONSOLE_DATA[2925] = {
     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
     32, 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32,
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index 736ae26..2857b59 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -234,6 +234,7 @@
     case kCommandPackage:      return doPackage(bundle);
     case kCommandCrunch:       return doCrunch(bundle);
     case kCommandSingleCrunch: return doSingleCrunch(bundle);
+    case kCommandDaemon:       return runInDaemonMode(bundle);
     default:
         fprintf(stderr, "%s: requested command not yet supported\n", gProgName);
         return 1;
@@ -275,6 +276,8 @@
         bundle.setCommand(kCommandCrunch);
     else if (argv[1][0] == 's')
         bundle.setCommand(kCommandSingleCrunch);
+    else if (argv[1][0] == 'm')
+        bundle.setCommand(kCommandDaemon);
     else {
         fprintf(stderr, "ERROR: Unknown command '%s'\n", argv[1]);
         wantUsage = true;
diff --git a/tools/aapt/Main.h b/tools/aapt/Main.h
index 089dde5..e84c4c5 100644
--- a/tools/aapt/Main.h
+++ b/tools/aapt/Main.h
@@ -36,6 +36,7 @@
 extern int doPackage(Bundle* bundle);
 extern int doCrunch(Bundle* bundle);
 extern int doSingleCrunch(Bundle* bundle);
+extern int runInDaemonMode(Bundle* bundle);
 
 extern int calcPercent(long uncompressedLen, long compressedLen);