Android: Display the benchmark results log in the GUI.
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index 322413b..70d99be 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -19,7 +19,6 @@
         </activity>
         <activity android:label="@string/title_activity_glmark2"
                   android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
-                  android:launchMode="singleTask"
                   android:screenOrientation="nosensor"
                   android:process=":glmark2"
                   android:name="org.linaro.glmark2.Glmark2Activity">
@@ -40,6 +39,12 @@
                 <action android:name="android.intent.action.MAIN" />
             </intent-filter>
         </activity>
+        <activity android:label="@string/title_activity_results"
+                  android:name="org.linaro.glmark2.ResultsActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+        </activity>
     </application>
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
diff --git a/android/res/drawable/menu_results.png b/android/res/drawable/menu_results.png
new file mode 100644
index 0000000..95a3217
--- /dev/null
+++ b/android/res/drawable/menu_results.png
Binary files differ
diff --git a/android/res/layout/activity_results.xml b/android/res/layout/activity_results.xml
new file mode 100644
index 0000000..46c8f66
--- /dev/null
+++ b/android/res/layout/activity_results.xml
@@ -0,0 +1,15 @@
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+
+    <HorizontalScrollView android:layout_width="match_parent"
+                          android:layout_height="wrap_content">
+
+        <TextView android:id="@+id/results"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:typeface="monospace" />
+
+    </HorizontalScrollView>
+
+</ScrollView>
diff --git a/android/res/menu/main_options_menu.xml b/android/res/menu/main_options_menu.xml
index ef4b056..e833173 100644
--- a/android/res/menu/main_options_menu.xml
+++ b/android/res/menu/main_options_menu.xml
@@ -16,6 +16,10 @@
           android:title="@string/settingsMainOptionsText"
           android:icon="@drawable/menu_settings" />
 
+    <item android:id="@+id/results"
+          android:title="@string/resultsMainOptionsText"
+          android:icon="@drawable/menu_results" />
+
     <item android:id="@+id/about"
           android:title="@string/aboutMainOptionsText"
           android:icon="@drawable/menu_about" />
diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml
index 04f0413..571541c 100644
--- a/android/res/values/strings.xml
+++ b/android/res/values/strings.xml
@@ -5,6 +5,7 @@
     <string name="title_activity_editor">GLMark2 Benchmark Editor</string>
     <string name="title_activity_preferences">GLMark2 Settings</string>
     <string name="title_activity_about">About GLMark2</string>
+    <string name="title_activity_results">GLMark2 Results</string>
     <string name="title_activity_glmark2">GLMark2</string>
     <string name="runButtonText">Run</string>
     <string name="saveButtonText">Save</string>
@@ -13,12 +14,17 @@
     <string name="loadMainOptionsText">Load list</string>
     <string name="deleteMainOptionsText">Delete list</string>
     <string name="settingsMainOptionsText">Settings</string>
+    <string name="resultsMainOptionsText">Last results</string>
     <string name="aboutMainOptionsText">About</string>
 
     <string name="externalSaveDialogText">Save to external storage</string>
 
     <string name="runForeverPreferenceTitle">Run forever</string>
     <string name="runForeverPreferenceSummary">Run indefinitely, looping from the last benchmark back to the first</string>
+    <string name="logDebugPreferenceTitle">Log debug messages</string>
+    <string name="logDebugPreferenceSummary">Display debug messages in the log</string>
+    <string name="showResultsPreferenceTitle">Show benchmark results</string>
+    <string name="showResultsPreferenceSummary">Show results after running benchmarks</string>
 
     <string name="about_name_version_format">GLMark2 %1$s</string>
     <string name="about_description">OpenGL (ES) 2.0 benchmark suite</string>
diff --git a/android/res/xml/preferences.xml b/android/res/xml/preferences.xml
index fe0f75f..be88f2a 100644
--- a/android/res/xml/preferences.xml
+++ b/android/res/xml/preferences.xml
@@ -4,4 +4,12 @@
                         android:title="@string/runForeverPreferenceTitle"
                         android:summary="@string/runForeverPreferenceSummary"
                         android:defaultValue="false" />
+    <CheckBoxPreference android:key="log_debug"
+                        android:title="@string/logDebugPreferenceTitle"
+                        android:summary="@string/logDebugPreferenceSummary"
+                        android:defaultValue="false" />
+    <CheckBoxPreference android:key="show_results"
+                        android:title="@string/showResultsPreferenceTitle"
+                        android:summary="@string/showResultsPreferenceSummary"
+                        android:defaultValue="true" />
 </PreferenceScreen>
