summaryrefslogtreecommitdiffstats
path: root/docs/html/ndk/samples
diff options
context:
space:
mode:
Diffstat (limited to 'docs/html/ndk/samples')
-rw-r--r--docs/html/ndk/samples/index.jd26
-rw-r--r--docs/html/ndk/samples/sample_hellojni.jd123
-rw-r--r--docs/html/ndk/samples/sample_na.jd259
-rw-r--r--docs/html/ndk/samples/sample_teapot.jd360
-rw-r--r--docs/html/ndk/samples/samples_toc.cs35
-rw-r--r--docs/html/ndk/samples/walkthroughs.jd13
6 files changed, 816 insertions, 0 deletions
diff --git a/docs/html/ndk/samples/index.jd b/docs/html/ndk/samples/index.jd
new file mode 100644
index 0000000..6b2cd16
--- /dev/null
+++ b/docs/html/ndk/samples/index.jd
@@ -0,0 +1,26 @@
+page.title=Samples: Overview
+@jd:body
+
+<p>Welcome to the NDK samples area. Here, you can download a variety of sample
+apps to help deepen your understanding the NDK.
+
+
+<p>From this page, you can download samples that provide a look at the NDK in action. A few of the
+topics covered are:</p>
+
+<ul>
+ <li>Managing your native app's activity lifecycle.</li>
+ <li>Using native OpenGL on an Android device.</li>
+ <li>Implementing native audio.</li>
+ <li>Exporting modules.</li>
+</ul>
+
+<p class="note"><strong>Note: </strong>These samples are also contained in the NDK installation
+package; if you have already downloaded the NDK, you have them. They reside in
+{@code $NDK/samples/}, where {@code $NDK} is the NDK installation root.</p>
+
+ <div id="sdk-terms-form">
+ <p><a href="{@docRoot}shareables/ndk/ndk-samples.zip" class="button">
+ Download ndk-samples.zip</a></p>
+ </div>
+
diff --git a/docs/html/ndk/samples/sample_hellojni.jd b/docs/html/ndk/samples/sample_hellojni.jd
new file mode 100644
index 0000000..fa61b28
--- /dev/null
+++ b/docs/html/ndk/samples/sample_hellojni.jd
@@ -0,0 +1,123 @@
+page.title=Sample: hello-jni
+@jd:body
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>On this page</h2>
+
+ <ol>
+ <li><a href="#an">Android.mk</a></li>
+ <li><a href="#ap">Application.mk</a></li>
+ <li><a href="#ji">Java-side Implementation</a></li>
+ <li><a href="#ci">C-side Implementation</a></li>
+ </ol>
+ </li>
+ </ol>
+ </div>
+ </div>
+
+<p>This sample guides you through HelloJNI, a minimal
+application built with the NDK. This sample is in the {@code samples/hello-jni/} directory
+under the root directory of your NDK installation.</p>
+
+<h2 id="an">Android.mk</h2>
+
+<p>The following two lines provide the name of the native source file, along
+with the name of the shared library to build. The full name of the built
+library is {@code libhello-jni.so}, once the build system adds the
+{@code lib} prefix and the {@code .so} extension.</p>
+
+<pre class="no-pretty-print">
+LOCAL_SRC_FILES := hello-jni.c
+LOCAL_MODULE := hello-jni
+</pre>
+
+<p>For more information about what the {@code Android.mk} file does, and how to use it, see
+<a href="{@docRoot}ndk/guides/android_mk.html">Android.mk</a>.</p>
+
+<h2 id="ap">Application.mk</h2>
+<p>This line tells the build system the CPU and architecture against which to build. In this
+example, the build system builds for all supported architectures.</p>
+
+<pre class="no-pretty-print">
+APP_ABI := all
+</pre>
+
+<p>For more information about the {@code Application.mk} file, and how to use it, see
+<a href="{@docRoot}ndk/guides/application_mk.html">Application.mk</a>.</p>
+
+<h2 id="ji">Java-side Implementation</h2>
+<p>The {@code helloJNI.java} file is located in {@code hellojni/src/com/example/hellojni/}. It calls
+a function to retrieve a string from the native side, then displays it on the screen.</p>
+
+<p>The source code contains three lines of particular interest to the NDK user.
+They are presented here in the order in which they are used, rather than by
+line order.</p>
+
+<p>This function call loads the {@code .so} file upon application startup.</p>
+
+<pre class="no-pretty-print">
+System.loadLibrary("hello-jni");
+</pre>
+
+<p>The {@code native} keyword in this method declaration tells the
+virtual machine that the function is in the shared library (that is, implemented on the native
+side).</p>
+
+<pre class="no-pretty-print">
+public native String stringFromJNI();
+</pre>
+
+<p>The Android framework calls the function loaded and declared in the
+previous steps, displaying the string on the screen.</p>
+
+<pre class="no-pretty-print">
+tv.setText( stringFromJNI() );
+</pre>
+
+<h2 id="ci">C-side Implementation</h2>
+<p>The {@code hello-jni.c} file is located in {@code hello-jni/jni/}. It contains a function that
+returns a string that <a href="#ji">the Java side requested</a>). The function declaration is as
+follows:</p>
+
+<pre>
+jstring
+Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
+ jobject thiz )
+</pre>
+
+<p>This declaration corresponds to the native function declared in the
+Java source code. The return type, {@code jstring}, is a data type defined
+in the
+<a href="http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html">Java Native
+Interface Specification</a>. It is not actually a string, but a
+pointer to a Java string.</p>
+
+<p>After {@code jstring} comes the function name, which is based on the
+Java function name and and the path to the file containing it. Construct it
+according to the following rules:</p>
+
+<ul>
+<li>Prepend {@code Java_} to it.</li>
+<li>Describe the filepath relative to the top-level source directory.</li>
+<li>Use underscores in place of forward slashes.</li>
+<li>Omit the {@code .java} file extension.</li>
+<li>After the last underscore, append the function name.</li>
+</ul>
+
+<p>Following these rules, this example uses the function name
+{@code Java_com_example_hellojni_HelloJni_stringFromJNI}. This name refers to a Java
+function called {@code stringFromJNI()}, which resides in
+{@code hellojni/src/com/example/hellojni/HelloJni.java}.</p>
+
+<p>{@code JNIEnv*} is the pointer to the VM, and
+{@code jobject} is a pointer to the implicit {@code this} object passed from
+the Java side.</p>
+
+<p>The following line calls the VM API {@code (*env)}, and passes it a return value:
+that is, the string that the function on the Java side had requested.</p>
+
+<pre class="no-pretty-print">
+return (*env)-&gt;NewStringUTF(env, "Hello from JNI !
+Compiled with ABI " ABI ".");
+</pre>
diff --git a/docs/html/ndk/samples/sample_na.jd b/docs/html/ndk/samples/sample_na.jd
new file mode 100644
index 0000000..a706be5
--- /dev/null
+++ b/docs/html/ndk/samples/sample_na.jd
@@ -0,0 +1,259 @@
+page.title=Sample: native-activity
+@jd:body
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>On this page</h2>
+
+ <ol>
+ <li><a href="#am">AndroidManifest.xml</a></li>
+ <li><a href="#anm">Android.mk</a></li>
+ <li><a href="#apm">Application.mk</a></li>
+ <li><a href="#mac">main.c</a></li>
+ </ol>
+ </li>
+ </ol>
+ </div>
+ </div>
+
+<p>The native-activity sample resides under the NDK installation root, in
+{@code samples/native-activity}. It is a very simple example of a purely native
+application, with no Java source code. In the absence of any Java source, the
+Java compiler still creates an executable stub for the virtual machine to run.
+The stub serves as a wrapper for the actual, native program, which is located in the {@code .so}
+file.</p>
+
+<p>The app itself simply renders a color onto the entire screen, and
+then changes the color partly in response to movement that it detects.</p>
+
+<h2 id="am">AndroidManifest.xml</h2>
+
+<p>An app with only native code must not specify an Android API level lower than 9, which introduced
+the <a href="{@docRoot}ndk/guides/concepts.html#naa">{@code NativeActivity}</a> framework class.</p>
+
+<pre class="no-pretty-print">
+&lt;uses-sdk android:minSdkVersion="9" /&gt;
+</pre>
+
+<p>The following line declares {@code android:hasCode} as {@code false}, as this app has only
+native code&ndash;no Java.
+</p>
+
+<pre class="no-pretty-print">
+&lt;application android:label="@string/app_name"
+android:hasCode="false"&gt;
+</pre>
+
+<p>The next line declares the {@code NativeActivity} class.</p>
+
+<pre class="no-pretty-print">
+&lt;activity android:name="android.app.NativeActivity"
+</pre>
+
+<p>Finally, the manifest specifies {@code android:value} as the name of the shared library to be
+built, minus the initial {@code lib} and the {@code .so} extension. This value must be the same as
+the name of {@code LOCAL_MODULE} in {@code Android.mk}.</p>
+
+<pre class="no-pretty-print">
+&lt;meta-data android:name="android.app.lib_name"
+ android:value="native-activity" /&gt;
+</pre>
+
+<h2 id="anm">Android.mk</h2>
+<p>This file begins by providing the name of the shared library to generate.</p>
+
+<pre class="no-pretty-print">
+LOCAL_MODULE := native-activity
+</pre>
+
+<p>Next, it declares the name of the native source-code file.</p>
+
+<pre class="no-pretty-print">
+LOCAL_SRC_FILES := main.c
+</pre>
+
+<p>Next, it lists the external libraries for the build system to use in building the binary. The
+{@code -l} (link-against) option precedes each library name.</p>
+
+<ul>
+<li>{@code log} is a logging library.</li>
+<li>{@code android} encompasses the standard Android support APIs for NDK. For more information about
+the APIs that Android and the NDK support, see <a href="stable_apis.html">Android NDK Native
+APIs</a>.</li>
+<li>{@code EGL} corresponds to the platform-specific portion of the graphics API.</li>
+<li>{@code GLESv1_CM} corresponds to OpenGL ES, the version of OpenGL for Android. This library
+depends on EGL.</li>
+</ul>
+
+<p>For each library:</p>
+
+<ul>
+<li>The actual file name starts with {@code lib}, and ends with the
+{@code .so} extension. For example, the actual file name for the
+{@code log} library is {@code liblog.so}.</li>
+<li>The library resides in the following directory, NDK root:
+{@code &lt;ndk&gt;/platforms/android-&lt;sdk_version&gt;/arch-&lt;abi&gt;/usr/lib/}.</li>
+</ul>
+
+<pre class="no-pretty-print">
+LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv1_CM
+</pre>
+
+<p>The next line provides the name of the static library, {@code android_native_app_glue}, which the
+application uses to manage {@code NativeActivity} lifecycle events and touch input.</p>
+
+<pre class="no-pretty-print">
+LOCAL_STATIC_LIBRARIES := android_native_app_glue
+</pre>
+
+<p>The final line tells the build system to build this static library.
+The {@code ndk-build} script places the built library
+({@code libandroid_native_app_glue.a}) into the {@code obj} directory
+generated during the build process. For more information about the {@code android_native_app_glue}
+library, see its {@code android_native_app_glue.h} header and corresponding {@code .c}source file.
+</p>
+
+
+<pre class="no-pretty-print">
+$(call import-module,android/native_app_glue)
+</pre>
+
+<p>For more information about the {@code Android.mk} file, see
+<a href="{@docRoot}ndk/guides/android_mk.html">Android.mk</a>.</p>
+
+
+<h2 id="apm">Application.mk</h2>
+
+<p>This line defines the minimum level of Android API Level support.</p>
+
+<pre class="no-pretty-print">
+APP_PLATFORM := android-10
+</pre>
+
+<p>Because there is no ABI definition, the build system defaults to building only for
+{@code armeabi}.</p>
+
+<h2 id="mac">main.c</h2>
+<p>This file essentially contains the entire progam.</p>
+
+<p>The following includes correspond to the libraries, both shared and static,
+enumerated in {@code Android.mk}.</p>
+
+<pre class="no-pretty-print">
+#include &lt;EGL/egl.h&gt;
+#include &lt;GLES/gl.h&gt;
+
+
+#include &lt;android/sensor.h&gt;
+#include &lt;android/log.h&gt;
+#include &lt;android_native_app_glue&gt;
+</pre>
+
+<p>The {@code android_native_app_glue} library calls the following function,
+passing it a predefined state structure. It also serves as a wrapper that
+simplifies handling of {@code NativeActivity} callbacks.</p>
+
+<pre class="no-pretty-print">
+void android_main(struct android_app* state) {
+</pre>
+
+<p>Next, the program handles events queued by the glue library. The event
+handler follows the state structure.</p>
+
+<pre class="no-pretty-print">
+struct engine engine;
+
+
+
+// Suppress link-time optimization that removes unreferenced code
+// to make sure glue isn't stripped.
+app_dummy();
+
+
+memset(&amp;engine, 0, sizeof(engine));
+state-&gt;userData = &amp;engine;
+state-&gt;onAppCmd = engine_handle_cmd;
+state-&gt;onInputEvent = engine_handle_input;
+engine.app = state;
+</pre>
+
+<p>The application prepares to start monitoring the sensors, using the
+APIs in {@code sensor.h}.</p>
+
+<pre class="no-pretty-print">
+ engine.sensorManager = ASensorManager_getInstance();
+ engine.accelerometerSensor =
+ ASensorManager_getDefaultSensor(engine.sensorManager,
+ ASENSOR_TYPE_ACCELEROMETER);
+ engine.sensorEventQueue =
+ ASensorManager_createEventQueue(engine.sensorManager,
+ state-&gt;looper, LOOPER_ID_USER, NULL, NULL);
+</pre>
+
+<p>Next, a loop begins, in which the application polls the system for
+messages (sensor events). It sends messages to
+{@code android_native_app_glue}, which checks to see whether they match
+any {@code onAppCmd} events defined in {@code android_main}. When a
+match occurs, the message is sent to the handler for execution.</p>
+
+<pre class="no-pretty-print">
+while (1) {
+ // Read all pending events.
+ int ident;
+ int events;
+ struct android_poll_source* source;
+
+
+ // If not animating, we will block forever waiting for events.
+ // If animating, we loop until all events are read, then continue
+ // to draw the next frame of animation.
+ while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, NULL,
+ &amp;events,
+ (void**)&amp;source)) &gt;= 0) {
+
+
+ // Process this event.
+ if (source != NULL) {
+ source-&gt;process(state, source);
+ }
+
+
+ // If a sensor has data, process it now.
+ if (ident == LOOPER_ID_USER) {
+ if (engine.accelerometerSensor != NULL) {
+ ASensorEvent event;
+ while (ASensorEventQueue_getEvents(engine.sensorEventQueue,
+ &amp;event, 1) &gt; 0) {
+ LOGI("accelerometer: x=%f y=%f z=%f",
+ event.acceleration.x, event.acceleration.y,
+ event.acceleration.z);
+ }
+ }
+ }
+
+
+ // Check if we are exiting.
+ if (state-&gt;destroyRequested != 0) {
+ engine_term_display(&amp;engine);
+ return;
+ }
+ }
+</pre>
+
+<p>Once the queue is empty, and the program exits the polling loop, the
+program calls OpenGL to draw the screen.</p>
+<pre class="no-pretty-print">
+ if (engine.animating) {
+ // Done with events; draw next animation frame.
+ engine.state.angle += .01f;
+ if (engine.state.angle &gt; 1) {
+ engine.state.angle = 0;
+ }
+
+
+ // Drawing is throttled to the screen update rate, so there
+ // is no need to do timing here.
+ engine_draw_frame(&amp;engine);
+ }
+}
+</pre>
diff --git a/docs/html/ndk/samples/sample_teapot.jd b/docs/html/ndk/samples/sample_teapot.jd
new file mode 100644
index 0000000..97708a7
--- /dev/null
+++ b/docs/html/ndk/samples/sample_teapot.jd
@@ -0,0 +1,360 @@
+page.title=Sample: Teapot
+@jd:body
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>On this page</h2>
+
+ <ol>
+ <li><a href="#am">AndroidManifest.xml</a></li>
+ <li><a href="#ap">Application.mk</a></li>
+ <li><a href="#ji">Java-side Implementation</a></li>
+ <li><a href="#ni">Native-side Implementation</a></li>
+ </ol>
+ </li>
+ </ol>
+ </div>
+ </div>
+
+<p>The Teapot sample is located under in the {@code samples/Teapot/} directory, under the NDK
+installation's root directory. This sample uses the OpenGL library to render the iconic
+<a href="http://math.hws.edu/bridgeman/courses/324/s06/doc/opengl.html#basic">Utah
+teapot</a>. In particular, it showcases the {@code ndk_helper} helper class,
+a collection of native helper functions required for implementing games and
+similar applications as native applications. This class provides:</p>
+
+<ul>
+<li>An abstraction layer, {@code GLContext}, that handles certain NDK-specific behaviors.</li>
+<li>Helper functions that are useful but not present in the NDK, such as tap detection.</li>
+<li>Wrappers for JNI calls for platform features such as texture loading.</li>
+</ul>
+
+<h2 id="am">AndroidManifest.xml</h2>
+<p>The activity declaration here is not {@link android.app.NativeActivity} itself, but
+a subclass of it: {@code TeapotNativeActivity}.</p>
+
+<pre class="no-pretty-print">
+ &lt;activity android:name="com.sample.teapot.TeapotNativeActivity"
+ android:label="@string/app_name"
+ android:configChanges="orientation|keyboardHidden"&gt;
+</pre>
+
+<p>Ultimately, the name of the shared-object file that the build system builds is
+{@code libTeapotNativeActivity.so}. The build system adds the {@code lib} prefix and the {@code .so}
+extension; neither is part of the value that the manifest originally assigns to
+{@code android:value}.</p>
+
+<pre class="no-pretty-print">
+ &lt;meta-data android:name="android.app.lib_name"
+ android:value="TeapotNativeActivity" /&gt;
+</pre>
+
+<h2 id="ap">Application.mk</h2>
+<p>An app that uses the {@link android.app.NativeActivity} framework class must not specify an
+Android API level lower than 9, which introduced that class. For more information about the
+{@link android.app.NativeActivity} class, see
+<a href="{@docRoot}ndk/guides/concepts.html#naa">Native Activities and Applications</a>.
+</p>
+
+<pre class="no-pretty-print">
+APP_PLATFORM := android-9
+</pre>
+
+<p>The next line tells the build system to build for all supported architectures.</p>
+<pre class="no-pretty-print">
+APP_ABI := all
+</pre>
+
+<p>Next, the file tells the build system which
+<a href="{@docRoot}ndk/guides/cpp-support.html">C++ runtime support library</a> to use. </p>
+
+<pre class="no-pretty-print">
+APP_STL := stlport_static
+</pre>
+
+<h2 id="ji">Java-side Implementation</h2>
+<p>The {@code TeapotNativeActivity.java} file is located in
+{@code samples/Teapot/src/com/sample/teapot}, under the NDK installation root directory. It handles
+activity lifecycle events, and also enables the app to display text on the screen. The following
+block of code is most important from the perspective of the native-side implementation: The native
+code calls it to display a popup window for displaying text.</p>
+
+<pre class="no-pretty-print">
+
+void setImmersiveSticky() {
+ View decorView = getWindow().getDecorView();
+ decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
+}
+</pre>
+
+<h2 id="ni">Native-side Implementation</h2>
+
+<p>This section explores the part of the Teapot app implemented in C++.</p>
+
+<h3>TeapotRenderer.h</h3>
+
+<p>These function calls perform the actual rendering of the teapot. It uses
+{@code ndk_helper} for matrix calculation and to reposition the camera
+based on where the user taps.</p>
+
+<pre class="no-pretty-print">
+ndk_helper::Mat4 mat_projection_;
+ndk_helper::Mat4 mat_view_;
+ndk_helper::Mat4 mat_model_;
+
+
+ndk_helper::TapCamera* camera_;
+</pre>
+
+<h3>TeapotNativeActivity.cpp</h3>
+
+<p>The following lines include {@code ndk_helper} in the native source file, and define the
+helper-class name.</p>
+
+<pre class="no-pretty-print">
+
+#include "NDKHelper.h"
+
+//-------------------------------------------------------------------------
+//Preprocessor
+//-------------------------------------------------------------------------
+#define HELPER_CLASS_NAME "com/sample/helper/NDKHelper" //Class name of helper
+function
+</pre>
+
+<p>The first use of the {@code ndk_helper} class is to handle the
+EGL-related lifecycle, associating EGL context states (created/lost) with
+Android lifecycle events. The {@code ndk_helper} class enables the application to preserve context
+information so that the system can restore a destroyed activity. This ability is useful, for
+example, when the target machine is rotated (causing an activity to be
+destroyed, then immediately restored in the new orientation), or when the lock
+screen appears.</p>
+
+<pre class="no-pretty-print">
+ndk_helper::GLContext* gl_context_; // handles EGL-related lifecycle.
+</pre>
+
+<p>Next, {@code ndk_helper} provides touch control.</p>
+
+<pre class="no-pretty-print">
+ndk_helper::DoubletapDetector doubletap_detector_;
+ndk_helper::PinchDetector pinch_detector_;
+ndk_helper::DragDetector drag_detector_;
+ndk_helper::PerfMonitor monitor_;
+</pre>
+
+<p>It also provides camera control (openGL view frustum).</p>
+
+<pre class="no-pretty-print">
+ndk_helper::TapCamera tap_camera_;
+</pre>
+
+<p>The app then prepares to use the device's sensors, using the native APIs provided in the NDK.</p>
+
+<pre class="no-pretty-print">
+ASensorManager* sensor_manager_;
+const ASensor* accelerometer_sensor_;
+ASensorEventQueue* sensor_event_queue_;
+</pre>
+
+<p>The app calls the following functions in response to various Android
+lifecycle events and EGL context state changes, using various functionalities
+provided by {@code ndk_helper} via the {@code Engine} class.</p>
+
+<pre class="no-pretty-print">
+
+void LoadResources();
+void UnloadResources();
+void DrawFrame();
+void TermDisplay();
+void TrimMemory();
+bool IsReady();
+</pre>
+
+<p>Then, the following function calls back to the Java side to update the UI display.</p>
+
+<pre class="no-pretty-print">
+void Engine::ShowUI()
+{
+ JNIEnv *jni;
+ app_-&gt;activity-&gt;vm-&gt;AttachCurrentThread( &amp;jni, NULL );
+
+
+ //Default class retrieval
+ jclass clazz = jni-&gt;GetObjectClass( app_-&gt;activity-&gt;clazz );
+ jmethodID methodID = jni-&gt;GetMethodID( clazz, "showUI", "()V" );
+ jni-&gt;CallVoidMethod( app_-&gt;activity-&gt;clazz, methodID );
+
+
+ app_-&gt;activity-&gt;vm-&gt;DetachCurrentThread();
+ return;
+}
+</pre>
+
+<p>Next, this function calls back to the Java side to draw a text box
+superimposed on the screen rendered on the native side, and showing frame
+count.</p>
+
+<pre class="no-pretty-print">
+void Engine::UpdateFPS( float fFPS )
+{
+ JNIEnv *jni;
+ app_-&gt;activity-&gt;vm-&gt;AttachCurrentThread( &amp;jni, NULL );
+
+
+ //Default class retrieval
+ jclass clazz = jni-&gt;GetObjectClass( app_-&gt;activity-&gt;clazz );
+ jmethodID methodID = jni-&gt;GetMethodID( clazz, "updateFPS", "(F)V" );
+ jni-&gt;CallVoidMethod( app_-&gt;activity-&gt;clazz, methodID, fFPS );
+
+
+ app_-&gt;activity-&gt;vm-&gt;DetachCurrentThread();
+ return;
+}
+</pre>
+
+<p>The application gets the system clock and supplies it to the renderer
+for time-based animation based on real-time clock. This information is used, for example, in
+calculating momentum, where speed declines as a function of time.</p>
+
+<pre class="no-pretty-print">
+renderer_.Update( monitor_.GetCurrentTime() );
+</pre>
+
+<p>The application now checks whether the context information that {@code GLcontext} holds is still
+valid. If not, {@code ndk-helper} swaps the buffer, reinstantiating the GL context.</p>
+
+<pre class="no-pretty-print">
+if( EGL_SUCCESS != gl_context_-&gt;Swap() ) // swaps
+buffer.
+</pre>
+
+<p>The program passes touch-motion events to the gesture detector defined
+in the {@code ndk_helper} class. The gesture detector tracks multitouch
+gestures, such as pinch-and-drag, and sends a notification when triggered by
+any of these events.</p>
+
+<pre class="no-pretty-print">
+ if( AInputEvent_getType( event ) == AINPUT_EVENT_TYPE_MOTION )
+ {
+ ndk_helper::GESTURE_STATE doubleTapState =
+ eng->doubletap_detector_.Detect( event );
+ ndk_helper::GESTURE_STATE dragState = eng->drag_detector_.Detect( event );
+ ndk_helper::GESTURE_STATE pinchState = eng->pinch_detector_.Detect( event );
+
+ //Double tap detector has a priority over other detectors
+ if( doubleTapState == ndk_helper::GESTURE_STATE_ACTION )
+ {
+ //Detect double tap
+ eng->tap_camera_.Reset( true );
+ }
+ else
+ {
+ //Handle drag state
+ if( dragState & ndk_helper::GESTURE_STATE_START )
+ {
+ //Otherwise, start dragging
+ ndk_helper::Vec2 v;
+ eng->drag_detector_.GetPointer( v );
+ eng->TransformPosition( v );
+ eng->tap_camera_.BeginDrag( v );
+ }
+ // ...else other possible drag states...
+
+ //Handle pinch state
+ if( pinchState & ndk_helper::GESTURE_STATE_START )
+ {
+ //Start new pinch
+ ndk_helper::Vec2 v1;
+ ndk_helper::Vec2 v2;
+ eng->pinch_detector_.GetPointers( v1, v2 );
+ eng->TransformPosition( v1 );
+ eng->TransformPosition( v2 );
+ eng->tap_camera_.BeginPinch( v1, v2 );
+ }
+ // ...else other possible pinch states...
+ }
+ return 1;
+ }
+</pre>
+
+<p>The {@code ndk_helper} class also provides access to a vector-math library
+({@code vecmath.h}), using it here to transform touch coordinates.</p>
+
+<pre class="no-pretty-print">
+void Engine::TransformPosition( ndk_helper::Vec2& vec )
+{
+ vec = ndk_helper::Vec2( 2.0f, 2.0f ) * vec
+ / ndk_helper::Vec2( gl_context_->GetScreenWidth(),
+ gl_context_->GetScreenHeight() ) - ndk_helper::Vec2( 1.f, 1.f );
+}
+</pre>
+</ul>
+
+<p>The {@code HandleCmd()} method handles commands posted from the
+android_native_app_glue library. For more information about what the messages
+mean, refer to the comments in the {@code android_native_app_glue.h} and
+{@code .c} source files.</p>
+
+<pre class="no-pretty-print">
+void Engine::HandleCmd( struct android_app* app,
+ int32_t cmd )
+{
+ Engine* eng = (Engine*) app->userData;
+ switch( cmd )
+ {
+ case APP_CMD_SAVE_STATE:
+ break;
+ case APP_CMD_INIT_WINDOW:
+ // The window is being shown, get it ready.
+ if( app->window != NULL )
+ {
+ eng->InitDisplay();
+ eng->DrawFrame();
+ }
+ break;
+ case APP_CMD_TERM_WINDOW:
+ // The window is being hidden or closed, clean it up.
+ eng->TermDisplay();
+ eng->has_focus_ = false;
+ break;
+ case APP_CMD_STOP:
+ break;
+ case APP_CMD_GAINED_FOCUS:
+ eng->ResumeSensors();
+ //Start animation
+ eng->has_focus_ = true;
+ break;
+ case APP_CMD_LOST_FOCUS:
+ eng->SuspendSensors();
+ // Also stop animating.
+ eng->has_focus_ = false;
+ eng->DrawFrame();
+ break;
+ case APP_CMD_LOW_MEMORY:
+ //Free up GL resources
+ eng->TrimMemory();
+ break;
+ }
+}
+</pre>
+
+<p>The {@code ndk_helper} class posts {@code APP_CMD_INIT_WINDOW} when {@code android_app_glue}
+receives an {@code onNativeWindowCreated()} callback from the system.
+Applications can normally perform window initializations, such as EGL
+initialization. They do this outside of the activity lifecycle, since the
+activity is not yet ready.</p>
+
+<pre class="no-pretty-print">
+ //Init helper functions
+ ndk_helper::JNIHelper::Init( state->activity, HELPER_CLASS_NAME );
+
+ state->userData = &g_engine;
+ state->onAppCmd = Engine::HandleCmd;
+ state->onInputEvent = Engine::HandleInput;
+</pre>
diff --git a/docs/html/ndk/samples/samples_toc.cs b/docs/html/ndk/samples/samples_toc.cs
new file mode 100644
index 0000000..92266b1
--- /dev/null
+++ b/docs/html/ndk/samples/samples_toc.cs
@@ -0,0 +1,35 @@
+<?cs # Table of contents for Dev Guide.
+
+ For each document available in translation, add an localized title to this TOC.
+ Do not add localized title for docs not available in translation.
+ Below are template spans for adding localized doc titles. Please ensure that
+ localized titles are added in the language order specified below.
+?>
+
+<ul id="nav">
+
+ <li class="nav-section">
+ <div class="nav-section-header empty"><a href="<?cs var:toroot ?>ndk/samples/index.html">
+ <span class="en">Overview</span></a></div>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>ndk/samples/walkthroughs.html">
+ <span class="en">Walkthroughs</span></a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>ndk/samples/sample_hellojni.html">hello-jni</a></li>
+ <li><a href="<?cs var:toroot ?>ndk/samples/sample_na.html">native-activity</a></li>
+ <li><a href="<?cs var:toroot ?>ndk/samples/sample_teapot.html">Teapot</a></li>
+ </ul>
+ </li>
+</ul>
+
+
+<script type="text/javascript">
+<!--
+ buildToggleLists();
+ changeNavLang(getLangPref());
+//-->
+</script>
+
diff --git a/docs/html/ndk/samples/walkthroughs.jd b/docs/html/ndk/samples/walkthroughs.jd
new file mode 100644
index 0000000..88ceb56
--- /dev/null
+++ b/docs/html/ndk/samples/walkthroughs.jd
@@ -0,0 +1,13 @@
+page.title=Samples: Walkthroughs
+@jd:body
+
+<p>This section provides detailed walkthroughs of several key samples. The samples are as
+follows:</p>
+
+<li><a href="{@docRoot}ndk/samples/sample_hellojni.html">hello-jni</a>: A very basic app that
+illustrates core workings of the NDK.</li>
+<li><a href="{@docRoot}ndk/samples/sample_na.html">native-activity</a>: An app that shows the
+fundamentals of constructing a purely native app. It places particular emphasis on the
+{@code android_native_app_glue library}.</li>
+<li><a href="<a href="{@docRoot}ndk/samples/sample_teapot.html">Teapot</a>: A simple OpenGL demo,
+showcasing the <code>ndk_helper</code> class.</li>