Add the PlatformLibrary sample to the new "sample" vendor
This adds the PlatformLibrary samples previously located in development/samples.
This also creates all the files required to build an add-on including the optional
library provided by PlatformLibrary
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..5053e7d
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..2649eae
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,3 @@
+To build the add-on:
+ make -j8 PRODUCT-sample_addon-sdk_addon
+
\ No newline at end of file
diff --git a/apps/Android.mk b/apps/Android.mk
new file mode 100644
index 0000000..5053e7d
--- /dev/null
+++ b/apps/Android.mk
@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)
diff --git a/apps/client/Android.mk b/apps/client/Android.mk
new file mode 100644
index 0000000..ac4058a
--- /dev/null
+++ b/apps/client/Android.mk
@@ -0,0 +1,37 @@
+#
+# 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.
+#
+
+# This makefile is an example of writing an application that will link against
+# a custom shared library included with an Android system.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := user
+
+# This is the target being built.
+LOCAL_PACKAGE_NAME := PlatformLibraryClient
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Link against the current Android SDK.
+LOCAL_SDK_VERSION := current
+
+# Also link against our own custom library.
+LOCAL_JAVA_LIBRARIES := com.example.android.platform_library
+
+include $(BUILD_PACKAGE)
diff --git a/apps/client/AndroidManifest.xml b/apps/client/AndroidManifest.xml
new file mode 100644
index 0000000..be0d9a1
--- /dev/null
+++ b/apps/client/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- This is an example of writing a client application for a custom
+ platform library. -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.platform_library.client">
+
+ <application android:label="Platform Lib Client">
+
+ <!-- This tells the system about the custom library used by the
+ application, so that it can be properly loaded and linked
+ to the app when the app is initialized. -->
+ <uses-library android:name="com.example.android.platform_library" />
+
+ <activity android:name="Client">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/apps/client/src/com/example/android/platform_library/client/Client.java b/apps/client/src/com/example/android/platform_library/client/Client.java
new file mode 100644
index 0000000..8722c72
--- /dev/null
+++ b/apps/client/src/com/example/android/platform_library/client/Client.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2007 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.example.android.platform_library.client;
+
+import com.example.android.platform_library.PlatformLibrary;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+/**
+ * Use a custom platform library.
+ */
+public class Client extends Activity {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Call an API on the library.
+ PlatformLibrary pl = new PlatformLibrary();
+ int res = pl.getInt(false);
+
+ // We'll just make our own view to show the result.
+ TextView tv = new TextView(this);
+ tv.setText("Got from lib: " + res);
+ setContentView(tv);
+ }
+}
+
diff --git a/frameworks/Android.mk b/frameworks/Android.mk
new file mode 100644
index 0000000..5053e7d
--- /dev/null
+++ b/frameworks/Android.mk
@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)
diff --git a/frameworks/PlatformLibrary/Android.mk b/frameworks/PlatformLibrary/Android.mk
new file mode 100644
index 0000000..d1a694a
--- /dev/null
+++ b/frameworks/PlatformLibrary/Android.mk
@@ -0,0 +1,57 @@
+#
+# 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.
+#
+
+# This makefile shows how to build your own shared library that can be
+# shipped on the system of a phone, and included additional examples of
+# including JNI code with the library and writing client applications against it.
+
+LOCAL_PATH := $(call my-dir)
+
+# the library
+# ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ $(call all-subdir-java-files)
+
+LOCAL_MODULE_TAGS := optional
+
+# This is the target being built.
+LOCAL_MODULE:= com.example.android.platform_library
+
+include $(BUILD_JAVA_LIBRARY)
+
+# the documentation
+# ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files) $(call all-subdir-html-files)
+
+LOCAL_MODULE:= platform_library
+LOCAL_DROIDDOC_OPTIONS := com.example.android.platform_library
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_DROIDDOC_USE_STANDARD_DOCLET := true
+
+include $(BUILD_DROIDDOC)
+
+# The JNI component
+# ============================================================
+# Also build all of the sub-targets under this one: the library's
+# associated JNI code, and a sample client of the library.
+include $(CLEAR_VARS)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
diff --git a/frameworks/PlatformLibrary/README.txt b/frameworks/PlatformLibrary/README.txt
new file mode 100644
index 0000000..5ce9d2f
--- /dev/null
+++ b/frameworks/PlatformLibrary/README.txt
@@ -0,0 +1,74 @@
+Platform Library Example
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+This directory contains a full example of writing your own Android platform
+shared library, without changing the Android framework. It also shows how to
+write JNI code for incorporating native code into the library, and a client
+application that uses the library.
+
+This example is ONLY for people working with the open source platform to
+create a system image that will be delivered on a device which will include
+a custom library as shown here. It can not be used to create a third party
+shared library, which is not currently supported in Android.
+
+To declare your library to the framework, you must place a file with a .xml
+extension in the /system/etc/permissions directory with the following contents:
+
+<?xml version="1.0" encoding="utf-8"?>
+<permissions>
+ <library name="com.example.android.platform_library"
+ file="/system/framework/com.example.android.platform_library.jar"/>
+</permissions>
+
+There are three major parts of this example, supplying three distinct
+build targets and corresponding build outputs:
+
+
+com.example.android.platform_library
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The top-level Android.mk defines the rules to build the shared library itself,
+whose target is "com.example.android.platform_library". The code for this
+library lives under java/.
+
+Note that the product for this library is a raw .jar file, NOT a .apk, which
+means there is no manifest or resources associated with the library.
+Unfortunately this means that if you need any resources for the library, such
+as drawables or layout files, you will need to add these to the core framework
+resources under frameworks/base/res. Please make sure when doing this that
+you do not make any of these resources public, they should not become part of
+the Android API. In the future we will allow shared libraries to have their
+own resources.
+
+Other than that, the library is very straight-forward, and you can write
+basically whatever code you want. You can also put code in other Java
+namespaces -- the namespace given in the <library> tag above is just the
+public unique name by which clients will link to your library, but once this
+link happens all of the Java namespaces in that library will be available
+to the client.
+
+
+libplatform_library_jni
+~~~~~~~~~~~~~~~~~~~~~~~
+
+This is an optional example of how to write JNI code associated with a
+shared library. This code lives under jni/. The jni/Android.mk file defines
+the rules for building the final .so in which the code lives. This example
+provides everything needed to hook up the native code with the Java library
+and call through to it, plus a very simple JNI call.
+
+
+PlatformLibraryClient
+~~~~~~~~~~~~~~~~~~~~~
+
+This shows an example of how you can write client applications for your new
+shared library. This code lives under client/. Note that the example is
+simply a regular Android .apk, like all of the other .apks created by the
+build system. The only two special things needed to use your library are:
+
+- A LOCAL_JAVA_LIBRARIES line in the Android.mk to have the build system link
+against your shared library.
+
+- A <uses-library> line in the AndroidManifest.xml to have the runtime load
+your library into the application.
diff --git a/frameworks/PlatformLibrary/com.example.android.platform_library.xml b/frameworks/PlatformLibrary/com.example.android.platform_library.xml
new file mode 100644
index 0000000..b9491d8
--- /dev/null
+++ b/frameworks/PlatformLibrary/com.example.android.platform_library.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<permissions>
+ <library name="com.example.android.platform_library"
+ file="/system/framework/com.example.android.platform_library.jar"/>
+</permissions>
diff --git a/frameworks/PlatformLibrary/java/com/example/android/platform_library/PlatformLibrary.java b/frameworks/PlatformLibrary/java/com/example/android/platform_library/PlatformLibrary.java
new file mode 100644
index 0000000..68154ec
--- /dev/null
+++ b/frameworks/PlatformLibrary/java/com/example/android/platform_library/PlatformLibrary.java
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+package com.example.android.platform_library;
+
+import android.util.Config;
+import android.util.Log;
+
+public final class PlatformLibrary {
+ static {
+ /*
+ * Load the library. If it's already loaded, this does nothing.
+ */
+ System.loadLibrary("platform_library_jni");
+ }
+
+ private int mJniInt = -1;
+
+ public PlatformLibrary() {}
+
+ /*
+ * Test native methods.
+ */
+ public int getInt(boolean bad) {
+ /* this alters mJniInt */
+ int result = getJniInt(bad);
+
+ /* reverse a string, for no very good reason */
+ String reverse = reverseString("Android!");
+
+ Log.i("PlatformLibrary", "getInt: " + result + ", '" + reverse + "'");
+
+ return mJniInt;
+ }
+
+ /*
+ * Simple method, called from native code.
+ */
+ private static void yodel(String msg) {
+ Log.d("PlatformLibrary", "yodel: " + msg);
+ }
+
+ /*
+ * Trivial native method call. If "bad" is true, this will throw an
+ * exception.
+ */
+ native private int getJniInt(boolean bad);
+
+ /*
+ * Native method that returns a new string that is the reverse of
+ * the original. This also calls yodel().
+ */
+ native private static String reverseString(String str);
+}
diff --git a/frameworks/PlatformLibrary/jni/Android.mk b/frameworks/PlatformLibrary/jni/Android.mk
new file mode 100644
index 0000000..96f2ba1
--- /dev/null
+++ b/frameworks/PlatformLibrary/jni/Android.mk
@@ -0,0 +1,53 @@
+#
+# 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.
+#
+
+# This makefile supplies the rules for building a library of JNI code for
+# use by our example platform shared library.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+# This is the target being built.
+LOCAL_MODULE:= libplatform_library_jni
+
+# All of the source files that we will compile.
+LOCAL_SRC_FILES:= \
+ PlatformLibrary.cpp
+
+# All of the shared libraries we link against.
+LOCAL_SHARED_LIBRARIES := \
+ libandroid_runtime \
+ libnativehelper \
+ libcutils \
+ libutils
+
+# No static libraries.
+LOCAL_STATIC_LIBRARIES :=
+
+# Also need the JNI headers.
+LOCAL_C_INCLUDES += \
+ $(JNI_H_INCLUDE)
+
+# No specia compiler flags.
+LOCAL_CFLAGS +=
+
+# Don't prelink this library. For more efficient code, you may want
+# to add this library to the prelink map and set this to true.
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/frameworks/PlatformLibrary/jni/PlatformLibrary.cpp b/frameworks/PlatformLibrary/jni/PlatformLibrary.cpp
new file mode 100644
index 0000000..ad60002
--- /dev/null
+++ b/frameworks/PlatformLibrary/jni/PlatformLibrary.cpp
@@ -0,0 +1,273 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "PlatformLibrary"
+#include "utils/Log.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include "jni.h"
+
+
+// ----------------------------------------------------------------------------
+
+/*
+ * Field/method IDs and class object references.
+ *
+ * You should not need to store the JNIEnv pointer in here. It is
+ * thread-specific and will be passed back in on every call.
+ */
+static struct {
+ jclass platformLibraryClass;
+ jfieldID jniInt;
+ jmethodID yodel;
+} gCachedState;
+
+// ----------------------------------------------------------------------------
+
+/*
+ * Helper function to throw an arbitrary exception.
+ *
+ * Takes the exception class name, a format string, and one optional integer
+ * argument (useful for including an error code, perhaps from errno).
+ */
+static void throwException(JNIEnv* env, const char* ex, const char* fmt,
+ int data) {
+
+ if (jclass cls = env->FindClass(ex)) {
+ if (fmt != NULL) {
+ char msg[1000];
+ snprintf(msg, sizeof(msg), fmt, data);
+ env->ThrowNew(cls, msg);
+ } else {
+ env->ThrowNew(cls, NULL);
+ }
+
+ /*
+ * This is usually not necessary -- local references are released
+ * automatically when the native code returns to the VM. It's
+ * required if the code doesn't actually return, e.g. it's sitting
+ * in a native event loop.
+ */
+ env->DeleteLocalRef(cls);
+ }
+}
+
+/*
+ * Trivial sample method.
+ *
+ * If "bad" is true, this throws an exception. Otherwise, this sets the
+ * "mJniInt" field to 42 and returns 24.
+ */
+static jint PlatformLibrary_getJniInt(JNIEnv* env, jobject thiz, jboolean bad) {
+ if (bad) {
+ throwException(env, "java/lang/IllegalStateException",
+ "you are bad", 0);
+ return 0; /* return value will be ignored */
+ }
+ env->SetIntField(thiz, gCachedState.jniInt, 42);
+ return (jint)24;
+}
+
+/*
+ * A more complex sample method.
+ *
+ * This takes a String as an argument, and returns a new String with
+ * characters in reverse order. The new string is passed to another method.
+ * This demonstrates basic String manipulation functions and method
+ * invocation.
+ *
+ * This method is declared "static", so there's no "this" pointer; instead,
+ * we get a pointer to the class object.
+ */
+static jstring PlatformLibrary_reverseString(JNIEnv* env, jclass clazz,
+ jstring str) {
+
+ if (str == NULL) {
+ throwException(env, "java/lang/NullPointerException", NULL, 0);
+ return NULL;
+ }
+
+ /*
+ * Get a pointer to the string's UTF-16 character data. The data
+ * may be a copy or a pointer to the original. Since String data
+ * is immutable, we're not allowed to touch it.
+ */
+ const jchar* strChars = env->GetStringChars(str, NULL);
+ if (strChars == NULL) {
+ /* something went wrong */
+ LOGW("Couldn't get string chars\n");
+ return NULL;
+ }
+ jsize strLength = env->GetStringLength(str);
+
+ /*
+ * Write a progress message to the log. Log messages are UTF-8, so
+ * we want to convert the string to show it.
+ */
+ const char* printable = env->GetStringUTFChars(str, NULL);
+ if (printable != NULL) {
+ LOGD("Reversing string '%s'\n", printable);
+ env->ReleaseStringUTFChars(str, printable);
+ }
+
+ /*
+ * Copy the characters to temporary storage, reversing as we go.
+ */
+ jchar tempChars[strLength];
+ for (int i = 0; i < strLength; i++) {
+ tempChars[i] = strChars[strLength -1 -i];
+ }
+
+ /*
+ * Release the original String. That way, if something fails later on,
+ * we don't have to worry about this leading to a memory leak.
+ */
+ env->ReleaseStringChars(str, strChars);
+ strChars = NULL; /* this pointer no longer valid */
+
+ /*
+ * Create a new String with the chars.
+ */
+ jstring result = env->NewString(tempChars, strLength);
+ if (result == NULL) {
+ LOGE("NewString failed\n");
+ return NULL;
+ }
+
+ /*
+ * Now let's do something with it. We already have the methodID for
+ * "yodel", so we can invoke it directly. It's in our class, so we
+ * can use the Class object reference that was passed in.
+ */
+ env->CallStaticVoidMethod(clazz, gCachedState.yodel, result);
+
+ return result;
+}
+
+
+// ----------------------------------------------------------------------------
+
+/*
+ * Array of methods.
+ *
+ * Each entry has three fields: the name of the method, the method
+ * signature, and a pointer to the native implementation.
+ */
+static const JNINativeMethod gMethods[] = {
+ { "getJniInt", "(Z)I",
+ (void*)PlatformLibrary_getJniInt },
+ { "reverseString", "(Ljava/lang/String;)Ljava/lang/String;",
+ (void*)PlatformLibrary_reverseString },
+};
+
+/*
+ * Do some (slow-ish) lookups now and save the results.
+ *
+ * Returns 0 on success.
+ */
+static int cacheIds(JNIEnv* env, jclass clazz) {
+ /*
+ * Save the class in case we want to use it later. Because this is a
+ * reference to the Class object, we need to convert it to a JNI global
+ * reference.
+ */
+ gCachedState.platformLibraryClass = (jclass) env->NewGlobalRef(clazz);
+ if (clazz == NULL) {
+ LOGE("Can't create new global ref\n");
+ return -1;
+ }
+
+ /*
+ * Cache field and method IDs. IDs are not references, which means we
+ * don't need to call NewGlobalRef on them.
+ */
+ gCachedState.jniInt = env->GetFieldID(clazz, "mJniInt", "I");
+ if (gCachedState.jniInt == NULL) {
+ LOGE("Can't find PlatformLibrary.mJniInt\n");
+ return -1;
+ }
+
+ gCachedState.yodel = env->GetStaticMethodID(clazz, "yodel",
+ "(Ljava/lang/String;)V");
+ if (gCachedState.yodel == NULL) {
+ LOGE("Can't find PlatformLibrary.yodel\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Explicitly register all methods for our class.
+ *
+ * While we're at it, cache some class references and method/field IDs.
+ *
+ * Returns 0 on success.
+ */
+static int registerMethods(JNIEnv* env) {
+ static const char* const kClassName =
+ "com/example/android/platform_library/PlatformLibrary";
+ jclass clazz;
+
+ /* look up the class */
+ clazz = env->FindClass(kClassName);
+ if (clazz == NULL) {
+ LOGE("Can't find class %s\n", kClassName);
+ return -1;
+ }
+
+ /* register all the methods */
+ if (env->RegisterNatives(clazz, gMethods,
+ sizeof(gMethods) / sizeof(gMethods[0])) != JNI_OK)
+ {
+ LOGE("Failed registering methods for %s\n", kClassName);
+ return -1;
+ }
+
+ /* fill out the rest of the ID cache */
+ return cacheIds(env, clazz);
+}
+
+// ----------------------------------------------------------------------------
+
+/*
+ * This is called by the VM when the shared library is first loaded.
+ */
+jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+ JNIEnv* env = NULL;
+ jint result = -1;
+
+ if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+ LOGE("ERROR: GetEnv failed\n");
+ goto bail;
+ }
+ assert(env != NULL);
+
+ if (registerMethods(env) != 0) {
+ LOGE("ERROR: PlatformLibrary native registration failed\n");
+ goto bail;
+ }
+
+ /* success -- return valid version number */
+ result = JNI_VERSION_1_4;
+
+bail:
+ return result;
+}
diff --git a/new b/new
deleted file mode 100644
index 3e75765..0000000
--- a/new
+++ /dev/null
@@ -1 +0,0 @@
-new
diff --git a/products/AndroidProducts.mk b/products/AndroidProducts.mk
new file mode 100644
index 0000000..ead83cd
--- /dev/null
+++ b/products/AndroidProducts.mk
@@ -0,0 +1,13 @@
+#
+# This file should set PRODUCT_MAKEFILES to a list of product makefiles
+# to expose to the build system. LOCAL_DIR will already be set to
+# the directory containing this file.
+#
+# This file may not rely on the value of any variable other than
+# LOCAL_DIR; do not use any conditionals, and do not look up the
+# value of any variable that isn't set in this file or in a file that
+# it includes.
+#
+
+PRODUCT_MAKEFILES := \
+ $(LOCAL_DIR)/sample_addon.mk
diff --git a/products/sample_addon.mk b/products/sample_addon.mk
new file mode 100644
index 0000000..c0d66fe
--- /dev/null
+++ b/products/sample_addon.mk
@@ -0,0 +1,28 @@
+PRODUCT_PACKAGES := \
+ PlatformLibraryClient \
+ com.example.android.platform_library \
+ libplatform_library_jni
+
+PRODUCT_COPY_FILES := \
+ vendor/sample/frameworks/PlatformLibrary/com.example.android.platform_library.xml:system/etc/permissions/com.example.android.platform_library.xml
+
+PRODUCT_SDK_ADDON_NAME := platform_library
+
+PRODUCT_SDK_ADDON_COPY_FILES := \
+ vendor/sample/sdk_addon/hardware.ini:hardware.ini \
+ vendor/sample/sdk_addon/manifest.ini:manifest.ini
+
+
+# Add this to PRODUCT_SDK_ADDON_COPY_FILES to copy the files for an
+# emulator skin (or for samples)
+# $(call find-copy-subdir-files,*,development/emulator/skins/HVGA,skins/HVGA)
+
+PRODUCT_SDK_ADDON_COPY_MODULES := \
+ com.example.android.platform_library:libs/platform_library.jar
+
+PRODUCT_SDK_ADDON_DOC_MODULE := platform_library
+
+$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk.mk)
+
+# Overrides
+PRODUCT_NAME := sample_addon
diff --git a/sdk_addon/hardware.ini b/sdk_addon/hardware.ini
new file mode 100644
index 0000000..e809bf5
--- /dev/null
+++ b/sdk_addon/hardware.ini
@@ -0,0 +1 @@
+#no custom hardware setup for google add-ons
diff --git a/sdk_addon/manifest.ini b/sdk_addon/manifest.ini
new file mode 100644
index 0000000..d91c53c
--- /dev/null
+++ b/sdk_addon/manifest.ini
@@ -0,0 +1,19 @@
+# SDK Add-on Manifest
+
+name=Sample Add-On
+vendor=Android Open Source Project
+description=sample add-on
+
+# version of the Android platform on which this add-on is built.
+api=3
+
+# version of the add-on
+version=1
+
+# list of libraries, separated by a semi-colon.
+libraries=com.example.android.platform_library
+
+# details for each library
+com.example.android.platform_library=platform_library.jar;Sample optional plaform library
+
+