diff --git a/android/src/org/linaro/glmark2/Glmark2Native.java b/android/src/org/linaro/glmark2/Glmark2Native.java
index 0f2fd26..c805385 100644
--- a/android/src/org/linaro/glmark2/Glmark2Native.java
+++ b/android/src/org/linaro/glmark2/Glmark2Native.java
@@ -24,7 +24,8 @@
 import android.content.res.AssetManager;
 
 class Glmark2Native {
-    public static native void init(AssetManager assetManager, String args);
+    public static native void init(AssetManager assetManager, String args,
+                                   String logFilePath);
     public static native void resize(int w, int h);
     public static native boolean render();
     public static native void done();
diff --git a/android/src/org/linaro/glmark2/Glmark2SurfaceView.java b/android/src/org/linaro/glmark2/Glmark2SurfaceView.java
index 1a64837..6cf65aa 100644
--- a/android/src/org/linaro/glmark2/Glmark2SurfaceView.java
+++ b/android/src/org/linaro/glmark2/Glmark2SurfaceView.java
@@ -1,5 +1,7 @@
 package org.linaro.glmark2;
 
+import java.io.File;
+
 import android.graphics.PixelFormat;
 import android.opengl.GLSurfaceView;
 import android.app.Activity;
@@ -203,7 +205,8 @@
 
     public void onSurfaceCreated(GL10 gl, EGLConfig config) {
         String args = mView.getActivity().getIntent().getStringExtra("args");
-        Glmark2Native.init(mView.getActivity().getAssets(), args);
+        File f = new File(mView.getActivity().getFilesDir(), "last_run.log");
+        Glmark2Native.init(mView.getActivity().getAssets(), args, f.getAbsolutePath());
     }
 
     private Glmark2SurfaceView mView;
diff --git a/android/src/org/linaro/glmark2/MainActivity.java b/android/src/org/linaro/glmark2/MainActivity.java
index 3de802b..36e3203 100644
--- a/android/src/org/linaro/glmark2/MainActivity.java
+++ b/android/src/org/linaro/glmark2/MainActivity.java
@@ -62,6 +62,9 @@
     public static final int DIALOG_LOAD_LIST_ID = 3;
     public static final int DIALOG_DELETE_LIST_ID = 4;
 
+    public static final int ACTIVITY_GLMARK2_REQUEST_CODE = 1;
+    public static final int ACTIVITY_EDITOR_REQUEST_CODE = 2;
+
     /**
      * The supported benchmark item actions.
      */
@@ -266,6 +269,10 @@
                 startActivity(new Intent(MainActivity.this, MainPreferencesActivity.class));
                 ret = true;
                 break;
+            case R.id.results:
+                startActivity(new Intent(MainActivity.this, ResultsActivity.class));
+                ret = true;
+                break;
             case R.id.about:
                 startActivity(new Intent(MainActivity.this, AboutActivity.class));
                 ret = true;
@@ -280,7 +287,14 @@
 
     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (resultCode == RESULT_OK) {
+        if (requestCode == ACTIVITY_GLMARK2_REQUEST_CODE)
+        {
+            startActivity(new Intent(this, ResultsActivity.class));
+            return;
+        }
+        else if (requestCode == ACTIVITY_EDITOR_REQUEST_CODE &&
+                 resultCode == RESULT_OK)
+        {
             String benchmarkText = data.getStringExtra("benchmark-text");
             int benchmarkPos = data.getIntExtra("benchmark-pos", 0);
             doBenchmarkItemAction(benchmarkPos, BenchmarkItemAction.EDIT, benchmarkText);
@@ -312,9 +326,15 @@
                     args += "-b " + benchmarks.get(i) + " ";
                 if (prefs.getBoolean("run_forever", false))
                     args += "--run-forever ";
+                if (prefs.getBoolean("log_debug", false))
+                    args += "--debug ";
                 if (!args.isEmpty())
                     intent.putExtra("args", args);
-                startActivity(intent);
+                
+                if (prefs.getBoolean("show_results", true))
+                    startActivityForResult(intent, ACTIVITY_GLMARK2_REQUEST_CODE);
+                else
+                    startActivity(intent);
             }
         });
 
@@ -332,7 +352,7 @@
                 intent.putExtra("benchmark-text", t);
                 intent.putExtra("benchmark-pos", position);
                 intent.putExtra("scene-info", sceneInfoList);
-                startActivityForResult(intent, 1);
+                startActivityForResult(intent, ACTIVITY_EDITOR_REQUEST_CODE);
             }
         });
 
diff --git a/android/src/org/linaro/glmark2/ResultsActivity.java b/android/src/org/linaro/glmark2/ResultsActivity.java
new file mode 100644
index 0000000..d0e8756
--- /dev/null
+++ b/android/src/org/linaro/glmark2/ResultsActivity.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *  Alexandros Frantzis
+ */
+package org.linaro.glmark2;
+
+import java.io.*;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+public class ResultsActivity extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.activity_results);
+        TextView tv = (TextView) findViewById(R.id.results);
+
+        File f = new File(getFilesDir(), "last_run.log");
+
+        try {
+            /* Read log from file */
+            BufferedReader reader = new BufferedReader(new FileReader(f));
+            String line = null;
+            StringBuffer sb = new StringBuffer();
+
+            while ((line = reader.readLine()) != null) {
+                sb.append(line);
+                sb.append('\n');
+            }
+
+            reader.close();
+            tv.setText(sb.toString());
+        }
+        catch (Exception ex) {
+        }
+    }
+}
+
diff --git a/src/android.cpp b/src/android.cpp
index 99a38c1..d7e0830 100644
--- a/src/android.cpp
+++ b/src/android.cpp
@@ -37,6 +37,7 @@
 static Canvas *g_canvas;
 static MainLoop *g_loop;
 static BenchmarkCollection *g_benchmark_collection;
+static std::ostream *g_log_extra;
 
 class MainLoopAndroid : public MainLoop
 {
@@ -258,7 +259,8 @@
 void
 Java_org_linaro_glmark2_native_init(JNIEnv* env, jclass clazz,
                                     jobject asset_manager,
-                                    jstring args)
+                                    jstring args,
+                                    jstring log_file)
 {
     static_cast<void>(clazz);
     static const std::string arguments_file("/data/glmark2/args");
@@ -282,10 +284,17 @@
     Options::parse_args(argc, argv);
     release_args(argc, argv);
 
+    /* Get the log file path and open the log file */
+    const char *log_file_c_str = env->GetStringUTFChars(log_file, 0);
+    if (log_file_c_str) {
+        g_log_extra = new std::ofstream(log_file_c_str, std::ios::binary);
+        env->ReleaseStringUTFChars(log_file, log_file_c_str);
+    }
+
     /* Force reuse of EGL/GL context */
     Options::reuse_context = true;
 
-    Log::init("glmark2", Options::show_debug);
+    Log::init("glmark2", Options::show_debug, g_log_extra);
     Util::android_set_asset_manager(AAssetManager_fromJava(env, asset_manager));
 
     g_canvas = new CanvasAndroid(100, 100);
@@ -340,6 +349,7 @@
     delete g_loop;
     delete g_benchmark_collection;
     delete g_canvas;
+    delete g_log_extra;
 }
 
 jboolean
@@ -409,7 +419,7 @@
 static JNINativeMethod glmark2_native_methods[] = {
     {
         "init",
-        "(Landroid/content/res/AssetManager;Ljava/lang/String;)V",
+        "(Landroid/content/res/AssetManager;Ljava/lang/String;Ljava/lang/String;)V",
         reinterpret_cast<void*>(Java_org_linaro_glmark2_native_init)
     },
     {
diff --git a/src/libmatrix/log.cc b/src/libmatrix/log.cc
index 25c9734..10603ae 100644
--- a/src/libmatrix/log.cc
+++ b/src/libmatrix/log.cc
@@ -10,6 +10,7 @@
 //     Alexandros Frantzis <alexandros.frantzis@linaro.org>
 //     Jesse Barker <jesse.barker@linaro.org>
 //
+#include <unistd.h>
 #include <cstdio>
 #include <cstdarg>
 #include <string>
@@ -26,8 +27,7 @@
 const string Log::continuation_prefix("\x10");
 string Log::appname_;
 bool Log::do_debug_(false);
-
-#ifndef ANDROID
+std::ostream* Log::extra_out_(0);
 
 static const string terminal_color_normal("\033[0m");
 static const string terminal_color_red("\033[1;31m");
@@ -96,17 +96,26 @@
     delete[] buf;
 }
 
+
 void
 Log::info(const char *fmt, ...)
 {
     static const string infoprefix("Info");
-    static const string& infocolor(isatty(fileno(stdout)) ? terminal_color_cyan : empty);
+    const string& prefix(do_debug_ ? infoprefix : empty);
     va_list ap;
     va_start(ap, fmt);
-    if (do_debug_)
-        print_prefixed_message(std::cout, infocolor, infoprefix, fmt, ap);
-    else
-        print_prefixed_message(std::cout, empty, empty, fmt, ap);
+
+#ifndef ANDROID
+    static const string& infocolor(isatty(fileno(stdout)) ? terminal_color_cyan : empty);
+    const string& color(do_debug_ ? infocolor : empty);
+    print_prefixed_message(std::cout, color, prefix, fmt, ap);
+#else
+    __android_log_vprint(ANDROID_LOG_INFO, appname_.c_str(), fmt, ap);
+#endif
+
+    if (extra_out_)
+        print_prefixed_message(*extra_out_, empty, prefix, fmt, ap);
+
     va_end(ap);
 }
 
@@ -114,12 +123,21 @@
 Log::debug(const char *fmt, ...)
 {
     static const string dbgprefix("Debug");
-    static const string& dbgcolor(isatty(fileno(stdout)) ? terminal_color_yellow : empty);
     if (!do_debug_)
         return;
     va_list ap;
     va_start(ap, fmt);
+
+#ifndef ANDROID
+    static const string& dbgcolor(isatty(fileno(stdout)) ? terminal_color_yellow : empty);
     print_prefixed_message(std::cout, dbgcolor, dbgprefix, fmt, ap);
+#else
+    __android_log_vprint(ANDROID_LOG_DEBUG, appname_.c_str(), fmt, ap);
+#endif
+
+    if (extra_out_)
+        print_prefixed_message(*extra_out_, empty, dbgprefix, fmt, ap);
+
     va_end(ap);
 }
 
@@ -127,52 +145,29 @@
 Log::error(const char *fmt, ...)
 {
     static const string errprefix("Error");
-    static const string& errcolor(isatty(fileno(stderr)) ? terminal_color_red : empty);
     va_list ap;
     va_start(ap, fmt);
+
+#ifndef ANDROID
+    static const string& errcolor(isatty(fileno(stderr)) ? terminal_color_red : empty);
     print_prefixed_message(std::cerr, errcolor, errprefix, fmt, ap);
+#else
+    __android_log_vprint(ANDROID_LOG_ERROR, appname_.c_str(), fmt, ap);
+#endif
+
+    if (extra_out_)
+        print_prefixed_message(*extra_out_, empty, errprefix, fmt, ap);
+
     va_end(ap);
 }
 
 void
 Log::flush()
 {
+#ifndef ANDROID
     std::cout.flush();
     std::cerr.flush();
-}
-#else
-void
-Log::info(const char *fmt, ...)
-{
-    va_list ap;
-    va_start(ap, fmt);
-    __android_log_vprint(ANDROID_LOG_INFO, appname_.c_str(), fmt, ap);
-    va_end(ap);
-}
-
-void
-Log::debug(const char *fmt, ...)
-{
-    if (!do_debug_)
-        return;
-    va_list ap;
-    va_start(ap, fmt);
-    __android_log_vprint(ANDROID_LOG_DEBUG, appname_.c_str(), fmt, ap);
-    va_end(ap);
-}
-
-void
-Log::error(const char *fmt, ...)
-{
-    va_list ap;
-    va_start(ap, fmt);
-    __android_log_vprint(ANDROID_LOG_ERROR, appname_.c_str(), fmt, ap);
-    va_end(ap);
-}
-
-void
-Log::flush()
-{
-}
-
 #endif
+    if (extra_out_)
+        extra_out_->flush();
+}
diff --git a/src/libmatrix/log.h b/src/libmatrix/log.h
index 96a696a..9054323 100644
--- a/src/libmatrix/log.h
+++ b/src/libmatrix/log.h
@@ -14,14 +14,17 @@
 #define LOG_H_
 
 #include <string>
+#include <iostream>
 
 class Log
 {
 public:
-    static void init(const std::string& appname, bool do_debug = false)
+    static void init(const std::string& appname, bool do_debug = false,
+                     std::ostream *extra_out = 0)
     {
         appname_ = appname;
         do_debug_ = do_debug;
+        extra_out_ = extra_out;
     }
     // Emit an informational message
     static void info(const char *fmt, ...);
@@ -41,6 +44,8 @@
     static std::string appname_;
     // Indicates whether debug level messages should generate any output
     static bool do_debug_;
+    // Extra stream to output log messages to
+    static std::ostream *extra_out_;
 };
 
 #endif /* LOG_H_ */
diff --git a/wscript b/wscript
index ddbc992..cd24a42 100644
--- a/wscript
+++ b/wscript
@@ -36,7 +36,7 @@
     ctx.check_tool('compiler_cxx')
 
     # Check required headers
-    req_headers = ['stdlib.h', 'string.h', 'stdint.h', 'stdio.h', 'jpeglib.h']
+    req_headers = ['stdlib.h', 'string.h', 'unistd.h', 'stdint.h', 'stdio.h', 'jpeglib.h']
     for header in req_headers:
         ctx.check_cxx(header_name = header, auto_add_header_name = True, mandatory = True)