am c84455c1: Introduce sample for RoundedBitmapDrawable

* commit 'c84455c11fdace9bc5c82aae99318bd9cd2480fa':
  Introduce sample for RoundedBitmapDrawable
diff --git a/apps/Development/Android.mk b/apps/Development/Android.mk
index 8c0f705..99133e8 100644
--- a/apps/Development/Android.mk
+++ b/apps/Development/Android.mk
@@ -3,7 +3,7 @@
 
 LOCAL_MODULE_TAGS := eng
 
-LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common org.apache.http.legacy
 
 LOCAL_SRC_FILES := $(call all-subdir-java-files) \
                 src/com/android/development/IRemoteService.aidl \
diff --git a/apps/Development/AndroidManifest.xml b/apps/Development/AndroidManifest.xml
index 5847201..3ac8190 100644
--- a/apps/Development/AndroidManifest.xml
+++ b/apps/Development/AndroidManifest.xml
@@ -47,6 +47,7 @@
 
     <application android:label="Dev Tools"
             android:icon="@mipmap/ic_launcher_devtools">
+        <uses-library android:name="org.apache.http.legacy" android:required="false" />
 
         <uses-library android:name="android.test.runner" />
 
diff --git a/apps/Development/res/layout/connectivity.xml b/apps/Development/res/layout/connectivity.xml
index d23a6b1..00ba508 100644
--- a/apps/Development/res/layout/connectivity.xml
+++ b/apps/Development/res/layout/connectivity.xml
@@ -350,6 +350,33 @@
           android:layout_height="wrap_content"
           android:text="@string/routed_socket_request" />
     </LinearLayout>
+
+    <!-- divider line -->
+    <View android:background="#FFFFFFFF"
+        android:layout_width="match_parent"
+        android:layout_height="3dip" />
+    <LinearLayout
+        android:orientation="horizontal"
+        android:paddingTop="4dip"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+        <Button android:id="@+id/link_stats"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/link_stats" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+        <TextView
+            android:id="@+id/stats"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/stats_results" />
+    </LinearLayout>
+
   </LinearLayout>
 </ScrollView>
 
diff --git a/apps/Development/res/values/strings.xml b/apps/Development/res/values/strings.xml
index d670cf4..3ef8845 100644
--- a/apps/Development/res/values/strings.xml
+++ b/apps/Development/res/values/strings.xml
@@ -33,6 +33,8 @@
     <string name="start_scan">Start Scan</string>
     <string name="scan_cycles">Scan Cycles: </string>
     <string name="disconnect">Disconnect</string>
+    <string name="link_stats">Link Stats</string>
+    <string name="stats_results"> results </string>
 
     <string name="start_tdls">Start TDLS</string>
     <string name="stop_tdls">Stop TDLS</string>
diff --git a/apps/Development/src/com/android/development/Connectivity.java b/apps/Development/src/com/android/development/Connectivity.java
index a576eb3..0f0030f 100644
--- a/apps/Development/src/com/android/development/Connectivity.java
+++ b/apps/Development/src/com/android/development/Connectivity.java
@@ -28,11 +28,16 @@
 import android.content.SharedPreferences;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
 import android.net.LinkAddress;
+import android.net.LinkProperties;
 import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
 import android.net.NetworkUtils;
 import android.net.RouteInfo;
 import android.net.wifi.ScanResult;
+import android.net.wifi.WifiActivityEnergyInfo;
 import android.net.wifi.WifiManager;
 import android.os.RemoteException;
 import android.os.Handler;
@@ -119,6 +124,8 @@
     private long mTotalScanTime = 0;
     private long mTotalScanCount = 0;
 
+    private TextView mLinkStatsResults;
+
     private String mTdlsAddr = null;
 
     private WifiManager mWm;
@@ -251,6 +258,34 @@
         }
     }
 
+    private static class DevToolsNetworkCallback extends NetworkCallback {
+        private static final String TAG = "DevToolsNetworkCallback";
+
+        public void onPreCheck(Network network) {
+            Log.d(TAG, "onPreCheck: " + network.netId);
+        }
+
+        public void onAvailable(Network network) {
+            Log.d(TAG, "onAvailable: " + network.netId);
+        }
+
+        public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) {
+            Log.d(TAG, "onCapabilitiesChanged: " + network.netId + " " + nc.toString());
+        }
+
+        public void onLinkPropertiesChanged(Network network, LinkProperties lp) {
+            Log.d(TAG, "onLinkPropertiesChanged: " + network.netId + " " + lp.toString());
+        }
+
+        public void onLosing(Network network, int maxMsToLive) {
+            Log.d(TAG, "onLosing: " + network.netId + " " + maxMsToLive);
+        }
+
+        public void onLost(Network network) {
+            Log.d(TAG, "onLost: " + network.netId);
+        }
+    }
+    private DevToolsNetworkCallback mCallback;
 
     @Override
     public void onCreate(Bundle icicle) {
@@ -316,13 +351,26 @@
         findViewById(R.id.routed_socket_request).setOnClickListener(mClickListener);
         findViewById(R.id.default_request).setOnClickListener(mClickListener);
         findViewById(R.id.default_socket).setOnClickListener(mClickListener);
+        findViewById(R.id.link_stats).setOnClickListener(mClickListener);
 
         registerReceiver(mReceiver, new IntentFilter(CONNECTIVITY_TEST_ALARM));
+
+        mLinkStatsResults = (TextView)findViewById(R.id.stats);
+        mLinkStatsResults.setVisibility(View.VISIBLE);
+
+        NetworkRequest.Builder builder = new NetworkRequest.Builder();
+        for (int i = 0; i < 255; i++) {
+            try { builder.removeCapability(i); } catch (IllegalArgumentException e) {}
+        }
+        NetworkRequest request = builder.build();
+        mCallback = new DevToolsNetworkCallback();
+        mCm.registerNetworkCallback(request, mCallback);
     }
 
     @Override
     public void onDestroy() {
         super.onDestroy();
+        mCm.unregisterNetworkCallback(mCallback);
         unregisterReceiver(mReceiver);
     }
 
@@ -408,6 +456,9 @@
                     mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
                             Phone.FEATURE_ENABLE_HIPRI);
                     break;
+                case R.id.link_stats:
+                    onLinkStats();
+                    break;
             }
         }
     };
@@ -544,6 +595,22 @@
         }
     }
 
+    private void onLinkStats() {
+        Log.e(TAG, "LINK STATS:  ");
+        try {
+            WifiActivityEnergyInfo info =
+                    mWm.getControllerActivityEnergyInfo(0);
+            if (info != null) {
+                mLinkStatsResults.setText(" power " + info.toString());
+            } else {
+                mLinkStatsResults.setText(" null! ");
+            }
+        } catch (Exception e) {
+            mLinkStatsResults.setText(" failed! " + e.toString());
+        }
+    }
+
+
     private void onAddDefaultRoute() {
         try {
             int netId = Integer.valueOf(((TextView) findViewById(R.id.netid)).getText().toString());
diff --git a/apps/Fallback/res/values-en-rAU/strings.xml b/apps/Fallback/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..a7c82cb
--- /dev/null
+++ b/apps/Fallback/res/values-en-rAU/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Fallback"</string>
+    <string name="title" msgid="8156274565006125136">"Unsupported action"</string>
+    <string name="error" msgid="6539615832923362301">"That action is not currently supported."</string>
+</resources>
diff --git a/apps/Fallback/res/values-gu-rIN/strings.xml b/apps/Fallback/res/values-gu-rIN/strings.xml
new file mode 100644
index 0000000..486a94f
--- /dev/null
+++ b/apps/Fallback/res/values-gu-rIN/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Fallback"</string>
+    <string name="title" msgid="8156274565006125136">"અસમર્થિત ક્રિયા"</string>
+    <string name="error" msgid="6539615832923362301">"તે ક્રિયા વર્તમાનમાં સમર્થિત નથી."</string>
+</resources>
diff --git a/apps/Fallback/res/values-pa-rIN/strings.xml b/apps/Fallback/res/values-pa-rIN/strings.xml
new file mode 100644
index 0000000..d358b1e
--- /dev/null
+++ b/apps/Fallback/res/values-pa-rIN/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"ਪਿੱਛੇ ਜਾਓ"</string>
+    <string name="title" msgid="8156274565006125136">"ਅਸਮਰਥਿਤ ਕਿਰਿਆ"</string>
+    <string name="error" msgid="6539615832923362301">"ਉਹ ਕਿਰਿਆ ਇਸ ਵੇਲੇ ਸਮਰਥਿਤ ਨਹੀਂ ਹੈ।"</string>
+</resources>
diff --git a/apps/Fallback/res/values-sl/strings.xml b/apps/Fallback/res/values-sl/strings.xml
index 322f466..16f30ab 100644
--- a/apps/Fallback/res/values-sl/strings.xml
+++ b/apps/Fallback/res/values-sl/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="appTitle" msgid="161410001913116606">"Nadomestni program"</string>
+    <string name="appTitle" msgid="161410001913116606">"Nadomestna aplikacija"</string>
     <string name="title" msgid="8156274565006125136">"Dejanje ni podprto."</string>
     <string name="error" msgid="6539615832923362301">"To dejanje trenutno še ni podprto."</string>
 </resources>
diff --git a/apps/Fallback/res/values-sq-rAL/strings.xml b/apps/Fallback/res/values-sq-rAL/strings.xml
new file mode 100644
index 0000000..88ad3da
--- /dev/null
+++ b/apps/Fallback/res/values-sq-rAL/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle" msgid="161410001913116606">"Alternativa"</string>
+    <string name="title" msgid="8156274565006125136">"Veprimi nuk mbështetet"</string>
+    <string name="error" msgid="6539615832923362301">"Ai veprim nuk mbështetet."</string>
+</resources>
diff --git a/apps/SdkSetup/src/com/android/sdksetup/DefaultActivity.java b/apps/SdkSetup/src/com/android/sdksetup/DefaultActivity.java
index 3a0b2a3..505a353 100644
--- a/apps/SdkSetup/src/com/android/sdksetup/DefaultActivity.java
+++ b/apps/SdkSetup/src/com/android/sdksetup/DefaultActivity.java
@@ -32,19 +32,21 @@
  *
  */
 public class DefaultActivity extends Activity {
-    
+
     @Override
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
-        
+
         // Add a persistent setting to allow other apps to know the device has been provisioned.
         Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);
 
+        Settings.Secure.putInt(getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 1);
+
         // Enable the GPS.
         // Not needed since this SDK will contain the Settings app.
         Settings.Secure.putString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
                 LocationManager.GPS_PROVIDER);
-        
+
         // enable install from non market
         Settings.Global.putInt(getContentResolver(), Settings.Global.INSTALL_NON_MARKET_APPS, 1);
 
diff --git a/build/Android.mk b/build/Android.mk
index 9a27edc..8b0124b 100644
--- a/build/Android.mk
+++ b/build/Android.mk
@@ -86,6 +86,9 @@
 # The uiautomator stubs
 ALL_SDK_FILES += $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/android_uiautomator_intermediates/javalib.jar
 
+# org.apache.http.legacy.jar stubs
+ALL_SDK_FILES += $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/org.apache.http.legacy_intermediates/javalib.jar
+
 # $(1): the Java library name
 define _package_sdk_library
 $(eval _psm_build_module := $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/$(1)_intermediates/javalib.jar)
@@ -122,7 +125,7 @@
 
 ALL_SDK_FILES += $(HOST_OUT)/development/sdk/generated-api-versions.xml
 
-api_gen_jar := $(TOPDIR)prebuilts/tools/common/api-generator/api-generator-22.9.1.jar
+api_gen_jar := $(TOPDIR)prebuilts/tools/common/api-generator/api-generator-22.9.2.jar
 api_gen_deps := \
   $(TOPDIR)prebuilts/tools/common/kxml2-tools/kxml2-2.3.0.jar \
   $(TOPDIR)prebuilts/tools/common/asm-tools/asm-4.0.jar \
diff --git a/build/build_android_stubs.mk b/build/build_android_stubs.mk
index a028900..f74d23c 100644
--- a/build/build_android_stubs.mk
+++ b/build/build_android_stubs.mk
@@ -19,6 +19,7 @@
 # resource files here.
 intermediates := $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/$(sdk_stub_name)_intermediates
 full_target := $(intermediates)/classes.jar
+jack_lib := $(intermediates)/classes.jack
 src_dir := $(intermediates)/src
 classes_dir := $(intermediates)/classes
 framework_res_package := $(call intermediates-dir-for,APPS,framework-res,,COMMON)/package-export.apk
@@ -49,3 +50,6 @@
 	$(hide) mkdir -p $(dir $@)
 	$(hide) jar -cf $@ -C $(PRIVATE_CLASS_INTERMEDIATES_DIR) .
 	$(hide) jar -u0f $@ -C $(PRIVATE_CLASS_INTERMEDIATES_DIR) resources.arsc
+
+$(jack_lib) : $(full_target) $(JILL_JAR) $(JACK_JAR)
+	$(transform-jar-to-jack)
\ No newline at end of file
diff --git a/build/optional.json b/build/optional.json
new file mode 100644
index 0000000..27216d9
--- /dev/null
+++ b/build/optional.json
@@ -0,0 +1,8 @@
+[
+  {
+    "name": "org.apache.http.legacy",
+    "jar": "org.apache.http.legacy.jar",
+    "manifest": false
+  }
+]
+
diff --git a/build/sdk-android-mips64.atree b/build/sdk-android-mips64.atree
new file mode 100644
index 0000000..b356b28
--- /dev/null
+++ b/build/sdk-android-mips64.atree
@@ -0,0 +1,21 @@
+#
+# Copyright (C) 2015 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.
+#
+
+# Copy the little-endian mips64-fp kernel image to .../kernel-qemu
+prebuilts/qemu-kernel/${TARGET_ARCH}/kernel-qemu system-images/${PLATFORM_NAME}/${TARGET_CPU_ABI}/kernel-qemu
+
+# version files for the SDK updater, from development.git
+development/sys-img-${TARGET_CPU_ABI}/images_mips64_source.properties   system-images/${PLATFORM_NAME}/${TARGET_CPU_ABI}/source.properties
diff --git a/build/sdk-darwin-x86.atree b/build/sdk-darwin-x86.atree
index 6efec25..0ed8e20 100644
--- a/build/sdk-darwin-x86.atree
+++ b/build/sdk-darwin-x86.atree
@@ -15,6 +15,12 @@
 #
 
 ##############################################################################
+# Platform Tools Component
+##############################################################################
+
+lib/libc++.dylib                                      strip platform-tools/lib/libc++.dylib
+
+##############################################################################
 # Build Tools Component
 ##############################################################################
 # Note that the build-tools sub-folder uses the platform-name as a placeholder
@@ -22,11 +28,11 @@
 # revision as specified in the source.properties.
 
 
-lib/libLLVM.dylib                                     strip build-tools/${PLATFORM_NAME}/../lib/libLLVM.dylib
-lib/libbcc.dylib                                      strip build-tools/${PLATFORM_NAME}/../lib/libbcc.dylib
-lib/libbcinfo.dylib                                   strip build-tools/${PLATFORM_NAME}/../lib/libbcinfo.dylib
-lib/libclang.dylib                                    strip build-tools/${PLATFORM_NAME}/../lib/libclang.dylib
-lib/libc++.dylib                                      strip build-tools/${PLATFORM_NAME}/../lib/libc++.dylib
+lib/libLLVM.dylib                                     strip build-tools/${PLATFORM_NAME}/lib/libLLVM.dylib
+lib/libbcc.dylib                                      strip build-tools/${PLATFORM_NAME}/lib/libbcc.dylib
+lib/libbcinfo.dylib                                   strip build-tools/${PLATFORM_NAME}/lib/libbcinfo.dylib
+lib/libclang.dylib                                    strip build-tools/${PLATFORM_NAME}/lib/libclang.dylib
+lib/libc++.dylib                                      strip build-tools/${PLATFORM_NAME}/lib/libc++.dylib
 
 prebuilts/sdk/tools/darwin/bin/arm-linux-androideabi-ld   strip build-tools/${PLATFORM_NAME}/arm-linux-androideabi-ld
 prebuilts/sdk/tools/darwin/bin/i686-linux-android-ld      strip build-tools/${PLATFORM_NAME}/i686-linux-android-ld
diff --git a/build/sdk-linux-x86.atree b/build/sdk-linux-x86.atree
index ec8364f..63dcbc3 100644
--- a/build/sdk-linux-x86.atree
+++ b/build/sdk-linux-x86.atree
@@ -15,6 +15,12 @@
 #
 
 ##############################################################################
+# Platform Tools Component
+##############################################################################
+
+lib/libc++.so                                        strip platform-tools/lib/libc++.so
+
+##############################################################################
 # Build Tools Component
 ##############################################################################
 # Note that the build-tools sub-folder uses the platform-name as a placeholder
@@ -22,11 +28,11 @@
 # revision as specified in the source.properties.
 
 
-lib/libLLVM.so                                       strip build-tools/${PLATFORM_NAME}/../lib/libLLVM.so
-lib/libbcc.so                                        strip build-tools/${PLATFORM_NAME}/../lib/libbcc.so
-lib/libbcinfo.so                                     strip build-tools/${PLATFORM_NAME}/../lib/libbcinfo.so
-lib/libclang.so                                      strip build-tools/${PLATFORM_NAME}/../lib/libclang.so
-lib/libc++.so                                        strip build-tools/${PLATFORM_NAME}/../lib/libc++.so
+lib/libLLVM.so                                       strip build-tools/${PLATFORM_NAME}/lib/libLLVM.so
+lib/libbcc.so                                        strip build-tools/${PLATFORM_NAME}/lib/libbcc.so
+lib/libbcinfo.so                                     strip build-tools/${PLATFORM_NAME}/lib/libbcinfo.so
+lib/libclang.so                                      strip build-tools/${PLATFORM_NAME}/lib/libclang.so
+lib/libc++.so                                        strip build-tools/${PLATFORM_NAME}/lib/libc++.so
 
 prebuilts/sdk/tools/linux/bin/arm-linux-androideabi-ld   strip build-tools/${PLATFORM_NAME}/arm-linux-androideabi-ld
 prebuilts/sdk/tools/linux/bin/i686-linux-android-ld      strip build-tools/${PLATFORM_NAME}/i686-linux-android-ld
diff --git a/build/sdk-windows-x86.atree b/build/sdk-windows-x86.atree
index 5fc9677..cbde057 100644
--- a/build/sdk-windows-x86.atree
+++ b/build/sdk-windows-x86.atree
@@ -78,19 +78,19 @@
 rm build-tools/${PLATFORM_NAME}/llvm-rs-cc
 bin/llvm-rs-cc.exe                      strip build-tools/${PLATFORM_NAME}/llvm-rs-cc.exe
 
-rm build-tools/${PLATFORM_NAME}/../lib/libLLVM.so
-lib/libLLVM.dll                         strip build-tools/${PLATFORM_NAME}/../lib/libLLVM.dll
+rm build-tools/${PLATFORM_NAME}/lib/libLLVM.so
+lib/libLLVM.dll                         strip build-tools/${PLATFORM_NAME}/lib/libLLVM.dll
 
-rm build-tools/${PLATFORM_NAME}/../lib/libclang.so
-lib/libclang.dll                        strip build-tools/${PLATFORM_NAME}/../lib/libclang.dll
+rm build-tools/${PLATFORM_NAME}/lib/libclang.so
+lib/libclang.dll                        strip build-tools/${PLATFORM_NAME}/lib/libclang.dll
 
 #bcc not yet compiled on windows
 
-rm build-tools/${PLATFORM_NAME}/../lib/libbcc.so
-lib/libbcc.dll                          strip build-tools/${PLATFORM_NAME}/../lib/libbcc.dll
+rm build-tools/${PLATFORM_NAME}/lib/libbcc.so
+lib/libbcc.dll                          strip build-tools/${PLATFORM_NAME}/lib/libbcc.dll
 
-rm build-tools/${PLATFORM_NAME}/../lib/libbcinfo.so
-lib/libbcinfo.dll                       strip build-tools/${PLATFORM_NAME}/../lib/libbcinfo.dll
+rm build-tools/${PLATFORM_NAME}/lib/libbcinfo.so
+lib/libbcinfo.dll                       strip build-tools/${PLATFORM_NAME}/lib/libbcinfo.dll
 
 rm build-tools/${PLATFORM_NAME}/bcc_compat
 bin/bcc_compat.exe                      strip build-tools/${PLATFORM_NAME}/bcc_compat.exe
diff --git a/build/sdk.atree b/build/sdk.atree
index c7cb28a..a39756c 100644
--- a/build/sdk.atree
+++ b/build/sdk.atree
@@ -53,6 +53,9 @@
 # API database for tools such as lint
 development/sdk/generated-api-versions.xml    platform-tools/api/api-versions.xml
 
+# API annotations database for lint
+prebuilts/sdk/sdk-annotations/annotations.zip   platform-tools/api/annotations.zip
+
 # systrace
 external/chromium-trace/systrace.py                   platform-tools/systrace/systrace.py
 external/chromium-trace/systrace-legacy.py            platform-tools/systrace/systrace-legacy.py
@@ -95,6 +98,7 @@
 prebuilts/sdk/renderscript/lib/arm/libcompiler_rt.a   build-tools/${PLATFORM_NAME}/renderscript/lib/intermediates/armeabi-v7a/libcompiler_rt.a
 prebuilts/sdk/renderscript/lib/arm/libRSSupport.so    build-tools/${PLATFORM_NAME}/renderscript/lib/packaged/armeabi-v7a/libRSSupport.so
 prebuilts/sdk/renderscript/lib/arm/librsjni.so        build-tools/${PLATFORM_NAME}/renderscript/lib/packaged/armeabi-v7a/librsjni.so
+prebuilts/sdk/renderscript/lib/arm/libblas.so        build-tools/${PLATFORM_NAME}/renderscript/lib/packaged/armeabi-v7a/libblas.so
 prebuilts/sdk/renderscript/lib/arm/libclcore.bc       build-tools/${PLATFORM_NAME}/renderscript/lib/bc/armeabi-v7a/libclcore.bc
 
 prebuilts/sdk/renderscript/lib/mips/libc.so            build-tools/${PLATFORM_NAME}/renderscript/lib/intermediates/mips/libc.so
@@ -102,6 +106,7 @@
 prebuilts/sdk/renderscript/lib/mips/libcompiler_rt.a   build-tools/${PLATFORM_NAME}/renderscript/lib/intermediates/mips/libcompiler_rt.a
 prebuilts/sdk/renderscript/lib/mips/libRSSupport.so    build-tools/${PLATFORM_NAME}/renderscript/lib/packaged/mips/libRSSupport.so
 prebuilts/sdk/renderscript/lib/mips/librsjni.so        build-tools/${PLATFORM_NAME}/renderscript/lib/packaged/mips/librsjni.so
+prebuilts/sdk/renderscript/lib/mips/libblas.so        build-tools/${PLATFORM_NAME}/renderscript/lib/packaged/mips/libblas.so
 prebuilts/sdk/renderscript/lib/mips/libclcore.bc       build-tools/${PLATFORM_NAME}/renderscript/lib/bc/mips/libclcore.bc
 
 prebuilts/sdk/renderscript/lib/x86/libc.so            build-tools/${PLATFORM_NAME}/renderscript/lib/intermediates/x86/libc.so
@@ -109,10 +114,10 @@
 prebuilts/sdk/renderscript/lib/x86/libcompiler_rt.a   build-tools/${PLATFORM_NAME}/renderscript/lib/intermediates/x86/libcompiler_rt.a
 prebuilts/sdk/renderscript/lib/x86/libRSSupport.so    build-tools/${PLATFORM_NAME}/renderscript/lib/packaged/x86/libRSSupport.so
 prebuilts/sdk/renderscript/lib/x86/librsjni.so        build-tools/${PLATFORM_NAME}/renderscript/lib/packaged/x86/librsjni.so
+prebuilts/sdk/renderscript/lib/x86/libblas.so        build-tools/${PLATFORM_NAME}/renderscript/lib/packaged/x86/libblas.so
 prebuilts/sdk/renderscript/lib/x86/libclcore.bc       build-tools/${PLATFORM_NAME}/renderscript/lib/bc/x86/libclcore.bc
 
 
-
 # dx
 bin/dx                                        build-tools/${PLATFORM_NAME}/dx
 framework/dx.jar                              build-tools/${PLATFORM_NAME}/lib/dx.jar
@@ -130,17 +135,21 @@
 ##############################################################################
 
 # version files for the SDK updater, from development.git
-${HOST_OUT}/development/sdk/platform_source.properties platforms/${PLATFORM_NAME}/source.properties
+${HOST_OUT}/development/sdk/platform_source.properties                                       platforms/${PLATFORM_NAME}/source.properties
 
 # copy build prop from out/.../sdk/
-sdk/sdk-build.prop                            platforms/${PLATFORM_NAME}/build.prop
+sdk/sdk-build.prop                                                                           platforms/${PLATFORM_NAME}/build.prop
 
-# the uper-jar file that apps link against. This is the public API
-${OUT_DIR}/target/common/obj/PACKAGING/android_jar_intermediates/android.jar              platforms/${PLATFORM_NAME}/android.jar
-${OUT_DIR}/target/common/obj/JAVA_LIBRARIES/android_uiautomator_intermediates/javalib.jar platforms/${PLATFORM_NAME}/uiautomator.jar
+# Main Public API jar
+${OUT_DIR}/target/common/obj/PACKAGING/android_jar_intermediates/android.jar                 platforms/${PLATFORM_NAME}/android.jar
+# optional API files.
+development/build/optional.json                                                              platforms/${PLATFORM_NAME}/optional/optional.json
+${OUT_DIR}/target/common/obj/JAVA_LIBRARIES/org.apache.http.legacy_intermediates/javalib.jar platforms/${PLATFORM_NAME}/optional/org.apache.http.legacy.jar
+# deprecated APIs
+${OUT_DIR}/target/common/obj/JAVA_LIBRARIES/android_uiautomator_intermediates/javalib.jar    platforms/${PLATFORM_NAME}/uiautomator.jar
 
 # the aidl precompiled include
-obj/framework.aidl platforms/${PLATFORM_NAME}/framework.aidl
+obj/framework.aidl                                                                           platforms/${PLATFORM_NAME}/framework.aidl
 
 # emulator skins from sdk.git
 development/tools/emulator/skins/QVGA          platforms/${PLATFORM_NAME}/skins/QVGA
@@ -171,7 +180,6 @@
 
 # Eclipse Editors support
 framework/layoutlib.jar                   platforms/${PLATFORM_NAME}/data/layoutlib.jar
-framework/icu4j.jar                       platforms/${PLATFORM_NAME}/data/icu4j.jar
 frameworks/base/core/res/res              platforms/${PLATFORM_NAME}/data/res
 docs/activity_actions.txt                 platforms/${PLATFORM_NAME}/data/activity_actions.txt
 docs/broadcast_actions.txt                platforms/${PLATFORM_NAME}/data/broadcast_actions.txt
@@ -250,11 +258,6 @@
 developers/build/prebuilts/gradle/MediaRecorder/                             samples/${PLATFORM_NAME}/media/MediaRecorder
 developers/build/prebuilts/gradle/BasicMediaRouter/                          samples/${PLATFORM_NAME}/media/BasicMediaRouter
 developers/build/prebuilts/gradle/BasicMediaDecoder/                         samples/${PLATFORM_NAME}/media/BasicMediaDecoder
-developers/build/prebuilts/gradle/MediaBrowserService/                       samples/${PLATFORM_NAME}/media/MediaBrowserService
-developers/build/prebuilts/gradle/BasicNotifications/                        samples/${PLATFORM_NAME}/notification/BasicNotifications
-developers/build/prebuilts/gradle/CustomNotifications/                       samples/${PLATFORM_NAME}/notification/CustomNotifications
-developers/build/prebuilts/gradle/LNotifications/                            samples/${PLATFORM_NAME}/notification/LNotifications
-developers/build/prebuilts/gradle/MessagingService/                          samples/${PLATFORM_NAME}/notification/MessagingService
 developers/build/prebuilts/gradle/BorderlessButtons/                         samples/${PLATFORM_NAME}/ui/BorderlessButtons
 developers/build/prebuilts/gradle/BasicAccessibility/                        samples/${PLATFORM_NAME}/ui/BasicAccessibility
 developers/build/prebuilts/gradle/CustomChoiceList/                          samples/${PLATFORM_NAME}/ui/CustomChoiceList
@@ -264,6 +267,8 @@
 developers/build/prebuilts/gradle/ActionBarCompat-ListPopupMenu/             samples/${PLATFORM_NAME}/ui/ActionBarCompat-ListPopupMenu
 developers/build/prebuilts/gradle/ActionBarCompat-ShareActionProvider/       samples/${PLATFORM_NAME}/ui/ActionBarCompat-ShareActionProvider
 developers/build/prebuilts/gradle/ActionBarCompat-Basic/                     samples/${PLATFORM_NAME}/ui/ActionBarCompat-Basic
+developers/build/prebuilts/gradle/BasicNotifications/                        samples/${PLATFORM_NAME}/ui/BasicNotifications
+developers/build/prebuilts/gradle/CustomNotifications/                       samples/${PLATFORM_NAME}/ui/CustomNotifications
 developers/build/prebuilts/gradle/DoneBar/                                   samples/${PLATFORM_NAME}/ui/DoneBar
 developers/build/prebuilts/gradle/BasicImmersiveMode/                        samples/${PLATFORM_NAME}/ui/BasicImmersiveMode
 developers/build/prebuilts/gradle/AdvancedImmersiveMode/                     samples/${PLATFORM_NAME}/ui/AdvancedImmersiveMode
@@ -302,6 +307,7 @@
 developers/build/prebuilts/gradle/AppRestrictionSchema                       samples/${PLATFORM_NAME}/admin/AppRestrictionSchema
 developers/build/prebuilts/gradle/RecyclerView                               samples/${PLATFORM_NAME}/ui/views/RecyclerView
 developers/build/prebuilts/gradle/CardView                                   samples/${PLATFORM_NAME}/ui/views/CardView
+developers/build/prebuilts/gradle/LNotifications                             samples/${PLATFORM_NAME}/ui/notifications/LNotifications
 developers/build/prebuilts/gradle/DrawableTinting                            samples/${PLATFORM_NAME}/ui/DrawableTinting
 developers/build/prebuilts/gradle/Interpolator                               samples/${PLATFORM_NAME}/ui/Interpolator
 developers/build/prebuilts/gradle/PdfRendererBasic                           samples/${PLATFORM_NAME}/ui/graphics/PdfRendererBasic
@@ -313,6 +319,13 @@
 developers/build/prebuilts/gradle/ScreenCapture                              samples/${PLATFORM_NAME}/media/ScreenCapture
 developers/build/prebuilts/gradle/NfcProvisioning                            samples/${PLATFORM_NAME}/nfc/NfcProvisioning
 developers/build/prebuilts/gradle/DeviceOwner                                samples/${PLATFORM_NAME}/admin/DeviceOwner
+developers/build/prebuilts/gradle/ConfirmCredential                          samples/${PLATFORM_NAME}/security/ConfirmCredential
+developers/build/prebuilts/gradle/FingerprintDialog                          samples/${PLATFORM_NAME}/security/FingerprintDialog
+developers/build/prebuilts/gradle/RuntimePermissions                         samples/${PLATFORM_NAME}/system/RuntimePermissions
+developers/build/prebuilts/gradle/RuntimePermissionsBasic                    samples/${PLATFORM_NAME}/system/RuntimePermissionsBasic
+developers/build/prebuilts/gradle/ActiveNotifications                        samples/${PLATFORM_NAME}/notification/ActiveNotifications
+developers/build/prebuilts/gradle/Camera2Raw                                 samples/${PLATFORM_NAME}/media/Camera2Raw
+developers/build/prebuilts/gradle/AutoBackupForApps                          samples/${PLATFORM_NAME}/content/AutoBackupForApps
 
 developers/build/prebuilts/androidtv                                         samples/${PLATFORM_NAME}/androidtv
 
@@ -339,7 +352,6 @@
 
 # Old sample tree
 development/samples/AccelerometerPlay          samples/${PLATFORM_NAME}/legacy/AccelerometerPlay
-development/samples/ActionBarCompat            samples/${PLATFORM_NAME}/legacy/ActionBarCompat
 development/samples/AndroidBeamDemo            samples/${PLATFORM_NAME}/legacy/AndroidBeamDemo
 development/samples/ApiDemos                   samples/${PLATFORM_NAME}/legacy/ApiDemos
 development/samples/AppNavigation              samples/${PLATFORM_NAME}/legacy/AppNavigation
diff --git a/build/tools/sdk_repo.mk b/build/tools/sdk_repo.mk
index db8808a..bc8481e 100644
--- a/build/tools/sdk_repo.mk
+++ b/build/tools/sdk_repo.mk
@@ -183,6 +183,7 @@
 # -----------------------------------------------------------------
 # Rules for sdk addon
 
+ifneq ($(filter sdk_addon,$(MAKECMDGOALS)),)
 ifneq ($(ADDON_SDK_ZIP),)
 
 # ADDON_SDK_ZIP is defined in build/core/tasks/sdk-addon.sh and is
@@ -224,6 +225,7 @@
 $(call dist-for-goals, sdk_repo, $(SDK_ADDON_IMG_XML))
 
 endif
+endif
 
 # -----------------------------------------------------------------
 # Rules for the SDK Repository XML
diff --git a/cmds/monkey/src/com/android/commands/monkey/Monkey.java b/cmds/monkey/src/com/android/commands/monkey/Monkey.java
index dfcb4b0..93bfcf0 100644
--- a/cmds/monkey/src/com/android/commands/monkey/Monkey.java
+++ b/cmds/monkey/src/com/android/commands/monkey/Monkey.java
@@ -31,15 +31,12 @@
 import android.os.ServiceManager;
 import android.os.StrictMode;
 import android.os.SystemClock;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.view.IWindowManager;
 import android.view.Surface;
 
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
 import java.io.File;
 import java.io.FileReader;
 import java.io.FileWriter;
@@ -47,12 +44,12 @@
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Writer;
-import java.security.SecureRandom;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Random;
+import java.util.Set;
 
 /**
  * Application that injects random key events and other actions into the system.
@@ -181,12 +178,6 @@
     /** Package whitelist file. */
     private String mPkgWhitelistFile;
 
-    /** Packages we are allowed to run, or empty if no restriction. */
-    private HashSet<String> mValidPackages = new HashSet<String>();
-
-    /** Packages we are not allowed to run. */
-    private HashSet<String> mInvalidPackages = new HashSet<String>();
-
     /** Categories we are allowed to launch **/
     private ArrayList<String> mMainCategories = new ArrayList<String>();
 
@@ -251,36 +242,20 @@
 
     private MonkeyNetworkMonitor mNetworkMonitor = new MonkeyNetworkMonitor();
 
+    private boolean mPermissionTargetSystem = false;
+
     // information on the current activity.
     public static Intent currentIntent;
 
     public static String currentPackage;
 
     /**
-     * Check whether we should run against the givn package.
-     *
-     * @param pkg The package name.
-     * @return Returns true if we should run against pkg.
-     */
-    private boolean checkEnteringPackage(String pkg) {
-        if (mInvalidPackages.size() > 0) {
-            if (mInvalidPackages.contains(pkg)) {
-                return false;
-            }
-        } else if (mValidPackages.size() > 0) {
-            if (!mValidPackages.contains(pkg)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
      * Monitor operations happening in the system.
      */
     private class ActivityController extends IActivityController.Stub {
         public boolean activityStarting(Intent intent, String pkg) {
-            boolean allow = checkEnteringPackage(pkg) || (DEBUG_ALLOW_ANY_STARTS != 0);
+            boolean allow = MonkeyUtils.getPackageFilter().checkEnteringPackage(pkg)
+                    || (DEBUG_ALLOW_ANY_STARTS != 0);
             if (mVerbose > 0) {
                 // StrictMode's disk checks end up catching this on
                 // userdebug/eng builds due to PrintStream going to a
@@ -301,7 +276,8 @@
         public boolean activityResuming(String pkg) {
             StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
             System.out.println("    // activityResuming(" + pkg + ")");
-            boolean allow = checkEnteringPackage(pkg) || (DEBUG_ALLOW_ANY_RESTARTS != 0);
+            boolean allow = MonkeyUtils.getPackageFilter().checkEnteringPackage(pkg)
+                    || (DEBUG_ALLOW_ANY_RESTARTS != 0);
             if (!allow) {
                 if (mVerbose > 0) {
                     System.out.println("    // " + (allow ? "Allowing" : "Rejecting")
@@ -559,18 +535,7 @@
 
         if (mVerbose > 0) {
             System.out.println(":Monkey: seed=" + mSeed + " count=" + mCount);
-            if (mValidPackages.size() > 0) {
-                Iterator<String> it = mValidPackages.iterator();
-                while (it.hasNext()) {
-                    System.out.println(":AllowPackage: " + it.next());
-                }
-            }
-            if (mInvalidPackages.size() > 0) {
-                Iterator<String> it = mInvalidPackages.iterator();
-                while (it.hasNext()) {
-                    System.out.println(":DisallowPackage: " + it.next());
-                }
-            }
+            MonkeyUtils.getPackageFilter().dump();
             if (mMainCategories.size() != 0) {
                 Iterator<String> it = mMainCategories.iterator();
                 while (it.hasNext()) {
@@ -626,7 +591,8 @@
             if (mVerbose >= 2) { // check seeding performance
                 System.out.println("// Seeded: " + mSeed);
             }
-            mEventSource = new MonkeySourceRandom(mRandom, mMainApps, mThrottle, mRandomizeThrottle);
+            mEventSource = new MonkeySourceRandom(mRandom, mMainApps,
+                    mThrottle, mRandomizeThrottle, mPermissionTargetSystem);
             mEventSource.setVerbose(mVerbose);
             // set any of the factors that has been set
             for (int i = 0; i < MonkeySourceRandom.FACTORZ_COUNT; i++) {
@@ -756,11 +722,12 @@
 
         try {
             String opt;
+            Set<String> validPackages = new HashSet<>();
             while ((opt = nextOption()) != null) {
                 if (opt.equals("-s")) {
                     mSeed = nextOptionLong("Seed");
                 } else if (opt.equals("-p")) {
-                    mValidPackages.add(nextOptionData());
+                    validPackages.add(nextOptionData());
                 } else if (opt.equals("-c")) {
                     mMainCategories.add(nextOptionData());
                 } else if (opt.equals("-v")) {
@@ -812,6 +779,9 @@
                 } else if (opt.equals("--pct-pinchzoom")) {
                     int i = MonkeySourceRandom.FACTOR_PINCHZOOM;
                     mFactors[i] = -nextOptionLong("pinch zoom events percentage");
+                } else if (opt.equals("--pct-permission")) {
+                    int i = MonkeySourceRandom.FACTOR_PERMISSION;
+                    mFactors[i] = -nextOptionLong("runtime permission toggle events percentage");
                 } else if (opt.equals("--pkg-blacklist-file")) {
                     mPkgBlacklistFile = nextOptionData();
                 } else if (opt.equals("--pkg-whitelist-file")) {
@@ -845,6 +815,8 @@
                 } else if (opt.equals("--periodic-bugreport")){
                     mGetPeriodicBugreport = true;
                     mBugreportFrequency = nextOptionLong("Number of iterations");
+                } else if (opt.equals("--permission-target-system")){
+                    mPermissionTargetSystem = true;
                 } else if (opt.equals("-h")) {
                     showUsage();
                     return false;
@@ -854,6 +826,7 @@
                     return false;
                 }
             }
+            MonkeyUtils.getPackageFilter().addValidPackages(validPackages);
         } catch (RuntimeException ex) {
             System.err.println("** Error: " + ex.toString());
             showUsage();
@@ -889,7 +862,7 @@
      * @param list The destination list.
      * @return Returns false if any error occurs.
      */
-    private static boolean loadPackageListFromFile(String fileName, HashSet<String> list) {
+    private static boolean loadPackageListFromFile(String fileName, Set<String> list) {
         BufferedReader reader = null;
         try {
             reader = new BufferedReader(new FileReader(fileName));
@@ -921,20 +894,24 @@
      * @return Returns false if any error occurs.
      */
     private boolean loadPackageLists() {
-        if (((mPkgWhitelistFile != null) || (mValidPackages.size() > 0))
+        if (((mPkgWhitelistFile != null) || (MonkeyUtils.getPackageFilter().hasValidPackages()))
                 && (mPkgBlacklistFile != null)) {
             System.err.println("** Error: you can not specify a package blacklist "
                     + "together with a whitelist or individual packages (via -p).");
             return false;
         }
+        Set<String> validPackages = new HashSet<>();
         if ((mPkgWhitelistFile != null)
-                && (!loadPackageListFromFile(mPkgWhitelistFile, mValidPackages))) {
+                && (!loadPackageListFromFile(mPkgWhitelistFile, validPackages))) {
             return false;
         }
+        MonkeyUtils.getPackageFilter().addValidPackages(validPackages);
+        Set<String> invalidPackages = new HashSet<>();
         if ((mPkgBlacklistFile != null)
-                && (!loadPackageListFromFile(mPkgBlacklistFile, mInvalidPackages))) {
+                && (!loadPackageListFromFile(mPkgBlacklistFile, invalidPackages))) {
             return false;
         }
+        MonkeyUtils.getPackageFilter().addInvalidPackages(invalidPackages);
         return true;
     }
 
@@ -1014,7 +991,7 @@
                 for (int a = 0; a < NA; a++) {
                     ResolveInfo r = mainApps.get(a);
                     String packageName = r.activityInfo.applicationInfo.packageName;
-                    if (checkEnteringPackage(packageName)) {
+                    if (MonkeyUtils.getPackageFilter().checkEnteringPackage(packageName)) {
                         if (mVerbose >= 2) { // very verbose
                             System.out.println("//   + Using main activity " + r.activityInfo.name
                                     + " (from package " + packageName + ")");
@@ -1352,6 +1329,7 @@
         usage.append("              [--pct-nav PERCENT] [--pct-majornav PERCENT]\n");
         usage.append("              [--pct-appswitch PERCENT] [--pct-flip PERCENT]\n");
         usage.append("              [--pct-anyevent PERCENT] [--pct-pinchzoom PERCENT]\n");
+        usage.append("              [--pct-permission PERCENT]\n");
         usage.append("              [--pkg-blacklist-file PACKAGE_BLACKLIST_FILE]\n");
         usage.append("              [--pkg-whitelist-file PACKAGE_WHITELIST_FILE]\n");
         usage.append("              [--wait-dbg] [--dbg-no-events]\n");
@@ -1365,6 +1343,7 @@
         usage.append("              [--script-log]\n");
         usage.append("              [--bugreport]\n");
         usage.append("              [--periodic-bugreport]\n");
+        usage.append("              [--permission-target-system]\n");
         usage.append("              COUNT\n");
         System.err.println(usage.toString());
     }
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java
index 0a06604..ccae799 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java
@@ -31,7 +31,8 @@
     public static final int EVENT_TYPE_ACTIVITY = 4;
     public static final int EVENT_TYPE_FLIP = 5; // Keyboard flip
     public static final int EVENT_TYPE_THROTTLE = 6;
-    public static final int EVENT_TYPE_NOOP = 7;
+    public static final int EVENT_TYPE_PERMISSION = 7;
+    public static final int EVENT_TYPE_NOOP = 8;
 
     public static final int INJECT_SUCCESS = 1;
     public static final int INJECT_FAIL = 0;
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyPermissionEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyPermissionEvent.java
new file mode 100644
index 0000000..130827b
--- /dev/null
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyPermissionEvent.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 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.monkey;
+
+import android.app.IActivityManager;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.content.pm.PermissionInfo;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.view.IWindowManager;
+
+public class MonkeyPermissionEvent extends MonkeyEvent {
+    private String mPkg;
+    private PermissionInfo mPermissionInfo;
+
+    public MonkeyPermissionEvent(String pkg, PermissionInfo permissionInfo) {
+        super(EVENT_TYPE_PERMISSION);
+        mPkg = pkg;
+        mPermissionInfo = permissionInfo;
+    }
+
+    @Override
+    public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) {
+        IPackageManager pm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
+        try {
+            // determine if we should grant or revoke permission
+            int perm = pm.checkPermission(mPermissionInfo.name, mPkg, UserHandle.myUserId());
+            boolean grant = perm == PackageManager.PERMISSION_DENIED;
+            // log before calling pm in case we hit an error
+            System.out.println(String.format(":Permission %s %s to package %s",
+                    grant ? "grant" : "revoke", mPermissionInfo.name, mPkg));
+            if (grant) {
+                pm.grantRuntimePermission(mPkg, mPermissionInfo.name, UserHandle.myUserId());
+            } else {
+                pm.revokeRuntimePermission(mPkg, mPermissionInfo.name, UserHandle.myUserId());
+            }
+            return MonkeyEvent.INJECT_SUCCESS;
+        } catch (RemoteException re) {
+            return MonkeyEvent.INJECT_ERROR_REMOTE_EXCEPTION;
+        }
+    }
+}
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyPermissionUtil.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyPermissionUtil.java
new file mode 100644
index 0000000..8ab4937
--- /dev/null
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyPermissionUtil.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2015 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.monkey;
+
+import android.Manifest;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PermissionInfo;
+import android.os.Build;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+/**
+ * Utility class that encapsulates runtime permission related methods for monkey
+ *
+ */
+public class MonkeyPermissionUtil {
+
+    private static final String PERMISSION_PREFIX = "android.permission.";
+    private static final String PERMISSION_GROUP_PREFIX = "android.permission-group.";
+
+    // from com.android.packageinstaller.permission.utils
+    private static final String[] MODERN_PERMISSION_GROUPS = {
+            Manifest.permission_group.CALENDAR, Manifest.permission_group.CAMERA,
+            Manifest.permission_group.CONTACTS, Manifest.permission_group.LOCATION,
+            Manifest.permission_group.SENSORS, Manifest.permission_group.SMS,
+            Manifest.permission_group.PHONE, Manifest.permission_group.MICROPHONE,
+            Manifest.permission_group.STORAGE
+    };
+
+    // from com.android.packageinstaller.permission.utils
+    private static boolean isModernPermissionGroup(String name) {
+        for (String modernGroup : MODERN_PERMISSION_GROUPS) {
+            if (modernGroup.equals(name)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * actual list of packages to target, with invalid packages excluded, and may optionally include
+     * system packages
+     */
+    private List<String> mTargetedPackages;
+    /** if we should target system packages regardless if they are listed */
+    private boolean mTargetSystemPackages;
+    private IPackageManager mPm;
+
+    /** keep track of runtime permissions requested for each package targeted */
+    private Map<String, List<PermissionInfo>> mPermissionMap;
+
+    public MonkeyPermissionUtil() {
+        mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
+    }
+
+    public void setTargetSystemPackages(boolean targetSystemPackages) {
+        mTargetSystemPackages = targetSystemPackages;
+    }
+
+    /**
+     * Decide if a package should be targeted by permission monkey
+     * @param info
+     * @return
+     */
+    private boolean shouldTargetPackage(PackageInfo info) {
+        // target if permitted by white listing / black listing rules
+        if (MonkeyUtils.getPackageFilter().checkEnteringPackage(info.packageName)) {
+            return true;
+        }
+        if (mTargetSystemPackages
+                // not explicitly black listed
+                && !MonkeyUtils.getPackageFilter().isPackageInvalid(info.packageName)
+                // is a system app
+                && (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+            return true;
+        }
+        return false;
+    }
+
+    private boolean shouldTargetPermission(String pkg, PermissionInfo pi) throws RemoteException {
+        int flags = mPm.getPermissionFlags(pi.name, pkg, UserHandle.myUserId());
+        int fixedPermFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
+                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
+        return pi.group != null && pi.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS
+                && ((flags & fixedPermFlags) == 0)
+                && isModernPermissionGroup(pi.group);
+    }
+
+    public boolean populatePermissionsMapping() {
+        mPermissionMap = new HashMap<>();
+        try {
+            List<?> pkgInfos = mPm.getInstalledPackages(
+                    PackageManager.GET_PERMISSIONS, UserHandle.myUserId()).getList();
+            for (Object o : pkgInfos) {
+                PackageInfo info = (PackageInfo)o;
+                if (!shouldTargetPackage(info)) {
+                    continue;
+                }
+                List<PermissionInfo> permissions = new ArrayList<>();
+                if (info.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) {
+                    // skip apps targetting lower API level
+                    continue;
+                }
+                if (info.requestedPermissions == null) {
+                    continue;
+                }
+                for (String perm : info.requestedPermissions) {
+                    PermissionInfo pi = mPm.getPermissionInfo(perm, 0);
+                    if (pi != null && shouldTargetPermission(info.packageName, pi)) {
+                        permissions.add(pi);
+                    }
+                }
+                if (!permissions.isEmpty()) {
+                    mPermissionMap.put(info.packageName, permissions);
+                }
+            }
+        } catch (RemoteException re) {
+            System.err.println("** Failed talking with package manager!");
+            return false;
+        }
+        if (!mPermissionMap.isEmpty()) {
+            mTargetedPackages = new ArrayList<>(mPermissionMap.keySet());
+        }
+        return true;
+    }
+
+    public void dump() {
+        System.out.println("// Targeted packages and permissions:");
+        for (Map.Entry<String, List<PermissionInfo>> e : mPermissionMap.entrySet()) {
+            System.out.println(String.format("//  + Using %s", e.getKey()));
+            for (PermissionInfo pi : e.getValue()) {
+                String name = pi.name;
+                if (name != null) {
+                    if (name.startsWith(PERMISSION_PREFIX)) {
+                        name = name.substring(PERMISSION_PREFIX.length());
+                    }
+                }
+                String group = pi.group;
+                if (group != null) {
+                    if (group.startsWith(PERMISSION_GROUP_PREFIX)) {
+                        group = group.substring(PERMISSION_GROUP_PREFIX.length());
+                    }
+                }
+                System.out.println(String.format("//    Permission: %s [%s]", name, group));
+            }
+        }
+    }
+
+    public MonkeyPermissionEvent generateRandomPermissionEvent(Random random) {
+        String pkg = mTargetedPackages.get(random.nextInt(mTargetedPackages.size()));
+        List<PermissionInfo> infos = mPermissionMap.get(pkg);
+        return new MonkeyPermissionEvent(pkg, infos.get(random.nextInt(infos.size())));
+    }
+}
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java
index af6a231..80c7e50 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java
@@ -26,7 +26,7 @@
 import android.view.MotionEvent;
 import android.view.Surface;
 
-import java.util.ArrayList;
+import java.util.List;
 import java.util.Random;
 
 /**
@@ -77,13 +77,14 @@
     public static final int FACTOR_PINCHZOOM    = 2;
     public static final int FACTOR_TRACKBALL    = 3;
     public static final int FACTOR_ROTATION     = 4;
-    public static final int FACTOR_NAV          = 5;
-    public static final int FACTOR_MAJORNAV     = 6;
-    public static final int FACTOR_SYSOPS       = 7;
-    public static final int FACTOR_APPSWITCH    = 8;
-    public static final int FACTOR_FLIP         = 9;
-    public static final int FACTOR_ANYTHING     = 10;
-    public static final int FACTORZ_COUNT       = 11;    // should be last+1
+    public static final int FACTOR_PERMISSION   = 5;
+    public static final int FACTOR_NAV          = 6;
+    public static final int FACTOR_MAJORNAV     = 7;
+    public static final int FACTOR_SYSOPS       = 8;
+    public static final int FACTOR_APPSWITCH    = 9;
+    public static final int FACTOR_FLIP         = 10;
+    public static final int FACTOR_ANYTHING     = 11;
+    public static final int FACTORZ_COUNT       = 12;    // should be last+1
 
     private static final int GESTURE_TAP = 0;
     private static final int GESTURE_DRAG = 1;
@@ -93,12 +94,13 @@
      * values after we read any optional values.
      **/
     private float[] mFactors = new float[FACTORZ_COUNT];
-    private ArrayList<ComponentName> mMainApps;
+    private List<ComponentName> mMainApps;
     private int mEventCount = 0;  //total number of events generated so far
     private MonkeyEventQueue mQ;
     private Random mRandom;
     private int mVerbose = 0;
     private long mThrottle = 0;
+    private MonkeyPermissionUtil mPermissionUtil;
 
     private boolean mKeyboardOpen = false;
 
@@ -117,8 +119,8 @@
         return KeyEvent.keyCodeFromString(keyName);
     }
 
-    public MonkeySourceRandom(Random random, ArrayList<ComponentName> MainApps,
-            long throttle, boolean randomizeThrottle) {
+    public MonkeySourceRandom(Random random, List<ComponentName> MainApps,
+            long throttle, boolean randomizeThrottle, boolean permissionTargetSystem) {
         // default values for random distributions
         // note, these are straight percentages, to match user input (cmd line args)
         // but they will be converted to 0..1 values before the main loop runs.
@@ -132,12 +134,16 @@
         mFactors[FACTOR_SYSOPS] = 2.0f;
         mFactors[FACTOR_APPSWITCH] = 2.0f;
         mFactors[FACTOR_FLIP] = 1.0f;
+        // disbale permission by default
+        mFactors[FACTOR_PERMISSION] = 0.0f;
         mFactors[FACTOR_ANYTHING] = 13.0f;
         mFactors[FACTOR_PINCHZOOM] = 2.0f;
 
         mRandom = random;
         mMainApps = MainApps;
         mQ = new MonkeyEventQueue(random, throttle, randomizeThrottle);
+        mPermissionUtil = new MonkeyPermissionUtil();
+        mPermissionUtil.setTargetSystemPackages(permissionTargetSystem);
     }
 
     /**
@@ -410,6 +416,9 @@
         } else if (cls < mFactors[FACTOR_ROTATION]) {
             generateRotationEvent(mRandom);
             return;
+        } else if (cls < mFactors[FACTOR_PERMISSION]) {
+            mQ.add(mPermissionUtil.generateRandomPermissionEvent(mRandom));
+            return;
         }
 
         // The remaining event categories are injected as key events
@@ -450,8 +459,15 @@
     }
 
     public boolean validate() {
-        //check factors
-        return adjustEventFactors();
+        boolean ret = true;
+        // only populate & dump permissions if enabled
+        if (mFactors[FACTOR_PERMISSION] != 0.0f) {
+            ret &= mPermissionUtil.populatePermissionsMapping();
+            if (ret && mVerbose >= 2) {
+                mPermissionUtil.dump();
+            }
+        }
+        return ret & adjustEventFactors();
     }
 
     public void setVerbose(int verbose) {
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyUtils.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyUtils.java
index aa7a666..8b447c0 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeyUtils.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyUtils.java
@@ -17,6 +17,9 @@
 package com.android.commands.monkey;
 
 import java.text.SimpleDateFormat;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
 
 /**
  * Misc utilities.
@@ -26,6 +29,7 @@
     private static final java.util.Date DATE = new java.util.Date();
     private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat(
         "yyyy-MM-dd HH:mm:ss.SSS ");
+    private static PackageFilter sFilter;
 
     private MonkeyUtils() {
     }
@@ -38,4 +42,72 @@
         return DATE_FORMATTER.format(DATE);
     }
 
+    public static PackageFilter getPackageFilter() {
+        if (sFilter == null) {
+            sFilter = new PackageFilter();
+        }
+        return sFilter;
+    }
+
+    public static class PackageFilter {
+        private Set<String> mValidPackages = new HashSet<>();
+        private Set<String> mInvalidPackages = new HashSet<>();
+
+        private PackageFilter() {
+        }
+
+        public void addValidPackages(Set<String> validPackages) {
+            mValidPackages.addAll(validPackages);
+        }
+
+        public void addInvalidPackages(Set<String> invalidPackages) {
+            mInvalidPackages.addAll(invalidPackages);
+        }
+
+        public boolean hasValidPackages() {
+            return mValidPackages.size() > 0;
+        }
+
+        public boolean isPackageValid(String pkg) {
+            return mValidPackages.contains(pkg);
+        }
+
+        public boolean isPackageInvalid(String pkg) {
+            return mInvalidPackages.contains(pkg);
+        }
+
+        /**
+         * Check whether we should run against the given package.
+         *
+         * @param pkg The package name.
+         * @return Returns true if we should run against pkg.
+         */
+        public boolean checkEnteringPackage(String pkg) {
+            if (mInvalidPackages.size() > 0) {
+                if (mInvalidPackages.contains(pkg)) {
+                    return false;
+                }
+            } else if (mValidPackages.size() > 0) {
+                if (!mValidPackages.contains(pkg)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        public void dump() {
+            if (mValidPackages.size() > 0) {
+                Iterator<String> it = mValidPackages.iterator();
+                while (it.hasNext()) {
+                    System.out.println(":AllowPackage: " + it.next());
+                }
+            }
+            if (mInvalidPackages.size() > 0) {
+                Iterator<String> it = mInvalidPackages.iterator();
+                while (it.hasNext()) {
+                    System.out.println(":DisallowPackage: " + it.next());
+                }
+            }
+        }
+    }
 }
diff --git a/ide/eclipse/.classpath b/ide/eclipse/.classpath
index 0cc0a3c..f9a715c 100644
--- a/ide/eclipse/.classpath
+++ b/ide/eclipse/.classpath
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
+	<classpathentry kind="src" path="packages/apps/Bluetooth/lib/mapapi"/>
 	<classpathentry kind="src" path="packages/apps/Bluetooth/src"/>
 	<classpathentry kind="src" path="packages/apps/Browser/src"/>
 	<classpathentry kind="src" path="packages/apps/Calendar/src"/>
@@ -9,6 +10,7 @@
 	<classpathentry kind="src" path="packages/apps/Contacts/src"/>
 	<classpathentry kind="src" path="packages/apps/ContactsCommon/src"/>
 	<classpathentry kind="src" path="packages/apps/Dialer/src"/>
+	<classpathentry kind="src" path="packages/apps/Email/provider_src"/>
 	<classpathentry kind="src" path="packages/apps/Email/src"/>
 	<classpathentry kind="src" path="packages/apps/Email/emailcommon/src"/>
 	<classpathentry kind="src" path="packages/apps/HTMLViewer/src"/>
@@ -29,6 +31,7 @@
 	<classpathentry kind="src" path="packages/providers/TelephonyProvider/src"/>
 	<classpathentry kind="src" path="packages/services/Telecomm/src"/>
 	<classpathentry kind="src" path="packages/services/Telecomm/tests/src"/>
+	<classpathentry kind="src" path="packages/services/Telephony/sip/src"/>
 	<classpathentry kind="src" path="packages/services/Telephony/src"/>
 	<classpathentry kind="src" path="packages/services/Telephony/common/src"/>
 	<classpathentry kind="src" path="packages/services/Telephony/tests/src"/>
@@ -52,6 +55,7 @@
 	<classpathentry kind="src" path="frameworks/base/opengl/java"/>
 	<classpathentry kind="src" path="frameworks/base/packages/FusedLocation/src"/>
 	<classpathentry kind="src" path="frameworks/base/packages/Keyguard/src"/>
+	<classpathentry kind="src" path="frameworks/base/packages/SettingsLib/src"/>
 	<classpathentry kind="src" path="frameworks/base/packages/SettingsProvider/src"/>
 	<classpathentry kind="src" path="frameworks/base/packages/SystemUI/src"/>
 	<classpathentry kind="src" path="frameworks/base/phone/java"/>
@@ -71,6 +75,7 @@
 	<classpathentry kind="src" path="frameworks/ex/camera2/public/src"/>
 	<classpathentry kind="src" path="frameworks/ex/common/java"/>
 	<classpathentry kind="src" path="frameworks/ex/variablespeed/src"/>
+	<classpathentry kind="src" path="frameworks/opt/bitmap/src"/>
 	<classpathentry kind="src" path="frameworks/opt/calendar/src"/>
 	<classpathentry kind="src" path="frameworks/opt/chips/src"/>
 	<classpathentry kind="src" path="frameworks/opt/colorpicker/src"/>
@@ -85,10 +90,16 @@
 	<classpathentry kind="src" path="frameworks/opt/telephony/src/java"/>
 	<classpathentry kind="src" path="frameworks/opt/timezonepicker/src"/>
 	<classpathentry kind="src" path="frameworks/opt/vcard/java"/>
+	<classpathentry kind="src" path="frameworks/support/v7/appcompat/src"/>
+	<classpathentry kind="src" path="frameworks/support/v7/cardview/api21"/>
+	<classpathentry kind="src" path="frameworks/support/v7/cardview/base"/>
+	<classpathentry kind="src" path="frameworks/support/v7/cardview/eclair-mr1"/>
+	<classpathentry kind="src" path="frameworks/support/v7/cardview/jellybean-mr1"/>
+	<classpathentry kind="src" path="frameworks/support/v7/cardview/src"/>
+	<classpathentry kind="src" path="frameworks/support/v7/palette/src/main/java"/>
 	<classpathentry kind="src" path="frameworks/support/v13/java"/>
 	<classpathentry kind="src" path="frameworks/support/v13/ics"/>
 	<classpathentry kind="src" path="frameworks/support/v13/ics-mr1"/>
-	<classpathentry kind="src" path="frameworks/support/v7/palette/src"/>
 	<classpathentry kind="src" path="libcore/dalvik/src/main/java"/>
 	<classpathentry kind="src" path="libcore/dex/src/main/java"/>
 	<classpathentry kind="src" path="libcore/json/src/main/java"/>
@@ -103,6 +114,7 @@
 	<classpathentry kind="src" path="out/target/common/obj/APPS/PackageInstaller_intermediates/src/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/APPS/QuickSearchBox_intermediates/src/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/APPS/Settings_intermediates/src/src"/>
+	<classpathentry kind="src" path="out/target/common/obj/APPS/SettingsProvider_intermediates/src/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/APPS/SystemUI_intermediates/src/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/APPS/TeleService_intermediates/src/src"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/com.android.emailcommon_intermediates/src/src"/>
@@ -122,6 +134,7 @@
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/telephony-common_intermediates/src/src/java"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/voip-common_intermediates/src/src/java"/>
 	<classpathentry kind="src" path="out/target/common/R"/>
+	<classpathentry kind="src" path="external/apache-http/android/src"/>
 	<classpathentry kind="src" path="external/apache-http/src"/>
 	<classpathentry kind="src" path="external/bouncycastle/bcprov/src/main/java"/>
 	<classpathentry kind="src" path="external/easymock/src"/>
@@ -131,7 +144,10 @@
 	<classpathentry kind="src" path="external/ksoap2/kobjects"/>
 	<classpathentry kind="src" path="external/ksoap2/ksoap2-base/src/main/java"/>
 	<classpathentry kind="src" path="external/ksoap2/ksoap2-j2se/src/main/java"/>
+	<classpathentry kind="src" path="external/libphonenumber/geocoder/src"/>
+	<classpathentry kind="src" path="external/libphonenumber/internal/prefixmapper/src"/>
 	<classpathentry kind="src" path="external/libphonenumber/java/src"/>
+	<classpathentry kind="src" path="external/libphonenumber/libphonenumber/src"/>
 	<classpathentry kind="src" path="external/mp4parser/isoparser/src/main/java"/>
 	<classpathentry kind="src" path="external/nist-sip/java"/>
 	<classpathentry kind="src" path="external/objenesis/main/src"/>
@@ -147,9 +163,8 @@
 	<classpathentry kind="lib" path="out/target/common/obj/JAVA_LIBRARIES/android-support-v13_intermediates/javalib.jar"/>
 	<classpathentry kind="lib" path="out/target/common/obj/JAVA_LIBRARIES/android-common_intermediates/javalib.jar"/>
 	<classpathentry kind="lib" path="out/target/common/obj/JAVA_LIBRARIES/guava_intermediates/javalib.jar"/>
-	<classpathentry kind="lib" path="packages/apps/ContactsCommon/libs/geocoder-2.9.jar"/>
-	<classpathentry kind="lib" path="packages/apps/ContactsCommon/libs/libphonenumber-5.8.jar"/>
 	<classpathentry kind="lib" path="packages/apps/Calculator/arity-2.1.2.jar"/>
 	<classpathentry kind="lib" path="out/target/common/obj/JAVA_LIBRARIES/junit-runner_intermediates/javalib.jar"/>
+	<classpathentry kind="lib" path="out/target/common/obj/JAVA_LIBRARIES/libphonenumber-platform_intermediates/javalib.jar"/>
 	<classpathentry kind="output" path="out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes"/>
 </classpath>
diff --git a/ide/intellij/codestyles/AndroidStyle.xml b/ide/intellij/codestyles/AndroidStyle.xml
index 672c4e5..5a21b7c 100644
--- a/ide/intellij/codestyles/AndroidStyle.xml
+++ b/ide/intellij/codestyles/AndroidStyle.xml
@@ -13,7 +13,7 @@
     </value>
   </option>
   <option name="FIELD_NAME_PREFIX" value="m" />
-  <option name="STATIC_FIELD_NAME_PREFIX" value="m" />
+  <option name="STATIC_FIELD_NAME_PREFIX" value="s" />
   <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="9999" />
   <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="9999" />
   <option name="IMPORT_LAYOUT_TABLE">
@@ -172,4 +172,3 @@
     <option name="PARENT_SETTINGS_INSTALLED" value="true" />
   </codeStyleSettings>
 </code_scheme>
-
diff --git a/ndk/platforms/android-M/include/android/multinetwork.h b/ndk/platforms/android-M/include/android/multinetwork.h
new file mode 100644
index 0000000..6c718c9
--- /dev/null
+++ b/ndk/platforms/android-M/include/android/multinetwork.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2015 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_MULTINETWORK_H
+#define ANDROID_MULTINETWORK_H
+
+#include <netdb.h>
+#include <stdlib.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+/**
+ * The corresponding C type for android.net.Network#getNetworkHandle() return
+ * values.  The Java signed long value can be safely cast to a net_handle_t:
+ *
+ *     [C]    ((net_handle_t) java_long_network_handle)
+ *     [C++]  static_cast<net_handle_t>(java_long_network_handle)
+ *
+ * as appropriate.
+ */
+typedef uint64_t net_handle_t;
+
+/**
+ * The value NETWORK_UNSPECIFIED indicates no specific network.
+ *
+ * For some functions (documented below), a previous binding may be cleared
+ * by an invocation with NETWORK_UNSPECIFIED.
+ *
+ * Depending on the context it may indicate an error.  It is expressly
+ * not used to indicate some notion of the "current default network".
+ */
+#define NETWORK_UNSPECIFIED  ((net_handle_t)0)
+
+
+/**
+ * All functions below that return an int return 0 on success or -1
+ * on failure with an appropriate errno value set.
+ */
+
+
+/**
+ * Set the network to be used by the given socket file descriptor.
+ *
+ * To clear a previous socket binding invoke with NETWORK_UNSPECIFIED.
+ *
+ * This is the equivalent of:
+ *
+ *     [ android.net.Network#bindSocket() ]
+ *     https://developer.android.com/reference/android/net/Network.html#bindSocket(java.net.Socket)
+ */
+int android_setsocknetwork(net_handle_t network, int fd);
+
+
+/**
+ * Binds the current process to |network|.  All sockets created in the future
+ * (and not explicitly bound via android_setsocknetwork()) will be bound to
+ * |network|.  All host name resolutions will be limited to |network| as well.
+ * Note that if the network identified by |network| ever disconnects, all
+ * sockets created in this way will cease to work and all host name
+ * resolutions will fail.  This is by design so an application doesn't
+ * accidentally use sockets it thinks are still bound to a particular network.
+ *
+ * To clear a previous process binding invoke with NETWORK_UNSPECIFIED.
+ *
+ * This is the equivalent of:
+ *
+ *     [ android.net.ConnectivityManager#setProcessDefaultNetwork() ]
+ *     https://developer.android.com/reference/android/net/ConnectivityManager.html#setProcessDefaultNetwork(android.net.Network)
+ */
+int android_setprocnetwork(net_handle_t network);
+
+
+/**
+ * Perform hostname resolution via the DNS servers associated with |network|.
+ *
+ * All arguments (apart from |network|) are used identically as those passed
+ * to getaddrinfo(3).  Return and error values are identical to those of
+ * getaddrinfo(3), and in particular gai_strerror(3) can be used as expected.
+ * Similar to getaddrinfo(3):
+ *     - |hints| may be NULL (in which case man page documented defaults apply)
+ *     - either |node| or |service| may be NULL, but not both
+ *     - |res| must not be NULL
+ *
+ * This is the equivalent of:
+ *
+ *     [ android.net.Network#getAllByName() ]
+ *     https://developer.android.com/reference/android/net/Network.html#getAllByName(java.lang.String)
+ */
+int android_getaddrinfofornetwork(net_handle_t network,
+        const char *node, const char *service,
+        const struct addrinfo *hints, struct addrinfo **res);
+
+__END_DECLS
+
+#endif  // ANDROID_MULTINETWORK_H
diff --git a/ndk/platforms/android-M/include/android/trace.h b/ndk/platforms/android-M/include/android/trace.h
new file mode 100644
index 0000000..e42e334
--- /dev/null
+++ b/ndk/platforms/android-M/include/android/trace.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015 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_NATIVE_TRACE_H
+#define ANDROID_NATIVE_TRACE_H
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Returns true if tracing is enabled. Use this signal to avoid expensive computation only necessary
+ * when tracing is enabled.
+ */
+bool ATrace_isEnabled();
+
+/**
+ * Writes a tracing message to indicate that the given section of code has begun. This call must be
+ * followed by a corresponding call to endSection() on the same thread.
+ *
+ * Note: At this time the vertical bar character '|' and newline character '\n' are used internally
+ * by the tracing mechanism. If sectionName contains these characters they will be replaced with a
+ * space character in the trace.
+ */
+void ATrace_beginSection(const char* sectionName);
+
+/**
+ * Writes a tracing message to indicate that a given section of code has ended. This call must be
+ * preceeded by a corresponding call to beginSection(char*) on the same thread. Calling this method
+ * will mark the end of the most recently begun section of code, so care must be taken to ensure
+ * that beginSection / endSection pairs are properly nested and called from the same thread.
+ */
+void ATrace_endSection();
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // ANDROID_NATIVE_TRACE_H
diff --git a/samples/ActionBarCompat/AndroidManifest.xml b/samples/ActionBarCompat/AndroidManifest.xml
deleted file mode 100644
index a78339b..0000000
--- a/samples/ActionBarCompat/AndroidManifest.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<!--
-  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.
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.example.android.actionbarcompat"
-    android:versionCode="1"
-    android:versionName="1.0">
-
-    <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="14" />
-    <uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
-    <supports-screens android:largeScreens="true"/>
-
-    <application android:label="@string/app_name"
-        android:icon="@drawable/ic_launcher"
-        android:theme="@style/AppTheme">
-        <activity android:name=".MainActivity" android:label="@string/app_name">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/samples/ActionBarCompat/_index.jd b/samples/ActionBarCompat/_index.jd
deleted file mode 100644
index 61b5e5e..0000000
--- a/samples/ActionBarCompat/_index.jd
+++ /dev/null
@@ -1,13 +0,0 @@
-page.tags="ActionBar", "UI", "Compatibility", "Support Library"
-sample.group=Input
-@jd:body
-
-<p>This sample shows how to use the action bar design pattern on pre-API 11 devices and the built-in
-<a href="../../../reference/android/app/ActionBar.html">ActionBar</a> on devices supporting API
-11 or greater. The example 'compatible' action bar, instantiated on pre-Android 3.0 devices,
-uses the same <a href="../../../guide/topics/resources/menu-resource.html">menu resource</a>-based
-action item definition mechanism as the new framework API, even supporting the
-<code>android:showAsAction</code> attribute to a limited extent.</p>
-
-<img alt="" src="../images/ActionBarCompat1.png" height="320" />
-<img alt="" src="../images/ActionBarCompat2.png" height="320" />
\ No newline at end of file
diff --git a/samples/ActionBarCompat/res/drawable-hdpi/actionbar_shadow.9.png b/samples/ActionBarCompat/res/drawable-hdpi/actionbar_shadow.9.png
deleted file mode 100644
index 3c80a3f..0000000
--- a/samples/ActionBarCompat/res/drawable-hdpi/actionbar_shadow.9.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-hdpi/ic_action_refresh.png b/samples/ActionBarCompat/res/drawable-hdpi/ic_action_refresh.png
deleted file mode 100644
index efe99e0..0000000
--- a/samples/ActionBarCompat/res/drawable-hdpi/ic_action_refresh.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-hdpi/ic_action_search.png b/samples/ActionBarCompat/res/drawable-hdpi/ic_action_search.png
deleted file mode 100644
index f6719d2..0000000
--- a/samples/ActionBarCompat/res/drawable-hdpi/ic_action_search.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-hdpi/ic_action_share.png b/samples/ActionBarCompat/res/drawable-hdpi/ic_action_share.png
deleted file mode 100644
index 7d0b872..0000000
--- a/samples/ActionBarCompat/res/drawable-hdpi/ic_action_share.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-hdpi/ic_home.png b/samples/ActionBarCompat/res/drawable-hdpi/ic_home.png
deleted file mode 100644
index 7e52ff5..0000000
--- a/samples/ActionBarCompat/res/drawable-hdpi/ic_home.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-hdpi/ic_launcher.png b/samples/ActionBarCompat/res/drawable-hdpi/ic_launcher.png
deleted file mode 100755
index e4b0492..0000000
--- a/samples/ActionBarCompat/res/drawable-hdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-hdpi/ic_menu_share.png b/samples/ActionBarCompat/res/drawable-hdpi/ic_menu_share.png
deleted file mode 100755
index a78bf7a..0000000
--- a/samples/ActionBarCompat/res/drawable-hdpi/ic_menu_share.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-mdpi/actionbar_shadow.9.png b/samples/ActionBarCompat/res/drawable-mdpi/actionbar_shadow.9.png
deleted file mode 100644
index cae1778..0000000
--- a/samples/ActionBarCompat/res/drawable-mdpi/actionbar_shadow.9.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-mdpi/ic_action_refresh.png b/samples/ActionBarCompat/res/drawable-mdpi/ic_action_refresh.png
deleted file mode 100644
index a85eee3..0000000
--- a/samples/ActionBarCompat/res/drawable-mdpi/ic_action_refresh.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-mdpi/ic_action_search.png b/samples/ActionBarCompat/res/drawable-mdpi/ic_action_search.png
deleted file mode 100755
index 45d2398..0000000
--- a/samples/ActionBarCompat/res/drawable-mdpi/ic_action_search.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-mdpi/ic_action_share.png b/samples/ActionBarCompat/res/drawable-mdpi/ic_action_share.png
deleted file mode 100644
index 26a39bd..0000000
--- a/samples/ActionBarCompat/res/drawable-mdpi/ic_action_share.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-mdpi/ic_home.png b/samples/ActionBarCompat/res/drawable-mdpi/ic_home.png
deleted file mode 100644
index 949b4aa..0000000
--- a/samples/ActionBarCompat/res/drawable-mdpi/ic_home.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-mdpi/ic_launcher.png b/samples/ActionBarCompat/res/drawable-mdpi/ic_launcher.png
deleted file mode 100755
index 78d0e29..0000000
--- a/samples/ActionBarCompat/res/drawable-mdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-mdpi/ic_menu_share.png b/samples/ActionBarCompat/res/drawable-mdpi/ic_menu_share.png
deleted file mode 100755
index 3329b6b..0000000
--- a/samples/ActionBarCompat/res/drawable-mdpi/ic_menu_share.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-xhdpi/actionbar_shadow.9.png b/samples/ActionBarCompat/res/drawable-xhdpi/actionbar_shadow.9.png
deleted file mode 100644
index 30778e3..0000000
--- a/samples/ActionBarCompat/res/drawable-xhdpi/actionbar_shadow.9.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-xhdpi/ic_action_refresh.png b/samples/ActionBarCompat/res/drawable-xhdpi/ic_action_refresh.png
deleted file mode 100644
index 6ce9376..0000000
--- a/samples/ActionBarCompat/res/drawable-xhdpi/ic_action_refresh.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-xhdpi/ic_action_search.png b/samples/ActionBarCompat/res/drawable-xhdpi/ic_action_search.png
deleted file mode 100644
index f89c4e9..0000000
--- a/samples/ActionBarCompat/res/drawable-xhdpi/ic_action_search.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-xhdpi/ic_action_share.png b/samples/ActionBarCompat/res/drawable-xhdpi/ic_action_share.png
deleted file mode 100644
index 47b27d1..0000000
--- a/samples/ActionBarCompat/res/drawable-xhdpi/ic_action_share.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-xhdpi/ic_home.png b/samples/ActionBarCompat/res/drawable-xhdpi/ic_home.png
deleted file mode 100644
index 03eb53d..0000000
--- a/samples/ActionBarCompat/res/drawable-xhdpi/ic_home.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-xhdpi/ic_launcher.png b/samples/ActionBarCompat/res/drawable-xhdpi/ic_launcher.png
deleted file mode 100755
index 485f7be..0000000
--- a/samples/ActionBarCompat/res/drawable-xhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable/actionbar_compat_item.xml b/samples/ActionBarCompat/res/drawable/actionbar_compat_item.xml
deleted file mode 100644
index 4b3960c..0000000
--- a/samples/ActionBarCompat/res/drawable/actionbar_compat_item.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<!--
-  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.
-  -->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:drawable="@drawable/actionbar_compat_item_pressed"
-        android:state_pressed="true" />
-    <item android:drawable="@drawable/actionbar_compat_item_focused"
-        android:state_focused="true" />
-    <item android:drawable="@android:color/transparent" />
-</selector>
diff --git a/samples/ActionBarCompat/res/drawable/actionbar_compat_item_focused.xml b/samples/ActionBarCompat/res/drawable/actionbar_compat_item_focused.xml
deleted file mode 100644
index 04811d3..0000000
--- a/samples/ActionBarCompat/res/drawable/actionbar_compat_item_focused.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!--
-  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.
-  -->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <solid android:color="#ef7000" />
-</shape>
diff --git a/samples/ActionBarCompat/res/drawable/actionbar_compat_item_pressed.xml b/samples/ActionBarCompat/res/drawable/actionbar_compat_item_pressed.xml
deleted file mode 100644
index 72ff4b4..0000000
--- a/samples/ActionBarCompat/res/drawable/actionbar_compat_item_pressed.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!--
-  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.
-  -->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <solid android:color="#eda700" />
-</shape>
diff --git a/samples/ActionBarCompat/res/layout-v11/actionbar_indeterminate_progress.xml b/samples/ActionBarCompat/res/layout-v11/actionbar_indeterminate_progress.xml
deleted file mode 100644
index c05750e..0000000
--- a/samples/ActionBarCompat/res/layout-v11/actionbar_indeterminate_progress.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-  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.
-  -->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:gravity="center">
-    <ProgressBar android:layout_width="32dp"
-        android:layout_height="32dp"
-        android:layout_marginLeft="12dp"
-        android:layout_marginRight="12dp"
-        android:layout_gravity="center"
-        style="?android:attr/indeterminateProgressStyle" />
-</FrameLayout>
diff --git a/samples/ActionBarCompat/res/layout/actionbar_compat.xml b/samples/ActionBarCompat/res/layout/actionbar_compat.xml
deleted file mode 100644
index ae6c44b..0000000
--- a/samples/ActionBarCompat/res/layout/actionbar_compat.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-  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.
-  -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@id/actionbar_compat"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    android:orientation="horizontal" />
diff --git a/samples/ActionBarCompat/res/layout/main.xml b/samples/ActionBarCompat/res/layout/main.xml
deleted file mode 100644
index a58a346..0000000
--- a/samples/ActionBarCompat/res/layout/main.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-  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.
-  -->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent">
-    <Button android:id="@+id/toggle_title"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:text="@string/toggle_title" />
-</FrameLayout>
diff --git a/samples/ActionBarCompat/res/menu/main.xml b/samples/ActionBarCompat/res/menu/main.xml
deleted file mode 100644
index a306a3c..0000000
--- a/samples/ActionBarCompat/res/menu/main.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<!--
-  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.
-  -->
-
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:id="@+id/menu_refresh"
-        android:title="@string/menu_refresh"
-        android:icon="@drawable/ic_action_refresh"
-        android:orderInCategory="1"
-        android:showAsAction="always" />
-    <item android:id="@+id/menu_search"
-        android:title="@string/menu_search"
-        android:icon="@drawable/ic_action_search"
-        android:orderInCategory="0"
-        android:showAsAction="always" />
-
-    <item android:id="@+id/menu_share"
-        android:title="@string/menu_share"
-        android:icon="@drawable/ic_menu_share"
-        android:orderInCategory="1"
-        android:showAsAction="never" />
-</menu>
diff --git a/samples/ActionBarCompat/res/values-v11/styles.xml b/samples/ActionBarCompat/res/values-v11/styles.xml
deleted file mode 100644
index dc1aa7c..0000000
--- a/samples/ActionBarCompat/res/values-v11/styles.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<!--
-  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.
-  -->
-
-<resources>
-
-    <style name="AppTheme" parent="android:style/Theme.Holo.Light">
-        <item name="android:actionBarStyle">@style/ActionBar</item>
-        <item name="android:windowContentOverlay">@drawable/actionbar_shadow</item>
-    </style>
-
-    <style name="ActionBar" parent="android:style/Widget.Holo.Light.ActionBar">
-        <item name="android:background">#eee</item>
-        <item name="android:titleTextStyle">@style/ActionBarTitle</item>
-        <item name="android:icon">@drawable/ic_home</item>
-    </style>
-
-    <style name="ActionBarTitle">
-        <item name="android:textColor">@color/actionbar_title_color</item>
-    </style>
-
-</resources>
diff --git a/samples/ActionBarCompat/res/values/attrs.xml b/samples/ActionBarCompat/res/values/attrs.xml
deleted file mode 100644
index c59822c..0000000
--- a/samples/ActionBarCompat/res/values/attrs.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-  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.
-  -->
-
-<resources>
-
-    <declare-styleable name="AppTheme">
-        <attr name="actionbarCompatTitleStyle" format="reference" />
-        <attr name="actionbarCompatItemStyle" format="reference" />
-        <attr name="actionbarCompatItemHomeStyle" format="reference" />
-        <attr name="actionbarCompatProgressIndicatorStyle" format="reference" />
-    </declare-styleable>
-
-    <declare-styleable name="BezelImageView">
-        <attr name="maskDrawable" format="reference" />
-        <attr name="borderDrawable" format="reference" />
-    </declare-styleable>
-
-</resources>
diff --git a/samples/ActionBarCompat/res/values/ids.xml b/samples/ActionBarCompat/res/values/ids.xml
deleted file mode 100644
index e0a4745..0000000
--- a/samples/ActionBarCompat/res/values/ids.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<!--
-  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.
-  -->
-
-<resources>
-    <item type="id" name="actionbar_compat" />
-    <item type="id" name="actionbar_compat_title" />
-    <item type="id" name="actionbar_compat_item_refresh_progress" />
-    <item type="id" name="actionbar_compat_item_refresh" />
-    <item type="id" name="menu_refresh" />
-</resources>
diff --git a/samples/ActionBarCompat/res/values/strings.xml b/samples/ActionBarCompat/res/values/strings.xml
deleted file mode 100644
index 234aa78..0000000
--- a/samples/ActionBarCompat/res/values/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-  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.
-  -->
-
-<resources>
-    <string name="app_name">Action Bar Demo</string>
-    <string name="alternate_title">An alternate title that is long</string>
-    <string name="toggle_title">Toggle title</string>
-
-    <string name="menu_refresh">Refresh</string>
-    <string name="menu_search">Search</string>
-    <string name="menu_share">Share</string>
-</resources>
diff --git a/samples/ActionBarCompat/res/values/styles.xml b/samples/ActionBarCompat/res/values/styles.xml
deleted file mode 100644
index 5d0c029..0000000
--- a/samples/ActionBarCompat/res/values/styles.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<!--
-  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.
-  -->
-
-<resources>
-
-    <style name="AppTheme" parent="android:style/Theme.Light">
-        <item name="android:windowTitleSize">@dimen/actionbar_compat_height</item>
-        <item name="android:windowTitleBackgroundStyle">@style/ActionBarCompat</item>
-        <item name="android:windowContentOverlay">@drawable/actionbar_shadow</item>
-
-        <!-- for programmatic instantiation -->
-        <item name="actionbarCompatTitleStyle">@style/ActionBarCompatTitle</item>
-        <item name="actionbarCompatItemStyle">@style/ActionBarCompatItem</item>
-        <item name="actionbarCompatItemHomeStyle">@style/ActionBarCompatHomeItem</item>
-        <item name="actionbarCompatProgressIndicatorStyle">@style/ActionBarCompatProgressIndicator</item>
-    </style>
-
-    <style name="ActionBarCompat">
-        <item name="android:background">#eee</item>
-    </style>
-
-    <style name="ActionBarCompatItemBase">
-        <!-- layout_width/height must be set in code -->
-        <item name="android:scaleType">center</item>
-        <item name="android:background">@drawable/actionbar_compat_item</item>
-    </style>
-
-    <style name="ActionBarCompatProgressIndicator" parent="android:style/Widget.ProgressBar.Large">
-        <item name="android:indeterminate">true</item>
-    </style>
-
-    <style name="ActionBarCompatTitleBase">
-        <item name="android:id">@id/actionbar_compat_title</item>
-        <!-- layout_width/height/weight must be set in code -->
-        <item name="android:gravity">center_vertical</item>
-        <item name="android:textSize">18sp</item>
-        <item name="android:paddingLeft">6dp</item>
-        <item name="android:paddingRight">6dp</item>
-        <item name="android:singleLine">true</item>
-        <item name="android:ellipsize">marquee</item>
-    </style>
-
-    <style name="ActionBarCompatTitle" parent="style/ActionBarCompatTitleBase">
-        <item name="android:textColor">@color/actionbar_title_color</item>
-    </style>
-
-    <style name="ActionBarCompatItem" parent="style/ActionBarCompatItemBase">
-    </style>
-
-    <style name="ActionBarCompatHomeItem" parent="style/ActionBarCompatItemBase">
-    </style>
-
-</resources>
diff --git a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarActivity.java b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarActivity.java
deleted file mode 100644
index 251e411..0000000
--- a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarActivity.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.
- */
-
-package com.example.android.actionbarcompat;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuInflater;
-
-/**
- * A base activity that defers common functionality across app activities to an {@link
- * ActionBarHelper}.
- *
- * NOTE: dynamically marking menu items as invisible/visible is not currently supported.
- *
- * NOTE: this may used with the Android Compatibility Package by extending
- * android.support.v4.app.FragmentActivity instead of {@link Activity}.
- */
-public abstract class ActionBarActivity extends Activity {
-    final ActionBarHelper mActionBarHelper = ActionBarHelper.createInstance(this);
-
-    /**
-     * Returns the {@link ActionBarHelper} for this activity.
-     */
-    protected ActionBarHelper getActionBarHelper() {
-        return mActionBarHelper;
-    }
-
-    /**{@inheritDoc}*/
-    @Override
-    public MenuInflater getMenuInflater() {
-        return mActionBarHelper.getMenuInflater(super.getMenuInflater());
-    }
-
-    /**{@inheritDoc}*/
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        mActionBarHelper.onCreate(savedInstanceState);
-    }
-
-    /**{@inheritDoc}*/
-    @Override
-    protected void onPostCreate(Bundle savedInstanceState) {
-        super.onPostCreate(savedInstanceState);
-        mActionBarHelper.onPostCreate(savedInstanceState);
-    }
-
-    /**
-     * Base action bar-aware implementation for
-     * {@link Activity#onCreateOptionsMenu(android.view.Menu)}.
-     *
-     * Note: marking menu items as invisible/visible is not currently supported.
-     */
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        boolean retValue = false;
-        retValue |= mActionBarHelper.onCreateOptionsMenu(menu);
-        retValue |= super.onCreateOptionsMenu(menu);
-        return retValue;
-    }
-
-    /**{@inheritDoc}*/
-    @Override
-    protected void onTitleChanged(CharSequence title, int color) {
-        mActionBarHelper.onTitleChanged(title, color);
-        super.onTitleChanged(title, color);
-    }
-}
diff --git a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelper.java b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelper.java
deleted file mode 100644
index 075f993..0000000
--- a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelper.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.
- */
-
-package com.example.android.actionbarcompat;
-
-import android.app.Activity;
-import android.os.Build;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuInflater;
-
-/**
- * An abstract class that handles some common action bar-related functionality in the app. This
- * class provides functionality useful for both phones and tablets, and does not require any Android
- * 3.0-specific features, although it uses them if available.
- *
- * Two implementations of this class are {@link ActionBarHelperBase} for a pre-Honeycomb version of
- * the action bar, and {@link ActionBarHelperHoneycomb}, which uses the built-in ActionBar features
- * in Android 3.0 and later.
- */
-public abstract class ActionBarHelper {
-    protected Activity mActivity;
-
-    /**
-     * Factory method for creating {@link ActionBarHelper} objects for a
-     * given activity. Depending on which device the app is running, either a basic helper or
-     * Honeycomb-specific helper will be returned.
-     */
-    public static ActionBarHelper createInstance(Activity activity) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
-            return new ActionBarHelperICS(activity);
-        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
-            return new ActionBarHelperHoneycomb(activity);
-        } else {
-            return new ActionBarHelperBase(activity);
-        }
-    }
-
-    protected ActionBarHelper(Activity activity) {
-        mActivity = activity;
-    }
-
-    /**
-     * Action bar helper code to be run in {@link Activity#onCreate(android.os.Bundle)}.
-     */
-    public void onCreate(Bundle savedInstanceState) {
-    }
-
-    /**
-     * Action bar helper code to be run in {@link Activity#onPostCreate(android.os.Bundle)}.
-     */
-    public void onPostCreate(Bundle savedInstanceState) {
-    }
-
-    /**
-     * Action bar helper code to be run in {@link Activity#onCreateOptionsMenu(android.view.Menu)}.
-     *
-     * NOTE: Setting the visibility of menu items in <em>menu</em> is not currently supported.
-     */
-    public boolean onCreateOptionsMenu(Menu menu) {
-        return true;
-    }
-
-    /**
-     * Action bar helper code to be run in {@link Activity#onTitleChanged(CharSequence, int)}.
-     */
-    protected void onTitleChanged(CharSequence title, int color) {
-    }
-
-    /**
-     * Sets the indeterminate loading state of the item with ID {@link R.id.menu_refresh}.
-     * (where the item ID was menu_refresh).
-     */
-    public abstract void setRefreshActionItemState(boolean refreshing);
-
-    /**
-     * Returns a {@link MenuInflater} for use when inflating menus. The implementation of this
-     * method in {@link ActionBarHelperBase} returns a wrapped menu inflater that can read
-     * action bar metadata from a menu resource pre-Honeycomb.
-     */
-    public MenuInflater getMenuInflater(MenuInflater superMenuInflater) {
-        return superMenuInflater;
-    }
-}
diff --git a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelperBase.java b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelperBase.java
deleted file mode 100644
index f70b54a..0000000
--- a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelperBase.java
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * 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.
- */
-
-package com.example.android.actionbarcompat;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.res.XmlResourceParser;
-import android.os.Bundle;
-import android.view.InflateException;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * A class that implements the action bar pattern for pre-Honeycomb devices.
- */
-public class ActionBarHelperBase extends ActionBarHelper {
-    private static final String MENU_RES_NAMESPACE = "http://schemas.android.com/apk/res/android";
-    private static final String MENU_ATTR_ID = "id";
-    private static final String MENU_ATTR_SHOW_AS_ACTION = "showAsAction";
-
-    protected Set<Integer> mActionItemIds = new HashSet<Integer>();
-
-    protected ActionBarHelperBase(Activity activity) {
-        super(activity);
-    }
-
-    /**{@inheritDoc}*/
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        mActivity.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
-    }
-
-    /**{@inheritDoc}*/
-    @Override
-    public void onPostCreate(Bundle savedInstanceState) {
-        mActivity.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
-                R.layout.actionbar_compat);
-        setupActionBar();
-
-        SimpleMenu menu = new SimpleMenu(mActivity);
-        mActivity.onCreatePanelMenu(Window.FEATURE_OPTIONS_PANEL, menu);
-        mActivity.onPrepareOptionsMenu(menu);
-        for (int i = 0; i < menu.size(); i++) {
-            MenuItem item = menu.getItem(i);
-            if (mActionItemIds.contains(item.getItemId())) {
-                addActionItemCompatFromMenuItem(item);
-            }
-        }
-    }
-
-    /**
-     * Sets up the compatibility action bar with the given title.
-     */
-    private void setupActionBar() {
-        final ViewGroup actionBarCompat = getActionBarCompat();
-        if (actionBarCompat == null) {
-            return;
-        }
-
-        LinearLayout.LayoutParams springLayoutParams = new LinearLayout.LayoutParams(
-                0, ViewGroup.LayoutParams.FILL_PARENT);
-        springLayoutParams.weight = 1;
-
-        // Add Home button
-        SimpleMenu tempMenu = new SimpleMenu(mActivity);
-        SimpleMenuItem homeItem = new SimpleMenuItem(
-                tempMenu, android.R.id.home, 0, mActivity.getString(R.string.app_name));
-        homeItem.setIcon(R.drawable.ic_home);
-        addActionItemCompatFromMenuItem(homeItem);
-
-        // Add title text
-        TextView titleText = new TextView(mActivity, null, R.attr.actionbarCompatTitleStyle);
-        titleText.setLayoutParams(springLayoutParams);
-        titleText.setText(mActivity.getTitle());
-        actionBarCompat.addView(titleText);
-    }
-
-    /**{@inheritDoc}*/
-    @Override
-    public void setRefreshActionItemState(boolean refreshing) {
-        View refreshButton = mActivity.findViewById(R.id.actionbar_compat_item_refresh);
-        View refreshIndicator = mActivity.findViewById(
-                R.id.actionbar_compat_item_refresh_progress);
-
-        if (refreshButton != null) {
-            refreshButton.setVisibility(refreshing ? View.GONE : View.VISIBLE);
-        }
-        if (refreshIndicator != null) {
-            refreshIndicator.setVisibility(refreshing ? View.VISIBLE : View.GONE);
-        }
-    }
-
-    /**
-     * Action bar helper code to be run in {@link Activity#onCreateOptionsMenu(android.view.Menu)}.
-     *
-     * NOTE: This code will mark on-screen menu items as invisible.
-     */
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        // Hides on-screen action items from the options menu.
-        for (Integer id : mActionItemIds) {
-            menu.findItem(id).setVisible(false);
-        }
-        return true;
-    }
-
-    /**{@inheritDoc}*/
-    @Override
-    protected void onTitleChanged(CharSequence title, int color) {
-        TextView titleView = (TextView) mActivity.findViewById(R.id.actionbar_compat_title);
-        if (titleView != null) {
-            titleView.setText(title);
-        }
-    }
-
-    /**
-     * Returns a {@link android.view.MenuInflater} that can read action bar metadata on
-     * pre-Honeycomb devices.
-     */
-    public MenuInflater getMenuInflater(MenuInflater superMenuInflater) {
-        return new WrappedMenuInflater(mActivity, superMenuInflater);
-    }
-
-    /**
-     * Returns the {@link android.view.ViewGroup} for the action bar on phones (compatibility action
-     * bar). Can return null, and will return null on Honeycomb.
-     */
-    private ViewGroup getActionBarCompat() {
-        return (ViewGroup) mActivity.findViewById(R.id.actionbar_compat);
-    }
-
-    /**
-     * Adds an action button to the compatibility action bar, using menu information from a {@link
-     * android.view.MenuItem}. If the menu item ID is <code>menu_refresh</code>, the menu item's
-     * state can be changed to show a loading spinner using
-     * {@link com.example.android.actionbarcompat.ActionBarHelperBase#setRefreshActionItemState(boolean)}.
-     */
-    private View addActionItemCompatFromMenuItem(final MenuItem item) {
-        final int itemId = item.getItemId();
-
-        final ViewGroup actionBar = getActionBarCompat();
-        if (actionBar == null) {
-            return null;
-        }
-
-        // Create the button
-        ImageButton actionButton = new ImageButton(mActivity, null,
-                itemId == android.R.id.home
-                        ? R.attr.actionbarCompatItemHomeStyle
-                        : R.attr.actionbarCompatItemStyle);
-        actionButton.setLayoutParams(new ViewGroup.LayoutParams(
-                (int) mActivity.getResources().getDimension(
-                        itemId == android.R.id.home
-                                ? R.dimen.actionbar_compat_button_home_width
-                                : R.dimen.actionbar_compat_button_width),
-                ViewGroup.LayoutParams.FILL_PARENT));
-        if (itemId == R.id.menu_refresh) {
-            actionButton.setId(R.id.actionbar_compat_item_refresh);
-        }
-        actionButton.setImageDrawable(item.getIcon());
-        actionButton.setScaleType(ImageView.ScaleType.CENTER);
-        actionButton.setContentDescription(item.getTitle());
-        actionButton.setOnClickListener(new View.OnClickListener() {
-            public void onClick(View view) {
-                mActivity.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, item);
-            }
-        });
-
-        actionBar.addView(actionButton);
-
-        if (item.getItemId() == R.id.menu_refresh) {
-            // Refresh buttons should be stateful, and allow for indeterminate progress indicators,
-            // so add those.
-            ProgressBar indicator = new ProgressBar(mActivity, null,
-                    R.attr.actionbarCompatProgressIndicatorStyle);
-
-            final int buttonWidth = mActivity.getResources().getDimensionPixelSize(
-                    R.dimen.actionbar_compat_button_width);
-            final int buttonHeight = mActivity.getResources().getDimensionPixelSize(
-                    R.dimen.actionbar_compat_height);
-            final int progressIndicatorWidth = buttonWidth / 2;
-
-            LinearLayout.LayoutParams indicatorLayoutParams = new LinearLayout.LayoutParams(
-                    progressIndicatorWidth, progressIndicatorWidth);
-            indicatorLayoutParams.setMargins(
-                    (buttonWidth - progressIndicatorWidth) / 2,
-                    (buttonHeight - progressIndicatorWidth) / 2,
-                    (buttonWidth - progressIndicatorWidth) / 2,
-                    0);
-            indicator.setLayoutParams(indicatorLayoutParams);
-            indicator.setVisibility(View.GONE);
-            indicator.setId(R.id.actionbar_compat_item_refresh_progress);
-            actionBar.addView(indicator);
-        }
-
-        return actionButton;
-    }
-
-    /**
-     * A {@link android.view.MenuInflater} that reads action bar metadata.
-     */
-    private class WrappedMenuInflater extends MenuInflater {
-        MenuInflater mInflater;
-
-        public WrappedMenuInflater(Context context, MenuInflater inflater) {
-            super(context);
-            mInflater = inflater;
-        }
-
-        @Override
-        public void inflate(int menuRes, Menu menu) {
-            loadActionBarMetadata(menuRes);
-            mInflater.inflate(menuRes, menu);
-        }
-
-        /**
-         * Loads action bar metadata from a menu resource, storing a list of menu item IDs that
-         * should be shown on-screen (i.e. those with showAsAction set to always or ifRoom).
-         * @param menuResId
-         */
-        private void loadActionBarMetadata(int menuResId) {
-            XmlResourceParser parser = null;
-            try {
-                parser = mActivity.getResources().getXml(menuResId);
-
-                int eventType = parser.getEventType();
-                int itemId;
-                int showAsAction;
-
-                boolean eof = false;
-                while (!eof) {
-                    switch (eventType) {
-                        case XmlPullParser.START_TAG:
-                            if (!parser.getName().equals("item")) {
-                                break;
-                            }
-
-                            itemId = parser.getAttributeResourceValue(MENU_RES_NAMESPACE,
-                                    MENU_ATTR_ID, 0);
-                            if (itemId == 0) {
-                                break;
-                            }
-
-                            showAsAction = parser.getAttributeIntValue(MENU_RES_NAMESPACE,
-                                    MENU_ATTR_SHOW_AS_ACTION, -1);
-                            if (showAsAction == MenuItem.SHOW_AS_ACTION_ALWAYS ||
-                                    showAsAction == MenuItem.SHOW_AS_ACTION_IF_ROOM) {
-                                mActionItemIds.add(itemId);
-                            }
-                            break;
-
-                        case XmlPullParser.END_DOCUMENT:
-                            eof = true;
-                            break;
-                    }
-
-                    eventType = parser.next();
-                }
-            } catch (XmlPullParserException e) {
-                throw new InflateException("Error inflating menu XML", e);
-            } catch (IOException e) {
-                throw new InflateException("Error inflating menu XML", e);
-            } finally {
-                if (parser != null) {
-                    parser.close();
-                }
-            }
-        }
-
-    }
-}
diff --git a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelperHoneycomb.java b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelperHoneycomb.java
deleted file mode 100644
index 16fba69..0000000
--- a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelperHoneycomb.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.
- */
-
-package com.example.android.actionbarcompat;
-
-import android.app.Activity;
-import android.content.Context;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-
-/**
- * An extension of {@link ActionBarHelper} that provides Android 3.0-specific functionality for
- * Honeycomb tablets. It thus requires API level 11.
- */
-public class ActionBarHelperHoneycomb extends ActionBarHelper {
-    private Menu mOptionsMenu;
-    private View mRefreshIndeterminateProgressView = null;
-
-    protected ActionBarHelperHoneycomb(Activity activity) {
-        super(activity);
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        mOptionsMenu = menu;
-        return super.onCreateOptionsMenu(menu);
-    }
-
-    @Override
-    public void setRefreshActionItemState(boolean refreshing) {
-        // On Honeycomb, we can set the state of the refresh button by giving it a custom
-        // action view.
-        if (mOptionsMenu == null) {
-            return;
-        }
-
-        final MenuItem refreshItem = mOptionsMenu.findItem(R.id.menu_refresh);
-        if (refreshItem != null) {
-            if (refreshing) {
-                if (mRefreshIndeterminateProgressView == null) {
-                    LayoutInflater inflater = (LayoutInflater)
-                            getActionBarThemedContext().getSystemService(
-                                    Context.LAYOUT_INFLATER_SERVICE);
-                    mRefreshIndeterminateProgressView = inflater.inflate(
-                            R.layout.actionbar_indeterminate_progress, null);
-                }
-
-                refreshItem.setActionView(mRefreshIndeterminateProgressView);
-            } else {
-                refreshItem.setActionView(null);
-            }
-        }
-    }
-
-    /**
-     * Returns a {@link Context} suitable for inflating layouts for the action bar. The
-     * implementation for this method in {@link ActionBarHelperICS} asks the action bar for a
-     * themed context.
-     */
-    protected Context getActionBarThemedContext() {
-        return mActivity;
-    }
-}
diff --git a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelperICS.java b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelperICS.java
deleted file mode 100644
index d2239db..0000000
--- a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelperICS.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.
- */
-
-package com.example.android.actionbarcompat;
-
-import android.app.Activity;
-import android.content.Context;
-import android.view.Menu;
-import android.view.MenuItem;
-
-/**
- * An extension of {@link com.example.android.actionbarcompat.ActionBarHelper} that provides Android
- * 4.0-specific functionality for IceCreamSandwich devices. It thus requires API level 14.
- */
-public class ActionBarHelperICS extends ActionBarHelperHoneycomb {
-    protected ActionBarHelperICS(Activity activity) {
-        super(activity);
-    }
-
-    @Override
-    protected Context getActionBarThemedContext() {
-        return mActivity.getActionBar().getThemedContext();
-    }
-}
diff --git a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/MainActivity.java b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/MainActivity.java
deleted file mode 100644
index facf1ae..0000000
--- a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/MainActivity.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.
- */
-
-package com.example.android.actionbarcompat;
-
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.Toast;
-
-public class MainActivity extends ActionBarActivity {
-    private boolean mAlternateTitle = false;
-
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.main);
-
-        findViewById(R.id.toggle_title).setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View view) {
-                if (mAlternateTitle) {
-                    setTitle(R.string.app_name);
-                } else {
-                    setTitle(R.string.alternate_title);
-                }
-                mAlternateTitle = !mAlternateTitle;
-            }
-        });
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        MenuInflater menuInflater = getMenuInflater();
-        menuInflater.inflate(R.menu.main, menu);
-
-        // Calling super after populating the menu is necessary here to ensure that the
-        // action bar helpers have a chance to handle this event.
-        return super.onCreateOptionsMenu(menu);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case android.R.id.home:
-                Toast.makeText(this, "Tapped home", Toast.LENGTH_SHORT).show();
-                break;
-
-            case R.id.menu_refresh:
-                Toast.makeText(this, "Fake refreshing...", Toast.LENGTH_SHORT).show();
-                getActionBarHelper().setRefreshActionItemState(true);
-                getWindow().getDecorView().postDelayed(
-                        new Runnable() {
-                            @Override
-                            public void run() {
-                                getActionBarHelper().setRefreshActionItemState(false);
-                            }
-                        }, 1000);
-                break;
-
-            case R.id.menu_search:
-                Toast.makeText(this, "Tapped search", Toast.LENGTH_SHORT).show();
-                break;
-
-            case R.id.menu_share:
-                Toast.makeText(this, "Tapped share", Toast.LENGTH_SHORT).show();
-                break;
-        }
-        return super.onOptionsItemSelected(item);
-    }
-}
diff --git a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/SimpleMenu.java b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/SimpleMenu.java
deleted file mode 100644
index 8b694d0..0000000
--- a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/SimpleMenu.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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.
- */
-
-package com.example.android.actionbarcompat;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.SubMenu;
-
-import java.util.ArrayList;
-
-/**
- * A <em>really</em> dumb implementation of the {@link android.view.Menu} interface, that's only
- * useful for our actionbar-compat purposes. See
- * <code>com.android.internal.view.menu.MenuBuilder</code> in AOSP for a more complete
- * implementation.
- */
-public class SimpleMenu implements Menu {
-
-    private Context mContext;
-    private Resources mResources;
-
-    private ArrayList<SimpleMenuItem> mItems;
-
-    public SimpleMenu(Context context) {
-        mContext = context;
-        mResources = context.getResources();
-        mItems = new ArrayList<SimpleMenuItem>();
-    }
-
-    public Context getContext() {
-        return mContext;
-    }
-
-    public Resources getResources() {
-        return mResources;
-    }
-
-    public MenuItem add(CharSequence title) {
-        return addInternal(0, 0, title);
-    }
-
-    public MenuItem add(int titleRes) {
-        return addInternal(0, 0, mResources.getString(titleRes));
-    }
-
-    public MenuItem add(int groupId, int itemId, int order, CharSequence title) {
-        return addInternal(itemId, order, title);
-    }
-
-    public MenuItem add(int groupId, int itemId, int order, int titleRes) {
-        return addInternal(itemId, order, mResources.getString(titleRes));
-    }
-
-    /**
-     * Adds an item to the menu.  The other add methods funnel to this.
-     */
-    private MenuItem addInternal(int itemId, int order, CharSequence title) {
-        final SimpleMenuItem item = new SimpleMenuItem(this, itemId, order, title);
-        mItems.add(findInsertIndex(mItems, order), item);
-        return item;
-    }
-
-    private static int findInsertIndex(ArrayList<? extends MenuItem> items, int order) {
-        for (int i = items.size() - 1; i >= 0; i--) {
-            MenuItem item = items.get(i);
-            if (item.getOrder() <= order) {
-                return i + 1;
-            }
-        }
-
-        return 0;
-    }
-
-    public int findItemIndex(int id) {
-        final int size = size();
-
-        for (int i = 0; i < size; i++) {
-            SimpleMenuItem item = mItems.get(i);
-            if (item.getItemId() == id) {
-                return i;
-            }
-        }
-
-        return -1;
-    }
-
-    public void removeItem(int itemId) {
-        removeItemAtInt(findItemIndex(itemId));
-    }
-
-    private void removeItemAtInt(int index) {
-        if ((index < 0) || (index >= mItems.size())) {
-            return;
-        }
-        mItems.remove(index);
-    }
-
-    public void clear() {
-        mItems.clear();
-    }
-
-    public MenuItem findItem(int id) {
-        final int size = size();
-        for (int i = 0; i < size; i++) {
-            SimpleMenuItem item = mItems.get(i);
-            if (item.getItemId() == id) {
-                return item;
-            }
-        }
-
-        return null;
-    }
-
-    public int size() {
-        return mItems.size();
-    }
-
-    public MenuItem getItem(int index) {
-        return mItems.get(index);
-    }
-
-    // Unsupported operations.
-
-    public SubMenu addSubMenu(CharSequence charSequence) {
-        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
-    }
-
-    public SubMenu addSubMenu(int titleRes) {
-        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
-    }
-
-    public SubMenu addSubMenu(int groupId, int itemId, int order, CharSequence title) {
-        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
-    }
-
-    public SubMenu addSubMenu(int groupId, int itemId, int order, int titleRes) {
-        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
-    }
-
-    public int addIntentOptions(int i, int i1, int i2, ComponentName componentName,
-            Intent[] intents, Intent intent, int i3, MenuItem[] menuItems) {
-        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
-    }
-
-    public void removeGroup(int i) {
-        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
-    }
-
-    public void setGroupCheckable(int i, boolean b, boolean b1) {
-        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
-    }
-
-    public void setGroupVisible(int i, boolean b) {
-        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
-    }
-
-    public void setGroupEnabled(int i, boolean b) {
-        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
-    }
-
-    public boolean hasVisibleItems() {
-        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
-    }
-
-    public void close() {
-        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
-    }
-
-    public boolean performShortcut(int i, KeyEvent keyEvent, int i1) {
-        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
-    }
-
-    public boolean isShortcutKey(int i, KeyEvent keyEvent) {
-        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
-    }
-
-    public boolean performIdentifierAction(int i, int i1) {
-        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
-    }
-
-    public void setQwertyMode(boolean b) {
-        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
-    }
-}
diff --git a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/SimpleMenuItem.java b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/SimpleMenuItem.java
deleted file mode 100644
index 425ba72..0000000
--- a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/SimpleMenuItem.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * 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.
- */
-
-package com.example.android.actionbarcompat;
-
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-import android.view.ActionProvider;
-import android.view.ContextMenu;
-import android.view.MenuItem;
-import android.view.SubMenu;
-import android.view.View;
-
-/**
- * A <em>really</em> dumb implementation of the {@link android.view.MenuItem} interface, that's only
- * useful for our actionbar-compat purposes. See
- * <code>com.android.internal.view.menu.MenuItemImpl</code> in AOSP for a more complete
- * implementation.
- */
-public class SimpleMenuItem implements MenuItem {
-
-    private SimpleMenu mMenu;
-
-    private final int mId;
-    private final int mOrder;
-    private CharSequence mTitle;
-    private CharSequence mTitleCondensed;
-    private Drawable mIconDrawable;
-    private int mIconResId = 0;
-    private boolean mEnabled = true;
-
-    public SimpleMenuItem(SimpleMenu menu, int id, int order, CharSequence title) {
-        mMenu = menu;
-        mId = id;
-        mOrder = order;
-        mTitle = title;
-    }
-
-    public int getItemId() {
-        return mId;
-    }
-
-    public int getOrder() {
-        return mOrder;
-    }
-
-    public MenuItem setTitle(CharSequence title) {
-        mTitle = title;
-        return this;
-    }
-
-    public MenuItem setTitle(int titleRes) {
-        return setTitle(mMenu.getContext().getString(titleRes));
-    }
-
-    public CharSequence getTitle() {
-        return mTitle;
-    }
-
-    public MenuItem setTitleCondensed(CharSequence title) {
-        mTitleCondensed = title;
-        return this;
-    }
-
-    public CharSequence getTitleCondensed() {
-        return mTitleCondensed != null ? mTitleCondensed : mTitle;
-    }
-
-    public MenuItem setIcon(Drawable icon) {
-        mIconResId = 0;
-        mIconDrawable = icon;
-        return this;
-    }
-
-    public MenuItem setIcon(int iconResId) {
-        mIconDrawable = null;
-        mIconResId = iconResId;
-        return this;
-    }
-
-    public Drawable getIcon() {
-        if (mIconDrawable != null) {
-            return mIconDrawable;
-        }
-
-        if (mIconResId != 0) {
-            return mMenu.getResources().getDrawable(mIconResId);
-        }
-
-        return null;
-    }
-
-    public MenuItem setEnabled(boolean enabled) {
-        mEnabled = enabled;
-        return this;
-    }
-
-    public boolean isEnabled() {
-        return mEnabled;
-    }
-
-    // No-op operations. We use no-ops to allow inflation from menu XML.
-
-    public int getGroupId() {
-        // Noop
-        return 0;
-    }
-
-    public View getActionView() {
-        // Noop
-        return null;
-    }
-
-    public MenuItem setActionProvider(ActionProvider actionProvider) {
-        // Noop
-        return this;
-    }
-
-    public ActionProvider getActionProvider() {
-        // Noop
-        return null;
-    }
-
-    public boolean expandActionView() {
-        // Noop
-        return false;
-    }
-
-    public boolean collapseActionView() {
-        // Noop
-        return false;
-    }
-
-    public boolean isActionViewExpanded() {
-        // Noop
-        return false;
-    }
-
-    @Override
-    public MenuItem setOnActionExpandListener(OnActionExpandListener onActionExpandListener) {
-        // Noop
-        return this;
-    }
-
-    public MenuItem setIntent(Intent intent) {
-        // Noop
-        return this;
-    }
-
-    public Intent getIntent() {
-        // Noop
-        return null;
-    }
-
-    public MenuItem setShortcut(char c, char c1) {
-        // Noop
-        return this;
-    }
-
-    public MenuItem setNumericShortcut(char c) {
-        // Noop
-        return this;
-    }
-
-    public char getNumericShortcut() {
-        // Noop
-        return 0;
-    }
-
-    public MenuItem setAlphabeticShortcut(char c) {
-        // Noop
-        return this;
-    }
-
-    public char getAlphabeticShortcut() {
-        // Noop
-        return 0;
-    }
-
-    public MenuItem setCheckable(boolean b) {
-        // Noop
-        return this;
-    }
-
-    public boolean isCheckable() {
-        // Noop
-        return false;
-    }
-
-    public MenuItem setChecked(boolean b) {
-        // Noop
-        return this;
-    }
-
-    public boolean isChecked() {
-        // Noop
-        return false;
-    }
-
-    public MenuItem setVisible(boolean b) {
-        // Noop
-        return this;
-    }
-
-    public boolean isVisible() {
-        // Noop
-        return true;
-    }
-
-    public boolean hasSubMenu() {
-        // Noop
-        return false;
-    }
-
-    public SubMenu getSubMenu() {
-        // Noop
-        return null;
-    }
-
-    public MenuItem setOnMenuItemClickListener(OnMenuItemClickListener onMenuItemClickListener) {
-        // Noop
-        return this;
-    }
-
-    public ContextMenu.ContextMenuInfo getMenuInfo() {
-        // Noop
-        return null;
-    }
-
-    public void setShowAsAction(int i) {
-        // Noop
-    }
-
-    public MenuItem setShowAsActionFlags(int i) {
-        // Noop
-        return null;
-    }
-
-    public MenuItem setActionView(View view) {
-        // Noop
-        return this;
-    }
-
-    public MenuItem setActionView(int i) {
-        // Noop
-        return this;
-    }
-}
diff --git a/samples/Alarm/AndroidManifest.xml b/samples/Alarm/AndroidManifest.xml
index 6a7a831..2242567 100644
--- a/samples/Alarm/AndroidManifest.xml
+++ b/samples/Alarm/AndroidManifest.xml
@@ -29,6 +29,7 @@
     <!--
         Declares the application, its icon, and its visible label
      -->
+    <uses-sdk android:minSdkVersion="11" />
     <application
         android:icon="@drawable/icon"
         android:label="@string/app_name">
diff --git a/samples/Alarm/src/com/example/android/newalarm/AlarmService.java b/samples/Alarm/src/com/example/android/newalarm/AlarmService.java
index 1f88206..ec3163c 100644
--- a/samples/Alarm/src/com/example/android/newalarm/AlarmService.java
+++ b/samples/Alarm/src/com/example/android/newalarm/AlarmService.java
@@ -181,13 +181,6 @@
         // Sets the text to use for the status bar and status list views.
         CharSequence notificationText = getText(R.string.alarm_service_started);
 
-        // Sets the icon, status bar text, and display time for the mNotification.
-        mNotification = new Notification(
-            R.drawable.stat_sample,  // the status icon
-            notificationText, // the status text
-            System.currentTimeMillis()  // the time stamp
-        );
-
         // Sets up the Intent that starts AlarmActivity
         mContentIntent = PendingIntent.getActivity(
             this,  // Start the Activity in the current context
@@ -196,14 +189,15 @@
             0  // Use an existing activity instance if available
         );
 
-        // Creates a new content view for the mNotification. The view appears when the user
-        // shows the expanded status window.
-        mNotification.setLatestEventInfo(
-            this,  //  Put the content view in the current context
-            getText(R.string.alarm_service_label),  // The text to use as the label of the entry
-            notificationText,  // The text to use as the contents of the entry
-            mContentIntent  // The intent to send when the entry is clicked
-        );
+        // Build the notification object.
+        mNotification = new Notification.Builder(this)  //  The builder requires the context
+                .setSmallIcon(R.drawable.stat_sample)  // the status icon
+                .setTicker(notificationText)  // the status text
+                .setWhen(System.currentTimeMillis())  // the time stamp
+                .setContentTitle(getText(R.string.alarm_service_label))  // the label of the entry
+                .setContentText(notificationText)  // the contents of the entry
+                .setContentIntent(mContentIntent)  // The intent to send when the entry is clicked
+                .build();
 
         // Sets a unique ID for the notification and sends it to NotificationManager to be
         // displayed. The ID is the integer marker for the notification string, which is
diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml
index b74e290..caac573 100644
--- a/samples/ApiDemos/AndroidManifest.xml
+++ b/samples/ApiDemos/AndroidManifest.xml
@@ -38,6 +38,7 @@
     <uses-permission android:name="android.permission.TRANSMIT_IR" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 
+
     <!-- For android.media.audiofx.Visualizer -->
     <uses-permission android:name="android.permission.RECORD_AUDIO" />
 
@@ -550,17 +551,7 @@
             </intent-filter>
         </activity>
 
-        <service android:name=".app.RemoteService" android:process=":remote">
-            <intent-filter>
-                <!-- These are the interfaces supported by the service, which
-                     you can bind to. -->
-                <action android:name="com.example.android.apis.app.IRemoteService" />
-                <action android:name="com.example.android.apis.app.ISecondary" />
-                <!-- This is an action code you can use to select the service
-                     without explicitly supplying the implementation class. -->
-                <action android:name="com.example.android.apis.app.REMOTE_SERVICE" />
-            </intent-filter>
-        </service>
+        <service android:name=".app.RemoteService" android:process=":remote" />
 
         <activity android:name=".app.RemoteService$Controller"
                 android:label="@string/activity_remote_service_controller"
@@ -1176,7 +1167,6 @@
             </intent-filter>
         </activity>
 
-        <!--
         <activity android:name=".content.TextUndoActivity" android:label="@string/activity_text_undo">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -1184,7 +1174,6 @@
                 <category android:name="android.intent.category.EMBED" />
             </intent-filter>
         </activity>
-        -->
 
         <activity android:name=".content.ResourcesLayoutReference"
                 android:label="@string/activity_resources_layout_reference">
@@ -1237,6 +1226,13 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".content.ShareContent" android:label="@string/activity_share_content">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".content.ChangedContacts" android:label="@string/activity_changed_contact">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
@@ -1263,8 +1259,25 @@
 
         <provider android:name=".content.FileProvider"
                   android:authorities="com.example.android.apis.content.FileProvider"
+                  android:grantUriPermissions="true"
+                  android:exported="false"
                   android:enabled="@bool/atLeastHoneycombMR2" />
 
+        <activity android:name=".content.ProcessTextLauncher"
+                android:label="@string/process_text_title" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".content.ProcessText" >
+            <intent-filter >
+                <action android:name="android.intent.action.PROCESS_TEXT"/>
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="text/plain" />
+            </intent-filter>
+        </activity>
+
         <!-- ************************************* -->
         <!--     HARDWARE PACKAGE SAMPLES          -->
         <!-- ************************************* -->
@@ -1536,12 +1549,6 @@
         <!--      VIEW/WIDGET PACKAGE SAMPLES      -->
         <!-- ************************************* -->
 
-        <activity android:name=".view.TextClockDemo" android:label="Views/TextClock">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.SAMPLE_CODE" />
-            </intent-filter>
-        </activity>
         <activity android:name=".view.ChronometerDemo" android:label="Views/Chronometer">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -2117,8 +2124,56 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".view.EditTextDemo"
+                  android:label="Views/Text/EditText">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".text.Link"
+                  android:label="Views/Text/Linkify">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".text.LogTextBox1"
+                  android:label="Views/Text/LogTextBox">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".text.Marquee"
+                  android:label="Views/Text/Marquee">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.TextClockDemo"
+                  android:label="Views/Text/TextClock">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".view.TextSwitcher1"
-                android:label="Views/TextSwitcher">
+                android:label="Views/Text/TextSwitcher">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.TextViewDemo"
+                  android:label="Views/Text/TextView">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
@@ -3084,27 +3139,6 @@
         <!--             OTHER SAMPLES             -->
         <!-- ************************************* -->
 
-        <activity android:name=".text.Link" android:label="Text/Linkify">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.SAMPLE_CODE" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name=".text.Marquee" android:label="Text/Marquee">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.SAMPLE_CODE" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name=".text.LogTextBox1" android:label="Text/LogTextBox">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.SAMPLE_CODE" />
-            </intent-filter>
-        </activity>
-
         <activity android:name=".nfc.ForegroundDispatch" android:label="NFC/ForegroundDispatch">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/samples/ApiDemos/res/anim/animator.xml b/samples/ApiDemos/res/anim/animator.xml
index 2432f19..67aca3f 100644
--- a/samples/ApiDemos/res/anim/animator.xml
+++ b/samples/ApiDemos/res/anim/animator.xml
@@ -14,6 +14,7 @@
      limitations under the License.
 -->
 
+<!-- BEGIN_INCLUDE(ValueAnimatorResources) -->
 <animator xmlns:android="http://schemas.android.com/apk/res/android"
     android:duration="1000"
     android:valueFrom="1"
@@ -21,3 +22,4 @@
     android:valueType="floatType"
     android:repeatCount="1"
     android:repeatMode="reverse"/>
+<!-- END_INCLUDE(ValueAnimatorResources) -->
diff --git a/samples/ApiDemos/res/anim/object_animator.xml b/samples/ApiDemos/res/anim/object_animator.xml
index 863d423..dc503d2 100644
--- a/samples/ApiDemos/res/anim/object_animator.xml
+++ b/samples/ApiDemos/res/anim/object_animator.xml
@@ -14,6 +14,7 @@
      limitations under the License.
 -->
 
+<!-- BEGIN_INCLUDE(ObjectAnimatorResources) -->
 <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
     android:duration="1000"
     android:valueTo="200"
@@ -21,3 +22,4 @@
     android:propertyName="y"
     android:repeatCount="1"
     android:repeatMode="reverse"/>
+<!-- END_INCLUDE(ObjectAnimatorResources) -->
diff --git a/samples/ApiDemos/res/anim/object_animator_pvh.xml b/samples/ApiDemos/res/anim/object_animator_pvh.xml
new file mode 100644
index 0000000..10c4e4d
--- /dev/null
+++ b/samples/ApiDemos/res/anim/object_animator_pvh.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<!-- BEGIN_INCLUDE(PropertyValuesHolderResources) -->
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+                android:duration="1000"
+                android:repeatCount="1"
+                android:repeatMode="reverse">
+    <propertyValuesHolder android:propertyName="x" android:valueTo="400"/>
+    <propertyValuesHolder android:propertyName="y" android:valueTo="200"/>
+</objectAnimator>
+<!-- END_INCLUDE(PropertyValuesHolderResources) -->
diff --git a/samples/ApiDemos/res/anim/object_animator_pvh_kf.xml b/samples/ApiDemos/res/anim/object_animator_pvh_kf.xml
new file mode 100644
index 0000000..cc93a5e
--- /dev/null
+++ b/samples/ApiDemos/res/anim/object_animator_pvh_kf.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+                android:duration="1000"
+                android:repeatCount="1"
+                android:repeatMode="reverse">
+    <propertyValuesHolder android:propertyName="x" >
+        <keyframe android:fraction="0" android:value="800" />
+        <keyframe android:fraction=".2" android:value="1000" />
+        <keyframe android:fraction="1" android:value="400" />
+    </propertyValuesHolder>
+    <propertyValuesHolder android:propertyName="y" >
+        <keyframe/>
+        <keyframe android:fraction=".2" android:value="300" />
+        <keyframe android:value="1000" />
+    </propertyValuesHolder>
+</objectAnimator>
diff --git a/samples/ApiDemos/res/anim/object_animator_pvh_kf_interpolated.xml b/samples/ApiDemos/res/anim/object_animator_pvh_kf_interpolated.xml
new file mode 100644
index 0000000..96a4cfe
--- /dev/null
+++ b/samples/ApiDemos/res/anim/object_animator_pvh_kf_interpolated.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+                android:duration="1000"
+                android:repeatCount="1"
+                android:repeatMode="reverse">
+    <!-- BEGIN_INCLUDE(KeyframeResources) -->
+    <propertyValuesHolder android:propertyName="x" >
+        <keyframe android:fraction="0" android:value="800" />
+        <keyframe android:fraction=".2"
+                  android:interpolator="@android:anim/accelerate_interpolator"
+                  android:value="1000" />
+        <keyframe android:fraction="1"
+                  android:interpolator="@android:anim/accelerate_interpolator"
+                  android:value="400" />
+    </propertyValuesHolder>
+    <propertyValuesHolder android:propertyName="y" >
+        <keyframe/>
+        <keyframe android:fraction=".2"
+                  android:interpolator="@android:anim/accelerate_interpolator"
+                  android:value="300"/>
+        <keyframe android:interpolator="@android:anim/accelerate_interpolator"
+                  android:value="1000" />
+    </propertyValuesHolder>
+    <!-- END_INCLUDE(KeyframeResources) -->
+</objectAnimator>
diff --git a/samples/ApiDemos/res/anim/value_animator_pvh_kf.xml b/samples/ApiDemos/res/anim/value_animator_pvh_kf.xml
new file mode 100644
index 0000000..86b2e17
--- /dev/null
+++ b/samples/ApiDemos/res/anim/value_animator_pvh_kf.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<!-- BEGIN_INCLUDE(ValueAnimatorKeyframeResources) -->
+<animator xmlns:android="http://schemas.android.com/apk/res/android"
+          android:duration="1000"
+          android:repeatCount="1"
+          android:repeatMode="reverse">
+    <propertyValuesHolder>
+        <keyframe android:fraction="0" android:value="1"/>
+        <keyframe android:fraction=".2" android:value=".4"/>
+        <keyframe android:fraction="1" android:value="0"/>
+    </propertyValuesHolder>
+</animator>
+<!-- END_INCLUDE(ValueAnimatorKeyframeResources) -->
diff --git a/samples/ApiDemos/res/layout/activity_animation.xml b/samples/ApiDemos/res/layout/activity_animation.xml
index 9d956b5..c087b33 100644
--- a/samples/ApiDemos/res/layout/activity_animation.xml
+++ b/samples/ApiDemos/res/layout/activity_animation.xml
@@ -59,5 +59,9 @@
         android:text="@string/activity_zoom_thumbnail_animation">
     </Button>
 
+    <Button android:id="@+id/no_animation"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:text="@string/activity_no_animation">
+    </Button>
 </LinearLayout>
 
diff --git a/samples/ApiDemos/res/layout/edit_text_demo.xml b/samples/ApiDemos/res/layout/edit_text_demo.xml
new file mode 100644
index 0000000..e7f5c95
--- /dev/null
+++ b/samples/ApiDemos/res/layout/edit_text_demo.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical" >
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical" >
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="EditText imeOptions=flagNoFullscreen" />
+
+        <EditText
+            android:id="@+id/edit0"
+            android:imeOptions="flagNoFullscreen"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="EditText imeOptions=actionSearch" />
+
+        <EditText
+            android:id="@+id/edit1"
+            android:imeOptions="actionSearch"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+    </LinearLayout>
+
+</ScrollView>
diff --git a/samples/ApiDemos/res/layout/keystore_usage.xml b/samples/ApiDemos/res/layout/keystore_usage.xml
index 2bf7845..bfaac7c 100644
--- a/samples/ApiDemos/res/layout/keystore_usage.xml
+++ b/samples/ApiDemos/res/layout/keystore_usage.xml
@@ -83,12 +83,12 @@
 
         <EditText
             android:id="@+id/plaintext"
-            android:layout_width="fill_parent"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_alignBaseline="@+id/plaintext_label"
             android:layout_alignParentRight="true"
-            android:layout_below="@+id/key_ops_header"
-            android:layout_toRightOf="@id/plaintext_label"
+            android:layout_toRightOf="@+id/plaintext_label"
+            android:layout_marginBottom="12dp"
             android:ems="10"
             android:maxLines="1" />
 
@@ -102,12 +102,12 @@
 
         <EditText
             android:id="@+id/ciphertext"
-            android:layout_width="fill_parent"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_alignBaseline="@+id/ciphertext_label"
             android:layout_alignParentRight="true"
-            android:layout_below="@+id/plaintext"
-            android:layout_toRightOf="@id/ciphertext_label"
+            android:layout_toRightOf="@+id/ciphertext_label"
+            android:layout_marginBottom="12dp"
             android:maxLines="1" />
 
         <LinearLayout
@@ -189,4 +189,4 @@
             android:ems="10" />
     </RelativeLayout>
 
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/presentation_list_item.xml b/samples/ApiDemos/res/layout/presentation_list_item.xml
index d28b5d9..7c4de91 100644
--- a/samples/ApiDemos/res/layout/presentation_list_item.xml
+++ b/samples/ApiDemos/res/layout/presentation_list_item.xml
@@ -17,32 +17,40 @@
 <!-- The content that we show on secondary displays.
      See corresponding Java code PresentationActivity.java. -->
 
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:orientation="horizontal">
+        android:orientation="vertical">
+    <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="horizontal">
 
-    <CheckBox
-        android:id="@+id/checkbox_presentation"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentLeft="true"
-        android:layout_centerVertical="true"
-        android:layout_marginRight="16dip"/>
+        <CheckBox
+            android:id="@+id/checkbox_presentation"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentLeft="true"
+            android:layout_centerVertical="true"
+            android:layout_marginRight="16dip"/>
 
-    <TextView android:id="@+id/display_id"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_toRightOf="@id/checkbox_presentation"
-        android:layout_centerVertical="true"
-        android:textAppearance="?android:attr/textAppearanceLarge"/>
+        <TextView android:id="@+id/display_id"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_toRightOf="@id/checkbox_presentation"
+            android:layout_centerVertical="true"
+            android:textAppearance="?android:attr/textAppearanceLarge"/>
 
-    <Button android:id="@+id/info"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentRight="true"
-        android:layout_centerVertical="true"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:text="@string/presentation_info_text"/>
+        <Button android:id="@+id/info"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:text="@string/presentation_info_text"/>
+    </RelativeLayout>
 
-</RelativeLayout>
+    <Spinner android:id="@+id/modes"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/process_text_main.xml b/samples/ApiDemos/res/layout/process_text_main.xml
new file mode 100644
index 0000000..c6d31a1
--- /dev/null
+++ b/samples/ApiDemos/res/layout/process_text_main.xml
@@ -0,0 +1,26 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    xmlns:card_view="http://schemas.android.com/apk/res-auto"
+    android:padding="10dip"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical" >
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/process_text_received_text_title"
+        android:textAppearance="@android:style/TextAppearance.Material.Title" />
+
+    <EditText
+        android:id="@+id/process_text_received_text_editable"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+
+    <Button
+        android:id="@+id/process_text_finish_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/process_text_finish" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/process_text_send.xml b/samples/ApiDemos/res/layout/process_text_send.xml
new file mode 100644
index 0000000..4b3d13e
--- /dev/null
+++ b/samples/ApiDemos/res/layout/process_text_send.xml
@@ -0,0 +1,21 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    xmlns:card_view="http://schemas.android.com/apk/res-auto"
+    android:padding="10dip"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/process_text_send_title"
+        android:textAppearance="@android:style/TextAppearance.Material.Title" />
+
+    <EditText
+        android:id="@+id/process_text_send_edit"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/process_text_send_description" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/seekbar_1.xml b/samples/ApiDemos/res/layout/seekbar_1.xml
index d3140b2..79ece37 100644
--- a/samples/ApiDemos/res/layout/seekbar_1.xml
+++ b/samples/ApiDemos/res/layout/seekbar_1.xml
@@ -14,23 +14,53 @@
      limitations under the License.
 -->
 
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:paddingStart="16dp"
+    android:paddingEnd="16dp"
+    android:paddingTop="16dp"
+    android:paddingBottom="16dp">
 
-    <SeekBar android:id="@+id/seek"
+    <CheckBox
+        android:id="@+id/enabled"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/enabled" />
+
+    <SeekBar
+        android:id="@+id/seekMin"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:max="100"
+        android:progress="0"
+        android:enabled="false" />
+
+    <SeekBar
+        android:id="@+id/seekMax"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:max="100"
+        android:progress="100"
+        android:enabled="false" />
+
+    <SeekBar
+        android:id="@+id/seek"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:max="100"
         android:progress="50"
         android:secondaryProgress="75" />
 
-    <TextView android:id="@+id/progress"
+    <TextView
+        android:id="@+id/progress"
        	android:layout_width="match_parent"
         android:layout_height="wrap_content" />
 
-    <TextView android:id="@+id/tracking"
+    <TextView
+        android:id="@+id/tracking"
        	android:layout_width="match_parent"
         android:layout_height="wrap_content" />
 </LinearLayout>
diff --git a/samples/ApiDemos/res/layout/share_content.xml b/samples/ApiDemos/res/layout/share_content.xml
new file mode 100644
index 0000000..e9d5479
--- /dev/null
+++ b/samples/ApiDemos/res/layout/share_content.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<!-- Demonstrates selecting various types of contact data. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <TextView
+        android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:paddingBottom="8dip"
+        android:text="@string/share_content_msg"/>
+
+    <Button android:id="@+id/share_image"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:text="@string/share_image">
+        <requestFocus />
+    </Button>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/layout/text_undo.xml b/samples/ApiDemos/res/layout/text_undo.xml
index f7d74e8..cf4ac6c 100644
--- a/samples/ApiDemos/res/layout/text_undo.xml
+++ b/samples/ApiDemos/res/layout/text_undo.xml
@@ -14,21 +14,20 @@
      limitations under the License.
 -->
 
-<!-- Demonstrates saving and restoring activity state.
-     See corresponding Java code com.android.sdk.app.SaveRestoreState.java. -->
+<!-- Demonstrates undo/redo behavior on a text field. -->
 
 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent" android:layout_height="match_parent">
     <LinearLayout android:orientation="vertical" android:padding="4dip"
         android:layout_width="match_parent" android:layout_height="wrap_content">
 
-        <TextView android:id="@+id/msg"
+        <TextView android:id="@+id/default_edit_msg"
             android:layout_width="match_parent" android:layout_height="wrap_content"
             android:layout_weight="0" android:textAppearance="?android:attr/textAppearanceMedium"
             android:paddingBottom="8dip"
-            android:text="@string/text_undo_msg" />
+            android:text="@string/text_undo_default_edit_msg" />
 
-        <EditText android:id="@+id/text"
+        <EditText android:id="@+id/default_text"
             android:layout_width="match_parent" android:layout_height="wrap_content"
             android:layout_weight="1"
             android:textAppearance="?android:attr/textAppearanceMedium"
@@ -41,18 +40,73 @@
             android:layout_height="match_parent"
             android:paddingTop="8dip">
             <Button
-                android:id="@+id/undo"
+                android:id="@+id/set_text"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:text="@string/undo"
+                android:text="@string/text_undo_set_text"
+                android:layout_gravity="bottom" />                
+            <Button
+                android:id="@+id/append_text"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/text_undo_append_text"
                 android:layout_gravity="bottom" />
             <Button
-                android:id="@+id/redo"
+                android:id="@+id/insert_text"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:text="@string/redo"
+                android:text="@string/text_undo_insert_text"
                 android:layout_gravity="bottom" />
         </LinearLayout>
 
+        <TextView android:id="@+id/undo_disabled_msg"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="0"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:paddingBottom="8dip"
+            android:text="@string/text_undo_undo_disabled_msg" />
+
+        <EditText android:id="@+id/undo_disabled_text"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:freezesText="true"
+            android:allowUndo="false">
+        </EditText>
+
+        <TextView android:id="@+id/length_limit_msg"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="0"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:paddingBottom="8dip"
+            android:text="@string/text_undo_length_limit_msg" />
+
+        <EditText android:id="@+id/length_limit_text"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:freezesText="true">
+        </EditText>
+
+        <TextView android:id="@+id/credit_card_msg"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="0"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:paddingBottom="8dip"
+            android:text="@string/text_undo_credit_card_msg" />
+
+        <EditText android:id="@+id/credit_card_text"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:freezesText="true">
+        </EditText>
+
     </LinearLayout>
 </ScrollView>
diff --git a/samples/ApiDemos/res/layout/text_view_demo.xml b/samples/ApiDemos/res/layout/text_view_demo.xml
new file mode 100644
index 0000000..ee0de97
--- /dev/null
+++ b/samples/ApiDemos/res/layout/text_view_demo.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical" >
+
+    <TextView
+            android:id="@+id/text_small"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Small"
+            android:textAppearance="?android:attr/textAppearanceSmall" />
+    <TextView
+            android:id="@+id/text_medium"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Medium"
+            android:textAppearance="?android:attr/textAppearanceMedium" />
+    <TextView
+            android:id="@+id/text_large"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Large"
+            android:textAppearance="?android:attr/textAppearanceLarge" />
+
+    <!-- The TextView must have an id to maintain selection on device rotation. -->
+    <TextView
+        android:id="@+id/text_selectable"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="10dp"
+        android:text="Selectable"
+        android:textAppearance="?android:attr/textAppearanceLarge"
+        android:textIsSelectable="true" />
+
+    <TextView
+            android:id="@+id/text_invisible"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Invisibible"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:visibility="invisible" />
+
+    <TextView
+            android:id="@+id/text_background_color"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="View background color"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:background="#ff00ff00" />
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/values/strings.xml b/samples/ApiDemos/res/values/strings.xml
index 65bfba3..8b672e6 100644
--- a/samples/ApiDemos/res/values/strings.xml
+++ b/samples/ApiDemos/res/values/strings.xml
@@ -77,6 +77,7 @@
     <string name="activity_modern_animation_zoom">Modern zoom in</string>
     <string name="activity_scale_up_animation">Scale up</string>
     <string name="activity_zoom_thumbnail_animation">Thumbnail zoom</string>
+    <string name="activity_no_animation">No Animation</string>
 
     <string name="activity_save_restore">App/Activity/Save &amp; Restore State</string>
     <string name="save_restore_msg">Demonstration of saving and restoring activity state in onSaveInstanceState() and onCreate().</string>
@@ -421,11 +422,14 @@
     <string name="styled_text">Plain, <b>bold</b>, <i>italic</i>, <b><i>bold-italic</i></b></string>
     <string name="styled_text_prog">Assigned programmatically:</string>
 
-    <string name="activity_text_undo">Content/Undo Manager/Text</string>
-    <string name="text_undo_msg">Demonstrates simple use of UndoManager with text editing
-            in a TextView.</string>
-    <string name="undo">Undo</string>
-    <string name="redo">Redo</string>
+    <string name="activity_text_undo">Content/Undo</string>
+    <string name="text_undo_default_edit_msg">TextView with the default Control-Z undo behavior.</string>
+    <string name="text_undo_set_text">SetText</string>
+    <string name="text_undo_append_text">Append</string>
+    <string name="text_undo_insert_text">Insert</string>
+    <string name="text_undo_undo_disabled_msg">TextView with undo disabled.</string>
+    <string name="text_undo_length_limit_msg">TextView with a length limit InputFilter.</string>
+    <string name="text_undo_credit_card_msg">Credit card input field with a TextWatcher.</string>
 
     <string name="activity_resources_layout_reference">Content/Resources/Layout Reference</string>
     <string name="resources_layout_reference_description">Shows how to write layout
@@ -456,6 +460,11 @@
     <string name="pick_phone">Pick a Phone</string>
     <string name="pick_address">Pick an Address</string>
 
+    <string name="activity_share_content">Content/Provider/Share Content</string>
+    <string name="share_content_msg">Share private data of the app by granting access
+        to a specific URI in its content provider.</string>
+    <string name="share_image">Share Image</string>
+
     <string name="activity_changed_contact">Content/Provider/Changed Contacts</string>
 
     <string name="activity_install_apk">Content/Packages/Install Apk</string>
@@ -974,6 +983,8 @@
     <string name="seekbar_tracking_off">Tracking off</string>
     <string name="seekbar_from_touch">from touch</string>
 
+    <string name="enabled">Enabled</string>
+
     <string name="ratingbar_rating">Rating:</string>
 
     <string name="popup_menu_search">Search</string>
@@ -1556,4 +1567,13 @@
     <string name="mms_status_downloading">Downloading</string>
 
     <string name="mms_enable_receiver">Enable MMS broadcast receiver</string>
+
+    <string name="process_text_title">Content/Process Text Intent</string>
+    <string name="process_text_received_text_title">Received text selection</string>
+    <string name="process_text_finish_readonly">Finish</string>
+    <string name="process_text_finish">Replace</string>
+    <string name="process_text_no_text_received">No text received.</string>
+    <string name="process_text_no_text_process_intent_received">Try selecting some text in another app and find this app\'s name in the list of options for its selection menu.</string>
+    <string name="process_text_send_title">Select text to process</string>
+    <string name="process_text_send_description">Select a piece of text from this box to trigger the text selection action mode. In there, you will find \"ApiDemos\". That is because this app declares it can handle text processing intents. Try selecting that action to send the selected text to that activity and retrieve processed text back.</string>
 </resources>
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/AnimationLoading.java b/samples/ApiDemos/src/com/example/android/apis/animation/AnimationLoading.java
index 910ee28..0f05528 100644
--- a/samples/ApiDemos/src/com/example/android/apis/animation/AnimationLoading.java
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/AnimationLoading.java
@@ -78,6 +78,10 @@
             addBall(200, 50);
             addBall(350, 50);
             addBall(500, 50, Color.GREEN);
+            addBall(650, 50);
+            addBall(800, 50);
+            addBall(950, 50);
+            addBall(800, 50, Color.YELLOW);
         }
 
         private void createAnimation() {
@@ -106,8 +110,37 @@
                         loadAnimator(appContext, R.anim.color_animator);
                 colorizer.setTarget(balls.get(3));
 
+                ObjectAnimator animPvh = (ObjectAnimator) AnimatorInflater.
+                        loadAnimator(appContext, R.anim.object_animator_pvh);
+                animPvh.setTarget(balls.get(4));
+
+
+                ObjectAnimator animPvhKf = (ObjectAnimator) AnimatorInflater.
+                        loadAnimator(appContext, R.anim.object_animator_pvh_kf);
+                animPvhKf.setTarget(balls.get(5));
+
+                ValueAnimator faderKf = (ValueAnimator) AnimatorInflater.
+                        loadAnimator(appContext, R.anim.value_animator_pvh_kf);
+                faderKf.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                    public void onAnimationUpdate(ValueAnimator animation) {
+                        balls.get(6).setAlpha((Float) animation.getAnimatedValue());
+                    }
+                });
+
+                // This animation has an accelerate interpolator applied on each
+                // keyframe interval. In comparison, the animation defined in
+                // R.anim.object_animator_pvh_kf uses the default linear interpolator
+                // throughout the animation. As these two animations use the
+                // exact same path, the effect of the per-keyframe interpolator
+                // has been made obvious.
+                ObjectAnimator animPvhKfInterpolated = (ObjectAnimator) AnimatorInflater.
+                        loadAnimator(appContext, R.anim.object_animator_pvh_kf_interpolated);
+                animPvhKfInterpolated.setTarget(balls.get(7));
+
                 animation = new AnimatorSet();
-                ((AnimatorSet) animation).playTogether(anim, fader, seq, colorizer);
+                ((AnimatorSet) animation).playTogether(anim, fader, seq, colorizer, animPvh,
+                        animPvhKf, faderKf, animPvhKfInterpolated);
+
             }
         }
 
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/AlarmService_Service.java b/samples/ApiDemos/src/com/example/android/apis/app/AlarmService_Service.java
index 6762ba9..cede9dc 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/AlarmService_Service.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/AlarmService_Service.java
@@ -99,17 +99,19 @@
         // In this sample, we'll use the same text for the ticker and the expanded notification
         CharSequence text = getText(R.string.alarm_service_started);
 
-        // Set the icon, scrolling text and timestamp
-        Notification notification = new Notification(R.drawable.stat_sample, text,
-                System.currentTimeMillis());
-
         // The PendingIntent to launch our activity if the user selects this notification
         PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                 new Intent(this, AlarmService.class), 0);
 
         // Set the info for the views that show in the notification panel.
-        notification.setLatestEventInfo(this, getText(R.string.alarm_service_label),
-                       text, contentIntent);
+        Notification notification = new Notification.Builder(this)
+                .setSmallIcon(R.drawable.stat_sample)  // the status icon
+                .setTicker(text)  // the status text
+                .setWhen(System.currentTimeMillis())  // the time stamp
+                .setContentTitle(getText(R.string.alarm_service_label))  // the label of the entry
+                .setContentText(text)  // the contents of the entry
+                .setContentIntent(contentIntent)  // The intent to send when the entry is clicked
+                .build();
 
         // Send the notification.
         // We use a layout id because it is a unique number.  We use it later to cancel.
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/AlertDialogSamples.java b/samples/ApiDemos/src/com/example/android/apis/app/AlertDialogSamples.java
index 1517cad..aa55b69 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/AlertDialogSamples.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/AlertDialogSamples.java
@@ -24,6 +24,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
@@ -56,6 +57,7 @@
  * </table> 
  */
 public class AlertDialogSamples extends Activity {
+    private static final String TAG = "AlertDialogSamples";
     private static final int DIALOG_YES_NO_MESSAGE = 1;
     private static final int DIALOG_YES_NO_LONG_MESSAGE = 2;
     private static final int DIALOG_LIST = 3;
@@ -469,4 +471,9 @@
             }
         };
     }
+
+    @Override
+    public void onEnterAnimationComplete() {
+        Log.i(TAG, "onEnterAnimationComplete");
+    }
 }
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/Animation.java b/samples/ApiDemos/src/com/example/android/apis/app/Animation.java
index a4a05e6..bb05b2e 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/Animation.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/Animation.java
@@ -26,6 +26,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.os.Bundle;
+import android.util.Log;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.Button;
@@ -35,6 +36,8 @@
  * <p>Example of using a custom animation when transitioning between activities.</p>
  */
 public class Animation extends Activity {
+    private static final String TAG = "Animation";
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -55,6 +58,8 @@
             button.setOnClickListener(mScaleUpListener);
             button = (Button)findViewById(R.id.zoom_thumbnail_animation);
             button.setOnClickListener(mZoomThumbnailListener);
+            button = (Button)findViewById(R.id.no_animation);
+            button.setOnClickListener(mNoAnimationListener);
         } else {
             findViewById(R.id.modern_fade_animation).setEnabled(false);
             findViewById(R.id.modern_zoom_animation).setEnabled(false);
@@ -63,8 +68,14 @@
         }
     }
 
+    @Override
+    public void onEnterAnimationComplete() {
+        Log.i(TAG, "onEnterAnimationComplete");
+    }
+
     private OnClickListener mFadeListener = new OnClickListener() {
         public void onClick(View v) {
+            Log.i(TAG, "Starting fade-in animation...");
             // Request the next activity transition (here starting a new one).
             startActivity(new Intent(Animation.this, AlertDialogSamples.class));
             // Supply a custom animation.  This one will just fade the new
@@ -77,6 +88,7 @@
 
     private OnClickListener mZoomListener = new OnClickListener() {
         public void onClick(View v) {
+            Log.i(TAG, "Starting zoom-in animation...");
             // Request the next activity transition (here starting a new one).
             startActivity(new Intent(Animation.this, AlertDialogSamples.class));
             // This is a more complicated animation, involving transformations
@@ -90,6 +102,7 @@
 
     private OnClickListener mModernFadeListener = new OnClickListener() {
         public void onClick(View v) {
+            Log.i(TAG, "Starting modern-fade-in animation...");
             // Create the desired custom animation, involving transformations
             // on both this (exit) and the new (enter) activity.  Note how for
             // the duration of the animation we force the exiting activity
@@ -104,6 +117,7 @@
 
     private OnClickListener mModernZoomListener = new OnClickListener() {
         public void onClick(View v) {
+            Log.i(TAG, "Starting modern-zoom-in animation...");
             // Create a more complicated animation, involving transformations
             // on both this (exit) and the new (enter) activity.  Note how for
             // the duration of the animation we force the exiting activity
@@ -118,6 +132,7 @@
 
     private OnClickListener mScaleUpListener = new OnClickListener() {
         public void onClick(View v) {
+            Log.i(TAG, "Starting scale-up animation...");
             // Create a scale-up animation that originates at the button
             // being pressed.
             ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(
@@ -129,6 +144,7 @@
 
     private OnClickListener mZoomThumbnailListener = new OnClickListener() {
         public void onClick(View v) {
+            Log.i(TAG, "Starting thumbnail-zoom animation...");
             // Create a thumbnail animation.  We are going to build our thumbnail
             // just from the view that was pressed.  We make sure the view is
             // not selected, because by the time the animation starts we will
@@ -146,5 +162,13 @@
             v.setDrawingCacheEnabled(false);
         }
     };
-}
 
+    private OnClickListener mNoAnimationListener = new OnClickListener() {
+        public void onClick(View v) {
+            Log.i(TAG, "Starting no animation transition...");
+            // Request the next activity transition (here starting a new one).
+            startActivity(new Intent(Animation.this, AlertDialogSamples.class));
+            overridePendingTransition(0, 0);
+        }
+    };
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.java b/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.java
index 15fbdc1..71badcd 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.java
@@ -406,8 +406,7 @@
                             if (featureString != null) {
                                 PersistableBundle bundle = new PersistableBundle();
                                 bundle.putStringArray("features", featureString.split(","));
-                                Log.w(TAG, "setTrustAgentConfigurat() is disabled");
-                                // mDPM.setTrustAgentConfiguration(mDeviceAdminSample, agent, bundle);
+                                mDPM.setTrustAgentConfiguration(mDeviceAdminSample, agent, bundle);
                             }
                         } else {
                             Log.w(TAG, "Invalid component: " + component);
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java b/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
index 123e369..19e41d8 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
@@ -166,18 +166,19 @@
             // In this sample, we'll use the same text for the ticker and the expanded notification
             CharSequence text = getText(R.string.foreground_service_started);
 
-            // Set the icon, scrolling text and timestamp
-            Notification notification = new Notification(R.drawable.stat_sample, text,
-                    System.currentTimeMillis());
-
-            // The PendingIntent to launch our activity if the user selects this notification
             PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                     new Intent(this, Controller.class), 0);
 
             // Set the info for the views that show in the notification panel.
-            notification.setLatestEventInfo(this, getText(R.string.local_service_label),
-                           text, contentIntent);
-            
+            Notification notification = new Notification.Builder(this)
+                    .setSmallIcon(R.drawable.stat_sample)  // the status icon
+                    .setTicker(text)  // the status text
+                    .setWhen(System.currentTimeMillis())  // the time stamp
+                    .setContentTitle(getText(R.string.alarm_service_label))  // the label
+                    .setContentText(text)  // the contents of the entry
+                    .setContentIntent(contentIntent)  // The intent to send when clicked
+                    .build();
+
             startForegroundCompat(R.string.foreground_service_started, notification);
             
         } else if (ACTION_BACKGROUND.equals(intent.getAction())) {
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessage.java b/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessage.java
index 63a254f..399f52d 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessage.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessage.java
@@ -121,24 +121,26 @@
         // The ticker text, this uses a formatted string so our message could be localized
         String tickerText = getString(R.string.imcoming_message_ticker_text, message);
 
-        // construct the Notification object.
-        Notification notif = new Notification(R.drawable.stat_sample, tickerText,
-                System.currentTimeMillis());
-
         // Set the info for the views that show in the notification panel.
-        notif.setLatestEventInfo(this, from, message, contentIntent);
+        Notification.Builder notifBuilder = new Notification.Builder(this)
+                .setSmallIcon(R.drawable.stat_sample)  // the status icon
+                .setTicker(tickerText)  // the status text
+                .setWhen(System.currentTimeMillis())  // the time stamp
+                .setContentTitle(from)  // the label of the entry
+                .setContentText(message)  // the contents of the entry
+                .setContentIntent(contentIntent);  // The intent to send when the entry is clicked
 
         // We'll have this notification do the default sound, vibration, and led.
         // Note that if you want any of these behaviors, you should always have
         // a preference for the user to turn them off.
-        notif.defaults = Notification.DEFAULT_ALL;
+        notifBuilder.setDefaults(Notification.DEFAULT_ALL);
 
         // Note that we use R.layout.incoming_message_panel as the ID for
         // the notification.  It could be any integer you want, but we use
         // the convention of using a resource id for a string related to
         // the notification.  It will always be a unique number within your
         // application.
-        nm.notify(R.string.imcoming_message_ticker_text, notif);
+        nm.notify(R.string.imcoming_message_ticker_text, notifBuilder.build());
     }
 //END_INCLUDE(app_notification)
 
@@ -174,24 +176,26 @@
         // The ticker text, this uses a formatted string so our message could be localized
         String tickerText = getString(R.string.imcoming_message_ticker_text, message);
 
-        // construct the Notification object.
-        Notification notif = new Notification(R.drawable.stat_sample, tickerText,
-                System.currentTimeMillis());
-
         // Set the info for the views that show in the notification panel.
-        notif.setLatestEventInfo(this, from, message, contentIntent);
+        Notification.Builder notifBuilder = new Notification.Builder(this)
+                .setSmallIcon(R.drawable.stat_sample)  // the status icon
+                .setTicker(tickerText)  // the status text
+                .setWhen(System.currentTimeMillis())  // the time stamp
+                .setContentTitle(from)  // the label of the entry
+                .setContentText(message)  // the contents of the entry
+                .setContentIntent(contentIntent);  // The intent to send when the entry is clicked
 
         // We'll have this notification do the default sound, vibration, and led.
         // Note that if you want any of these behaviors, you should always have
         // a preference for the user to turn them off.
-        notif.defaults = Notification.DEFAULT_ALL;
+        notifBuilder.setDefaults(Notification.DEFAULT_ALL);
 
         // Note that we use R.layout.incoming_message_panel as the ID for
         // the notification.  It could be any integer you want, but we use
         // the convention of using a resource id for a string related to
         // the notification.  It will always be a unique number within your
         // application.
-        nm.notify(R.string.imcoming_message_ticker_text, notif);
+        nm.notify(R.string.imcoming_message_ticker_text, notifBuilder.build());
     }
 //END_INCLUDE(interstitial_notification)
 }
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/LocalService.java b/samples/ApiDemos/src/com/example/android/apis/app/LocalService.java
index 0c7c108..a3742ca 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/LocalService.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/LocalService.java
@@ -23,6 +23,7 @@
 import android.content.Intent;
 import android.os.Binder;
 import android.os.IBinder;
+import android.os.PowerManager;
 import android.util.Log;
 import android.widget.Toast;
 
@@ -71,9 +72,7 @@
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
         Log.i("LocalService", "Received start id " + startId + ": " + intent);
-        // We want this service to continue running until it is explicitly
-        // stopped, so return sticky.
-        return START_STICKY;
+        return START_NOT_STICKY;
     }
 
     @Override
@@ -101,17 +100,19 @@
         // In this sample, we'll use the same text for the ticker and the expanded notification
         CharSequence text = getText(R.string.local_service_started);
 
-        // Set the icon, scrolling text and timestamp
-        Notification notification = new Notification(R.drawable.stat_sample, text,
-                System.currentTimeMillis());
-
         // The PendingIntent to launch our activity if the user selects this notification
         PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                 new Intent(this, LocalServiceActivities.Controller.class), 0);
 
         // Set the info for the views that show in the notification panel.
-        notification.setLatestEventInfo(this, getText(R.string.local_service_label),
-                       text, contentIntent);
+        Notification notification = new Notification.Builder(this)
+                .setSmallIcon(R.drawable.stat_sample)  // the status icon
+                .setTicker(text)  // the status text
+                .setWhen(System.currentTimeMillis())  // the time stamp
+                .setContentTitle(getText(R.string.local_service_label))  // the label of the entry
+                .setContentText(text)  // the contents of the entry
+                .setContentIntent(contentIntent)  // The intent to send when the entry is clicked
+                .build();
 
         // Send the notification.
         mNM.notify(NOTIFICATION, notification);
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.java b/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.java
index a21763e..f25af91 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.java
@@ -149,17 +149,19 @@
         // In this sample, we'll use the same text for the ticker and the expanded notification
         CharSequence text = getText(R.string.remote_service_started);
 
-        // Set the icon, scrolling text and timestamp
-        Notification notification = new Notification(R.drawable.stat_sample, text,
-                System.currentTimeMillis());
-
         // The PendingIntent to launch our activity if the user selects this notification
         PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                 new Intent(this, Controller.class), 0);
 
         // Set the info for the views that show in the notification panel.
-        notification.setLatestEventInfo(this, getText(R.string.remote_service_label),
-                       text, contentIntent);
+        Notification notification = new Notification.Builder(this)
+                .setSmallIcon(R.drawable.stat_sample)  // the status icon
+                .setTicker(text)  // the status text
+                .setWhen(System.currentTimeMillis())  // the time stamp
+                .setContentTitle(getText(R.string.local_service_label))  // the label of the entry
+                .setContentText(text)  // the contents of the entry
+                .setContentIntent(contentIntent)  // The intent to send when the entry is clicked
+                .build();
 
         // Send the notification.
         // We use a string id because it is a unique number.  We use it later to cancel.
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/NotifyingService.java b/samples/ApiDemos/src/com/example/android/apis/app/NotifyingService.java
index 3b8139f..acb0095 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/NotifyingService.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/NotifyingService.java
@@ -94,20 +94,23 @@
         // In this sample, we'll use the same text for the ticker and the expanded notification
         CharSequence text = getText(textId);
 
-        // Set the icon, scrolling text and timestamp.
-        // Note that in this example, we pass null for tickerText.  We update the icon enough that
-        // it is distracting to show the ticker text every time it changes.  We strongly suggest
-        // that you do this as well.  (Think of of the "New hardware found" or "Network connection
-        // changed" messages that always pop up)
-        Notification notification = new Notification(moodId, null, System.currentTimeMillis());
-
         // The PendingIntent to launch our activity if the user selects this notification
         PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                 new Intent(this, NotifyingController.class), 0);
 
+        // Set the icon and timestamp.
+        // Note that in this example, we do not set the tickerText.  We update the icon enough that
+        // it is distracting to show the ticker text every time it changes.  We strongly suggest
+        // that you do this as well.  (Think of of the "New hardware found" or "Network connection
+        // changed" messages that always pop up)
         // Set the info for the views that show in the notification panel.
-        notification.setLatestEventInfo(this, getText(R.string.status_bar_notifications_mood_title),
-                       text, contentIntent);
+        Notification notification = new Notification.Builder(this)
+                .setSmallIcon(moodId)
+                .setWhen(System.currentTimeMillis())
+                .setContentTitle(getText(R.string.status_bar_notifications_mood_title))
+                .setContentText(text)  // the contents of the entry
+                .setContentIntent(contentIntent)  // The intent to send when the entry is clicked
+                .build();
 
         // Send the notification.
         // We use a layout id because it is a unique number.  We use it later to cancel.
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/PresentationActivity.java b/samples/ApiDemos/src/com/example/android/apis/app/PresentationActivity.java
index c626022..48ffc44 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/PresentationActivity.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/PresentationActivity.java
@@ -39,13 +39,17 @@
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
+import android.view.WindowManager;
 import android.widget.CheckBox;
 import android.widget.CompoundButton;
 import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
 import android.widget.ArrayAdapter;
 import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.ListView;
+import android.widget.Spinner;
 import android.widget.TextView;
 
 //BEGIN_INCLUDE(activity)
@@ -74,7 +78,7 @@
  * </p>
  */
 public class PresentationActivity extends Activity
-        implements OnCheckedChangeListener, OnClickListener {
+        implements OnCheckedChangeListener, OnClickListener, OnItemSelectedListener {
     private final String TAG = "PresentationActivity";
 
     // Key for storing saved instance state.
@@ -97,7 +101,7 @@
     // List of presentation contents indexed by displayId.
     // This state persists so that we can restore the old presentation
     // contents when the activity is paused or resumed.
-    private SparseArray<PresentationContents> mSavedPresentationContents;
+    private SparseArray<DemoPresentationContents> mSavedPresentationContents;
 
     // List of all currently visible presentations indexed by display id.
     private final SparseArray<DemoPresentation> mActivePresentations =
@@ -118,7 +122,7 @@
             mSavedPresentationContents =
                     savedInstanceState.getSparseParcelableArray(PRESENTATION_KEY);
         } else {
-            mSavedPresentationContents = new SparseArray<PresentationContents>();
+            mSavedPresentationContents = new SparseArray<DemoPresentationContents>();
         }
 
         // Get the display manager service.
@@ -151,7 +155,7 @@
         final int numDisplays = mDisplayListAdapter.getCount();
         for (int i = 0; i < numDisplays; i++) {
             final Display display = mDisplayListAdapter.getItem(i);
-            final PresentationContents contents =
+            final DemoPresentationContents contents =
                     mSavedPresentationContents.get(display.getDisplayId());
             if (contents != null) {
                 showPresentation(display, contents);
@@ -192,7 +196,7 @@
     /**
      * Shows a {@link Presentation} on the specified display.
      */
-    private void showPresentation(Display display, PresentationContents contents) {
+    private void showPresentation(Display display, DemoPresentationContents contents) {
         final int displayId = display.getDisplayId();
         if (mActivePresentations.get(displayId) != null) {
             return;
@@ -223,6 +227,20 @@
         mActivePresentations.delete(displayId);
     }
 
+    /**
+     * Sets the display mode of the {@link Presentation} on the specified display
+     * if it is already shown.
+     */
+    private void setPresentationDisplayMode(Display display, int displayModeId) {
+        final int displayId = display.getDisplayId();
+        DemoPresentation presentation = mActivePresentations.get(displayId);
+        if (presentation == null) {
+            return;
+        }
+
+        presentation.setPreferredDisplayMode(displayModeId);
+    }
+
     private int getNextPhoto() {
         final int photo = mNextImageNumber;
         mNextImageNumber = (mNextImageNumber + 1) % PHOTOS.length;
@@ -242,11 +260,12 @@
             // Display item checkbox was toggled.
             final Display display = (Display)buttonView.getTag();
             if (isChecked) {
-                PresentationContents contents = new PresentationContents(getNextPhoto());
+                DemoPresentationContents contents = new DemoPresentationContents(getNextPhoto());
                 showPresentation(display, contents);
             } else {
                 hidePresentation(display);
             }
+            mDisplayListAdapter.updateContents();
         }
     }
 
@@ -276,6 +295,26 @@
     }
 
     /**
+     * Called when a display mode has been selected.
+     */
+    @Override
+    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+        final Display display = (Display)parent.getTag();
+        final Display.Mode[] modes = display.getSupportedModes();
+        setPresentationDisplayMode(display, position >= 1 && position <= modes.length ?
+                modes[position - 1].getModeId() : 0);
+    }
+
+    /**
+     * Called when a display mode has been unselected.
+     */
+    @Override
+    public void onNothingSelected(AdapterView<?> parent) {
+        final Display display = (Display)parent.getTag();
+        setPresentationDisplayMode(display, 0);
+    }
+
+    /**
      * Listens for displays to be added, changed or removed.
      * We use it to update the list and show a new {@link Presentation} when a
      * display is connected.
@@ -345,11 +384,17 @@
             final Display display = getItem(position);
             final int displayId = display.getDisplayId();
 
+            DemoPresentation presentation = mActivePresentations.get(displayId);
+            DemoPresentationContents contents = presentation != null ?
+                    presentation.mContents : null;
+            if (contents == null) {
+                contents = mSavedPresentationContents.get(displayId);
+            }
+
             CheckBox cb = (CheckBox)v.findViewById(R.id.checkbox_presentation);
             cb.setTag(display);
             cb.setOnCheckedChangeListener(PresentationActivity.this);
-            cb.setChecked(mActivePresentations.indexOfKey(displayId) >= 0
-                    || mSavedPresentationContents.indexOfKey(displayId) >= 0);
+            cb.setChecked(contents != null);
 
             TextView tv = (TextView)v.findViewById(R.id.display_id);
             tv.setText(v.getContext().getResources().getString(
@@ -359,6 +404,32 @@
             b.setTag(display);
             b.setOnClickListener(PresentationActivity.this);
 
+            Spinner s = (Spinner)v.findViewById(R.id.modes);
+            Display.Mode[] modes = display.getSupportedModes();
+            if (contents == null || modes.length == 1) {
+                s.setVisibility(View.GONE);
+                s.setAdapter(null);
+            } else {
+                ArrayAdapter<String> modeAdapter = new ArrayAdapter<String>(mContext,
+                        android.R.layout.simple_list_item_1);
+                s.setVisibility(View.VISIBLE);
+                s.setAdapter(modeAdapter);
+                s.setTag(display);
+                s.setOnItemSelectedListener(PresentationActivity.this);
+
+                modeAdapter.add("<default mode>");
+
+                for (Display.Mode mode : modes) {
+                    modeAdapter.add(String.format("Mode %d: %dx%d/%.1ffps",
+                            mode.getModeId(),
+                            mode.getPhysicalWidth(), mode.getPhysicalHeight(),
+                            mode.getRefreshRate()));
+                    if (contents.displayModeId == mode.getModeId()) {
+                        s.setSelection(modeAdapter.getCount() - 1);
+                    }
+                }
+            }
+
             return v;
         }
 
@@ -394,13 +465,25 @@
      */
     private final class DemoPresentation extends Presentation {
 
-        final PresentationContents mContents;
+        final DemoPresentationContents mContents;
 
-        public DemoPresentation(Context context, Display display, PresentationContents contents) {
+        public DemoPresentation(Context context, Display display,
+                DemoPresentationContents contents) {
             super(context, display);
             mContents = contents;
         }
 
+        /**
+         * Sets the preferred display mode id for the presentation.
+         */
+        public void setPreferredDisplayMode(int modeId) {
+            mContents.displayModeId = modeId;
+
+            WindowManager.LayoutParams params = getWindow().getAttributes();
+            params.preferredDisplayModeId = modeId;
+            getWindow().setAttributes(params);
+        }
+
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             // Be sure to call the super class.
@@ -440,35 +523,37 @@
     }
 
     /**
-     * Information about the content we want to show in a presentation.
+     * Information about the content we want to show in the presentation.
      */
-    private final static class PresentationContents implements Parcelable {
+    private final static class DemoPresentationContents implements Parcelable {
         final int photo;
         final int[] colors;
+        int displayModeId;
 
-        public static final Creator<PresentationContents> CREATOR =
-                new Creator<PresentationContents>() {
+        public static final Creator<DemoPresentationContents> CREATOR =
+                new Creator<DemoPresentationContents>() {
             @Override
-            public PresentationContents createFromParcel(Parcel in) {
-                return new PresentationContents(in);
+            public DemoPresentationContents createFromParcel(Parcel in) {
+                return new DemoPresentationContents(in);
             }
 
             @Override
-            public PresentationContents[] newArray(int size) {
-                return new PresentationContents[size];
+            public DemoPresentationContents[] newArray(int size) {
+                return new DemoPresentationContents[size];
             }
         };
 
-        public PresentationContents(int photo) {
+        public DemoPresentationContents(int photo) {
             this.photo = photo;
             colors = new int[] {
                     ((int) (Math.random() * Integer.MAX_VALUE)) | 0xFF000000,
                     ((int) (Math.random() * Integer.MAX_VALUE)) | 0xFF000000 };
         }
 
-        private PresentationContents(Parcel in) {
+        private DemoPresentationContents(Parcel in) {
             photo = in.readInt();
             colors = new int[] { in.readInt(), in.readInt() };
+            displayModeId = in.readInt();
         }
 
         @Override
@@ -481,6 +566,7 @@
             dest.writeInt(photo);
             dest.writeInt(colors[0]);
             dest.writeInt(colors[1]);
+            dest.writeInt(displayModeId);
         }
     }
 }
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java b/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
index 76458f4..41b9d88 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
@@ -32,6 +32,7 @@
 import android.os.Message;
 import android.os.Process;
 import android.os.RemoteCallbackList;
+import android.util.Log;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.Button;
@@ -80,6 +81,12 @@
     }
 
     @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        Log.i("LocalService", "Received start id " + startId + ": " + intent);
+        return START_NOT_STICKY;
+    }
+
+    @Override
     public void onDestroy() {
         // Cancel the persistent notification.
         mNM.cancel(R.string.remote_service_started);
@@ -183,17 +190,19 @@
         // In this sample, we'll use the same text for the ticker and the expanded notification
         CharSequence text = getText(R.string.remote_service_started);
 
-        // Set the icon, scrolling text and timestamp
-        Notification notification = new Notification(R.drawable.stat_sample, text,
-                System.currentTimeMillis());
-
         // The PendingIntent to launch our activity if the user selects this notification
         PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                 new Intent(this, Controller.class), 0);
 
         // Set the info for the views that show in the notification panel.
-        notification.setLatestEventInfo(this, getText(R.string.remote_service_label),
-                       text, contentIntent);
+        Notification notification = new Notification.Builder(this)
+                .setSmallIcon(R.drawable.stat_sample)  // the status icon
+                .setTicker(text)  // the status text
+                .setWhen(System.currentTimeMillis())  // the time stamp
+                .setContentTitle(getText(R.string.remote_service_label))  // the label of the entry
+                .setContentText(text)  // the contents of the entry
+                .setContentIntent(contentIntent)  // The intent to send when the entry is clicked
+                .build();
 
         // Send the notification.
         // We use a string id because it is a unique number.  We use it later to cancel.
@@ -232,8 +241,7 @@
                 // We use an action code here, instead of explictly supplying
                 // the component name, so that other packages can replace
                 // the service.
-                startService(new Intent(
-                        "com.example.android.apis.app.REMOTE_SERVICE"));
+                startService(new Intent(Controller.this, RemoteService.class));
             }
         };
 
@@ -242,8 +250,7 @@
                 // Cancel a previous call to startService().  Note that the
                 // service will not actually stop at this point if there are
                 // still bound clients.
-                stopService(new Intent(
-                        "com.example.android.apis.app.REMOTE_SERVICE"));
+                stopService(new Intent(Controller.this, RemoteService.class));
             }
         };
     }
@@ -361,10 +368,11 @@
                 // by interface names.  This allows other applications to be
                 // installed that replace the remote service by implementing
                 // the same interface.
-                bindService(new Intent(IRemoteService.class.getName()),
-                        mConnection, Context.BIND_AUTO_CREATE);
-                bindService(new Intent(ISecondary.class.getName()),
-                        mSecondaryConnection, Context.BIND_AUTO_CREATE);
+                Intent intent = new Intent(Binding.this, RemoteService.class);
+                intent.setAction(IRemoteService.class.getName());
+                bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+                intent.setAction(ISecondary.class.getName());
+                bindService(intent, mSecondaryConnection, Context.BIND_AUTO_CREATE);
                 mIsBound = true;
                 mCallbackText.setText("Binding.");
             }
@@ -471,6 +479,7 @@
     public static class BindingOptions extends Activity {
         ServiceConnection mCurConnection;
         TextView mCallbackText;
+        Intent mBindIntent;
 
         class MyServiceConnection implements ServiceConnection {
             final boolean mUnbindOnDisconnect;
@@ -539,6 +548,9 @@
 
             mCallbackText = (TextView)findViewById(R.id.callback);
             mCallbackText.setText("Not attached.");
+
+            mBindIntent = new Intent(this, RemoteService.class);
+            mBindIntent.setAction(IRemoteService.class.getName());
         }
 
         private OnClickListener mBindNormalListener = new OnClickListener() {
@@ -548,8 +560,7 @@
                     mCurConnection = null;
                 }
                 ServiceConnection conn = new MyServiceConnection();
-                if (bindService(new Intent(IRemoteService.class.getName()),
-                        conn, Context.BIND_AUTO_CREATE)) {
+                if (bindService(mBindIntent, conn, Context.BIND_AUTO_CREATE)) {
                     mCurConnection = conn;
                 }
             }
@@ -562,8 +573,8 @@
                     mCurConnection = null;
                 }
                 ServiceConnection conn = new MyServiceConnection();
-                if (bindService(new Intent(IRemoteService.class.getName()),
-                        conn, Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND)) {
+                if (bindService(mBindIntent, conn,
+                        Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND)) {
                     mCurConnection = conn;
                 }
             }
@@ -590,8 +601,8 @@
                     mCurConnection = null;
                 }
                 ServiceConnection conn = new MyServiceConnection();
-                if (bindService(new Intent(IRemoteService.class.getName()),
-                        conn, Context.BIND_AUTO_CREATE | Context.BIND_ALLOW_OOM_MANAGEMENT)) {
+                if (bindService(mBindIntent, conn,
+                        Context.BIND_AUTO_CREATE | Context.BIND_ALLOW_OOM_MANAGEMENT)) {
                     mCurConnection = conn;
                 }
             }
@@ -604,8 +615,8 @@
                     mCurConnection = null;
                 }
                 ServiceConnection conn = new MyServiceConnection(true);
-                if (bindService(new Intent(IRemoteService.class.getName()),
-                        conn, Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY)) {
+                if (bindService(mBindIntent, conn,
+                        Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY)) {
                     mCurConnection = conn;
                 }
             }
@@ -618,8 +629,8 @@
                     mCurConnection = null;
                 }
                 ServiceConnection conn = new MyServiceConnection();
-                if (bindService(new Intent(IRemoteService.class.getName()),
-                        conn, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT)) {
+                if (bindService(mBindIntent, conn,
+                        Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT)) {
                     mCurConnection = conn;
                 }
             }
@@ -632,8 +643,8 @@
                     mCurConnection = null;
                 }
                 ServiceConnection conn = new MyServiceConnection();
-                if (bindService(new Intent(IRemoteService.class.getName()),
-                        conn, Context.BIND_AUTO_CREATE | Context.BIND_ADJUST_WITH_ACTIVITY
+                if (bindService(mBindIntent, conn,
+                        Context.BIND_AUTO_CREATE | Context.BIND_ADJUST_WITH_ACTIVITY
                         | Context.BIND_WAIVE_PRIORITY)) {
                     mCurConnection = conn;
                 }
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArguments.java b/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArguments.java
index f551447..584dff3 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArguments.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArguments.java
@@ -174,24 +174,25 @@
      * Show a notification while this service is running.
      */
     private void showNotification(String text) {
-        // Set the icon, scrolling text and timestamp
-        Notification notification = new Notification(R.drawable.stat_sample, text,
-                System.currentTimeMillis());
-
         // The PendingIntent to launch our activity if the user selects this notification
         PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                 new Intent(this, Controller.class), 0);
 
         // Set the info for the views that show in the notification panel.
-        notification.setLatestEventInfo(this, getText(R.string.service_start_arguments_label),
-                       text, contentIntent);
+        Notification.Builder noteBuilder = new Notification.Builder(this)
+                .setSmallIcon(R.drawable.stat_sample)  // the status icon
+                .setTicker(text)  // the status text
+                .setWhen(System.currentTimeMillis())  // the time stamp
+                .setContentTitle(getText(R.string.service_start_arguments_label))  // the label
+                .setContentText(text)  // the contents of the entry
+                .setContentIntent(contentIntent);  // The intent to send when the entry is clicked
 
         // We show this for as long as our service is processing a command.
-        notification.flags |= Notification.FLAG_ONGOING_EVENT;
+        noteBuilder.setOngoing(true);
         
         // Send the notification.
         // We use a string id because it is a unique number.  We use it later to cancel.
-        mNM.notify(R.string.service_created, notification);
+        mNM.notify(R.string.service_created, noteBuilder.build());
     }
     
     private void hideNotification() {
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/StatusBarNotifications.java b/samples/ApiDemos/src/com/example/android/apis/app/StatusBarNotifications.java
index 7179b25..4ae7553 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/StatusBarNotifications.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/StatusBarNotifications.java
@@ -194,20 +194,25 @@
         // In this sample, we'll use the same text for the ticker and the expanded notification
         CharSequence text = getText(textId);
 
-        // choose the ticker text
-        String tickerText = showTicker ? getString(textId) : null;
-
-        // Set the icon, scrolling text and timestamp
-        Notification notification = new Notification(moodId, tickerText,
-                System.currentTimeMillis());
+        // In this sample, we'll use this text for the title of the notification
+        CharSequence title = getText(R.string.status_bar_notifications_mood_title);
 
         // Set the info for the views that show in the notification panel.
-        notification.setLatestEventInfo(this, getText(R.string.status_bar_notifications_mood_title),
-                       text, makeMoodIntent(moodId));
+        Notification.Builder notifBuidler = new Notification.Builder(this) // the context to use
+                .setSmallIcon(moodId)  // the status icon
+                .setWhen(System.currentTimeMillis())  // the timestamp for the notification
+                .setContentTitle(title)  // the title for the notification
+                .setContentText(text)  // the details to display in the notification
+                .setContentIntent(makeMoodIntent(moodId));  // The intent to send clicked
+
+        if (showTicker) {
+            // include the ticker text
+            notifBuidler.setTicker(getString(textId));
+        }
 
         // Send the notification.
         // We use a layout id because it is a unique number.  We use it later to cancel.
-        mNotificationManager.notify(MOOD_NOTIFICATIONS, notification);
+        mNotificationManager.notify(MOOD_NOTIFICATIONS, notifBuidler.build());
     }
 
     private void setMoodView(int moodId, int textId) {
@@ -239,29 +244,27 @@
     }
     
     private void setDefault(int defaults) {
-        
-        // This method sets the defaults on the notification before posting it.
-        
+
         // This is who should be launched if the user selects our notification.
         PendingIntent contentIntent = makeDefaultIntent();
 
         // In this sample, we'll use the same text for the ticker and the expanded notification
         CharSequence text = getText(R.string.status_bar_notifications_happy_message);
 
-        final Notification notification = new Notification(
-                R.drawable.stat_happy,       // the icon for the status bar
-                text,                        // the text to display in the ticker
-                System.currentTimeMillis()); // the timestamp for the notification
+        // In this sample, we'll use this text for the title of the notification
+        CharSequence title = getText(R.string.status_bar_notifications_mood_title);
 
-        notification.setLatestEventInfo(
-                this,                        // the context to use
-                getText(R.string.status_bar_notifications_mood_title),
-                                             // the title for the notification
-                text,                        // the details to display in the notification
-                contentIntent);              // the contentIntent (see above)
+        // Set the info for the views that show in the notification panel.
+        Notification notification = new Notification.Builder(this) // the context to use
+                .setSmallIcon(R.drawable.stat_happy)  // the status icon
+                .setTicker(text)  // the text to display in the ticker
+                .setWhen(System.currentTimeMillis())  // the timestamp for the notification
+                .setContentTitle(title)  // the title for the notification
+                .setContentText(text)  // the details to display in the notification
+                .setContentIntent(contentIntent)  // The intent to send when the entry is clicked
+                .setDefaults(defaults)
+                .build();
 
-        notification.defaults = defaults;
-        
         mNotificationManager.notify(
                 MOOD_NOTIFICATIONS, // we use a string id because it is a unique
                                     // number.  we use it later to cancel the notification
diff --git a/samples/ApiDemos/src/com/example/android/apis/content/FileProvider.java b/samples/ApiDemos/src/com/example/android/apis/content/FileProvider.java
index f26bcda..63d891d 100644
--- a/samples/ApiDemos/src/com/example/android/apis/content/FileProvider.java
+++ b/samples/ApiDemos/src/com/example/android/apis/content/FileProvider.java
@@ -111,14 +111,19 @@
     }
 
     @Override
-    public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
+    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
         // Try to open an asset with the given name.
         try {
-            InputStream is = getContext().getAssets().open(uri.getPath());
-            // Start a new thread that pipes the stream data back to the caller.
-            return new AssetFileDescriptor(
-                    openPipeHelper(uri, null, null, is, this), 0,
-                    AssetFileDescriptor.UNKNOWN_LENGTH);
+            String path = uri.getPath();
+            int off = path.indexOf('/', 1);
+            if (off < 0 || off >= (path.length()-1)) {
+                throw new FileNotFoundException("Unable to open " + uri);
+            }
+            int cookie = Integer.parseInt(path.substring(1, off));
+            String assetPath = path.substring(off+1);
+            AssetFileDescriptor asset = getContext().getAssets().openNonAssetFd(cookie, assetPath);
+            return new ParcelFileDescriptor(openPipeHelper(uri, null, null,
+                    asset.createInputStream(), this));
         } catch (IOException e) {
             FileNotFoundException fnf = new FileNotFoundException("Unable to open " + uri);
             throw fnf;
diff --git a/samples/ApiDemos/src/com/example/android/apis/content/ProcessText.java b/samples/ApiDemos/src/com/example/android/apis/content/ProcessText.java
new file mode 100644
index 0000000..9b7779b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/content/ProcessText.java
@@ -0,0 +1,57 @@
+package com.example.android.apis.content;
+
+//Need the following import to get access to the app resources, since this
+//class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.EditText;
+
+public class ProcessText extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.process_text_main);
+
+        CharSequence text = getIntent().getCharSequenceExtra(Intent.EXTRA_PROCESS_TEXT);
+        boolean readonly =
+                getIntent().getBooleanExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, false);
+
+        EditText edit = (EditText) findViewById(R.id.process_text_received_text_editable);
+        edit.setText(text);
+        edit.setSelection(edit.getText().length());
+
+        Button finishButton = (Button) findViewById(R.id.process_text_finish_button);
+        finishButton.setText(readonly
+                ? R.string.process_text_finish_readonly : R.string.process_text_finish);
+        finishButton.setOnClickListener(
+                new OnClickListener() {
+                    @Override
+                    public void onClick(View arg0) {
+                        finish();
+                    }
+                });
+    }
+
+    @Override
+    public void finish() {
+        EditText edit = (EditText) findViewById(R.id.process_text_received_text_editable);
+        Intent intent = getIntent();
+        intent.putExtra(Intent.EXTRA_PROCESS_TEXT, edit.getText());
+        setResult(RESULT_OK, intent);
+        super.finish();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        return false;
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/content/ProcessTextLauncher.java b/samples/ApiDemos/src/com/example/android/apis/content/ProcessTextLauncher.java
new file mode 100644
index 0000000..10863cb
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/content/ProcessTextLauncher.java
@@ -0,0 +1,24 @@
+package com.example.android.apis.content;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Menu;
+
+//Need the following import to get access to the app resources, since this
+//class is in a sub-package.
+import com.example.android.apis.R;
+
+public class ProcessTextLauncher extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.process_text_send);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        return false;
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/content/ShareContent.java b/samples/ApiDemos/src/com/example/android/apis/content/ShareContent.java
new file mode 100644
index 0000000..247c7fc
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/content/ShareContent.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2015, 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.apis.content;
+
+import android.app.Activity;
+import android.content.ClipData;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.Button;
+import com.example.android.apis.R;
+
+/**
+ * Example of sharing content from a private content provider.
+ */
+public class ShareContent extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.share_content);
+
+        // Watch for button clicks.
+        ((Button)findViewById(R.id.share_image)).setOnClickListener(new View.OnClickListener() {
+            @Override public void onClick(View v) {
+                Intent intent = new Intent(Intent.ACTION_SEND);
+                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+                Uri.Builder b = new Uri.Builder();
+                b.scheme("content");
+                b.authority("com.example.android.apis.content.FileProvider");
+                TypedValue tv = new TypedValue();
+                getResources().getValue(R.drawable.jellies, tv, true);
+                b.appendEncodedPath(Integer.toString(tv.assetCookie));
+                b.appendEncodedPath(tv.string.toString());
+                Uri uri = b.build();
+                intent.setType("image/jpeg");
+                intent.putExtra(Intent.EXTRA_STREAM, uri);
+                intent.setClipData(ClipData.newUri(getContentResolver(), "image", uri));
+                startActivity(Intent.createChooser(intent, "Select share target"));
+            }
+        });
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/content/TextUndoActivity.java b/samples/ApiDemos/src/com/example/android/apis/content/TextUndoActivity.java
index 6b9dc8e..d782d31 100644
--- a/samples/ApiDemos/src/com/example/android/apis/content/TextUndoActivity.java
+++ b/samples/ApiDemos/src/com/example/android/apis/content/TextUndoActivity.java
@@ -16,58 +16,123 @@
 
 package com.example.android.apis.content;
 
-import android.app.Activity;
-//import android.content.UndoManager;
-import android.os.Parcelable;
-import android.view.View;
-import android.widget.Button;
 import com.example.android.apis.R;
 
+import android.app.Activity;
 import android.os.Bundle;
-import android.widget.TextView;
+import android.text.Editable;
+import android.text.InputFilter;
+import android.text.Spanned;
+import android.text.TextWatcher;
+import android.text.method.DigitsKeyListener;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
 
 /**
  * Simple example of using an UndoManager for editing text in a TextView.
  */
 public class TextUndoActivity extends Activity {
-    //UndoManager mUndoManager;
+    // Characters allowed as input in the credit card field.
+    private static final String CREDIT_CARD_CHARS = "0123456789 ";
+
+    EditText mDefaultText;
+    EditText mLengthLimitText;
+    EditText mCreditCardText;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        /*
-        mUndoManager = new UndoManager();
-        if (savedInstanceState != null) {
-            Parcelable p = savedInstanceState.getParcelable("undo");
-            if (p != null) {
-                mUndoManager.restoreInstanceState(p);
-            }
-        }
-        */
-
         setContentView(R.layout.text_undo);
 
-        /*
-        ((TextView)findViewById(R.id.text)).setUndoManager(mUndoManager, "text");
-        ((Button)findViewById(R.id.undo)).setOnClickListener(new View.OnClickListener() {
+        mDefaultText = (EditText) findViewById(R.id.default_text);
+        ((Button) findViewById(R.id.set_text)).setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                mUndoManager.undo(null, 1);
+                mDefaultText.setText("some text");
             }
         });
-        ((Button)findViewById(R.id.redo)).setOnClickListener(new View.OnClickListener() {
+        ((Button) findViewById(R.id.append_text)).setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                mUndoManager.redo(null, 1);
+                mDefaultText.append(" append");
             }
         });
-        */
+        ((Button) findViewById(R.id.insert_text)).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Editable editable = mDefaultText.getText();
+                editable.insert(0, "insert ");
+            }
+        });
+
+        mLengthLimitText = (EditText) findViewById(R.id.length_limit_text);
+        mLengthLimitText.setFilters(new InputFilter[] { new InputFilter.LengthFilter(4) });
+
+        mCreditCardText = (EditText) findViewById(R.id.credit_card_text);
+        mCreditCardText.setKeyListener(DigitsKeyListener.getInstance(CREDIT_CARD_CHARS));
+        mCreditCardText.addTextChangedListener(new CreditCardTextWatcher());
      }
 
-    @Override
-    protected void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        //outState.putParcelable("undo", mUndoManager.saveInstanceState());
+    /**
+     * A simple credit card input formatter that adds spaces every 4 characters.
+     */
+    private static class CreditCardTextWatcher implements TextWatcher {
+        @Override
+        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+        }
+
+        @Override
+        public void onTextChanged(CharSequence s, int start, int before, int count) {
+        }
+
+        @Override
+        public void afterTextChanged(Editable s) {
+            String original = s.toString();
+            String formatted = addSpaces(getNumbers(original));
+            // This is an ugly way to avoid infinite recursion, but it's common in app code.
+            if (!formatted.equals(original)) {
+                s.replace(0, s.length(), formatted);
+            }
+        }
+
+        /**
+         * @return Returns a string with a space added every 4 characters.
+         */
+        private static String addSpaces(CharSequence str) {
+            StringBuilder builder = new StringBuilder();
+            int len = str.length();
+            for (int i = 0; i < len; i += 4) {
+                if (i + 4 < len) {
+                    builder.append(str.subSequence(i, i + 4));
+                    builder.append(' ');
+                } else {
+                    // Don't put a space after the end.
+                    builder.append(str.subSequence(i, len));
+                }
+            }
+            return builder.toString();
+        }
+
+        /**
+         * @return Returns a string containing only the digits from a character sequence.
+         */
+        private static String getNumbers(CharSequence cc) {
+            StringBuilder sb = new StringBuilder(16);
+            for (int i = 0, count = cc.length(); i < count; ++i) {
+                char c = cc.charAt(i);
+                if (isNumber(c)) {
+                    sb.append(c);
+                }
+            }
+            return sb.toString();
+        }
+
+        private static boolean isNumber(char c) {
+            return c >= '0' && c <= '9';
+        }
+
     }
 }
diff --git a/samples/ApiDemos/src/com/example/android/apis/security/KeyStoreUsage.java b/samples/ApiDemos/src/com/example/android/apis/security/KeyStoreUsage.java
index 901806a..cde68b0 100644
--- a/samples/ApiDemos/src/com/example/android/apis/security/KeyStoreUsage.java
+++ b/samples/ApiDemos/src/com/example/android/apis/security/KeyStoreUsage.java
@@ -23,7 +23,8 @@
 import android.database.DataSetObserver;
 import android.os.AsyncTask;
 import android.os.Bundle;
-import android.security.KeyPairGeneratorSpec;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProperties;
 import android.util.Base64;
 import android.util.Log;
 import android.view.View;
@@ -55,8 +56,6 @@
 import java.security.UnrecoverableEntryException;
 import java.security.cert.CertificateException;
 import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
 import java.util.Enumeration;
 import java.util.List;
 
@@ -129,6 +128,7 @@
         ListView lv = (ListView) findViewById(R.id.entries_list);
         mAdapter = new AliasAdapter(getApplicationContext());
         lv.setAdapter(mAdapter);
+        lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
         lv.setOnItemClickListener(new OnItemClickListener() {
             @Override
             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
@@ -250,6 +250,8 @@
      * enabled or disabled.
      */
     private void setKeyActionButtonsEnabled(boolean enabled) {
+        mPlainText.setEnabled(enabled);
+        mCipherText.setEnabled(enabled);
         mSignButton.setEnabled(enabled);
         mVerifyButton.setEnabled(enabled);
         mDeleteButton.setEnabled(enabled);
@@ -302,24 +304,18 @@
             try {
 // BEGIN_INCLUDE(generate)
                 /*
-                 * Generate a new entry in the KeyStore by using the
-                 * KeyPairGenerator API. We have to specify the attributes for a
-                 * self-signed X.509 certificate here so the KeyStore can attach
-                 * the public key part to it. It can be replaced later with a
-                 * certificate signed by a Certificate Authority (CA) if needed.
+                 * Generate a new EC key pair entry in the Android Keystore by
+                 * using the KeyPairGenerator API. The private key can only be
+                 * used for signing or verification and only with SHA-256 or
+                 * SHA-512 as the message digest.
                  */
-                Calendar cal = Calendar.getInstance();
-                Date now = cal.getTime();
-                cal.add(Calendar.YEAR, 1);
-                Date end = cal.getTime();
-
-                KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
-                kpg.initialize(new KeyPairGeneratorSpec.Builder(getApplicationContext())
-                        .setAlias(alias)
-                        .setStartDate(now)
-                        .setEndDate(end)
-                        .setSerialNumber(BigInteger.valueOf(1))
-                        .setSubject(new X500Principal("CN=test1"))
+                KeyPairGenerator kpg = KeyPairGenerator.getInstance(
+                        KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
+                kpg.initialize(new KeyGenParameterSpec.Builder(
+                        alias,
+                        KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
+                        .setDigests(KeyProperties.DIGEST_SHA256,
+                            KeyProperties.DIGEST_SHA512)
                         .build());
 
                 KeyPair kp = kpg.generateKeyPair();
@@ -368,7 +364,7 @@
                     Log.w(TAG, "Not an instance of a PrivateKeyEntry");
                     return null;
                 }
-                Signature s = Signature.getInstance("SHA256withRSA");
+                Signature s = Signature.getInstance("SHA256withECDSA");
                 s.initSign(((PrivateKeyEntry) entry).getPrivateKey());
                 s.update(data);
                 byte[] signature = s.sign();
@@ -439,7 +435,7 @@
                     Log.w(TAG, "Not an instance of a PrivateKeyEntry");
                     return false;
                 }
-                Signature s = Signature.getInstance("SHA256withRSA");
+                Signature s = Signature.getInstance("SHA256withECDSA");
                 s.initVerify(((PrivateKeyEntry) entry).getCertificate());
                 s.update(data);
                 boolean valid = s.verify(signature);
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/EditTextDemo.java b/samples/ApiDemos/src/com/example/android/apis/view/EditTextDemo.java
new file mode 100644
index 0000000..94893d5
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/EditTextDemo.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 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.apis.view;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+
+/**
+ * Demonstrates the {@link android.widget.EditText} widget.
+ */
+public class EditTextDemo extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.edit_text_demo);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/SeekBar1.java b/samples/ApiDemos/src/com/example/android/apis/view/SeekBar1.java
index 15bb013..65d01d4 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/SeekBar1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/SeekBar1.java
@@ -18,6 +18,9 @@
 
 import android.app.Activity;
 import android.os.Bundle;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
 import android.widget.SeekBar;
 import android.widget.TextView;
 
@@ -39,10 +42,20 @@
 
         setContentView(R.layout.seekbar_1);
         
-        mSeekBar = (SeekBar)findViewById(R.id.seek);
+        mSeekBar = (SeekBar) findViewById(R.id.seek);
         mSeekBar.setOnSeekBarChangeListener(this);
-        mProgressText = (TextView)findViewById(R.id.progress);
-        mTrackingText = (TextView)findViewById(R.id.tracking);
+        mProgressText = (TextView) findViewById(R.id.progress);
+        mTrackingText = (TextView) findViewById(R.id.tracking);
+
+        ((CheckBox) findViewById(R.id.enabled)).setOnCheckedChangeListener(
+                new OnCheckedChangeListener() {
+                    @Override
+                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                        findViewById(R.id.seekMin).setEnabled(isChecked);
+                        findViewById(R.id.seekMax).setEnabled(isChecked);
+                        mSeekBar.setEnabled(isChecked);
+                    }
+                });
     }
 
     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TextViewDemo.java b/samples/ApiDemos/src/com/example/android/apis/view/TextViewDemo.java
new file mode 100644
index 0000000..78b7ff1
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TextViewDemo.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 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.apis.view;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+
+/**
+ * Demonstrates the {@link android.widget.TextView} widget.
+ */
+public class TextViewDemo extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.text_view_demo);
+    }
+}
diff --git a/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MusicService.java b/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MusicService.java
index 25f5d81..5c3ccf4 100644
--- a/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MusicService.java
+++ b/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MusicService.java
@@ -150,7 +150,7 @@
     AudioManager mAudioManager;
     NotificationManager mNotificationManager;
 
-    Notification mNotification = null;
+    Notification.Builder mNotificationBuilder = null;
 
     /**
      * Makes sure the media player exists and has been reset. This will create the media player
@@ -516,8 +516,9 @@
         PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0,
                 new Intent(getApplicationContext(), MainActivity.class),
                 PendingIntent.FLAG_UPDATE_CURRENT);
-        mNotification.setLatestEventInfo(getApplicationContext(), "RandomMusicPlayer", text, pi);
-        mNotificationManager.notify(NOTIFICATION_ID, mNotification);
+        mNotificationBuilder.setContentText(text)
+                .setContentIntent(pi);
+        mNotificationManager.notify(NOTIFICATION_ID, mNotificationBuilder.build());
     }
 
     /**
@@ -529,13 +530,18 @@
         PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0,
                 new Intent(getApplicationContext(), MainActivity.class),
                 PendingIntent.FLAG_UPDATE_CURRENT);
-        mNotification = new Notification();
-        mNotification.tickerText = text;
-        mNotification.icon = R.drawable.ic_stat_playing;
-        mNotification.flags |= Notification.FLAG_ONGOING_EVENT;
-        mNotification.setLatestEventInfo(getApplicationContext(), "RandomMusicPlayer",
-                text, pi);
-        startForeground(NOTIFICATION_ID, mNotification);
+
+        // Build the notification object.
+        mNotificationBuilder = new Notification.Builder(getApplicationContext())
+                .setSmallIcon(R.drawable.ic_stat_playing)
+                .setTicker(text)
+                .setWhen(System.currentTimeMillis())
+                .setContentTitle("RandomMusicPlayer")
+                .setContentText(text)
+                .setContentIntent(pi)
+                .setOngoing(true);
+
+        startForeground(NOTIFICATION_ID, mNotificationBuilder.build());
     }
 
     /**
diff --git a/samples/ActionBarCompat/Android.mk b/samples/ReceiveShareDemo/Android.mk
similarity index 89%
rename from samples/ActionBarCompat/Android.mk
rename to samples/ReceiveShareDemo/Android.mk
index d9da54a..ad62f63 100644
--- a/samples/ActionBarCompat/Android.mk
+++ b/samples/ReceiveShareDemo/Android.mk
@@ -6,7 +6,7 @@
 # Only compile source java files in this apk.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := ActionBarCompat
+LOCAL_PACKAGE_NAME := ReceiveShareDemo
 
 LOCAL_SDK_VERSION := current
 
diff --git a/samples/ReceiveShareDemo/AndroidManifest.xml b/samples/ReceiveShareDemo/AndroidManifest.xml
new file mode 100644
index 0000000..1e07091
--- /dev/null
+++ b/samples/ReceiveShareDemo/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.receiveshare">
+    <application android:label="@string/app_name">
+        <activity android:name=".ReceiveShare">
+            <intent-filter>
+                <action android:name="android.intent.action.SEND" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="*/*" />
+            </intent-filter>
+        </activity>
+
+        <service android:name=".ReceiveShareService" android:process=":service">
+        </service>
+    </application>
+</manifest>
diff --git a/samples/ReceiveShareDemo/res/layout/receive_share.xml b/samples/ReceiveShareDemo/res/layout/receive_share.xml
new file mode 100644
index 0000000..6d33a1b
--- /dev/null
+++ b/samples/ReceiveShareDemo/res/layout/receive_share.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<!-- Demonstrates selecting various types of contact data. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <TextView
+        android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:text="@string/receive_share_msg"/>
+
+    <TextView android:id="@+id/receive_share_data"
+        android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:paddingTop="8dip"
+        android:paddingBottom="8dip"/>
+
+    <Button android:id="@+id/send_to_service"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:text="@string/send_to_service">
+        <requestFocus />
+    </Button>
+</LinearLayout>
diff --git a/samples/ReceiveShareDemo/res/values/strings.xml b/samples/ReceiveShareDemo/res/values/strings.xml
new file mode 100644
index 0000000..662ce3b
--- /dev/null
+++ b/samples/ReceiveShareDemo/res/values/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name">Receive Share Demo</string>
+    <string name="receive_share_msg">Received a share from another application.  This is
+         the data received:</string>
+    <string name="send_to_service">Send to service</string>
+    <string name="preparing_to_process_share">Preparing to process share...</string>
+</resources>
diff --git a/samples/ReceiveShareDemo/src/com/example/android/receiveshare/ReceiveShare.java b/samples/ReceiveShareDemo/src/com/example/android/receiveshare/ReceiveShare.java
new file mode 100644
index 0000000..a0abf6d
--- /dev/null
+++ b/samples/ReceiveShareDemo/src/com/example/android/receiveshare/ReceiveShare.java
@@ -0,0 +1,114 @@
+/**
+ * Copyright (c) 2015, 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.receiveshare;
+
+import android.app.Activity;
+import android.content.ClipData;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.content.res.AssetFileDescriptor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.SpannableStringBuilder;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+public class ReceiveShare extends Activity {
+    static Uri getShareUri(Intent intent) {
+        Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
+        if (uri == null) {
+            ClipData clip = intent.getClipData();
+            if (clip != null && clip.getItemCount() > 0) {
+                uri = clip.getItemAt(0).getUri();
+            }
+        }
+        return uri;
+    }
+
+    static CharSequence buildShareInfo(ContentResolver resolver, Intent intent) {
+        SpannableStringBuilder sb = new SpannableStringBuilder();
+        if (intent.getType() != null) {
+            sb.append("Type: "); sb.append(intent.getType()); sb.append("\n");
+        }
+        CharSequence text = intent.getCharSequenceExtra(Intent.EXTRA_TEXT);
+        if (text != null) {
+            sb.append("Text: "); sb.append(text);
+            String html = intent.getStringExtra(Intent.EXTRA_HTML_TEXT);
+            if (html != null) {
+                sb.append("\n\n"); sb.append("HTML: "); sb.append(html);
+            }
+        } else {
+            Uri uri = getShareUri(intent);
+            if (uri != null) {
+                sb.append("Uri: "); sb.append(uri.toString()); sb.append("\n");
+                try {
+                    AssetFileDescriptor afd = resolver.openAssetFileDescriptor(
+                            uri, "r");
+                    sb.append("Start offset: ");
+                    sb.append(Long.toString(afd.getStartOffset()));
+                    sb.append("\n");
+                    sb.append("Length: ");
+                    sb.append(Long.toString(afd.getLength()));
+                    sb.append("\n");
+                    afd.close();
+                } catch (FileNotFoundException e) {
+                    sb.append(e.toString());
+                } catch (SecurityException e) {
+                    sb.append(e.toString());
+                } catch (IOException e) {
+                    sb.append(e.toString());
+                }
+            }
+        }
+        return sb;
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.receive_share);
+
+        Button sendButton = (Button)findViewById(R.id.send_to_service);
+        final Uri uri = getShareUri(getIntent());
+        if (uri != null) {
+            sendButton.setEnabled(true);
+        } else {
+            sendButton.setEnabled(false);
+        }
+
+        TextView content = (TextView)findViewById(R.id.receive_share_data);
+        content.append(buildShareInfo(getContentResolver(), getIntent()));
+
+        // Watch for button clicks.
+        sendButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent intent = new Intent(ReceiveShare.this, ReceiveShareService.class);
+                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+                ClipData clip = ClipData.newUri(getContentResolver(), "Something", uri);
+                intent.setClipData(clip);
+                startService(intent);
+                finish();
+            }
+        });
+    }
+}
diff --git a/samples/ReceiveShareDemo/src/com/example/android/receiveshare/ReceiveShareService.java b/samples/ReceiveShareDemo/src/com/example/android/receiveshare/ReceiveShareService.java
new file mode 100644
index 0000000..548650f
--- /dev/null
+++ b/samples/ReceiveShareDemo/src/com/example/android/receiveshare/ReceiveShareService.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2015, 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.receiveshare;
+
+import android.app.IntentService;
+import android.content.Intent;
+import android.os.Handler;
+import android.util.Log;
+import android.widget.Toast;
+
+public class ReceiveShareService extends IntentService {
+    Handler mHandler;
+
+    public ReceiveShareService() {
+        super("ReceiveShareService");
+    }
+
+    public void onCreate() {
+        super.onCreate();
+        mHandler = new Handler(getMainLooper());
+    }
+
+    @Override
+    protected void onHandleIntent(Intent intent) {
+        mHandler.post(new Runnable() {
+            @Override public void run() {
+                Toast.makeText(ReceiveShareService.this, R.string.preparing_to_process_share,
+                        Toast.LENGTH_LONG).show();
+            }
+        });
+        try {
+            // Give the activity a chance to finish.
+            Thread.sleep(5*1000);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+
+        final CharSequence text = ReceiveShare.buildShareInfo(getContentResolver(), intent);
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                Toast.makeText(ReceiveShareService.this, text, Toast.LENGTH_LONG).show();
+            }
+        });
+        Log.i("ReceiveShare", text.toString());
+    }
+}
diff --git a/samples/SampleSyncAdapter/Android.mk b/samples/SampleSyncAdapter/Android.mk
index eec507b..3861a95 100644
--- a/samples/SampleSyncAdapter/Android.mk
+++ b/samples/SampleSyncAdapter/Android.mk
@@ -8,7 +8,7 @@
 
 LOCAL_PACKAGE_NAME := SampleSyncAdapter
 
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := 15
 
 include $(BUILD_PACKAGE)
 
diff --git a/samples/SampleSyncAdapter/samplesyncadapter_server/app.yaml b/samples/SampleSyncAdapter/samplesyncadapter_server/app.yaml
index 8526177..0c4c3b2 100644
--- a/samples/SampleSyncAdapter/samplesyncadapter_server/app.yaml
+++ b/samples/SampleSyncAdapter/samplesyncadapter_server/app.yaml
@@ -12,7 +12,10 @@
 # License for the specific language governing permissions and limitations under
 # the License.
 
-application: samplesyncadapter2
+# Note the app name used to be "samplesyncadapter2", but it's now "samplesyncadapterhr" because
+# it's been migrated to HR.  But it's still accessible under the old URL,
+# http://samplesyncadapter2.appspot.com/
+application: samplesyncadapterhr
 version: 1
 runtime: python
 api_version: 1
diff --git a/samples/Support7Demos/AndroidManifest.xml b/samples/Support7Demos/AndroidManifest.xml
index e3337a6..288b124 100644
--- a/samples/Support7Demos/AndroidManifest.xml
+++ b/samples/Support7Demos/AndroidManifest.xml
@@ -316,6 +316,15 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".app.DialogFragmentUsage"
+                  android:label="@string/dialogfragment_usage"
+                  android:theme="@style/Theme.AppCompat.Light">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.example.android.supportv7.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <provider android:name=".app.RecentSuggestionsProvider"
                   android:authorities="com.example.android.supportv7.RecentSuggestionsProvider" />
 
diff --git a/samples/Support7Demos/res/values/arrays.xml b/samples/Support7Demos/res/values/arrays.xml
index c4d3987..a32c09e 100644
--- a/samples/Support7Demos/res/values/arrays.xml
+++ b/samples/Support7Demos/res/values/arrays.xml
@@ -31,7 +31,6 @@
 
     <string-array name="dialog_types">
         <item>Simple</item>
-        <item>Simple with Action Bar</item>
         <item>Button bar</item>
     </string-array>
 
diff --git a/samples/Support7Demos/res/values/strings.xml b/samples/Support7Demos/res/values/strings.xml
index 98d2087..accf739 100644
--- a/samples/Support7Demos/res/values/strings.xml
+++ b/samples/Support7Demos/res/values/strings.xml
@@ -137,6 +137,7 @@
     <string name="dialog_title">My great dialog</string>
     <string name="dialog_content">My great dialog is great</string>
     <string name="alert_dialog_usage">AppCompat/Dialog/AlertDialog Usage</string>
+    <string name="dialogfragment_usage">AppCompat/Dialog/DialogFragment Usage</string>
 
     <string name="sample_media_route_provider_remote">Remote Playback (Simulated)</string>
     <string name="sample_media_route_activity_local">Local Playback</string>
@@ -180,6 +181,7 @@
     <string name="sorted_list_activity">Sorted List</string>
     <string name="add_new_item">Add New Item</string>
     <string name="start_action_mode">Start Action Mode</string>
+
     <string name="swipe_to_dismiss_activity">RecyclerView/ItemTouchHelper/Swipe To Dismiss</string>
     <string name="drag_and_drop_activity">RecyclerView/ItemTouchHelper/Drag and Drop Activity</string>
     <string name="swipe_start">start</string>
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/app/DialogFragmentUsage.java b/samples/Support7Demos/src/com/example/android/supportv7/app/DialogFragmentUsage.java
new file mode 100644
index 0000000..f44a0df
--- /dev/null
+++ b/samples/Support7Demos/src/com/example/android/supportv7/app/DialogFragmentUsage.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2015 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.supportv7.app;
+
+import com.example.android.supportv7.R;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.view.WindowCompat;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.app.AppCompatDialog;
+import android.support.v7.app.AppCompatDialogFragment;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Spinner;
+import android.widget.Toast;
+
+/**
+ * This demonstrates idiomatic usage of AppCompatDialogFragment.
+ */
+public class DialogFragmentUsage extends AppCompatActivity {
+
+    private Spinner mSpinner;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.dialog_usage);
+
+        mSpinner = (Spinner) findViewById(R.id.spinner_dialogs);
+
+        // Add an OnClickListener to show our selected dialog
+        findViewById(R.id.btn_show_dialog).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                showSelectedDialog();
+            }
+        });
+    }
+
+    private void showSelectedDialog() {
+        switch (mSpinner.getSelectedItemPosition()) {
+            case 0:
+                showSimpleDialog();
+                break;
+            case 1:
+                showButtonBarDialog();
+                break;
+        }
+    }
+
+    private void showSimpleDialog() {
+        MenuDialogFragment fragment = MenuDialogFragment.create(R.layout.dialog_content);
+        fragment.show(getSupportFragmentManager(), null);
+    }
+
+    private void showButtonBarDialog() {
+        MenuDialogFragment fragment = MenuDialogFragment.create(R.layout.dialog_content_buttons);
+        fragment.show(getSupportFragmentManager(), null);
+    }
+
+    /**
+     * A simple {@link AppCompatDialog} implementation which
+     * inflates some items into it's options menu, and shows a toast when one is selected.
+     */
+    public static class MenuDialogFragment extends AppCompatDialogFragment {
+
+        private static final String PARAM_CONTENT_VIEW = "content_view";
+
+        static MenuDialogFragment create(int contentView) {
+            Bundle b = new Bundle();
+            b.putInt(PARAM_CONTENT_VIEW, contentView);
+
+            MenuDialogFragment fragment = new MenuDialogFragment();
+            fragment.setArguments(b);
+
+            return fragment;
+        }
+
+        @Override
+        public void onCreate(@Nullable Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setHasOptionsMenu(true);
+        }
+
+        @Nullable
+        @Override
+        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
+                @Nullable Bundle savedInstanceState) {
+            Bundle args = getArguments();
+            int contentView = args.getInt(PARAM_CONTENT_VIEW);
+            return inflater.inflate(contentView, container, false);
+        }
+
+        @Override
+        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+            inflater.inflate(R.menu.actions, menu);
+        }
+
+        @Override
+        public boolean onOptionsItemSelected(MenuItem item) {
+            Toast.makeText(getActivity(), "Dialog action selected: " + item.getTitle(),
+                    Toast.LENGTH_SHORT).show();
+            return true;
+        }
+    }
+
+}
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/app/DialogUsage.java b/samples/Support7Demos/src/com/example/android/supportv7/app/DialogUsage.java
index cf48d80..ea1a07d 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/app/DialogUsage.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/app/DialogUsage.java
@@ -58,9 +58,6 @@
                 showSimpleDialog();
                 break;
             case 1:
-                showSimpleDialogWithActionBar();
-                break;
-            case 2:
                 showButtonBarDialog();
                 break;
         }
@@ -73,15 +70,6 @@
         dialog.show();
     }
 
-    private void showSimpleDialogWithActionBar() {
-        AppCompatDialog dialog = new MenuDialog(this);
-        // Request the support Action Bar window feature
-        dialog.supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR);
-        dialog.setTitle(R.string.dialog_title);
-        dialog.setContentView(R.layout.dialog_content);
-        dialog.show();
-    }
-
     private void showButtonBarDialog() {
         Dialog dialog = new AppCompatDialog(this);
         dialog.setTitle(R.string.dialog_title);
diff --git a/samples/Wiktionary/Android.mk b/samples/Wiktionary/Android.mk
index d6ce1f1..0d015fd 100644
--- a/samples/Wiktionary/Android.mk
+++ b/samples/Wiktionary/Android.mk
@@ -8,7 +8,7 @@
 
 LOCAL_PACKAGE_NAME := Wiktionary
 
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := 8
 
 include $(BUILD_PACKAGE)
 
diff --git a/samples/WiktionarySimple/Android.mk b/samples/WiktionarySimple/Android.mk
index a5a1423..670cd82 100644
--- a/samples/WiktionarySimple/Android.mk
+++ b/samples/WiktionarySimple/Android.mk
@@ -8,7 +8,7 @@
 
 LOCAL_PACKAGE_NAME := WiktionarySimple
 
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := 8
 
 include $(BUILD_PACKAGE)
 
diff --git a/samples/XmlAdapters/Android.mk b/samples/XmlAdapters/Android.mk
index e12ce57..6c46e19 100644
--- a/samples/XmlAdapters/Android.mk
+++ b/samples/XmlAdapters/Android.mk
@@ -10,7 +10,7 @@
 
 LOCAL_PROGUARD_ENABLED := disabled
 
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := 8
 
 include $(BUILD_PACKAGE)
 
diff --git a/samples/browseable/ActiveNotifications/AndroidManifest.xml b/samples/browseable/ActiveNotifications/AndroidManifest.xml
new file mode 100644
index 0000000..3a39282
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.activenotifications"
+    android:versionCode="1"
+    android:versionName="1.0">
+
+    <application android:allowBackup="true"
+        android:label="@string/app_name"
+        android:icon="@mipmap/ic_launcher"
+        android:theme="@style/AppTheme">
+
+        <activity android:name=".ActiveNotificationActivity"
+                  android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+
+</manifest>
diff --git a/samples/browseable/ActiveNotifications/_index.jd b/samples/browseable/ActiveNotifications/_index.jd
new file mode 100644
index 0000000..d8ce4a9
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/_index.jd
@@ -0,0 +1,13 @@
+
+page.tags="ActiveNotification"
+sample.group=Notification
+@jd:body
+
+<p>
+            
+The NotificationManager can tell you how many notifications your application is currently showing.
+This sample demonstrates how to use this API that has been introduced with Android M.
+To get started, press the "add a notification" button.
+When a notification is being canceled, the count gets updated via a PendingIntent.
+            
+        </p>
diff --git a/samples/browseable/ActiveNotifications/res/drawable-hdpi/tile.9.png b/samples/browseable/ActiveNotifications/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/samples/browseable/ActiveNotifications/res/layout-w720dp/activity_main.xml b/samples/browseable/ActiveNotifications/res/layout-w720dp/activity_main.xml
new file mode 100755
index 0000000..c9a52f6
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/layout-w720dp/activity_main.xml
@@ -0,0 +1,73 @@
+<!--
+  Copyright 2013 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.
+  -->
+<LinearLayout
+      xmlns:android="http://schemas.android.com/apk/res/android"
+      android:orientation="horizontal"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:id="@+id/sample_main_layout">
+
+    <LinearLayout
+          android:id="@+id/sample_output"
+          android:layout_width="0px"
+          android:layout_height="match_parent"
+          android:layout_weight="1"
+          android:orientation="vertical">
+
+        <FrameLayout
+              style="@style/Widget.SampleMessageTile"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content">
+
+            <TextView
+                  style="@style/Widget.SampleMessage"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:paddingLeft="@dimen/margin_medium"
+                  android:paddingRight="@dimen/margin_medium"
+                  android:paddingTop="@dimen/margin_large"
+                  android:paddingBottom="@dimen/margin_large"
+                  android:text="@string/intro_message" />
+        </FrameLayout>
+
+        <View
+              android:layout_width="match_parent"
+              android:layout_height="1dp"
+              android:background="@android:color/darker_gray" />
+
+        <fragment
+              android:name="com.example.android.common.logger.LogFragment"
+              android:id="@+id/log_fragment"
+              android:layout_width="match_parent"
+              android:layout_height="0px"
+              android:layout_weight="1" />
+
+    </LinearLayout>
+
+    <View
+          android:layout_width="1dp"
+          android:layout_height="match_parent"
+          android:background="@android:color/darker_gray" />
+
+    <FrameLayout
+          android:id="@+id/sample_content_fragment"
+          android:layout_weight="2"
+          android:layout_width="0px"
+          android:layout_height="match_parent" />
+
+</LinearLayout>
+
+
diff --git a/samples/browseable/ActiveNotifications/res/layout/activity_main.xml b/samples/browseable/ActiveNotifications/res/layout/activity_main.xml
new file mode 100755
index 0000000..1ae4f98
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/layout/activity_main.xml
@@ -0,0 +1,65 @@
+<!--
+  Copyright 2013 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.
+  -->
+<LinearLayout
+      xmlns:android="http://schemas.android.com/apk/res/android"
+      android:orientation="vertical"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:id="@+id/sample_main_layout">
+
+    <ViewAnimator
+          android:id="@+id/sample_output"
+          android:layout_width="match_parent"
+          android:layout_height="0px"
+          android:layout_weight="1">
+
+        <ScrollView
+              style="@style/Widget.SampleMessageTile"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+            <TextView
+                  style="@style/Widget.SampleMessage"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:paddingLeft="@dimen/horizontal_page_margin"
+                  android:paddingRight="@dimen/horizontal_page_margin"
+                  android:paddingTop="@dimen/vertical_page_margin"
+                  android:paddingBottom="@dimen/vertical_page_margin"
+                  android:text="@string/intro_message" />
+        </ScrollView>
+
+        <fragment
+              android:name="com.example.android.common.logger.LogFragment"
+              android:id="@+id/log_fragment"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent" />
+
+    </ViewAnimator>
+
+    <View
+          android:layout_width="match_parent"
+          android:layout_height="1dp"
+          android:background="@android:color/darker_gray" />
+
+    <FrameLayout
+          android:id="@+id/sample_content_fragment"
+          android:layout_weight="2"
+          android:layout_width="match_parent"
+          android:layout_height="0px" />
+
+</LinearLayout>
+
diff --git a/samples/browseable/ActiveNotifications/res/layout/fragment_notification_builder.xml b/samples/browseable/ActiveNotifications/res/layout/fragment_notification_builder.xml
new file mode 100644
index 0000000..379cd5e
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/layout/fragment_notification_builder.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2015 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.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+    <Button
+        android:id="@+id/add_notification"
+        android:text="@string/add_a_notification"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+    </LinearLayout>
+
+    <TextView
+        style="@android:style/TextAppearance.Material.Large"
+        android:id="@+id/number_of_notifications"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+</LinearLayout>
diff --git a/samples/ActionBarCompat/res/values/dimens.xml b/samples/browseable/ActiveNotifications/res/menu/main.xml
similarity index 67%
copy from samples/ActionBarCompat/res/values/dimens.xml
copy to samples/browseable/ActiveNotifications/res/menu/main.xml
index 67c8436..b49c2c5 100644
--- a/samples/ActionBarCompat/res/values/dimens.xml
+++ b/samples/browseable/ActiveNotifications/res/menu/main.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -14,8 +14,8 @@
   limitations under the License.
   -->
 
-<resources>
-    <dimen name="actionbar_compat_height">48dp</dimen>
-    <dimen name="actionbar_compat_button_width">48dp</dimen>
-    <dimen name="actionbar_compat_button_home_width">56dp</dimen>
-</resources>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/menu_toggle_log"
+          android:showAsAction="always"
+          android:title="@string/sample_show_log" />
+</menu>
diff --git a/samples/browseable/ActiveNotifications/res/mipmap-hdpi/ic_launcher.png b/samples/browseable/ActiveNotifications/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..b176e69
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/ActiveNotifications/res/mipmap-hdpi/ic_notification.png b/samples/browseable/ActiveNotifications/res/mipmap-hdpi/ic_notification.png
new file mode 100644
index 0000000..efb231d
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/mipmap-hdpi/ic_notification.png
Binary files differ
diff --git a/samples/browseable/ActiveNotifications/res/mipmap-mdpi/ic_launcher.png b/samples/browseable/ActiveNotifications/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..205654f
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/ActiveNotifications/res/mipmap-mdpi/ic_notification.png b/samples/browseable/ActiveNotifications/res/mipmap-mdpi/ic_notification.png
new file mode 100644
index 0000000..b5f1bc9
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/mipmap-mdpi/ic_notification.png
Binary files differ
diff --git a/samples/browseable/ActiveNotifications/res/mipmap-xhdpi/ic_launcher.png b/samples/browseable/ActiveNotifications/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..98262ee
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/ActiveNotifications/res/mipmap-xhdpi/ic_notification.png b/samples/browseable/ActiveNotifications/res/mipmap-xhdpi/ic_notification.png
new file mode 100644
index 0000000..3361f2d
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/mipmap-xhdpi/ic_notification.png
Binary files differ
diff --git a/samples/browseable/ActiveNotifications/res/mipmap-xxhdpi/ic_launcher.png b/samples/browseable/ActiveNotifications/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..325875a
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/ActiveNotifications/res/mipmap-xxhdpi/ic_notification.png b/samples/browseable/ActiveNotifications/res/mipmap-xxhdpi/ic_notification.png
new file mode 100644
index 0000000..7d1946a
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/mipmap-xxhdpi/ic_notification.png
Binary files differ
diff --git a/samples/browseable/ActiveNotifications/res/mipmap-xxxhdpi/ic_launcher.png b/samples/browseable/ActiveNotifications/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..254c775
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/ActiveNotifications/res/mipmap-xxxhdpi/ic_notification.png b/samples/browseable/ActiveNotifications/res/mipmap-xxxhdpi/ic_notification.png
new file mode 100644
index 0000000..47b12c9
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/mipmap-xxxhdpi/ic_notification.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/values/dimens.xml b/samples/browseable/ActiveNotifications/res/values-sw600dp/template-dimens.xml
similarity index 71%
rename from samples/ActionBarCompat/res/values/dimens.xml
rename to samples/browseable/ActiveNotifications/res/values-sw600dp/template-dimens.xml
index 67c8436..22074a2 100644
--- a/samples/ActionBarCompat/res/values/dimens.xml
+++ b/samples/browseable/ActiveNotifications/res/values-sw600dp/template-dimens.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -15,7 +15,10 @@
   -->
 
 <resources>
-    <dimen name="actionbar_compat_height">48dp</dimen>
-    <dimen name="actionbar_compat_button_width">48dp</dimen>
-    <dimen name="actionbar_compat_button_home_width">56dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
 </resources>
diff --git a/samples/ActionBarCompat/res/values-v13/styles.xml b/samples/browseable/ActiveNotifications/res/values-sw600dp/template-styles.xml
similarity index 67%
rename from samples/ActionBarCompat/res/values-v13/styles.xml
rename to samples/browseable/ActiveNotifications/res/values-sw600dp/template-styles.xml
index 8a042b4..03d1974 100644
--- a/samples/ActionBarCompat/res/values-v13/styles.xml
+++ b/samples/browseable/ActiveNotifications/res/values-sw600dp/template-styles.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -16,8 +16,10 @@
 
 <resources>
 
-    <style name="ActionBarTitle" parent="android:style/TextAppearance.Holo.Widget.ActionBar.Title">
-        <item name="android:textColor">@color/actionbar_title_color</item>
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceLarge</item>
+        <item name="android:lineSpacingMultiplier">1.2</item>
+        <item name="android:shadowDy">-6.5</item>
     </style>
 
 </resources>
diff --git a/samples/ActionBarCompat/res/values/colors.xml b/samples/browseable/ActiveNotifications/res/values-v11/template-styles.xml
similarity index 79%
rename from samples/ActionBarCompat/res/values/colors.xml
rename to samples/browseable/ActiveNotifications/res/values-v11/template-styles.xml
index 4edc6d6..8c1ea66 100644
--- a/samples/ActionBarCompat/res/values/colors.xml
+++ b/samples/browseable/ActiveNotifications/res/values-v11/template-styles.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -15,5 +15,8 @@
   -->
 
 <resources>
-    <color name="actionbar_title_color">#224894</color>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
 </resources>
diff --git a/samples/browseable/ActiveNotifications/res/values-v21/base-colors.xml b/samples/browseable/ActiveNotifications/res/values-v21/base-colors.xml
new file mode 100644
index 0000000..8b6ec3f
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/values-v21/base-colors.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+
+</resources>
diff --git a/samples/browseable/ActiveNotifications/res/values-v21/base-template-styles.xml b/samples/browseable/ActiveNotifications/res/values-v21/base-template-styles.xml
new file mode 100644
index 0000000..c778e4f
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/values-v21/base-template-styles.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Material.Light">
+    </style>
+
+</resources>
diff --git a/samples/browseable/ActiveNotifications/res/values/base-strings.xml b/samples/browseable/ActiveNotifications/res/values/base-strings.xml
new file mode 100644
index 0000000..5fc846c
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/values/base-strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+    <string name="app_name">ActiveNotification</string>
+    <string name="intro_message">
+        <![CDATA[
+        
+            
+The NotificationManager can tell you how many notifications your application is currently showing.
+This sample demonstrates how to use this API that has been introduced with Android M.
+To get started, press the "add a notification" button.
+When a notification is being canceled, the count gets updated via a PendingIntent.
+            
+        
+        ]]>
+    </string>
+</resources>
diff --git a/samples/ActionBarCompat/res/values/colors.xml b/samples/browseable/ActiveNotifications/res/values/fragmentview_strings.xml
old mode 100644
new mode 100755
similarity index 77%
copy from samples/ActionBarCompat/res/values/colors.xml
copy to samples/browseable/ActiveNotifications/res/values/fragmentview_strings.xml
index 4edc6d6..7b9d9ec
--- a/samples/ActionBarCompat/res/values/colors.xml
+++ b/samples/browseable/ActiveNotifications/res/values/fragmentview_strings.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -12,8 +12,8 @@
   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.
-  -->
-
+-->
 <resources>
-    <color name="actionbar_title_color">#224894</color>
+    <string name="sample_show_log">Show Log</string>
+    <string name="sample_hide_log">Hide Log</string>
 </resources>
diff --git a/samples/browseable/ActiveNotifications/res/values/strings.xml b/samples/browseable/ActiveNotifications/res/values/strings.xml
new file mode 100644
index 0000000..0f2977d
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+<resources>
+ <string name="add_a_notification">Add a notification</string>
+ <string name="active_notifications">Active Notifications: %1$s</string>
+ <string name="update_notification_count">Update count</string>
+ <string name="sample_notification_content">This is a sample notification.</string>
+</resources>
diff --git a/samples/browseable/ActiveNotifications/res/values/template-dimens.xml b/samples/browseable/ActiveNotifications/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+  Copyright 2013 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.
+  -->
+
+<resources>
+
+    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+    <dimen name="margin_tiny">4dp</dimen>
+    <dimen name="margin_small">8dp</dimen>
+    <dimen name="margin_medium">16dp</dimen>
+    <dimen name="margin_large">32dp</dimen>
+    <dimen name="margin_huge">64dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/samples/browseable/ActiveNotifications/res/values/template-styles.xml b/samples/browseable/ActiveNotifications/res/values/template-styles.xml
new file mode 100644
index 0000000..6e7d593
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+  Copyright 2013 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.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+
+    <style name="Theme.Base" parent="android:Theme.Light" />
+
+    <style name="Theme.Sample" parent="Theme.Base" />
+
+    <style name="AppTheme" parent="Theme.Sample" />
+    <!-- Widget styling -->
+
+    <style name="Widget" />
+
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceMedium</item>
+        <item name="android:lineSpacingMultiplier">1.1</item>
+    </style>
+
+    <style name="Widget.SampleMessageTile">
+        <item name="android:background">@drawable/tile</item>
+        <item name="android:shadowColor">#7F000000</item>
+        <item name="android:shadowDy">-3.5</item>
+        <item name="android:shadowRadius">2</item>
+    </style>
+
+</resources>
diff --git a/samples/browseable/ActiveNotifications/src/com.example.android.activenotifications/ActiveNotificationActivity.java b/samples/browseable/ActiveNotifications/src/com.example.android.activenotifications/ActiveNotificationActivity.java
new file mode 100644
index 0000000..bdb5421
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/src/com.example.android.activenotifications/ActiveNotificationActivity.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2015 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.activenotifications;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.PersistableBundle;
+
+public class ActiveNotificationActivity extends MainActivity {
+
+    private ActiveNotificationFragment mFragment;
+
+    protected static final String ACTION_NOTIFICATION_DELETE
+            = "com.example.android.activenotifications.delete";
+
+    private BroadcastReceiver mDeleteReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (mFragment == null) {
+                findFragment();
+            }
+            mFragment.updateNumberOfNotifications();
+        }
+    };
+
+    @Override
+    public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
+        super.onCreate(savedInstanceState, persistentState);
+        findFragment();
+        mFragment.updateNumberOfNotifications();
+    }
+
+    private void findFragment() {
+        mFragment = (ActiveNotificationFragment) getSupportFragmentManager()
+                .findFragmentById(R.id.sample_content_fragment);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        registerReceiver(mDeleteReceiver, new IntentFilter(ACTION_NOTIFICATION_DELETE));
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        unregisterReceiver(mDeleteReceiver);
+    }
+}
diff --git a/samples/browseable/ActiveNotifications/src/com.example.android.activenotifications/ActiveNotificationFragment.java b/samples/browseable/ActiveNotifications/src/com.example.android.activenotifications/ActiveNotificationFragment.java
new file mode 100644
index 0000000..3e87849
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/src/com.example.android.activenotifications/ActiveNotificationFragment.java
@@ -0,0 +1,124 @@
+package com.example.android.activenotifications;
+/*
+* Copyright 2015 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.
+*/
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.service.notification.StatusBarNotification;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.example.android.common.logger.Log;
+
+/**
+ * A fragment that enables display of notifications.
+ */
+public class ActiveNotificationFragment extends Fragment {
+
+    private static final String TAG = "ActiveNotificationFragment";
+
+    private NotificationManager mNotificationManager;
+    private TextView mNumberOfNotifications;
+
+    // Every notification needs a unique ID otherwise the previous one would be overwritten.
+    private int mNotificationId = 0;
+    private PendingIntent mDeletePendingIntent;
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.fragment_notification_builder, container, false);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        updateNumberOfNotifications();
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+        mNotificationManager = (NotificationManager) getActivity().getSystemService(
+                Context.NOTIFICATION_SERVICE);
+        mNumberOfNotifications = (TextView) view.findViewById(R.id.number_of_notifications);
+
+        // Supply actions to the button that is displayed on screen.
+        View.OnClickListener onClickListener = new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                switch (v.getId()) {
+                    case R.id.add_notification: {
+                        addNotificationAndReadNumber();
+                        break;
+                    }
+                }
+            }
+        };
+        view.findViewById(R.id.add_notification).setOnClickListener(onClickListener);
+
+        // [BEGIN create_pending_intent_for_deletion]
+        // Create a PendingIntent to be fired upon deletion of a Notification.
+        Intent deleteIntent = new Intent(ActiveNotificationActivity.ACTION_NOTIFICATION_DELETE);
+        mDeletePendingIntent = PendingIntent.getBroadcast(getActivity(),
+                2323 /* requestCode */, deleteIntent, 0);
+        // [END create_pending_intent_for_deletion]
+    }
+
+    /**
+     * Add a new {@link Notification} with sample data and send it to the system.
+     * Then read the current number of displayed notifications for this application.
+     */
+    private void addNotificationAndReadNumber() {
+        // [BEGIN create_notification]
+        // Create a Notification and notify the system.
+        final Notification.Builder builder = new Notification.Builder(getActivity())
+                .setSmallIcon(R.mipmap.ic_notification)
+                .setContentTitle(getString(R.string.app_name))
+                .setContentText(getString(R.string.sample_notification_content))
+                .setAutoCancel(true)
+                .setDeleteIntent(mDeletePendingIntent);
+
+        final Notification notification = builder.build();
+        mNotificationManager.notify(++mNotificationId, notification);
+        // [END create_notification]
+        Log.i(TAG, "Add a notification");
+        updateNumberOfNotifications();
+    }
+
+    /**
+     * Request the current number of notifications from the {@link NotificationManager} and
+     * display them to the user.
+     */
+    protected void updateNumberOfNotifications() {
+        // [BEGIN get_active_notifications]
+        // Query the currently displayed notifications.
+        final StatusBarNotification[] activeNotifications = mNotificationManager
+                .getActiveNotifications();
+        // [END get_active_notifications]
+        final int numberOfNotifications = activeNotifications.length;
+        mNumberOfNotifications.setText(getString(R.string.active_notifications,
+                numberOfNotifications));
+        Log.i(TAG, getString(R.string.active_notifications, numberOfNotifications));
+    }
+}
diff --git a/samples/browseable/ActiveNotifications/src/com.example.android.activenotifications/MainActivity.java b/samples/browseable/ActiveNotifications/src/com.example.android.activenotifications/MainActivity.java
new file mode 100644
index 0000000..bf11b8e
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/src/com.example.android.activenotifications/MainActivity.java
@@ -0,0 +1,110 @@
+/*
+* Copyright 2013 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.activenotifications;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.ViewAnimator;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description, sample log and a custom
+ * {@link android.support.v4.app.Fragment} which can display a view.
+ * <p>
+ * For devices with displays with a width of 720dp or greater, the sample log is always visible,
+ * on other devices it's visibility is controlled by an item on the Action Bar.
+ */
+public class MainActivity extends SampleActivityBase {
+
+    public static final String TAG = "MainActivity";
+
+    // Whether the Log Fragment is currently shown
+    private boolean mLogShown;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        if (savedInstanceState == null) {
+            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+            ActiveNotificationFragment fragment = new ActiveNotificationFragment();
+            transaction.replace(R.id.sample_content_fragment, fragment);
+            transaction.commit();
+        }
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.main, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        MenuItem logToggle = menu.findItem(R.id.menu_toggle_log);
+        logToggle.setVisible(findViewById(R.id.sample_output) instanceof ViewAnimator);
+        logToggle.setTitle(mLogShown ? R.string.sample_hide_log : R.string.sample_show_log);
+
+        return super.onPrepareOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch(item.getItemId()) {
+            case R.id.menu_toggle_log:
+                mLogShown = !mLogShown;
+                ViewAnimator output = (ViewAnimator) findViewById(R.id.sample_output);
+                if (mLogShown) {
+                    output.setDisplayedChild(1);
+                } else {
+                    output.setDisplayedChild(0);
+                }
+                supportInvalidateOptionsMenu();
+                return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    /** Create a chain of targets that will receive log data */
+    @Override
+    public void initializeLogging() {
+        // Wraps Android's native log framework.
+        LogWrapper logWrapper = new LogWrapper();
+        // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+        Log.setLogNode(logWrapper);
+
+        // Filter strips out everything except the message text.
+        MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+        logWrapper.setNext(msgFilter);
+
+        // On screen logging via a fragment with a TextView.
+        LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+                .findFragmentById(R.id.log_fragment);
+        msgFilter.setNext(logFragment.getLogView());
+
+        Log.i(TAG, "Ready");
+    }
+}
diff --git a/samples/browseable/ActiveNotifications/src/com.example.android.common/activities/SampleActivityBase.java b/samples/browseable/ActiveNotifications/src/com.example.android.common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/src/com.example.android.common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 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.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+    public static final String TAG = "SampleActivityBase";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    protected  void onStart() {
+        super.onStart();
+        initializeLogging();
+    }
+
+    /** Set up targets to receive log data */
+    public void initializeLogging() {
+        // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+        // Wraps Android's native log framework
+        LogWrapper logWrapper = new LogWrapper();
+        Log.setLogNode(logWrapper);
+
+        Log.i(TAG, "Ready");
+    }
+}
diff --git a/samples/browseable/ActiveNotifications/src/com.example.android.common/logger/Log.java b/samples/browseable/ActiveNotifications/src/com.example.android.common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/src/com.example.android.common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+    // Grabbing the native values from Android's native logging facilities,
+    // to make for easy migration and interop.
+    public static final int NONE = -1;
+    public static final int VERBOSE = android.util.Log.VERBOSE;
+    public static final int DEBUG = android.util.Log.DEBUG;
+    public static final int INFO = android.util.Log.INFO;
+    public static final int WARN = android.util.Log.WARN;
+    public static final int ERROR = android.util.Log.ERROR;
+    public static final int ASSERT = android.util.Log.ASSERT;
+
+    // Stores the beginning of the LogNode topology.
+    private static LogNode mLogNode;
+
+    /**
+     * Returns the next LogNode in the linked list.
+     */
+    public static LogNode getLogNode() {
+        return mLogNode;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to.
+     */
+    public static void setLogNode(LogNode node) {
+        mLogNode = node;
+    }
+
+    /**
+     * Instructs the LogNode to print the log data provided. Other LogNodes can
+     * be chained to the end of the LogNode as desired.
+     *
+     * @param priority Log level of the data being logged. Verbose, Error, etc.
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void println(int priority, String tag, String msg, Throwable tr) {
+        if (mLogNode != null) {
+            mLogNode.println(priority, tag, msg, tr);
+        }
+    }
+
+    /**
+     * Instructs the LogNode to print the log data provided. Other LogNodes can
+     * be chained to the end of the LogNode as desired.
+     *
+     * @param priority Log level of the data being logged. Verbose, Error, etc.
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     */
+    public static void println(int priority, String tag, String msg) {
+        println(priority, tag, msg, null);
+    }
+
+   /**
+     * Prints a message at VERBOSE priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void v(String tag, String msg, Throwable tr) {
+        println(VERBOSE, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at VERBOSE priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void v(String tag, String msg) {
+        v(tag, msg, null);
+    }
+
+
+    /**
+     * Prints a message at DEBUG priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void d(String tag, String msg, Throwable tr) {
+        println(DEBUG, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at DEBUG priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void d(String tag, String msg) {
+        d(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at INFO priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void i(String tag, String msg, Throwable tr) {
+        println(INFO, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at INFO priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void i(String tag, String msg) {
+        i(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void w(String tag, String msg, Throwable tr) {
+        println(WARN, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void w(String tag, String msg) {
+        w(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void w(String tag, Throwable tr) {
+        w(tag, null, tr);
+    }
+
+    /**
+     * Prints a message at ERROR priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void e(String tag, String msg, Throwable tr) {
+        println(ERROR, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at ERROR priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void e(String tag, String msg) {
+        e(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void wtf(String tag, String msg, Throwable tr) {
+        println(ASSERT, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void wtf(String tag, String msg) {
+        wtf(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void wtf(String tag, Throwable tr) {
+        wtf(tag, null, tr);
+    }
+}
diff --git a/samples/browseable/ActiveNotifications/src/com.example.android.common/logger/LogFragment.java b/samples/browseable/ActiveNotifications/src/com.example.android.common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/src/com.example.android.common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+    private LogView mLogView;
+    private ScrollView mScrollView;
+
+    public LogFragment() {}
+
+    public View inflateViews() {
+        mScrollView = new ScrollView(getActivity());
+        ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT);
+        mScrollView.setLayoutParams(scrollParams);
+
+        mLogView = new LogView(getActivity());
+        ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+        logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+        mLogView.setLayoutParams(logParams);
+        mLogView.setClickable(true);
+        mLogView.setFocusable(true);
+        mLogView.setTypeface(Typeface.MONOSPACE);
+
+        // Want to set padding as 16 dips, setPadding takes pixels.  Hooray math!
+        int paddingDips = 16;
+        double scale = getResources().getDisplayMetrics().density;
+        int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+        mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+        mLogView.setCompoundDrawablePadding(paddingPixels);
+
+        mLogView.setGravity(Gravity.BOTTOM);
+        mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+        mScrollView.addView(mLogView);
+        return mScrollView;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+
+        View result = inflateViews();
+
+        mLogView.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+            }
+        });
+        return result;
+    }
+
+    public LogView getLogView() {
+        return mLogView;
+    }
+}
\ No newline at end of file
diff --git a/samples/browseable/ActiveNotifications/src/com.example.android.common/logger/LogNode.java b/samples/browseable/ActiveNotifications/src/com.example.android.common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/src/com.example.android.common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 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.example.android.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+    /**
+     * Instructs first LogNode in the list to print the log data provided.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/samples/browseable/ActiveNotifications/src/com.example.android.common/logger/LogView.java b/samples/browseable/ActiveNotifications/src/com.example.android.common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/src/com.example.android.common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+    public LogView(Context context) {
+        super(context);
+    }
+
+    public LogView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public LogView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    /**
+     * Formats the log data and prints it out to the LogView.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+
+        
+        String priorityStr = null;
+
+        // For the purposes of this View, we want to print the priority as readable text.
+        switch(priority) {
+            case android.util.Log.VERBOSE:
+                priorityStr = "VERBOSE";
+                break;
+            case android.util.Log.DEBUG:
+                priorityStr = "DEBUG";
+                break;
+            case android.util.Log.INFO:
+                priorityStr = "INFO";
+                break;
+            case android.util.Log.WARN:
+                priorityStr = "WARN";
+                break;
+            case android.util.Log.ERROR:
+                priorityStr = "ERROR";
+                break;
+            case android.util.Log.ASSERT:
+                priorityStr = "ASSERT";
+                break;
+            default:
+                break;
+        }
+
+        // Handily, the Log class has a facility for converting a stack trace into a usable string.
+        String exceptionStr = null;
+        if (tr != null) {
+            exceptionStr = android.util.Log.getStackTraceString(tr);
+        }
+
+        // Take the priority, tag, message, and exception, and concatenate as necessary
+        // into one usable line of text.
+        final StringBuilder outputBuilder = new StringBuilder();
+
+        String delimiter = "\t";
+        appendIfNotNull(outputBuilder, priorityStr, delimiter);
+        appendIfNotNull(outputBuilder, tag, delimiter);
+        appendIfNotNull(outputBuilder, msg, delimiter);
+        appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+        // In case this was originally called from an AsyncTask or some other off-UI thread,
+        // make sure the update occurs within the UI thread.
+        ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+            @Override
+            public void run() {
+                // Display the text we just generated within the LogView.
+                appendToLog(outputBuilder.toString());
+            }
+        })));
+
+        if (mNext != null) {
+            mNext.println(priority, tag, msg, tr);
+        }
+    }
+
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+    /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+     * the logger takes so many arguments that might be null, this method helps cut out some of the
+     * agonizing tedium of writing the same 3 lines over and over.
+     * @param source StringBuilder containing the text to append to.
+     * @param addStr The String to append
+     * @param delimiter The String to separate the source and appended strings. A tab or comma,
+     *                  for instance.
+     * @return The fully concatenated String as a StringBuilder
+     */
+    private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+        if (addStr != null) {
+            if (addStr.length() == 0) {
+                delimiter = "";
+            }
+
+            return source.append(addStr).append(delimiter);
+        }
+        return source;
+    }
+
+    // The next LogNode in the chain.
+    LogNode mNext;
+
+    /** Outputs the string as a new line of log data in the LogView. */
+    public void appendToLog(String s) {
+        append("\n" + s);
+    }
+
+
+}
diff --git a/samples/browseable/ActiveNotifications/src/com.example.android.common/logger/LogWrapper.java b/samples/browseable/ActiveNotifications/src/com.example.android.common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/src/com.example.android.common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 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.example.android.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface.  This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+    // For piping:  The next node to receive Log data after this one has done its work.
+    private LogNode mNext;
+
+    /**
+     * Returns the next LogNode in the linked list.
+     */
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to..
+     */
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+    /**
+     * Prints data out to the console using Android's native log mechanism.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+        // There actually are log methods that don't take a msg parameter.  For now,
+        // if that's the case, just convert null to the empty string and move on.
+        String useMsg = msg;
+        if (useMsg == null) {
+            useMsg = "";
+        }
+
+        // If an exeption was provided, convert that exception to a usable string and attach
+        // it to the end of the msg method.
+        if (tr != null) {
+            msg += "\n" + Log.getStackTraceString(tr);
+        }
+
+        // This is functionally identical to Log.x(tag, useMsg);
+        // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+        Log.println(priority, tag, useMsg);
+
+        // If this isn't the last node in the chain, move things along.
+        if (mNext != null) {
+            mNext.println(priority, tag, msg, tr);
+        }
+    }
+}
diff --git a/samples/browseable/ActiveNotifications/src/com.example.android.common/logger/MessageOnlyLogFilter.java b/samples/browseable/ActiveNotifications/src/com.example.android.common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/samples/browseable/ActiveNotifications/src/com.example.android.common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+    LogNode mNext;
+
+    /**
+     * Takes the "next" LogNode as a parameter, to simplify chaining.
+     *
+     * @param next The next LogNode in the pipeline.
+     */
+    public MessageOnlyLogFilter(LogNode next) {
+        mNext = next;
+    }
+
+    public MessageOnlyLogFilter() {
+    }
+
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+        if (mNext != null) {
+            getNext().println(Log.NONE, null, msg, null);
+        }
+    }
+
+    /**
+     * Returns the next LogNode in the chain.
+     */
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to..
+     */
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+}
diff --git a/samples/browseable/AlwaysOn/src/com.example.android.wearable.wear.alwayson/MainActivity.java b/samples/browseable/AlwaysOn/src/com.example.android.wearable.wear.alwayson/MainActivity.java
index 0eb7f47..3673545 100644
--- a/samples/browseable/AlwaysOn/src/com.example.android.wearable.wear.alwayson/MainActivity.java
+++ b/samples/browseable/AlwaysOn/src/com.example.android.wearable.wear.alwayson/MainActivity.java
@@ -264,7 +264,6 @@
              * Otherwise, it is easy for the AlarmManager launch intent to open a new activity
              * every time the Alarm is triggered rather than reusing this Activity.
              */
-            mAmbientStateAlarmManager.cancel(mAmbientStatePendingIntent);
             mAmbientStateAlarmManager.setExact(
                     AlarmManager.RTC_WAKEUP,
                     triggerTimeMs,
diff --git a/samples/browseable/AutoBackupForApps/AndroidManifest.xml b/samples/browseable/AutoBackupForApps/AndroidManifest.xml
new file mode 100644
index 0000000..7dad1e0
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.autobackupsample" >
+
+    <application
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme"
+        android:fullBackupContent="@xml/backup">
+        <activity
+            android:name=".MainActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".AddFileActivity" />
+    </application>
+
+</manifest>
diff --git a/samples/browseable/AutoBackupForApps/_index.jd b/samples/browseable/AutoBackupForApps/_index.jd
new file mode 100644
index 0000000..904681a
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/_index.jd
@@ -0,0 +1,16 @@
+
+page.tags="Automatic Backup"
+sample.group=Content
+@jd:body
+
+<p>
+            
+This sample demonstrates how to selectively disable Automatic Backups in Android M, either by
+adjusting the location where data files are stored using getNoBackupFilesDir(), or by using a custom
+XML configuration file.
+
+This sample can also be used as a utility to test the behavior of the Automatic Backup feature.
+Executing "adb shell bmgr restore com.example.android.autobackup" from a terminal will cause the
+sample\'s data to be cleared and replaced with a copy from the backup server.
+            
+        </p>
diff --git a/samples/browseable/AutoBackupForApps/res/drawable-hdpi/tile.9.png b/samples/browseable/AutoBackupForApps/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/samples/browseable/AutoBackupForApps/res/layout/activity_main.xml b/samples/browseable/AutoBackupForApps/res/layout/activity_main.xml
new file mode 100644
index 0000000..4a7879d
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/layout/activity_main.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<fragment xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools" android:id="@+id/fragment"
+    android:name="com.example.android.autobackupsample.MainActivityFragment"
+    tools:layout="@layout/fragment_main" android:layout_width="match_parent"
+    android:layout_height="match_parent" />
diff --git a/samples/browseable/AutoBackupForApps/res/layout/add_file.xml b/samples/browseable/AutoBackupForApps/res/layout/add_file.xml
new file mode 100644
index 0000000..9249bf4
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/layout/add_file.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:gravity="center_horizontal">
+
+    <RelativeLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="40dp">
+
+        <!-- File -->
+        <TextView
+            android:id="@+id/file_label"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="File"
+            android:textAlignment="center"
+            android:textSize="16sp"
+            android:textStyle="bold"
+            android:layout_marginRight="20dp"
+            android:layout_alignBaseline="@+id/file_name"/>
+
+        <EditText
+            android:id="@+id/file_name"
+            android:layout_width="300sp"
+            android:layout_height="wrap_content"
+            android:layout_toRightOf="@+id/file_label"
+            android:layout_marginBottom="20dp"
+            android:inputType="text"
+            android:text="foo.txt" />
+
+        <!-- Size -->
+        <TextView
+            android:id="@+id/size_label"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@+id/file_name"
+            android:layout_alignBaseline="@+id/file_size"
+            android:text="Size"
+            android:textSize="16sp"
+            android:textStyle="bold" />
+
+        <EditText
+            android:id="@+id/file_size"
+            android:layout_width="100dp"
+            android:layout_height="wrap_content"
+            android:layout_below="@+id/file_name"
+            android:layout_alignStart="@+id/file_name"
+            android:layout_marginBottom="20dp"
+            android:inputType="numberDecimal"
+            android:text="10" />
+
+        <Spinner
+            android:id="@+id/file_size_spinner"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_below="@+id/file_name"
+            android:layout_toRightOf="@+id/file_size"
+            android:layout_alignEnd="@+id/file_name"
+            android:layout_marginBottom="20dp"
+            />
+
+        <!-- Storage -->
+        <TextView
+            android:id="@+id/storage_label"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@+id/file_size_spinner"
+            android:layout_alignBaseline="@+id/storage_spinner"
+            android:paddingRight="20dp"
+            android:text="Storage"
+            android:textAlignment="center"
+            android:textSize="16sp"
+            android:textStyle="bold" />
+
+        <Spinner
+            android:id="@+id/storage_spinner"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_below="@+id/file_size_spinner"
+            android:layout_toRightOf="@+id/file_size"
+            android:layout_alignEnd="@+id/file_name"/>
+
+        <Button
+            android:id="@+id/create_file_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@+id/storage_spinner"
+            android:layout_centerInParent="true"
+            android:layout_marginTop="40dp"
+            android:paddingLeft="20dp"
+            android:paddingRight="20dp"
+            android:onClick="onCreateFileButtonClick"
+            android:text="Create" />
+
+    </RelativeLayout>
+</LinearLayout>
diff --git a/samples/browseable/AutoBackupForApps/res/layout/file_list_item.xml b/samples/browseable/AutoBackupForApps/res/layout/file_list_item.xml
new file mode 100644
index 0000000..e2d1866
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/layout/file_list_item.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:padding="20px"
+    android:orientation="horizontal">
+
+    <TextView android:id="@+id/file_name"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_weight="3"/>
+
+    <TextView android:id="@+id/file_size"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/browseable/AutoBackupForApps/res/layout/fragment_main.xml b/samples/browseable/AutoBackupForApps/res/layout/fragment_main.xml
new file mode 100644
index 0000000..35ba962
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/layout/fragment_main.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
+    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_horizontal_margin"
+    android:paddingTop="@dimen/activity_vertical_margin"
+    android:paddingBottom="@dimen/activity_vertical_margin"
+    android:orientation="vertical"
+    tools:context=".MainActivity$PlaceholderFragment">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:padding="20sp"
+        android:background="@android:color/darker_gray">
+
+        <TextView
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="3"
+            android:textStyle="bold"
+            android:text="File name" />
+        <TextView
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:textStyle="bold"
+            android:text="Size (bytes)" />
+
+    </LinearLayout>
+
+
+    <ListView android:id="@+id/file_list"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+
+    <TextView android:id="@+id/empty_file_list_message"
+        android:text="@string/no_files_click_add_files_menu"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="gone" />
+
+</LinearLayout>
diff --git a/samples/browseable/AutoBackupForApps/res/menu/menu_main.xml b/samples/browseable/AutoBackupForApps/res/menu/menu_main.xml
new file mode 100644
index 0000000..ebb08b6
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/menu/menu_main.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
+    <item android:id="@+id/action_add_file" android:title="@string/action_add_file"
+        android:orderInCategory="100" android:showAsAction="ifRoom" />
+    <item android:id="@+id/action_settings" android:title="@string/action_settings"
+        android:orderInCategory="100" android:showAsAction="never" />
+</menu>
diff --git a/samples/browseable/AutoBackupForApps/res/mipmap-hdpi/ic_launcher.png b/samples/browseable/AutoBackupForApps/res/mipmap-hdpi/ic_launcher.png
new file mode 100755
index 0000000..91153b2
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/AutoBackupForApps/res/mipmap-mdpi/ic_launcher.png b/samples/browseable/AutoBackupForApps/res/mipmap-mdpi/ic_launcher.png
new file mode 100755
index 0000000..9a44bc4
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/AutoBackupForApps/res/mipmap-xhdpi/ic_launcher.png b/samples/browseable/AutoBackupForApps/res/mipmap-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..0e1fb39
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/AutoBackupForApps/res/mipmap-xxhdpi/ic_launcher.png b/samples/browseable/AutoBackupForApps/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100755
index 0000000..e8ae88d
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/AutoBackupForApps/res/mipmap-xxxhdpi/ic_launcher.png b/samples/browseable/AutoBackupForApps/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100755
index 0000000..497fde1
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/values/dimens.xml b/samples/browseable/AutoBackupForApps/res/values-sw600dp/template-dimens.xml
similarity index 71%
copy from samples/ActionBarCompat/res/values/dimens.xml
copy to samples/browseable/AutoBackupForApps/res/values-sw600dp/template-dimens.xml
index 67c8436..22074a2 100644
--- a/samples/ActionBarCompat/res/values/dimens.xml
+++ b/samples/browseable/AutoBackupForApps/res/values-sw600dp/template-dimens.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -15,7 +15,10 @@
   -->
 
 <resources>
-    <dimen name="actionbar_compat_height">48dp</dimen>
-    <dimen name="actionbar_compat_button_width">48dp</dimen>
-    <dimen name="actionbar_compat_button_home_width">56dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
 </resources>
diff --git a/samples/ActionBarCompat/res/values-v13/styles.xml b/samples/browseable/AutoBackupForApps/res/values-sw600dp/template-styles.xml
similarity index 67%
copy from samples/ActionBarCompat/res/values-v13/styles.xml
copy to samples/browseable/AutoBackupForApps/res/values-sw600dp/template-styles.xml
index 8a042b4..03d1974 100644
--- a/samples/ActionBarCompat/res/values-v13/styles.xml
+++ b/samples/browseable/AutoBackupForApps/res/values-sw600dp/template-styles.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -16,8 +16,10 @@
 
 <resources>
 
-    <style name="ActionBarTitle" parent="android:style/TextAppearance.Holo.Widget.ActionBar.Title">
-        <item name="android:textColor">@color/actionbar_title_color</item>
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceLarge</item>
+        <item name="android:lineSpacingMultiplier">1.2</item>
+        <item name="android:shadowDy">-6.5</item>
     </style>
 
 </resources>
diff --git a/samples/ActionBarCompat/res/values/colors.xml b/samples/browseable/AutoBackupForApps/res/values-v11/template-styles.xml
similarity index 79%
copy from samples/ActionBarCompat/res/values/colors.xml
copy to samples/browseable/AutoBackupForApps/res/values-v11/template-styles.xml
index 4edc6d6..8c1ea66 100644
--- a/samples/ActionBarCompat/res/values/colors.xml
+++ b/samples/browseable/AutoBackupForApps/res/values-v11/template-styles.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -15,5 +15,8 @@
   -->
 
 <resources>
-    <color name="actionbar_title_color">#224894</color>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
 </resources>
diff --git a/samples/browseable/AutoBackupForApps/res/values-v21/base-colors.xml b/samples/browseable/AutoBackupForApps/res/values-v21/base-colors.xml
new file mode 100644
index 0000000..8b6ec3f
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/values-v21/base-colors.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+
+</resources>
diff --git a/samples/browseable/AutoBackupForApps/res/values-v21/base-template-styles.xml b/samples/browseable/AutoBackupForApps/res/values-v21/base-template-styles.xml
new file mode 100644
index 0000000..c778e4f
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/values-v21/base-template-styles.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Material.Light">
+    </style>
+
+</resources>
diff --git a/samples/browseable/AutoBackupForApps/res/values-w820dp/dimens.xml b/samples/browseable/AutoBackupForApps/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..82d3fbe
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/values-w820dp/dimens.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<resources>
+    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
+         (such as screen margins) for screens with more than 820dp of available width. This
+         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
+    <dimen name="activity_horizontal_margin">64dp</dimen>
+</resources>
diff --git a/samples/browseable/AutoBackupForApps/res/values/base-strings.xml b/samples/browseable/AutoBackupForApps/res/values/base-strings.xml
new file mode 100644
index 0000000..a6cef5e
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/values/base-strings.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+    <string name="app_name">Automatic Backup</string>
+    <string name="intro_message">
+        <![CDATA[
+        
+            
+This sample demonstrates how to selectively disable Automatic Backups in Android M, either by
+adjusting the location where data files are stored using getNoBackupFilesDir(), or by using a custom
+XML configuration file.
+
+This sample can also be used as a utility to test the behavior of the Automatic Backup feature.
+Executing "adb shell bmgr restore com.example.android.autobackup" from a terminal will cause the
+sample\'s data to be cleared and replaced with a copy from the backup server.
+            
+        
+        ]]>
+    </string>
+</resources>
diff --git a/samples/browseable/AutoBackupForApps/res/values/dimens.xml b/samples/browseable/AutoBackupForApps/res/values/dimens.xml
new file mode 100644
index 0000000..7d5dcce
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/values/dimens.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<resources>
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
diff --git a/samples/browseable/AutoBackupForApps/res/values/strings.xml b/samples/browseable/AutoBackupForApps/res/values/strings.xml
new file mode 100644
index 0000000..30512e8
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/values/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<resources>
+    <string name="action_add_file">Add File</string>
+    <string name="action_settings">Settings</string>
+    <string name="list_of_files">App Data:</string>
+    <string name="file_exists">Please specify a different name. A file with this name exists already.</string>
+    <string name="no_files_click_add_files_menu">Please click on Add File menu in order to create test files.</string>
+    <string name="file_size_is_invalid">Please specify a correct file size.</string>
+    <string name="external_storage_unavailable">The External storage is not available.</string>
+    <string-array name="file_size_array">
+        <item>Bytes</item>
+        <item>Kilobytes</item>
+        <item>Megabytes</item>
+    </string-array>
+    <string-array name="file_storage_array">
+        <item>Internal</item>
+        <item>External</item>
+        <item>Do not Backup</item>
+    </string-array>
+</resources>
diff --git a/samples/browseable/AutoBackupForApps/res/values/template-dimens.xml b/samples/browseable/AutoBackupForApps/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+  Copyright 2013 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.
+  -->
+
+<resources>
+
+    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+    <dimen name="margin_tiny">4dp</dimen>
+    <dimen name="margin_small">8dp</dimen>
+    <dimen name="margin_medium">16dp</dimen>
+    <dimen name="margin_large">32dp</dimen>
+    <dimen name="margin_huge">64dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/samples/browseable/AutoBackupForApps/res/values/template-styles.xml b/samples/browseable/AutoBackupForApps/res/values/template-styles.xml
new file mode 100644
index 0000000..6e7d593
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+  Copyright 2013 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.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+
+    <style name="Theme.Base" parent="android:Theme.Light" />
+
+    <style name="Theme.Sample" parent="Theme.Base" />
+
+    <style name="AppTheme" parent="Theme.Sample" />
+    <!-- Widget styling -->
+
+    <style name="Widget" />
+
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceMedium</item>
+        <item name="android:lineSpacingMultiplier">1.1</item>
+    </style>
+
+    <style name="Widget.SampleMessageTile">
+        <item name="android:background">@drawable/tile</item>
+        <item name="android:shadowColor">#7F000000</item>
+        <item name="android:shadowDy">-3.5</item>
+        <item name="android:shadowRadius">2</item>
+    </style>
+
+</resources>
diff --git a/samples/browseable/AutoBackupForApps/res/xml/backup.xml b/samples/browseable/AutoBackupForApps/res/xml/backup.xml
new file mode 100644
index 0000000..334cfa2
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/res/xml/backup.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<full-backup-content xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- This file is referenced from android:fullBackupContent in AndroidManifest.xml, and controls
+         exclusions/inclusions for the default backup policy. -->
+
+    <!-- Shared preferences files can be excluded using the "sharedpref" domain. -->
+    <!-- Be sure to exclude any device-specific identifiers, such as the GCM registration key. -->
+    <!-- You may also wish to exclude directories that contain device-specific session tokens or
+         sensitive user credentials. -->
+    <exclude domain="sharedpref" path="gcm"/>
+    <exclude domain="sharedpref" path="user_credentials"/>
+
+    <!-- Databases can be excluded using the "database" domain. -->
+    <exclude domain="database" path="local_secrets.db"/>
+
+    <!-- Additional domains include "file", "external", "root", and "path". See
+         http://developer.android.com/preview/backup/index.html for more details.
+
+         Additionally, content in the cache directory, external storage, and the no_backup directory
+         (see android.content.Context#getNoBackupFilesDir()) are excluded by default. If you need
+         to backup data in one of these locations, use the <include> directive. -->
+
+</full-backup-content>
\ No newline at end of file
diff --git a/samples/browseable/AutoBackupForApps/src/com.example.android.autobackupsample/AddFileActivity.java b/samples/browseable/AutoBackupForApps/src/com.example.android.autobackupsample/AddFileActivity.java
new file mode 100644
index 0000000..00cd1e3
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/src/com.example.android.autobackupsample/AddFileActivity.java
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2015 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.autobackupsample;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.Toast;
+
+import com.example.android.autobackupsample.MainActivityFragment;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+
+/**
+ * The purpose of AddFileActivity activity is to create a data file based on the
+ * file name and size parameters specified as an Intent external parameters or with the
+ * activity UI.
+ * <p/>
+ * The optional intent parameters are
+ * {@link com.example.android.autobackupsample.AddFileActivity#FILE_NAME} and
+ * {@link com.example.android.autobackupsample.AddFileActivity#FILE_SIZE_IN_BYTES}.
+ * {@link com.example.android.autobackupsample.AddFileActivity#FILE_STORAGE}.
+ * <p/>
+ * The activity will return an
+ * {@link com.example.android.autobackupsample.MainActivityFragment#ADD_FILE_RESULT_ERROR}
+ * if intent parameters are specified incorrectly or it will display Toast messages to the user
+ * if those parameters are specified via the activity UI.
+ */
+public class AddFileActivity extends Activity {
+
+    private static final String TAG = "AutoBackupSample";
+
+    /**
+     * The intent parameter that specifies a file name. The file name must be unique for the
+     * application internal directory.
+     */
+    public static final String FILE_NAME = "file_name";
+
+    /**
+     * The intent parameter that specifies a file size in bytes. The size must be a number
+     * larger or equal to 0.
+     */
+    public static final String FILE_SIZE_IN_BYTES = "file_size_in_bytes";
+
+    /**
+     * The file storage is an optional parameter. It should be one of these:
+     * "INTERNAL", "EXTERNAL", "DONOTBACKUP". The default option is "INTERNAL".
+     */
+    public static final String FILE_STORAGE = "file_storage";
+
+    /**
+     * A file size multiplier. It is used to calculate the total number of bytes to be added
+     * to the file.
+     */
+    private int mSizeMultiplier = 1;
+
+    /**
+     * Defines File Storage options.
+     */
+    private static enum FileStorage {
+        INTERNAL,
+        EXTERNAL,
+        DONOTBACKUP;
+    }
+
+    /**
+     * Contains a selected by a user file storage option.
+     */
+    private FileStorage mFileStorage = FileStorage.INTERNAL;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.add_file);
+        initFileSizeSpinner();
+        initFileStorageSpinner();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        // If an intent has extra parameters, create the file and finish the activity.
+        if (getIntent().hasExtra(FILE_NAME) && getIntent().hasExtra(FILE_SIZE_IN_BYTES)) {
+            String fileName = getIntent().getStringExtra(FILE_NAME);
+            String sizeInBytesParamValue = getIntent().getStringExtra(FILE_SIZE_IN_BYTES);
+            String fileStorageParamValue = FileStorage.INTERNAL.toString();
+
+            if (getIntent().hasExtra(FILE_STORAGE)) {
+                fileStorageParamValue = getIntent().getStringExtra(FILE_STORAGE);
+            }
+
+            if (TextUtils.isEmpty(fileName) ||
+                    isFileExists(fileName) ||
+                    !isSizeValid(sizeInBytesParamValue) ||
+                    !isFileStorageParamValid(fileStorageParamValue)) {
+                setResult(MainActivityFragment.ADD_FILE_RESULT_ERROR);
+                finish();
+                return;
+            }
+
+            mFileStorage = FileStorage.valueOf(fileStorageParamValue);
+
+            if (mFileStorage == FileStorage.EXTERNAL && !Utils.isExternalStorageAvailable()) {
+                setResult(MainActivityFragment.ADD_FILE_RESULT_ERROR);
+                finish();
+                return;
+            }
+
+            createFileWithRandomDataAndFinishActivity(fileName, mFileStorage,
+                    sizeInBytesParamValue);
+        }
+    }
+
+    /**
+     * A handler function for a Create File button click event.
+     *
+     * @param view a reference to the Create File button view.
+     */
+    public void onCreateFileButtonClick(View view) {
+        EditText fileNameEditText = (EditText) findViewById(R.id.file_name);
+        EditText fileSizeEditText = (EditText) findViewById(R.id.file_size);
+        String fileName = fileNameEditText.getText().toString();
+        String fileSizeEditTextValue = fileSizeEditText.getText().toString();
+
+        if (TextUtils.isEmpty(fileName) || isFileExists(fileName)) {
+            Toast toast = Toast.makeText(this, getText(R.string.file_exists), Toast.LENGTH_LONG);
+            toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
+            toast.show();
+            return;
+        }
+
+        if (!isSizeValid(fileSizeEditTextValue)) {
+            Toast toast = Toast.makeText(this, getText(R.string.file_size_is_invalid),
+                    Toast.LENGTH_LONG);
+            toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
+            toast.show();
+            return;
+        }
+
+        long fileSize = Integer.valueOf(fileSizeEditTextValue) * mSizeMultiplier;
+
+        if (mFileStorage == FileStorage.EXTERNAL && !Utils.isExternalStorageAvailable()) {
+            Toast toast = Toast.makeText(this,
+                    getText(R.string.external_storage_unavailable), Toast.LENGTH_LONG);
+            toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
+            toast.show();
+            return;
+        }
+
+        createFileWithRandomDataAndFinishActivity(fileName, mFileStorage, String.valueOf(fileSize));
+    }
+
+    private void initFileSizeSpinner() {
+        Spinner spinner = (Spinner) findViewById(R.id.file_size_spinner);
+        final ArrayAdapter<CharSequence> adapter =
+                ArrayAdapter.createFromResource(this, R.array.file_size_array,
+                        android.R.layout.simple_spinner_item);
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        spinner.setAdapter(adapter);
+        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+                String sizeMeasure = adapter.getItem(position).toString();
+                mSizeMultiplier = (int) Math.pow(1024, position);
+                if (Log.isLoggable(TAG, Log.DEBUG)) {
+                    Log.d(TAG, String.format("Selected: %s, %d", sizeMeasure,
+                            mSizeMultiplier));
+                }
+            }
+
+            @Override
+            public void onNothingSelected(AdapterView<?> parent) {
+
+            }
+        });
+    }
+
+    private void initFileStorageSpinner() {
+        Spinner spinner = (Spinner) findViewById(R.id.storage_spinner);
+        final ArrayAdapter<CharSequence> adapter =
+                ArrayAdapter.createFromResource(this, R.array.file_storage_array,
+                        android.R.layout.simple_spinner_item);
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        spinner.setAdapter(adapter);
+        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+                mFileStorage = FileStorage.values()[position];
+            }
+
+            @Override
+            public void onNothingSelected(AdapterView<?> parent) {
+
+            }
+        });
+    }
+
+    private void createFileWithRandomDataAndFinishActivity(String fileName, FileStorage storage,
+                                                           String sizeInBytes) {
+        long size = Long.valueOf(sizeInBytes);
+        File file = null;
+        FileOutputStream out = null;
+        BufferedOutputStream bufOut = null;
+        try {
+            switch (storage) {
+                case INTERNAL:
+                    file = getInternalFile(fileName);
+                    out = openFileOutput(file.getName(), Context.MODE_PRIVATE);
+                    break;
+                case EXTERNAL:
+                    assert Utils.isExternalStorageAvailable() :
+                            "The external storage is not available";
+                    File externalAppDir = getExternalFilesDir(null);
+                    file = new File(externalAppDir, fileName);
+                    out = new FileOutputStream(file);
+                    break;
+                case DONOTBACKUP:
+                    file = new File(getNoBackupFilesDir(), fileName);
+                    out = new FileOutputStream(file);
+                    break;
+            }
+
+            if (file == null || out == null) {
+                Log.d(TAG, "Unable to create file output stream");
+                // Returning back to the caller activity.
+                setResult(MainActivityFragment.ADD_FILE_RESULT_ERROR);
+                finish();
+                return;
+            }
+
+            bufOut = new BufferedOutputStream(out);
+            for (int i = 0; i < size; i++) {
+                byte b = (byte) (255 * Math.random());
+                bufOut.write(b);
+            }
+
+            String message = String.format("File created: %s, size: %s bytes",
+                    file.getAbsolutePath(), sizeInBytes);
+
+            Toast toast = Toast.makeText(this, message, Toast.LENGTH_LONG);
+            toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
+            toast.show();
+            Log.d(TAG, message);
+
+            // Returning back to the caller activity.
+            setResult(MainActivityFragment.ADD_FILE_RESULT_SUCCESS);
+            finish();
+        } catch (Exception e) {
+            Log.e(TAG, e.getMessage(), e);
+            // Returning back to the caller activity.
+            setResult(MainActivityFragment.ADD_FILE_RESULT_ERROR);
+            finish();
+        } finally {
+            if (bufOut != null) {
+                try {
+                    bufOut.close();
+                } catch (Exception e) {
+                    // Ignore.
+                }
+            }
+        }
+    }
+
+    private boolean isFileExists(String fileName) {
+        File file = getInternalFile(fileName);
+        if (file.exists()) {
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "This file exists: " + file.getName());
+            }
+            return true;
+        }
+        return false;
+    }
+
+    private boolean isSizeValid(String sizeInBytesParamValue) {
+        long sizeInBytes = 0;
+        try {
+            sizeInBytes = Long.valueOf(sizeInBytesParamValue);
+        } catch (NumberFormatException e) {
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "Invalid file size: " + sizeInBytesParamValue);
+            }
+            return false;
+        }
+
+        // Validate file size value. It should be 0 or a positive number.
+        if (sizeInBytes < 0) {
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "Invalid file size: " + sizeInBytes);
+            }
+            return false;
+        }
+        return true;
+    }
+
+    private boolean isFileStorageParamValid(String fileStorage) {
+        try {
+            mFileStorage = FileStorage.valueOf(fileStorage);
+        } catch (IllegalArgumentException e) {
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "Invalid file storage: " + fileStorage);
+            }
+            return false;
+        }
+        return true;
+    }
+
+    private File getInternalFile(String fileName) {
+        File internalAppDir = getFilesDir();
+        return new File(internalAppDir, fileName);
+    }
+
+}
\ No newline at end of file
diff --git a/samples/browseable/AutoBackupForApps/src/com.example.android.autobackupsample/MainActivity.java b/samples/browseable/AutoBackupForApps/src/com.example.android.autobackupsample/MainActivity.java
new file mode 100644
index 0000000..b5af289
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/src/com.example.android.autobackupsample/MainActivity.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2015 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.autobackupsample;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+
+
+public class MainActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+    }
+}
diff --git a/samples/browseable/AutoBackupForApps/src/com.example.android.autobackupsample/MainActivityFragment.java b/samples/browseable/AutoBackupForApps/src/com.example.android.autobackupsample/MainActivityFragment.java
new file mode 100644
index 0000000..c07f6b8
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/src/com.example.android.autobackupsample/MainActivityFragment.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2015 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.autobackupsample;
+
+import android.app.Fragment;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Environment;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.io.File;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+
+
+/**
+ * A placeholder fragment containing a simple view.
+ */
+public class MainActivityFragment extends Fragment {
+
+    private static final String TAG = "AutoBackupSample";
+    public static final int ADD_FILE_REQUEST = 1;
+    public static final int ADD_FILE_RESULT_SUCCESS = 101;
+    public static final int ADD_FILE_RESULT_ERROR = 102;
+
+    private ArrayAdapter<File> mFilesArrayAdapter;
+    private ArrayList<File> mFiles;
+
+    public MainActivityFragment() {
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        setHasOptionsMenu(true);
+        return inflater.inflate(R.layout.fragment_main, container, false);
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+
+        if (requestCode == ADD_FILE_REQUEST && resultCode == ADD_FILE_RESULT_SUCCESS) {
+            updateListOfFiles();
+        }
+    }
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        // Inflate the menu; this adds items to the action bar if it is present.
+        inflater.inflate(R.menu.menu_main, menu);
+        super.onCreateOptionsMenu(menu, inflater);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        // Handle action bar item clicks here. The action bar will
+        // automatically handle clicks on the Home/Up button, so long
+        // as you specify a parent activity in AndroidManifest.xml.
+        int id = item.getItemId();
+
+        //noinspection SimplifiableIfStatement
+        if (id == R.id.action_settings) {
+            return true;
+        } else if (id == R.id.action_add_file) {
+            Intent addFileIntent = new Intent(getActivity(), AddFileActivity.class);
+            startActivityForResult(addFileIntent, ADD_FILE_REQUEST);
+            return true;
+        }
+
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        if (mFilesArrayAdapter == null) {
+            mFiles = createListOfFiles();
+            mFilesArrayAdapter = new ArrayAdapter<File>(getActivity(),
+                    R.layout.file_list_item, mFiles) {
+
+                @Override
+                public View getView(int position, View convertView, ViewGroup parent) {
+                    LayoutInflater inflater = LayoutInflater.from(getContext());
+                    View itemView = inflater.inflate(R.layout.file_list_item, parent, false);
+                    TextView fileNameView = (TextView) itemView.findViewById(R.id.file_name);
+                    String fileName = getItem(position).getAbsolutePath();
+                    fileNameView.setText(fileName);
+                    TextView fileSize = (TextView) itemView.findViewById(R.id.file_size);
+                    String fileSizeInBytes = NumberFormat.getInstance()
+                            .format(getItem(position).length());
+                    fileSize.setText(fileSizeInBytes);
+                    return itemView;
+                }
+            };
+            updateListOfFiles();
+            ListView filesListView = (ListView) getView().findViewById(R.id.file_list);
+            filesListView.setAdapter(mFilesArrayAdapter);
+        }
+    }
+
+    private ArrayList<File> createListOfFiles() {
+        ArrayList<File> listOfFiles = new ArrayList<File>();
+        addFilesToList(listOfFiles, getActivity().getFilesDir());
+        if (Utils.isExternalStorageAvailable()) {
+            addFilesToList(listOfFiles, getActivity().getExternalFilesDir(null));
+        }
+        addFilesToList(listOfFiles, getActivity().getNoBackupFilesDir());
+        return listOfFiles;
+    }
+
+    private void addFilesToList(ArrayList<File> listOfFiles, File dir) {
+        File[] files = dir.listFiles();
+        for (File file: files) {
+            listOfFiles.add(file);
+        }
+    }
+
+    public void updateListOfFiles() {
+        TextView emptyFileListMessage =
+                (TextView) getView().findViewById(R.id.empty_file_list_message);
+        mFiles = createListOfFiles();
+        if (mFilesArrayAdapter.getCount() > 0) {
+            mFilesArrayAdapter.clear();
+        }
+        for (File file: mFiles) {
+            mFilesArrayAdapter.add(file);
+        }
+        // Display a message instructing to add files if no files found.
+        if (mFiles.size() == 0) {
+            emptyFileListMessage.setVisibility(View.VISIBLE);
+        } else {
+            emptyFileListMessage.setVisibility(View.GONE);
+        }
+    }
+}
+
diff --git a/samples/browseable/AutoBackupForApps/src/com.example.android.autobackupsample/Utils.java b/samples/browseable/AutoBackupForApps/src/com.example.android.autobackupsample/Utils.java
new file mode 100644
index 0000000..b9a9833
--- /dev/null
+++ b/samples/browseable/AutoBackupForApps/src/com.example.android.autobackupsample/Utils.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 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.autobackupsample;
+
+import android.os.Environment;
+import android.util.Log;
+
+/**
+ * Utility methods for the app.
+ */
+public class Utils {
+
+    private static final String TAG = "AutoBackupSample";
+
+    public static boolean isExternalStorageAvailable() {
+        String state = Environment.getExternalStorageState();
+        if (!Environment.MEDIA_MOUNTED.equals(state)) {
+            Log.d(TAG, "The external storage is not available.");
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/samples/browseable/Camera2Raw/AndroidManifest.xml b/samples/browseable/Camera2Raw/AndroidManifest.xml
new file mode 100644
index 0000000..f948c6a
--- /dev/null
+++ b/samples/browseable/Camera2Raw/AndroidManifest.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2015 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.camera2raw"
+    android:versionCode="1"
+    android:versionName="1.0">
+
+    <!-- Min/target SDK versions (<uses-sdk>) managed by build.gradle -->
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+
+    <!-- A camera with RAW capability is required to use this application -->
+    <uses-feature android:name="android.hardware.camera" />
+    <uses-feature android:name="android.hardware.camera.raw" />
+
+    <application android:allowBackup="true"
+        android:label="@string/app_name"
+        android:icon="@drawable/ic_launcher"
+        android:theme="@style/MaterialTheme">
+
+        <activity android:name="com.example.android.camera2raw.CameraActivity"
+                  android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
diff --git a/samples/browseable/Camera2Raw/_index.jd b/samples/browseable/Camera2Raw/_index.jd
new file mode 100644
index 0000000..0ef2ae2
--- /dev/null
+++ b/samples/browseable/Camera2Raw/_index.jd
@@ -0,0 +1,11 @@
+
+page.tags="Camera2Raw"
+sample.group=Media
+@jd:body
+
+<p>
+            
+            This sample demonstrates how to use the Camera2 API to capture RAW
+            camera buffers and save them as DNG files.
+            
+        </p>
diff --git a/samples/browseable/Camera2Raw/res/drawable-hdpi/ic_action_info.png b/samples/browseable/Camera2Raw/res/drawable-hdpi/ic_action_info.png
new file mode 100644
index 0000000..32bd1aa
--- /dev/null
+++ b/samples/browseable/Camera2Raw/res/drawable-hdpi/ic_action_info.png
Binary files differ
diff --git a/samples/browseable/Camera2Raw/res/drawable-hdpi/ic_launcher.png b/samples/browseable/Camera2Raw/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..bba1165
--- /dev/null
+++ b/samples/browseable/Camera2Raw/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/Camera2Raw/res/drawable-hdpi/tile.9.png b/samples/browseable/Camera2Raw/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/samples/browseable/Camera2Raw/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/samples/browseable/Camera2Raw/res/drawable-mdpi/ic_action_info.png b/samples/browseable/Camera2Raw/res/drawable-mdpi/ic_action_info.png
new file mode 100644
index 0000000..8efbbf8
--- /dev/null
+++ b/samples/browseable/Camera2Raw/res/drawable-mdpi/ic_action_info.png
Binary files differ
diff --git a/samples/browseable/Camera2Raw/res/drawable-mdpi/ic_launcher.png b/samples/browseable/Camera2Raw/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..4304591
--- /dev/null
+++ b/samples/browseable/Camera2Raw/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/Camera2Raw/res/drawable-xhdpi/ic_action_info.png b/samples/browseable/Camera2Raw/res/drawable-xhdpi/ic_action_info.png
new file mode 100644
index 0000000..ba143ea
--- /dev/null
+++ b/samples/browseable/Camera2Raw/res/drawable-xhdpi/ic_action_info.png
Binary files differ
diff --git a/samples/browseable/Camera2Raw/res/drawable-xhdpi/ic_launcher.png b/samples/browseable/Camera2Raw/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..80c5eba
--- /dev/null
+++ b/samples/browseable/Camera2Raw/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/Camera2Raw/res/drawable-xxhdpi/ic_action_info.png b/samples/browseable/Camera2Raw/res/drawable-xxhdpi/ic_action_info.png
new file mode 100644
index 0000000..394eb7e
--- /dev/null
+++ b/samples/browseable/Camera2Raw/res/drawable-xxhdpi/ic_action_info.png
Binary files differ
diff --git a/samples/browseable/Camera2Raw/res/drawable-xxhdpi/ic_launcher.png b/samples/browseable/Camera2Raw/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..9baac9b
--- /dev/null
+++ b/samples/browseable/Camera2Raw/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/Camera2Raw/res/layout-land/fragment_camera2_basic.xml b/samples/browseable/Camera2Raw/res/layout-land/fragment_camera2_basic.xml
new file mode 100644
index 0000000..3eb68db
--- /dev/null
+++ b/samples/browseable/Camera2Raw/res/layout-land/fragment_camera2_basic.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ Copyright 2015 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <com.example.android.camera2raw.AutoFitTextureView
+        android:id="@+id/texture"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentStart="true"
+        android:layout_alignParentTop="true" />
+
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentEnd="true"
+        android:layout_alignParentTop="true"
+        android:layout_below="@id/texture"
+        android:layout_toRightOf="@id/texture"
+        android:background="#4285f4"
+        android:orientation="horizontal">
+
+        <Button
+            android:id="@+id/picture"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:text="@string/picture" />
+
+        <ImageButton
+            android:id="@+id/info"
+            style="@android:style/Widget.Material.Light.Button.Borderless"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal|bottom"
+            android:contentDescription="@string/description_info"
+            android:padding="20dp"
+            android:src="@drawable/ic_action_info" />
+
+
+    </FrameLayout>
+
+</RelativeLayout>
diff --git a/samples/browseable/Camera2Raw/res/layout/activity_camera.xml b/samples/browseable/Camera2Raw/res/layout/activity_camera.xml
new file mode 100644
index 0000000..b6db9a1
--- /dev/null
+++ b/samples/browseable/Camera2Raw/res/layout/activity_camera.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ Copyright 2015 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.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#000"
+    tools:context="com.example.android.camera2raw.CameraActivity" />
diff --git a/samples/browseable/Camera2Raw/res/layout/fragment_camera2_basic.xml b/samples/browseable/Camera2Raw/res/layout/fragment_camera2_basic.xml
new file mode 100644
index 0000000..e8ed001
--- /dev/null
+++ b/samples/browseable/Camera2Raw/res/layout/fragment_camera2_basic.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ Copyright 2015 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <com.example.android.camera2raw.AutoFitTextureView
+        android:id="@+id/texture"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentStart="true"
+        android:layout_alignParentTop="true" />
+
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentStart="true"
+        android:layout_below="@id/texture"
+        android:background="#4285f4">
+
+        <Button
+            android:id="@+id/picture"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:text="@string/picture" />
+
+        <ImageButton
+            android:id="@+id/info"
+            android:contentDescription="@string/description_info"
+            style="@android:style/Widget.Material.Light.Button.Borderless"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical|right"
+            android:padding="20dp"
+            android:src="@drawable/ic_action_info" />
+
+    </FrameLayout>
+
+</RelativeLayout>
diff --git a/samples/ActionBarCompat/res/values/dimens.xml b/samples/browseable/Camera2Raw/res/values-sw600dp/template-dimens.xml
similarity index 71%
copy from samples/ActionBarCompat/res/values/dimens.xml
copy to samples/browseable/Camera2Raw/res/values-sw600dp/template-dimens.xml
index 67c8436..22074a2 100644
--- a/samples/ActionBarCompat/res/values/dimens.xml
+++ b/samples/browseable/Camera2Raw/res/values-sw600dp/template-dimens.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -15,7 +15,10 @@
   -->
 
 <resources>
-    <dimen name="actionbar_compat_height">48dp</dimen>
-    <dimen name="actionbar_compat_button_width">48dp</dimen>
-    <dimen name="actionbar_compat_button_home_width">56dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
 </resources>
diff --git a/samples/ActionBarCompat/res/values-v13/styles.xml b/samples/browseable/Camera2Raw/res/values-sw600dp/template-styles.xml
similarity index 67%
copy from samples/ActionBarCompat/res/values-v13/styles.xml
copy to samples/browseable/Camera2Raw/res/values-sw600dp/template-styles.xml
index 8a042b4..03d1974 100644
--- a/samples/ActionBarCompat/res/values-v13/styles.xml
+++ b/samples/browseable/Camera2Raw/res/values-sw600dp/template-styles.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -16,8 +16,10 @@
 
 <resources>
 
-    <style name="ActionBarTitle" parent="android:style/TextAppearance.Holo.Widget.ActionBar.Title">
-        <item name="android:textColor">@color/actionbar_title_color</item>
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceLarge</item>
+        <item name="android:lineSpacingMultiplier">1.2</item>
+        <item name="android:shadowDy">-6.5</item>
     </style>
 
 </resources>
diff --git a/samples/ActionBarCompat/res/values/colors.xml b/samples/browseable/Camera2Raw/res/values-v11/template-styles.xml
similarity index 79%
copy from samples/ActionBarCompat/res/values/colors.xml
copy to samples/browseable/Camera2Raw/res/values-v11/template-styles.xml
index 4edc6d6..8c1ea66 100644
--- a/samples/ActionBarCompat/res/values/colors.xml
+++ b/samples/browseable/Camera2Raw/res/values-v11/template-styles.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -15,5 +15,8 @@
   -->
 
 <resources>
-    <color name="actionbar_title_color">#224894</color>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
 </resources>
diff --git a/samples/browseable/Camera2Raw/res/values-v21/base-colors.xml b/samples/browseable/Camera2Raw/res/values-v21/base-colors.xml
new file mode 100644
index 0000000..8b6ec3f
--- /dev/null
+++ b/samples/browseable/Camera2Raw/res/values-v21/base-colors.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+
+</resources>
diff --git a/samples/browseable/Camera2Raw/res/values-v21/base-template-styles.xml b/samples/browseable/Camera2Raw/res/values-v21/base-template-styles.xml
new file mode 100644
index 0000000..c778e4f
--- /dev/null
+++ b/samples/browseable/Camera2Raw/res/values-v21/base-template-styles.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Material.Light">
+    </style>
+
+</resources>
diff --git a/samples/browseable/Camera2Raw/res/values/base-strings.xml b/samples/browseable/Camera2Raw/res/values/base-strings.xml
new file mode 100644
index 0000000..c3f8c21
--- /dev/null
+++ b/samples/browseable/Camera2Raw/res/values/base-strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+    <string name="app_name">Camera2Raw</string>
+    <string name="intro_message">
+        <![CDATA[
+        
+            
+            This sample demonstrates how to use the Camera2 API to capture RAW
+            camera buffers and save them as DNG files.
+            
+        
+        ]]>
+    </string>
+</resources>
diff --git a/samples/browseable/Camera2Raw/res/values/strings.xml b/samples/browseable/Camera2Raw/res/values/strings.xml
new file mode 100644
index 0000000..0f56ce9
--- /dev/null
+++ b/samples/browseable/Camera2Raw/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ Copyright 2015 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.
+-->
+<resources>
+    <string name="picture">Picture</string>
+    <string name="description_info">Info</string>
+</resources>
diff --git a/samples/browseable/Camera2Raw/res/values/styles.xml b/samples/browseable/Camera2Raw/res/values/styles.xml
new file mode 100644
index 0000000..34d16bd
--- /dev/null
+++ b/samples/browseable/Camera2Raw/res/values/styles.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ Copyright 2015 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.
+-->
+<resources>
+    <style name="MaterialTheme" parent="android:Theme.Material.Light.NoActionBar.Fullscreen" />
+</resources>
diff --git a/samples/browseable/Camera2Raw/res/values/template-dimens.xml b/samples/browseable/Camera2Raw/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/samples/browseable/Camera2Raw/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+  Copyright 2013 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.
+  -->
+
+<resources>
+
+    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+    <dimen name="margin_tiny">4dp</dimen>
+    <dimen name="margin_small">8dp</dimen>
+    <dimen name="margin_medium">16dp</dimen>
+    <dimen name="margin_large">32dp</dimen>
+    <dimen name="margin_huge">64dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/samples/browseable/Camera2Raw/res/values/template-styles.xml b/samples/browseable/Camera2Raw/res/values/template-styles.xml
new file mode 100644
index 0000000..6e7d593
--- /dev/null
+++ b/samples/browseable/Camera2Raw/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+  Copyright 2013 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.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+
+    <style name="Theme.Base" parent="android:Theme.Light" />
+
+    <style name="Theme.Sample" parent="Theme.Base" />
+
+    <style name="AppTheme" parent="Theme.Sample" />
+    <!-- Widget styling -->
+
+    <style name="Widget" />
+
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceMedium</item>
+        <item name="android:lineSpacingMultiplier">1.1</item>
+    </style>
+
+    <style name="Widget.SampleMessageTile">
+        <item name="android:background">@drawable/tile</item>
+        <item name="android:shadowColor">#7F000000</item>
+        <item name="android:shadowDy">-3.5</item>
+        <item name="android:shadowRadius">2</item>
+    </style>
+
+</resources>
diff --git a/samples/browseable/Camera2Raw/src/com.example.android.camera2raw/AutoFitTextureView.java b/samples/browseable/Camera2Raw/src/com.example.android.camera2raw/AutoFitTextureView.java
new file mode 100644
index 0000000..e02e8b8
--- /dev/null
+++ b/samples/browseable/Camera2Raw/src/com.example.android.camera2raw/AutoFitTextureView.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2015 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.camera2raw;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.TextureView;
+
+/**
+ * A {@link TextureView} that can be adjusted to a specified aspect ratio.
+ */
+public class AutoFitTextureView extends TextureView {
+
+    private int mRatioWidth = 0;
+    private int mRatioHeight = 0;
+
+    public AutoFitTextureView(Context context) {
+        this(context, null);
+    }
+
+    public AutoFitTextureView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public AutoFitTextureView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    /**
+     * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio
+     * calculated from the parameters. Note that the actual sizes of parameters don't matter, that
+     * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.
+     *
+     * @param width  Relative horizontal size
+     * @param height Relative vertical size
+     */
+    public void setAspectRatio(int width, int height) {
+        if (width < 0 || height < 0) {
+            throw new IllegalArgumentException("Size cannot be negative.");
+        }
+        if (mRatioWidth == width && mRatioHeight == height) {
+            return;
+        }
+        mRatioWidth = width;
+        mRatioHeight = height;
+        requestLayout();
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        int width = MeasureSpec.getSize(widthMeasureSpec);
+        int height = MeasureSpec.getSize(heightMeasureSpec);
+        if (0 == mRatioWidth || 0 == mRatioHeight) {
+            setMeasuredDimension(width, height);
+        } else {
+            if (width < height * mRatioWidth / mRatioHeight) {
+                setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
+            } else {
+                setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
+            }
+        }
+    }
+
+}
diff --git a/samples/browseable/Camera2Raw/src/com.example.android.camera2raw/Camera2RawFragment.java b/samples/browseable/Camera2Raw/src/com.example.android.camera2raw/Camera2RawFragment.java
new file mode 100644
index 0000000..6460bf3
--- /dev/null
+++ b/samples/browseable/Camera2Raw/src/com.example.android.camera2raw/Camera2RawFragment.java
@@ -0,0 +1,1674 @@
+/*
+ * Copyright 2015 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.camera2raw;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.Fragment;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.graphics.ImageFormat;
+import android.graphics.Matrix;
+import android.graphics.RectF;
+import android.graphics.SurfaceTexture;
+import android.hardware.SensorManager;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.CaptureFailure;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.DngCreator;
+import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.media.Image;
+import android.media.ImageReader;
+import android.media.MediaScannerConnection;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.SystemClock;
+import android.util.Log;
+import android.util.Size;
+import android.util.SparseIntArray;
+import android.view.LayoutInflater;
+import android.view.OrientationEventListener;
+import android.view.Surface;
+import android.view.TextureView;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Toast;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * A fragment that demonstrates use of the Camera2 API to capture RAW and JPEG photos.
+ *
+ * In this example, the lifecycle of a single request to take a photo is:
+ * <ul>
+ * <li>
+ * The user presses the "Picture" button, resulting in a call to {@link #takePicture()}.
+ * </li>
+ * <li>
+ * {@link #takePicture()} initiates a pre-capture sequence that triggers the camera's built-in
+ * auto-focus, auto-exposure, and auto-white-balance algorithms (aka. "3A") to run.
+ * </li>
+ * <li>
+ * When the pre-capture sequence has finished, a {@link CaptureRequest} with a monotonically
+ * increasing request ID set by calls to {@link CaptureRequest.Builder#setTag(Object)} is sent to
+ * the camera to begin the JPEG and RAW capture sequence, and an
+ * {@link ImageSaver.ImageSaverBuilder} is stored for this request in the
+ * {@link #mJpegResultQueue} and {@link #mRawResultQueue}.
+ * </li>
+ * <li>
+ * As {@link CaptureResult}s and {@link Image}s become available via callbacks in a background
+ * thread, a {@link ImageSaver.ImageSaverBuilder} is looked up by the request ID in
+ * {@link #mJpegResultQueue} and {@link #mRawResultQueue} and updated.
+ * </li>
+ * <li>
+ * When all of the necessary results to save an image are available, the an {@link ImageSaver} is
+ * constructed by the {@link ImageSaver.ImageSaverBuilder} and passed to a separate background
+ * thread to save to a file.
+ * </li>
+ * </ul>
+ */
+public class Camera2RawFragment extends Fragment implements View.OnClickListener {
+    /**
+     * Conversion from screen rotation to JPEG orientation.
+     */
+    private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
+
+    static {
+        ORIENTATIONS.append(Surface.ROTATION_0, 0);
+        ORIENTATIONS.append(Surface.ROTATION_90, 90);
+        ORIENTATIONS.append(Surface.ROTATION_180, 180);
+        ORIENTATIONS.append(Surface.ROTATION_270, 270);
+    }
+
+    /**
+     * Timeout for the pre-capture sequence.
+     */
+    private static final long PRECAPTURE_TIMEOUT_MS = 1000;
+
+    /**
+     * Tolerance when comparing aspect ratios.
+     */
+    private static final double ASPECT_RATIO_TOLERANCE = 0.005;
+
+    /**
+     * Tag for the {@link Log}.
+     */
+    private static final String TAG = "Camera2RawFragment";
+
+    /**
+     * Camera state: Device is closed.
+     */
+    private static final int STATE_CLOSED = 0;
+
+    /**
+     * Camera state: Device is opened, but is not capturing.
+     */
+    private static final int STATE_OPENED = 1;
+
+    /**
+     * Camera state: Showing camera preview.
+     */
+    private static final int STATE_PREVIEW = 2;
+
+    /**
+     * Camera state: Waiting for 3A convergence before capturing a photo.
+     */
+    private static final int STATE_WAITING_FOR_3A_CONVERGENCE = 3;
+
+    /**
+     * An {@link OrientationEventListener} used to determine when device rotation has occurred.
+     * This is mainly necessary for when the device is rotated by 180 degrees, in which case
+     * onCreate or onConfigurationChanged is not called as the view dimensions remain the same,
+     * but the orientation of the has changed, and thus the preview rotation must be updated.
+     */
+    private OrientationEventListener mOrientationListener;
+
+    /**
+     * {@link TextureView.SurfaceTextureListener} handles several lifecycle events of a
+     * {@link TextureView}.
+     */
+    private final TextureView.SurfaceTextureListener mSurfaceTextureListener
+            = new TextureView.SurfaceTextureListener() {
+
+        @Override
+        public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
+            configureTransform(width, height);
+        }
+
+        @Override
+        public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {
+            configureTransform(width, height);
+        }
+
+        @Override
+        public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
+            synchronized (mCameraStateLock) {
+                mPreviewSize = null;
+            }
+            return true;
+        }
+
+        @Override
+        public void onSurfaceTextureUpdated(SurfaceTexture texture) {
+        }
+
+    };
+
+    /**
+     * An {@link AutoFitTextureView} for camera preview.
+     */
+    private AutoFitTextureView mTextureView;
+
+    /**
+     * An additional thread for running tasks that shouldn't block the UI.  This is used for all
+     * callbacks from the {@link CameraDevice} and {@link CameraCaptureSession}s.
+     */
+    private HandlerThread mBackgroundThread;
+
+    /**
+     * A counter for tracking corresponding {@link CaptureRequest}s and {@link CaptureResult}s
+     * across the {@link CameraCaptureSession} capture callbacks.
+     */
+    private final AtomicInteger mRequestCounter = new AtomicInteger();
+
+    /**
+     * A {@link Semaphore} to prevent the app from exiting before closing the camera.
+     */
+    private final Semaphore mCameraOpenCloseLock = new Semaphore(1);
+
+    /**
+     * A lock protecting camera state.
+     */
+    private final Object mCameraStateLock = new Object();
+
+    // *********************************************************************************************
+    // State protected by mCameraStateLock.
+    //
+    // The following state is used across both the UI and background threads.  Methods with "Locked"
+    // in the name expect mCameraStateLock to be held while calling.
+
+    /**
+     * ID of the current {@link CameraDevice}.
+     */
+    private String mCameraId;
+
+    /**
+     * A {@link CameraCaptureSession } for camera preview.
+     */
+    private CameraCaptureSession mCaptureSession;
+
+    /**
+     * A reference to the open {@link CameraDevice}.
+     */
+    private CameraDevice mCameraDevice;
+
+    /**
+     * The {@link Size} of camera preview.
+     */
+    private Size mPreviewSize;
+
+    /**
+     * The {@link CameraCharacteristics} for the currently configured camera device.
+     */
+    private CameraCharacteristics mCharacteristics;
+
+    /**
+     * A {@link Handler} for running tasks in the background.
+     */
+    private Handler mBackgroundHandler;
+
+    /**
+     * A reference counted holder wrapping the {@link ImageReader} that handles JPEG image captures.
+     * This is used to allow us to clean up the {@link ImageReader} when all background tasks using
+     * its {@link Image}s have completed.
+     */
+    private RefCountedAutoCloseable<ImageReader> mJpegImageReader;
+
+    /**
+     * A reference counted holder wrapping the {@link ImageReader} that handles RAW image captures.
+     * This is used to allow us to clean up the {@link ImageReader} when all background tasks using
+     * its {@link Image}s have completed.
+     */
+    private RefCountedAutoCloseable<ImageReader> mRawImageReader;
+
+    /**
+     * Whether or not the currently configured camera device is fixed-focus.
+     */
+    private boolean mNoAFRun = false;
+
+    /**
+     * Number of pending user requests to capture a photo.
+     */
+    private int mPendingUserCaptures = 0;
+
+    /**
+     * Request ID to {@link ImageSaver.ImageSaverBuilder} mapping for in-progress JPEG captures.
+     */
+    private final TreeMap<Integer, ImageSaver.ImageSaverBuilder> mJpegResultQueue = new TreeMap<>();
+
+    /**
+     * Request ID to {@link ImageSaver.ImageSaverBuilder} mapping for in-progress RAW captures.
+     */
+    private final TreeMap<Integer, ImageSaver.ImageSaverBuilder> mRawResultQueue = new TreeMap<>();
+
+    /**
+     * {@link CaptureRequest.Builder} for the camera preview
+     */
+    private CaptureRequest.Builder mPreviewRequestBuilder;
+
+    /**
+     * The state of the camera device.
+     *
+     * @see #mPreCaptureCallback
+     */
+    private int mState = STATE_CLOSED;
+
+    /**
+     * Timer to use with pre-capture sequence to ensure a timely capture if 3A convergence is taking
+     * too long.
+     */
+    private long mCaptureTimer;
+
+    //**********************************************************************************************
+
+    /**
+     * {@link CameraDevice.StateCallback} is called when the currently active {@link CameraDevice}
+     * changes its state.
+     */
+    private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
+
+        @Override
+        public void onOpened(CameraDevice cameraDevice) {
+            // This method is called when the camera is opened.  We start camera preview here if
+            // the TextureView displaying this has been set up.
+            synchronized (mCameraStateLock) {
+                mState = STATE_OPENED;
+                mCameraOpenCloseLock.release();
+                mCameraDevice = cameraDevice;
+
+                // Start the preview session if the TextureView has been set up already.
+                if (mPreviewSize != null && mTextureView.isAvailable()) {
+                    createCameraPreviewSessionLocked();
+                }
+            }
+        }
+
+        @Override
+        public void onDisconnected(CameraDevice cameraDevice) {
+            synchronized (mCameraStateLock) {
+                mState = STATE_CLOSED;
+                mCameraOpenCloseLock.release();
+                cameraDevice.close();
+                mCameraDevice = null;
+            }
+        }
+
+        @Override
+        public void onError(CameraDevice cameraDevice, int error) {
+            Log.e(TAG, "Received camera device error: " + error);
+            synchronized(mCameraStateLock) {
+                mState = STATE_CLOSED;
+                mCameraOpenCloseLock.release();
+                cameraDevice.close();
+                mCameraDevice = null;
+            }
+            Activity activity = getActivity();
+            if (null != activity) {
+                activity.finish();
+            }
+        }
+
+    };
+
+    /**
+     * This a callback object for the {@link ImageReader}. "onImageAvailable" will be called when a
+     * JPEG image is ready to be saved.
+     */
+    private final ImageReader.OnImageAvailableListener mOnJpegImageAvailableListener
+            = new ImageReader.OnImageAvailableListener() {
+
+        @Override
+        public void onImageAvailable(ImageReader reader) {
+            dequeueAndSaveImage(mJpegResultQueue, mJpegImageReader);
+        }
+
+    };
+
+    /**
+     * This a callback object for the {@link ImageReader}. "onImageAvailable" will be called when a
+     * RAW image is ready to be saved.
+     */
+    private final ImageReader.OnImageAvailableListener mOnRawImageAvailableListener
+            = new ImageReader.OnImageAvailableListener() {
+
+        @Override
+        public void onImageAvailable(ImageReader reader) {
+            dequeueAndSaveImage(mRawResultQueue, mRawImageReader);
+        }
+
+    };
+
+    /**
+     * A {@link CameraCaptureSession.CaptureCallback} that handles events for the preview and
+     * pre-capture sequence.
+     */
+    private CameraCaptureSession.CaptureCallback mPreCaptureCallback
+            = new CameraCaptureSession.CaptureCallback() {
+
+        private void process(CaptureResult result) {
+            synchronized(mCameraStateLock) {
+                switch (mState) {
+                    case STATE_PREVIEW: {
+                        // We have nothing to do when the camera preview is running normally.
+                        break;
+                    }
+                    case STATE_WAITING_FOR_3A_CONVERGENCE: {
+                        boolean readyToCapture = true;
+                        if (!mNoAFRun) {
+                            int afState = result.get(CaptureResult.CONTROL_AF_STATE);
+
+                            // If auto-focus has reached locked state, we are ready to capture
+                            readyToCapture =
+                                    (afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED ||
+                                    afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
+                        }
+
+                        // If we are running on an non-legacy device, we should also wait until
+                        // auto-exposure and auto-white-balance have converged as well before
+                        // taking a picture.
+                        if (!isLegacyLocked()) {
+                            int aeState = result.get(CaptureResult.CONTROL_AE_STATE);
+                            int awbState = result.get(CaptureResult.CONTROL_AWB_STATE);
+
+                            readyToCapture = readyToCapture &&
+                                    aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED &&
+                                    awbState == CaptureResult.CONTROL_AWB_STATE_CONVERGED;
+                        }
+
+                        // If we haven't finished the pre-capture sequence but have hit our maximum
+                        // wait timeout, too bad! Begin capture anyway.
+                        if (!readyToCapture && hitTimeoutLocked()) {
+                            Log.w(TAG, "Timed out waiting for pre-capture sequence to complete.");
+                            readyToCapture = true;
+                        }
+
+                        if (readyToCapture && mPendingUserCaptures > 0) {
+                            // Capture once for each user tap of the "Picture" button.
+                            while (mPendingUserCaptures > 0) {
+                                captureStillPictureLocked();
+                                mPendingUserCaptures--;
+                            }
+                            // After this, the camera will go back to the normal state of preview.
+                            mState = STATE_PREVIEW;
+                        }
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request,
+                                        CaptureResult partialResult) {
+            process(partialResult);
+        }
+
+        @Override
+        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
+                                       TotalCaptureResult result) {
+            process(result);
+        }
+
+    };
+
+    /**
+     * A {@link CameraCaptureSession.CaptureCallback} that handles the still JPEG and RAW capture
+     * request.
+     */
+    private final CameraCaptureSession.CaptureCallback mCaptureCallback
+            = new CameraCaptureSession.CaptureCallback() {
+        @Override
+        public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request,
+                                     long timestamp, long frameNumber) {
+            String currentDateTime = generateTimestamp();
+            File rawFile = new File(Environment.
+                    getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),
+                    "RAW_" + currentDateTime + ".dng");
+            File jpegFile = new File(Environment.
+                    getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),
+                    "JPEG_" + currentDateTime + ".jpg");
+
+            // Look up the ImageSaverBuilder for this request and update it with the file name
+            // based on the capture start time.
+            ImageSaver.ImageSaverBuilder jpegBuilder;
+            ImageSaver.ImageSaverBuilder rawBuilder;
+            int requestId = (int) request.getTag();
+            synchronized (mCameraStateLock) {
+                jpegBuilder = mJpegResultQueue.get(requestId);
+                rawBuilder = mRawResultQueue.get(requestId);
+            }
+
+            if (jpegBuilder != null) jpegBuilder.setFile(jpegFile);
+            if (rawBuilder != null) rawBuilder.setFile(rawFile);
+        }
+
+        @Override
+        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
+                                       TotalCaptureResult result) {
+            int requestId = (int) request.getTag();
+            ImageSaver.ImageSaverBuilder jpegBuilder;
+            ImageSaver.ImageSaverBuilder rawBuilder;
+            StringBuilder sb = new StringBuilder();
+
+            // Look up the ImageSaverBuilder for this request and update it with the CaptureResult
+            synchronized (mCameraStateLock) {
+                jpegBuilder = mJpegResultQueue.get(requestId);
+                rawBuilder = mRawResultQueue.get(requestId);
+
+                // If we have all the results necessary, save the image to a file in the background.
+                handleCompletionLocked(requestId, jpegBuilder, mJpegResultQueue);
+                handleCompletionLocked(requestId, rawBuilder, mRawResultQueue);
+
+                if (jpegBuilder != null) {
+                    jpegBuilder.setResult(result);
+                    sb.append("Saving JPEG as: ");
+                    sb.append(jpegBuilder.getSaveLocation());
+                }
+                if (rawBuilder != null) {
+                    rawBuilder.setResult(result);
+                    if (jpegBuilder != null) sb.append(", ");
+                    sb.append("Saving RAW as: ");
+                    sb.append(rawBuilder.getSaveLocation());
+                }
+                finishedCaptureLocked();
+            }
+
+            showToast(sb.toString());
+        }
+
+        @Override
+        public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request,
+                                    CaptureFailure failure) {
+            int requestId = (int) request.getTag();
+            synchronized (mCameraStateLock) {
+                mJpegResultQueue.remove(requestId);
+                mRawResultQueue.remove(requestId);
+                finishedCaptureLocked();
+            }
+            showToast("Capture failed!");
+        }
+
+    };
+
+    /**
+     * A {@link Handler} for showing {@link Toast}s on the UI thread.
+     */
+    private final Handler mMessageHandler = new Handler(Looper.getMainLooper()) {
+        @Override
+        public void handleMessage(Message msg) {
+            Activity activity = getActivity();
+            if (activity != null) {
+                Toast.makeText(activity, (String) msg.obj, Toast.LENGTH_SHORT).show();
+            }
+        }
+    };
+
+    public static Camera2RawFragment newInstance() {
+        Camera2RawFragment fragment = new Camera2RawFragment();
+        fragment.setRetainInstance(true);
+        return fragment;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.fragment_camera2_basic, container, false);
+    }
+
+    @Override
+    public void onViewCreated(final View view, Bundle savedInstanceState) {
+        view.findViewById(R.id.picture).setOnClickListener(this);
+        view.findViewById(R.id.info).setOnClickListener(this);
+        mTextureView = (AutoFitTextureView) view.findViewById(R.id.texture);
+
+        // Setup a new OrientationEventListener.  This is used to handle rotation events like a
+        // 180 degree rotation that do not normally trigger a call to onCreate to do view re-layout
+        // or otherwise cause the preview TextureView's size to change.
+        mOrientationListener = new OrientationEventListener(getActivity(),
+                SensorManager.SENSOR_DELAY_NORMAL) {
+            @Override
+            public void onOrientationChanged(int orientation) {
+                if (mTextureView != null && mTextureView.isAvailable()) {
+                    configureTransform(mTextureView.getWidth(), mTextureView.getHeight());
+                }
+            }
+        };
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        startBackgroundThread();
+        openCamera();
+
+        // When the screen is turned off and turned back on, the SurfaceTexture is already
+        // available, and "onSurfaceTextureAvailable" will not be called. In that case, we should
+        // configure the preview bounds here (otherwise, we wait until the surface is ready in
+        // the SurfaceTextureListener).
+        if (mTextureView.isAvailable()) {
+            configureTransform(mTextureView.getWidth(), mTextureView.getHeight());
+        } else {
+            mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
+        }
+        if (mOrientationListener != null && mOrientationListener.canDetectOrientation()) {
+            mOrientationListener.enable();
+        }
+    }
+
+    @Override
+    public void onPause() {
+        if (mOrientationListener != null) {
+            mOrientationListener.disable();
+        }
+        closeCamera();
+        stopBackgroundThread();
+        super.onPause();
+    }
+
+    @Override
+    public void onClick(View view) {
+        switch (view.getId()) {
+            case R.id.picture: {
+                takePicture();
+                break;
+            }
+            case R.id.info: {
+                Activity activity = getActivity();
+                if (null != activity) {
+                    new AlertDialog.Builder(activity)
+                            .setMessage(R.string.intro_message)
+                            .setPositiveButton(android.R.string.ok, null)
+                            .show();
+                }
+                break;
+            }
+        }
+    }
+
+    /**
+     * Sets up state related to camera that is needed before opening a {@link CameraDevice}.
+     */
+    private boolean setUpCameraOutputs() {
+        Activity activity = getActivity();
+        CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
+        if (manager == null) {
+            ErrorDialog.buildErrorDialog("This device doesn't support Camera2 API.").
+                    show(getFragmentManager(), "dialog");
+            return false;
+        }
+        try {
+            // Find a CameraDevice that supports RAW captures, and configure state.
+            for (String cameraId : manager.getCameraIdList()) {
+                CameraCharacteristics characteristics
+                        = manager.getCameraCharacteristics(cameraId);
+
+                // We only use a camera that supports RAW in this sample.
+                if (!contains(characteristics.get(
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES),
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
+                    continue;
+                }
+
+                StreamConfigurationMap map = characteristics.get(
+                        CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+
+                // For still image captures, we use the largest available size.
+                Size largestJpeg = Collections.max(
+                        Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)),
+                        new CompareSizesByArea());
+
+                Size largestRaw = Collections.max(
+                        Arrays.asList(map.getOutputSizes(ImageFormat.RAW_SENSOR)),
+                        new CompareSizesByArea());
+
+                synchronized(mCameraStateLock) {
+                    // Set up ImageReaders for JPEG and RAW outputs.  Place these in a reference
+                    // counted wrapper to ensure they are only closed when all background tasks
+                    // using them are finished.
+                    if (mJpegImageReader == null || mJpegImageReader.getAndRetain() == null) {
+                        mJpegImageReader = new RefCountedAutoCloseable<>(
+                                ImageReader.newInstance(largestJpeg.getWidth(),
+                                largestJpeg.getHeight(), ImageFormat.JPEG, /*maxImages*/5));
+                    }
+                    mJpegImageReader.get().setOnImageAvailableListener(
+                            mOnJpegImageAvailableListener, mBackgroundHandler);
+
+                    if (mRawImageReader == null || mRawImageReader.getAndRetain() == null) {
+                        mRawImageReader = new RefCountedAutoCloseable<>(
+                                ImageReader.newInstance(largestRaw.getWidth(),
+                                largestRaw.getHeight(), ImageFormat.RAW_SENSOR, /*maxImages*/ 5));
+                    }
+                    mRawImageReader.get().setOnImageAvailableListener(
+                            mOnRawImageAvailableListener, mBackgroundHandler);
+
+                    mCharacteristics = characteristics;
+                    mCameraId = cameraId;
+                }
+                return true;
+            }
+        } catch (CameraAccessException e) {
+            e.printStackTrace();
+        }
+
+        // If we found no suitable cameras for capturing RAW, warn the user.
+        ErrorDialog.buildErrorDialog("This device doesn't support capturing RAW photos").
+                show(getFragmentManager(), "dialog");
+        return false;
+    }
+
+    /**
+     * Opens the camera specified by {@link #mCameraId}.
+     */
+    private void openCamera() {
+        if (!setUpCameraOutputs()) {
+            return;
+        }
+
+        Activity activity = getActivity();
+        CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
+        try {
+            // Wait for any previously running session to finish.
+            if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
+                throw new RuntimeException("Time out waiting to lock camera opening.");
+            }
+
+            String cameraId;
+            Handler backgroundHandler;
+            synchronized (mCameraStateLock) {
+                cameraId = mCameraId;
+                backgroundHandler = mBackgroundHandler;
+            }
+
+            // Attempt to open the camera. mStateCallback will be called on the background handler's
+            // thread when this succeeds or fails.
+            manager.openCamera(cameraId, mStateCallback, backgroundHandler);
+        } catch (CameraAccessException e) {
+            e.printStackTrace();
+        } catch (InterruptedException e) {
+            throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
+        }
+    }
+
+    /**
+     * Closes the current {@link CameraDevice}.
+     */
+    private void closeCamera() {
+        try {
+            mCameraOpenCloseLock.acquire();
+            synchronized(mCameraStateLock) {
+
+                // Reset state and clean up resources used by the camera.
+                // Note: After calling this, the ImageReaders will be closed after any background
+                // tasks saving Images from these readers have been completed.
+                mPendingUserCaptures = 0;
+                mState = STATE_CLOSED;
+                if (null != mCaptureSession) {
+                    mCaptureSession.close();
+                    mCaptureSession = null;
+                }
+                if (null != mCameraDevice) {
+                    mCameraDevice.close();
+                    mCameraDevice = null;
+                }
+                if (null != mJpegImageReader) {
+                    mJpegImageReader.close();
+                    mJpegImageReader = null;
+                }
+                if (null != mRawImageReader) {
+                    mRawImageReader.close();
+                    mRawImageReader = null;
+                }
+            }
+        } catch (InterruptedException e) {
+            throw new RuntimeException("Interrupted while trying to lock camera closing.", e);
+        } finally {
+            mCameraOpenCloseLock.release();
+        }
+    }
+
+    /**
+     * Starts a background thread and its {@link Handler}.
+     */
+    private void startBackgroundThread() {
+        mBackgroundThread = new HandlerThread("CameraBackground");
+        mBackgroundThread.start();
+        synchronized(mCameraStateLock) {
+            mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
+        }
+    }
+
+    /**
+     * Stops the background thread and its {@link Handler}.
+     */
+    private void stopBackgroundThread() {
+        mBackgroundThread.quitSafely();
+        try {
+            mBackgroundThread.join();
+            mBackgroundThread = null;
+            synchronized (mCameraStateLock) {
+                mBackgroundHandler = null;
+            }
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Creates a new {@link CameraCaptureSession} for camera preview.
+     *
+     * Call this only with {@link #mCameraStateLock} held.
+     */
+    private void createCameraPreviewSessionLocked() {
+        try {
+            SurfaceTexture texture = mTextureView.getSurfaceTexture();
+            // We configure the size of default buffer to be the size of camera preview we want.
+            texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
+
+            // This is the output Surface we need to start preview.
+            Surface surface = new Surface(texture);
+
+            // We set up a CaptureRequest.Builder with the output Surface.
+            mPreviewRequestBuilder
+                    = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+            mPreviewRequestBuilder.addTarget(surface);
+
+            // Here, we create a CameraCaptureSession for camera preview.
+            mCameraDevice.createCaptureSession(Arrays.asList(surface,
+                    mJpegImageReader.get().getSurface(),
+                    mRawImageReader.get().getSurface()), new CameraCaptureSession.StateCallback() {
+                        @Override
+                        public void onConfigured(CameraCaptureSession cameraCaptureSession) {
+                            synchronized (mCameraStateLock) {
+                                // The camera is already closed
+                                if (null == mCameraDevice) {
+                                    return;
+                                }
+
+                                try {
+                                    setup3AControlsLocked(mPreviewRequestBuilder);
+                                    // Finally, we start displaying the camera preview.
+                                    cameraCaptureSession.setRepeatingRequest(
+                                            mPreviewRequestBuilder.build(),
+                                            mPreCaptureCallback, mBackgroundHandler);
+                                    mState = STATE_PREVIEW;
+                                } catch (CameraAccessException|IllegalStateException e) {
+                                    e.printStackTrace();
+                                    return;
+                                }
+                                // When the session is ready, we start displaying the preview.
+                                mCaptureSession = cameraCaptureSession;
+                            }
+                        }
+
+                        @Override
+                        public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
+                            showToast("Failed to configure camera.");
+                        }
+                    }, mBackgroundHandler
+            );
+        } catch (CameraAccessException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Configure the given {@link CaptureRequest.Builder} to use auto-focus, auto-exposure, and
+     * auto-white-balance controls if available.
+     *
+     * Call this only with {@link #mCameraStateLock} held.
+     *
+     * @param builder the builder to configure.
+     */
+    private void setup3AControlsLocked(CaptureRequest.Builder builder) {
+        // Enable auto-magical 3A run by camera device
+        builder.set(CaptureRequest.CONTROL_MODE,
+                CaptureRequest.CONTROL_MODE_AUTO);
+
+        Float minFocusDist =
+                mCharacteristics.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE);
+
+        // If MINIMUM_FOCUS_DISTANCE is 0, lens is fixed-focus and we need to skip the AF run.
+        mNoAFRun = (minFocusDist == null || minFocusDist == 0);
+
+        if (!mNoAFRun) {
+            // If there is a "continuous picture" mode available, use it, otherwise default to AUTO.
+            if (contains(mCharacteristics.get(
+                            CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES),
+                    CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE)) {
+                builder.set(CaptureRequest.CONTROL_AF_MODE,
+                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
+            } else {
+                builder.set(CaptureRequest.CONTROL_AF_MODE,
+                        CaptureRequest.CONTROL_AF_MODE_AUTO);
+            }
+        }
+
+        // If there is an auto-magical flash control mode available, use it, otherwise default to
+        // the "on" mode, which is guaranteed to always be available.
+        if (contains(mCharacteristics.get(
+                        CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES),
+                CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH)) {
+            builder.set(CaptureRequest.CONTROL_AE_MODE,
+                    CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
+        } else {
+            builder.set(CaptureRequest.CONTROL_AE_MODE,
+                    CaptureRequest.CONTROL_AE_MODE_ON);
+        }
+
+        // If there is an auto-magical white balance control mode available, use it.
+        if (contains(mCharacteristics.get(
+                        CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES),
+                CaptureRequest.CONTROL_AWB_MODE_AUTO)) {
+            // Allow AWB to run auto-magically if this device supports this
+            builder.set(CaptureRequest.CONTROL_AWB_MODE,
+                    CaptureRequest.CONTROL_AWB_MODE_AUTO);
+        }
+    }
+
+    /**
+     * Configure the necessary {@link android.graphics.Matrix} transformation to `mTextureView`,
+     * and start/restart the preview capture session if necessary.
+     *
+     * This method should be called after the camera state has been initialized in
+     * setUpCameraOutputs.
+     *
+     * @param viewWidth  The width of `mTextureView`
+     * @param viewHeight The height of `mTextureView`
+     */
+    private void configureTransform(int viewWidth, int viewHeight) {
+        Activity activity = getActivity();
+        synchronized(mCameraStateLock) {
+            if (null == mTextureView || null == activity) {
+                return;
+            }
+
+            StreamConfigurationMap map = mCharacteristics.get(
+                    CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+
+            // For still image captures, we always use the largest available size.
+            Size largestJpeg = Collections.max(Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)),
+                    new CompareSizesByArea());
+
+            // Find the rotation of the device relative to the native device orientation.
+            int deviceRotation = activity.getWindowManager().getDefaultDisplay().getRotation();
+
+            // Find the rotation of the device relative to the camera sensor's orientation.
+            int totalRotation = sensorToDeviceRotation(mCharacteristics, deviceRotation);
+
+            // Swap the view dimensions for calculation as needed if they are rotated relative to
+            // the sensor.
+            boolean swappedDimensions = totalRotation == 90 || totalRotation == 270;
+            int rotatedViewWidth = viewWidth;
+            int rotatedViewHeight = viewHeight;
+            if (swappedDimensions) {
+                rotatedViewWidth = viewHeight;
+                rotatedViewHeight = viewWidth;
+            }
+
+            // Find the best preview size for these view dimensions and configured JPEG size.
+            Size previewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),
+                    rotatedViewWidth, rotatedViewHeight, largestJpeg);
+
+            if (swappedDimensions) {
+                mTextureView.setAspectRatio(
+                        previewSize.getHeight(), previewSize.getWidth());
+            } else {
+                mTextureView.setAspectRatio(
+                        previewSize.getWidth(), previewSize.getHeight());
+            }
+
+            // Find rotation of device in degrees (reverse device orientation for front-facing
+            // cameras).
+            int rotation = (mCharacteristics.get(CameraCharacteristics.LENS_FACING) ==
+                    CameraCharacteristics.LENS_FACING_FRONT) ?
+                    (360 + ORIENTATIONS.get(deviceRotation)) % 360 :
+                    (360 - ORIENTATIONS.get(deviceRotation)) % 360;
+
+            Matrix matrix = new Matrix();
+            RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
+            RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth());
+            float centerX = viewRect.centerX();
+            float centerY = viewRect.centerY();
+
+            // Initially, output stream images from the Camera2 API will be rotated to the native
+            // device orientation from the sensor's orientation, and the TextureView will default to
+            // scaling these buffers to fill it's view bounds.  If the aspect ratios and relative
+            // orientations are correct, this is fine.
+            //
+            // However, if the device orientation has been rotated relative to its native
+            // orientation so that the TextureView's dimensions are swapped relative to the
+            // native device orientation, we must do the following to ensure the output stream
+            // images are not incorrectly scaled by the TextureView:
+            //   - Undo the scale-to-fill from the output buffer's dimensions (i.e. its dimensions
+            //     in the native device orientation) to the TextureView's dimension.
+            //   - Apply a scale-to-fill from the output buffer's rotated dimensions
+            //     (i.e. its dimensions in the current device orientation) to the TextureView's
+            //     dimensions.
+            //   - Apply the rotation from the native device orientation to the current device
+            //     rotation.
+            if (Surface.ROTATION_90 == deviceRotation || Surface.ROTATION_270 == deviceRotation) {
+                bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
+                matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
+                float scale = Math.max(
+                        (float) viewHeight / previewSize.getHeight(),
+                        (float) viewWidth / previewSize.getWidth());
+                matrix.postScale(scale, scale, centerX, centerY);
+
+            }
+            matrix.postRotate(rotation, centerX, centerY);
+
+            mTextureView.setTransform(matrix);
+
+            // Start or restart the active capture session if the preview was initialized or
+            // if its aspect ratio changed significantly.
+            if (mPreviewSize == null || !checkAspectsEqual(previewSize, mPreviewSize)) {
+                mPreviewSize = previewSize;
+                if (mState != STATE_CLOSED) {
+                    createCameraPreviewSessionLocked();
+                }
+            }
+        }
+    }
+
+    /**
+     * Initiate a still image capture.
+     *
+     * This function sends a capture request that initiates a pre-capture sequence in our state
+     * machine that waits for auto-focus to finish, ending in a "locked" state where the lens is no
+     * longer moving, waits for auto-exposure to choose a good exposure value, and waits for
+     * auto-white-balance to converge.
+     */
+    private void takePicture() {
+        synchronized(mCameraStateLock) {
+            mPendingUserCaptures++;
+
+            // If we already triggered a pre-capture sequence, or are in a state where we cannot
+            // do this, return immediately.
+            if (mState != STATE_PREVIEW) {
+                return;
+            }
+
+            try {
+                // Trigger an auto-focus run if camera is capable. If the camera is already focused,
+                // this should do nothing.
+                if (!mNoAFRun) {
+                    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
+                            CameraMetadata.CONTROL_AF_TRIGGER_START);
+                }
+
+                // If this is not a legacy device, we can also trigger an auto-exposure metering
+                // run.
+                if (!isLegacyLocked()) {
+                    // Tell the camera to lock focus.
+                    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
+                            CameraMetadata.CONTROL_AE_PRECAPTURE_TRIGGER_START);
+                }
+
+                // Update state machine to wait for auto-focus, auto-exposure, and
+                // auto-white-balance (aka. "3A") to converge.
+                mState = STATE_WAITING_FOR_3A_CONVERGENCE;
+
+                // Start a timer for the pre-capture sequence.
+                startTimerLocked();
+
+                // Replace the existing repeating request with one with updated 3A triggers.
+                mCaptureSession.capture(mPreviewRequestBuilder.build(), mPreCaptureCallback,
+                        mBackgroundHandler);
+            } catch (CameraAccessException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * Send a capture request to the camera device that initiates a capture targeting the JPEG and
+     * RAW outputs.
+     *
+     * Call this only with {@link #mCameraStateLock} held.
+     */
+    private void captureStillPictureLocked() {
+        try {
+            final Activity activity = getActivity();
+            if (null == activity || null == mCameraDevice) {
+                return;
+            }
+            // This is the CaptureRequest.Builder that we use to take a picture.
+            final CaptureRequest.Builder captureBuilder =
+                    mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
+
+            captureBuilder.addTarget(mJpegImageReader.get().getSurface());
+            captureBuilder.addTarget(mRawImageReader.get().getSurface());
+
+            // Use the same AE and AF modes as the preview.
+            setup3AControlsLocked(captureBuilder);
+
+            // Set orientation.
+            int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
+            captureBuilder.set(CaptureRequest.JPEG_ORIENTATION,
+                    sensorToDeviceRotation(mCharacteristics, rotation));
+
+            // Set request tag to easily track results in callbacks.
+            captureBuilder.setTag(mRequestCounter.getAndIncrement());
+
+            CaptureRequest request = captureBuilder.build();
+
+            // Create an ImageSaverBuilder in which to collect results, and add it to the queue
+            // of active requests.
+            ImageSaver.ImageSaverBuilder jpegBuilder = new ImageSaver.ImageSaverBuilder(activity)
+                    .setCharacteristics(mCharacteristics);
+            ImageSaver.ImageSaverBuilder rawBuilder = new ImageSaver.ImageSaverBuilder(activity)
+                    .setCharacteristics(mCharacteristics);
+
+            mJpegResultQueue.put((int) request.getTag(), jpegBuilder);
+            mRawResultQueue.put((int) request.getTag(), rawBuilder);
+
+            mCaptureSession.capture(request, mCaptureCallback, mBackgroundHandler);
+
+        } catch (CameraAccessException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Called after a RAW/JPEG capture has completed; resets the AF trigger state for the
+     * pre-capture sequence.
+     *
+     * Call this only with {@link #mCameraStateLock} held.
+     */
+    private void finishedCaptureLocked() {
+        try {
+            // Reset the auto-focus trigger in case AF didn't run quickly enough.
+            if (!mNoAFRun) {
+                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
+                        CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
+
+                mCaptureSession.capture(mPreviewRequestBuilder.build(), mPreCaptureCallback,
+                        mBackgroundHandler);
+
+                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
+                        CameraMetadata.CONTROL_AF_TRIGGER_IDLE);
+            }
+        } catch (CameraAccessException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Retrieve the next {@link Image} from a reference counted {@link ImageReader}, retaining
+     * that {@link ImageReader} until that {@link Image} is no longer in use, and set this
+     * {@link Image} as the result for the next request in the queue of pending requests.  If
+     * all necessary information is available, begin saving the image to a file in a background
+     * thread.
+     *
+     * @param pendingQueue the currently active requests.
+     * @param reader a reference counted wrapper containing an {@link ImageReader} from which to
+     *               acquire an image.
+     */
+    private void dequeueAndSaveImage(TreeMap<Integer, ImageSaver.ImageSaverBuilder> pendingQueue,
+                                     RefCountedAutoCloseable<ImageReader> reader) {
+        synchronized (mCameraStateLock) {
+            Map.Entry<Integer, ImageSaver.ImageSaverBuilder> entry =
+                    pendingQueue.firstEntry();
+            ImageSaver.ImageSaverBuilder builder = entry.getValue();
+
+            // Increment reference count to prevent ImageReader from being closed while we
+            // are saving its Images in a background thread (otherwise their resources may
+            // be freed while we are writing to a file).
+            if (reader == null || reader.getAndRetain() == null) {
+                Log.e(TAG, "Paused the activity before we could save the image," +
+                        " ImageReader already closed.");
+                pendingQueue.remove(entry.getKey());
+                return;
+            }
+
+            Image image;
+            try {
+                image = reader.get().acquireNextImage();
+            } catch (IllegalStateException e) {
+                Log.e(TAG, "Too many images queued for saving, dropping image for request: " +
+                        entry.getKey());
+                pendingQueue.remove(entry.getKey());
+                return;
+            }
+
+            builder.setRefCountedReader(reader).setImage(image);
+
+            handleCompletionLocked(entry.getKey(), builder, pendingQueue);
+        }
+    }
+
+    /**
+     * Runnable that saves an {@link Image} into the specified {@link File}, and updates
+     * {@link android.provider.MediaStore} to include the resulting file.
+     *
+     * This can be constructed through an {@link ImageSaverBuilder} as the necessary image and
+     * result information becomes available.
+     */
+    private static class ImageSaver implements Runnable {
+
+        /**
+         * The image to save.
+         */
+        private final Image mImage;
+        /**
+         * The file we save the image into.
+         */
+        private final File mFile;
+
+        /**
+         * The CaptureResult for this image capture.
+         */
+        private final CaptureResult mCaptureResult;
+
+        /**
+         * The CameraCharacteristics for this camera device.
+         */
+        private final CameraCharacteristics mCharacteristics;
+
+        /**
+         * The Context to use when updating MediaStore with the saved images.
+         */
+        private final Context mContext;
+
+        /**
+         * A reference counted wrapper for the ImageReader that owns the given image.
+         */
+        private final RefCountedAutoCloseable<ImageReader> mReader;
+
+        private ImageSaver(Image image, File file, CaptureResult result,
+                CameraCharacteristics characteristics, Context context,
+                RefCountedAutoCloseable<ImageReader> reader) {
+            mImage = image;
+            mFile = file;
+            mCaptureResult = result;
+            mCharacteristics = characteristics;
+            mContext = context;
+            mReader = reader;
+        }
+
+        @Override
+        public void run() {
+            boolean success = false;
+            int format = mImage.getFormat();
+            switch(format) {
+                case ImageFormat.JPEG: {
+                    ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
+                    byte[] bytes = new byte[buffer.remaining()];
+                    buffer.get(bytes);
+                    FileOutputStream output = null;
+                    try {
+                        output = new FileOutputStream(mFile);
+                        output.write(bytes);
+                        success = true;
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    } finally {
+                        mImage.close();
+                        closeOutput(output);
+                    }
+                    break;
+                }
+                case ImageFormat.RAW_SENSOR: {
+                    DngCreator dngCreator = new DngCreator(mCharacteristics, mCaptureResult);
+                    FileOutputStream output = null;
+                    try {
+                        output = new FileOutputStream(mFile);
+                        dngCreator.writeImage(output, mImage);
+                        success = true;
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    } finally {
+                        mImage.close();
+                        closeOutput(output);
+                    }
+                    break;
+                }
+                default: {
+                    Log.e(TAG, "Cannot save image, unexpected image format:" + format);
+                    break;
+                }
+            }
+
+            // Decrement reference count to allow ImageReader to be closed to free up resources.
+            mReader.close();
+
+            // If saving the file succeeded, update MediaStore.
+            if (success) {
+                MediaScannerConnection.scanFile(mContext, new String[] { mFile.getPath()},
+                /*mimeTypes*/null, new MediaScannerConnection.MediaScannerConnectionClient() {
+                    @Override
+                    public void onMediaScannerConnected() {
+                        // Do nothing
+                    }
+
+                    @Override
+                    public void onScanCompleted(String path, Uri uri) {
+                        Log.i(TAG, "Scanned " + path + ":");
+                        Log.i(TAG, "-> uri=" + uri);
+                    }
+                });
+            }
+        }
+
+        /**
+         * Builder class for constructing {@link ImageSaver}s.
+         *
+         * This class is thread safe.
+         */
+        public static class ImageSaverBuilder {
+            private Image mImage;
+            private File mFile;
+            private CaptureResult mCaptureResult;
+            private CameraCharacteristics mCharacteristics;
+            private Context mContext;
+            private RefCountedAutoCloseable<ImageReader> mReader;
+
+            /**
+             * Construct a new ImageSaverBuilder using the given {@link Context}.
+             * @param context a {@link Context} to for accessing the
+             *                  {@link android.provider.MediaStore}.
+             */
+            public ImageSaverBuilder(final Context context) {
+                mContext = context;
+            }
+
+            public synchronized ImageSaverBuilder setRefCountedReader(
+                    RefCountedAutoCloseable<ImageReader> reader) {
+                if (reader == null ) throw new NullPointerException();
+
+                mReader = reader;
+                return this;
+            }
+
+            public synchronized ImageSaverBuilder setImage(final Image image) {
+                if (image == null) throw new NullPointerException();
+                mImage = image;
+                return this;
+            }
+
+            public synchronized ImageSaverBuilder setFile(final File file) {
+                if (file == null) throw new NullPointerException();
+                mFile = file;
+                return this;
+            }
+
+            public synchronized ImageSaverBuilder setResult(final CaptureResult result) {
+                if (result == null) throw new NullPointerException();
+                mCaptureResult = result;
+                return this;
+            }
+
+            public synchronized ImageSaverBuilder setCharacteristics(
+                    final CameraCharacteristics characteristics) {
+                if (characteristics == null) throw new NullPointerException();
+                mCharacteristics = characteristics;
+                return this;
+            }
+
+            public synchronized ImageSaver buildIfComplete() {
+                if (!isComplete()) {
+                    return null;
+                }
+                return new ImageSaver(mImage, mFile, mCaptureResult, mCharacteristics, mContext,
+                        mReader);
+            }
+
+            public synchronized String getSaveLocation() {
+                return (mFile == null) ? "Unknown" : mFile.toString();
+            }
+
+            private boolean isComplete() {
+                return mImage != null && mFile != null && mCaptureResult != null
+                        && mCharacteristics != null;
+            }
+        }
+    }
+
+    // Utility classes and methods:
+    // *********************************************************************************************
+
+    /**
+     * Comparator based on area of the given {@link Size} objects.
+     */
+    static class CompareSizesByArea implements Comparator<Size> {
+
+        @Override
+        public int compare(Size lhs, Size rhs) {
+            // We cast here to ensure the multiplications won't overflow
+            return Long.signum((long) lhs.getWidth() * lhs.getHeight() -
+                    (long) rhs.getWidth() * rhs.getHeight());
+        }
+
+    }
+
+    /**
+     * A dialog fragment for displaying non-recoverable errors; this {@ling Activity} will be
+     * finished once the dialog has been acknowledged by the user.
+     */
+    public static class ErrorDialog extends DialogFragment {
+
+        private String mErrorMessage;
+
+        public ErrorDialog() {
+            mErrorMessage = "Unknown error occurred!";
+        }
+
+        // Build a dialog with a custom message (Fragments require default constructor).
+        public static ErrorDialog buildErrorDialog(String errorMessage) {
+            ErrorDialog dialog = new ErrorDialog();
+            dialog.mErrorMessage = errorMessage;
+            return dialog;
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            final Activity activity = getActivity();
+            return new AlertDialog.Builder(activity)
+                    .setMessage(mErrorMessage)
+                    .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialogInterface, int i) {
+                            activity.finish();
+                        }
+                    })
+                    .create();
+        }
+    }
+
+    /**
+     * A wrapper for an {@link AutoCloseable} object that implements reference counting to allow
+     * for resource management.
+     */
+    public static class RefCountedAutoCloseable<T extends AutoCloseable> implements AutoCloseable {
+        private T mObject;
+        private long mRefCount = 0;
+
+        /**
+         * Wrap the given object.
+         * @param object an object to wrap.
+         */
+        public RefCountedAutoCloseable(T object) {
+            if (object == null) throw new NullPointerException();
+            mObject = object;
+        }
+
+        /**
+         * Increment the reference count and return the wrapped object.
+         *
+         * @return the wrapped object, or null if the object has been released.
+         */
+        public synchronized T getAndRetain() {
+            if (mRefCount < 0) {
+                return null;
+            }
+            mRefCount++;
+            return mObject;
+        }
+
+        /**
+         * Return the wrapped object.
+         *
+         * @return the wrapped object, or null if the object has been released.
+         */
+        public synchronized T get() {
+            return mObject;
+        }
+
+        /**
+         * Decrement the reference count and release the wrapped object if there are no other
+         * users retaining this object.
+         */
+        @Override
+        public synchronized void close() {
+            if (mRefCount >= 0) {
+                mRefCount--;
+                if (mRefCount < 0) {
+                    try {
+                        mObject.close();
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    } finally {
+                        mObject = null;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose
+     * width and height are at least as large as the respective requested values, and whose aspect
+     * ratio matches with the specified value.
+     *
+     * @param choices     The list of sizes that the camera supports for the intended output class
+     * @param width       The minimum desired width
+     * @param height      The minimum desired height
+     * @param aspectRatio The aspect ratio
+     * @return The optimal {@code Size}, or an arbitrary one if none were big enough
+     */
+    private static Size chooseOptimalSize(Size[] choices, int width, int height, Size aspectRatio) {
+        // Collect the supported resolutions that are at least as big as the preview Surface
+        List<Size> bigEnough = new ArrayList<>();
+        int w = aspectRatio.getWidth();
+        int h = aspectRatio.getHeight();
+        for (Size option : choices) {
+            if (option.getHeight() == option.getWidth() * h / w &&
+                    option.getWidth() >= width && option.getHeight() >= height) {
+                bigEnough.add(option);
+            }
+        }
+
+        // Pick the smallest of those, assuming we found any
+        if (bigEnough.size() > 0) {
+            return Collections.min(bigEnough, new CompareSizesByArea());
+        } else {
+            Log.e(TAG, "Couldn't find any suitable preview size");
+            return choices[0];
+        }
+    }
+
+    /**
+     * Generate a string containing a formatted timestamp with the current date and time.
+     *
+     * @return a {@link String} representing a time.
+     */
+    private static String generateTimestamp() {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS", Locale.US);
+        return sdf.format(new Date());
+    }
+
+    /**
+     * Cleanup the given {@link OutputStream}.
+     *
+     * @param outputStream the stream to close.
+     */
+    private static void closeOutput(OutputStream outputStream) {
+        if (null != outputStream) {
+            try {
+                outputStream.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * Return true if the given array contains the given integer.
+     *
+     * @param modes array to check.
+     * @param mode integer to get for.
+     * @return true if the array contains the given integer, otherwise false.
+     */
+    private static boolean contains(int[] modes, int mode) {
+        if (modes == null) {
+            return false;
+        }
+        for (int i : modes) {
+            if (i == mode) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Return true if the two given {@link Size}s have the same aspect ratio.
+     *
+     * @param a first {@link Size} to compare.
+     * @param b second {@link Size} to compare.
+     * @return true if the sizes have the same aspect ratio, otherwise false.
+     */
+    private static boolean checkAspectsEqual(Size a, Size b) {
+        double aAspect = a.getWidth() / (double) a.getHeight();
+        double bAspect = b.getWidth() / (double) b.getHeight();
+        return Math.abs(aAspect - bAspect) <= ASPECT_RATIO_TOLERANCE;
+    }
+
+    /**
+     * Rotation need to transform from the camera sensor orientation to the device's current
+     * orientation.
+     * @param c the {@link CameraCharacteristics} to query for the camera sensor orientation.
+     * @param deviceOrientation the current device orientation relative to the native device
+     *                          orientation.
+     * @return the total rotation from the sensor orientation to the current device orientation.
+     */
+    private static int sensorToDeviceRotation(CameraCharacteristics c, int deviceOrientation) {
+        int sensorOrientation = c.get(CameraCharacteristics.SENSOR_ORIENTATION);
+
+        // Get device orientation in degrees
+        deviceOrientation = ORIENTATIONS.get(deviceOrientation);
+
+        // Reverse device orientation for front-facing cameras
+        if (c.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) {
+            deviceOrientation = -deviceOrientation;
+        }
+
+        // Calculate desired JPEG orientation relative to camera orientation to make
+        // the image upright relative to the device orientation
+        return (sensorOrientation + deviceOrientation + 360) % 360;
+    }
+
+    /**
+     * Shows a {@link Toast} on the UI thread.
+     *
+     * @param text The message to show.
+     */
+    private void showToast(String text) {
+        // We show a Toast by sending request message to mMessageHandler. This makes sure that the
+        // Toast is shown on the UI thread.
+        Message message = Message.obtain();
+        message.obj = text;
+        mMessageHandler.sendMessage(message);
+    }
+
+    /**
+     * If the given request has been completed, remove it from the queue of active requests and
+     * send an {@link ImageSaver} with the results from this request to a background thread to
+     * save a file.
+     *
+     * Call this only with {@link #mCameraStateLock} held.
+     *
+     * @param requestId the ID of the {@link CaptureRequest} to handle.
+     * @param builder the {@link ImageSaver.ImageSaverBuilder} for this request.
+     * @param queue the queue to remove this request from, if completed.
+     */
+    private void handleCompletionLocked(int requestId, ImageSaver.ImageSaverBuilder builder,
+                                        TreeMap<Integer, ImageSaver.ImageSaverBuilder> queue) {
+        if (builder == null) return;
+        ImageSaver saver = builder.buildIfComplete();
+        if (saver != null) {
+            queue.remove(requestId);
+            AsyncTask.THREAD_POOL_EXECUTOR.execute(saver);
+        }
+    }
+
+    /**
+     * Check if we are using a device that only supports the LEGACY hardware level.
+     *
+     * Call this only with {@link #mCameraStateLock} held.
+     *
+     * @return true if this is a legacy device.
+     */
+    private boolean isLegacyLocked() {
+        return mCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) ==
+                CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY;
+    }
+
+    /**
+     * Start the timer for the pre-capture sequence.
+     *
+     * Call this only with {@link #mCameraStateLock} held.
+     */
+    private void startTimerLocked() {
+        mCaptureTimer = SystemClock.elapsedRealtime();
+    }
+
+    /**
+     * Check if the timer for the pre-capture sequence has been hit.
+     *
+     * Call this only with {@link #mCameraStateLock} held.
+     *
+     * @return true if the timeout occurred.
+     */
+    private boolean hitTimeoutLocked() {
+        return (SystemClock.elapsedRealtime() - mCaptureTimer) > PRECAPTURE_TIMEOUT_MS;
+    }
+
+    // *********************************************************************************************
+
+}
diff --git a/samples/browseable/Camera2Raw/src/com.example.android.camera2raw/CameraActivity.java b/samples/browseable/Camera2Raw/src/com.example.android.camera2raw/CameraActivity.java
new file mode 100644
index 0000000..e56efab
--- /dev/null
+++ b/samples/browseable/Camera2Raw/src/com.example.android.camera2raw/CameraActivity.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2015 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.camera2raw;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Activity displaying a fragment that implements RAW photo captures.
+ */
+public class CameraActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_camera);
+        if (null == savedInstanceState) {
+            getFragmentManager().beginTransaction()
+                    .replace(R.id.container, Camera2RawFragment.newInstance())
+                    .commit();
+        }
+    }
+
+}
diff --git a/samples/browseable/ConfirmCredential/AndroidManifest.xml b/samples/browseable/ConfirmCredential/AndroidManifest.xml
new file mode 100644
index 0000000..12f9456
--- /dev/null
+++ b/samples/browseable/ConfirmCredential/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 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
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.example.android.confirmcredential" >
+
+    <application
+            android:allowBackup="true"
+            android:icon="@mipmap/ic_launcher"
+            android:label="@string/app_name"
+            android:theme="@style/AppTheme" >
+        <activity
+                android:name=".MainActivity"
+                android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
diff --git a/samples/browseable/ConfirmCredential/_index.jd b/samples/browseable/ConfirmCredential/_index.jd
new file mode 100644
index 0000000..206db44
--- /dev/null
+++ b/samples/browseable/ConfirmCredential/_index.jd
@@ -0,0 +1,11 @@
+
+page.tags="Confirm Credential"
+sample.group=security
+@jd:body
+
+<p>
+            
+This sample demonstrates how you can use device credentials (PIN, Pattern, Password) in your app
+to authenticate the user before they are trying to complete some actions.
+            
+        </p>
diff --git a/samples/browseable/ConfirmCredential/res/drawable-hdpi/tile.9.png b/samples/browseable/ConfirmCredential/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/samples/browseable/ConfirmCredential/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/samples/browseable/ConfirmCredential/res/drawable-nodpi/android_robot.png b/samples/browseable/ConfirmCredential/res/drawable-nodpi/android_robot.png
new file mode 100644
index 0000000..40bf934
--- /dev/null
+++ b/samples/browseable/ConfirmCredential/res/drawable-nodpi/android_robot.png
Binary files differ
diff --git a/samples/browseable/ConfirmCredential/res/drawable/card.xml b/samples/browseable/ConfirmCredential/res/drawable/card.xml
new file mode 100644
index 0000000..691a4c5
--- /dev/null
+++ b/samples/browseable/ConfirmCredential/res/drawable/card.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 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
+  -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <solid
+        android:color="#fefefe"/>
+
+    <corners
+        android:radius="2dp" />
+</shape>
\ No newline at end of file
diff --git a/samples/browseable/ConfirmCredential/res/layout/activity_main.xml b/samples/browseable/ConfirmCredential/res/layout/activity_main.xml
new file mode 100644
index 0000000..da65a00
--- /dev/null
+++ b/samples/browseable/ConfirmCredential/res/layout/activity_main.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 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
+  -->
+<ScrollView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:orientation="vertical">
+
+        <ImageView
+                android:layout_width="150dp"
+                android:layout_height="150dp"
+                android:layout_marginTop="32dp"
+                android:layout_marginBottom="32dp"
+                android:layout_gravity="center_horizontal"
+                android:scaleType="fitCenter"
+                android:src="@drawable/android_robot"/>
+
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="8dp"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="8dp"
+                android:orientation="vertical"
+                android:background="@drawable/card"
+                android:elevation="4dp"
+                android:paddingTop="16dp"
+                android:paddingBottom="16dp"
+                android:paddingStart="16dp"
+                android:paddingEnd="16dp">
+
+            <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textAppearance="@android:style/TextAppearance.Material.Headline"
+                    android:text="@string/item_title"/>
+
+            <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textAppearance="@android:style/TextAppearance.Material.Body2"
+                    android:textColor="?android:attr/colorAccent"
+                    android:text="@string/item_price"/>
+
+            <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="16dp"
+                    android:textAppearance="@android:style/TextAppearance.Material.Body1"
+                    android:textColor="?android:attr/textColorSecondary"
+                    android:text="@string/item_description"/>
+
+        </LinearLayout>
+        <Button style="@android:style/Widget.Material.Button.Colored"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="8dp"
+                android:layout_marginEnd="4dp"
+                android:layout_gravity="end"
+                android:textColor="?android:attr/textColorPrimaryInverse"
+                android:text="@string/purchase"
+                android:id="@+id/purchase_button"
+                android:layout_alignParentEnd="true"/>
+
+        <TextView
+                android:id="@+id/confirmation_message"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="16dp"
+                android:paddingStart="16dp"
+                android:paddingEnd="16dp"
+                android:textAppearance="@android:style/TextAppearance.Material.Body2"
+                android:textColor="?android:attr/colorAccent"
+                android:text="@string/purchase_done"
+                android:visibility="gone"/>
+
+        <TextView
+                android:id="@+id/already_has_valid_device_credential_message"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="16dp"
+                android:paddingStart="16dp"
+                android:paddingEnd="16dp"
+                android:textAppearance="@android:style/TextAppearance.Material.Body2"
+                android:textColor="?android:attr/colorAccent"
+                android:text="@string/already_confirmed_device_credentials_within_last_x_seconds"
+                android:visibility="gone"/>
+    </LinearLayout>
+</ScrollView>
diff --git a/samples/browseable/ConfirmCredential/res/mipmap-hdpi/ic_launcher.png b/samples/browseable/ConfirmCredential/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..e9cd9e3
--- /dev/null
+++ b/samples/browseable/ConfirmCredential/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/ConfirmCredential/res/mipmap-mdpi/ic_launcher.png b/samples/browseable/ConfirmCredential/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..b6c3e31
--- /dev/null
+++ b/samples/browseable/ConfirmCredential/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/ConfirmCredential/res/mipmap-xhdpi/ic_launcher.png b/samples/browseable/ConfirmCredential/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..85a14a0
--- /dev/null
+++ b/samples/browseable/ConfirmCredential/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/ConfirmCredential/res/mipmap-xxhdpi/ic_launcher.png b/samples/browseable/ConfirmCredential/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..d9d35b0
--- /dev/null
+++ b/samples/browseable/ConfirmCredential/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/ConfirmCredential/res/mipmap-xxxhdpi/ic_launcher.png b/samples/browseable/ConfirmCredential/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..a764233
--- /dev/null
+++ b/samples/browseable/ConfirmCredential/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/values/dimens.xml b/samples/browseable/ConfirmCredential/res/values-sw600dp/template-dimens.xml
similarity index 71%
copy from samples/ActionBarCompat/res/values/dimens.xml
copy to samples/browseable/ConfirmCredential/res/values-sw600dp/template-dimens.xml
index 67c8436..22074a2 100644
--- a/samples/ActionBarCompat/res/values/dimens.xml
+++ b/samples/browseable/ConfirmCredential/res/values-sw600dp/template-dimens.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -15,7 +15,10 @@
   -->
 
 <resources>
-    <dimen name="actionbar_compat_height">48dp</dimen>
-    <dimen name="actionbar_compat_button_width">48dp</dimen>
-    <dimen name="actionbar_compat_button_home_width">56dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
 </resources>
diff --git a/samples/ActionBarCompat/res/values-v13/styles.xml b/samples/browseable/ConfirmCredential/res/values-sw600dp/template-styles.xml
similarity index 67%
copy from samples/ActionBarCompat/res/values-v13/styles.xml
copy to samples/browseable/ConfirmCredential/res/values-sw600dp/template-styles.xml
index 8a042b4..03d1974 100644
--- a/samples/ActionBarCompat/res/values-v13/styles.xml
+++ b/samples/browseable/ConfirmCredential/res/values-sw600dp/template-styles.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -16,8 +16,10 @@
 
 <resources>
 
-    <style name="ActionBarTitle" parent="android:style/TextAppearance.Holo.Widget.ActionBar.Title">
-        <item name="android:textColor">@color/actionbar_title_color</item>
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceLarge</item>
+        <item name="android:lineSpacingMultiplier">1.2</item>
+        <item name="android:shadowDy">-6.5</item>
     </style>
 
 </resources>
diff --git a/samples/ActionBarCompat/res/values/colors.xml b/samples/browseable/ConfirmCredential/res/values-v11/template-styles.xml
similarity index 79%
copy from samples/ActionBarCompat/res/values/colors.xml
copy to samples/browseable/ConfirmCredential/res/values-v11/template-styles.xml
index 4edc6d6..8c1ea66 100644
--- a/samples/ActionBarCompat/res/values/colors.xml
+++ b/samples/browseable/ConfirmCredential/res/values-v11/template-styles.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -15,5 +15,8 @@
   -->
 
 <resources>
-    <color name="actionbar_title_color">#224894</color>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
 </resources>
diff --git a/samples/browseable/ConfirmCredential/res/values-v21/base-colors.xml b/samples/browseable/ConfirmCredential/res/values-v21/base-colors.xml
new file mode 100644
index 0000000..8b6ec3f
--- /dev/null
+++ b/samples/browseable/ConfirmCredential/res/values-v21/base-colors.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+
+</resources>
diff --git a/samples/browseable/ConfirmCredential/res/values-v21/base-template-styles.xml b/samples/browseable/ConfirmCredential/res/values-v21/base-template-styles.xml
new file mode 100644
index 0000000..c778e4f
--- /dev/null
+++ b/samples/browseable/ConfirmCredential/res/values-v21/base-template-styles.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Material.Light">
+    </style>
+
+</resources>
diff --git a/samples/browseable/ConfirmCredential/res/values/base-strings.xml b/samples/browseable/ConfirmCredential/res/values/base-strings.xml
new file mode 100644
index 0000000..b3dab90
--- /dev/null
+++ b/samples/browseable/ConfirmCredential/res/values/base-strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+    <string name="app_name">Confirm Credential</string>
+    <string name="intro_message">
+        <![CDATA[
+        
+            
+This sample demonstrates how you can use device credentials (PIN, Pattern, Password) in your app
+to authenticate the user before they are trying to complete some actions.
+            
+        
+        ]]>
+    </string>
+</resources>
diff --git a/samples/browseable/ConfirmCredential/res/values/strings.xml b/samples/browseable/ConfirmCredential/res/values/strings.xml
new file mode 100644
index 0000000..b6ff9d3
--- /dev/null
+++ b/samples/browseable/ConfirmCredential/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 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
+  -->
+<resources>
+    <string name="purchase">Purchase</string>
+    <string name="item_title">White Mesh Pluto Backpack</string>
+    <string name="item_price">$62.68</string>
+    <string name="item_description">Mesh backpack in white. Black textile trim throughout.</string>
+    <string name="purchase_done">Device credential confirmed.</string>
+    <string name="already_confirmed_device_credentials_within_last_x_seconds">
+        The device credential has been already confirmed within the last %1$s seconds.</string>
+</resources>
diff --git a/samples/browseable/ConfirmCredential/res/values/template-dimens.xml b/samples/browseable/ConfirmCredential/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/samples/browseable/ConfirmCredential/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+  Copyright 2013 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.
+  -->
+
+<resources>
+
+    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+    <dimen name="margin_tiny">4dp</dimen>
+    <dimen name="margin_small">8dp</dimen>
+    <dimen name="margin_medium">16dp</dimen>
+    <dimen name="margin_large">32dp</dimen>
+    <dimen name="margin_huge">64dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/samples/browseable/ConfirmCredential/res/values/template-styles.xml b/samples/browseable/ConfirmCredential/res/values/template-styles.xml
new file mode 100644
index 0000000..6e7d593
--- /dev/null
+++ b/samples/browseable/ConfirmCredential/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+  Copyright 2013 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.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+
+    <style name="Theme.Base" parent="android:Theme.Light" />
+
+    <style name="Theme.Sample" parent="Theme.Base" />
+
+    <style name="AppTheme" parent="Theme.Sample" />
+    <!-- Widget styling -->
+
+    <style name="Widget" />
+
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceMedium</item>
+        <item name="android:lineSpacingMultiplier">1.1</item>
+    </style>
+
+    <style name="Widget.SampleMessageTile">
+        <item name="android:background">@drawable/tile</item>
+        <item name="android:shadowColor">#7F000000</item>
+        <item name="android:shadowDy">-3.5</item>
+        <item name="android:shadowRadius">2</item>
+    </style>
+
+</resources>
diff --git a/samples/browseable/ConfirmCredential/src/com.example.android.confirmcredential/MainActivity.java b/samples/browseable/ConfirmCredential/src/com.example.android.confirmcredential/MainActivity.java
new file mode 100644
index 0000000..b8cf6e1
--- /dev/null
+++ b/samples/browseable/ConfirmCredential/src/com.example.android.confirmcredential/MainActivity.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2015 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.confirmcredential;
+
+import android.app.Activity;
+import android.app.KeyguardManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyPermanentlyInvalidatedException;
+import android.security.keystore.KeyProperties;
+import android.security.keystore.UserNotAuthenticatedException;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+
+/**
+ * Main entry point for the sample, showing a backpack and "Purchase" button.
+ */
+public class MainActivity extends Activity {
+
+    /** Alias for our key in the Android Key Store. */
+    private static final String KEY_NAME = "my_key";
+    private static final byte[] SECRET_BYTE_ARRAY = new byte[] {1, 2, 3, 4, 5, 6};
+
+    private static final int REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS = 1;
+
+    /**
+     * If the user has unlocked the device Within the last this number of seconds,
+     * it can be considered as an authenticator.
+     */
+    private static final int AUTHENTICATION_DURATION_SECONDS = 30;
+
+    private KeyguardManager mKeyguardManager;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+        mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
+        Button purchaseButton = (Button) findViewById(R.id.purchase_button);
+        if (!mKeyguardManager.isKeyguardSecure()) {
+            // Show a message that the user hasn't set up a lock screen.
+            Toast.makeText(this,
+                    "Secure lock screen hasn't set up.\n"
+                            + "Go to 'Settings -> Security -> Screenlock' to set up a lock screen",
+                    Toast.LENGTH_LONG).show();
+            purchaseButton.setEnabled(false);
+            return;
+        }
+        createKey();
+        findViewById(R.id.purchase_button).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                // Test to encrypt something. It might fail if the timeout expired (30s).
+                tryEncrypt();
+            }
+        });
+    }
+
+    /**
+     * Tries to encrypt some data with the generated key in {@link #createKey} which is
+     * only works if the user has just authenticated via device credentials.
+     */
+    private void tryEncrypt() {
+        try {
+            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            SecretKey secretKey = (SecretKey) keyStore.getKey(KEY_NAME, null);
+            Cipher cipher = Cipher.getInstance(
+                    KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_CBC + "/"
+                            + KeyProperties.ENCRYPTION_PADDING_PKCS7);
+
+            // Try encrypting something, it will only work if the user authenticated within
+            // the last AUTHENTICATION_DURATION_SECONDS seconds.
+            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
+            cipher.doFinal(SECRET_BYTE_ARRAY);
+
+            // If the user has recently authenticated, you will reach here.
+            showAlreadyAuthenticated();
+        } catch (UserNotAuthenticatedException e) {
+            // User is not authenticated, let's authenticate with device credentials.
+            showAuthenticationScreen();
+        } catch (KeyPermanentlyInvalidatedException e) {
+            // This happens if the lock screen has been disabled or reset after the key was
+            // generated after the key was generated.
+            Toast.makeText(this, "Keys are invalidated after created. Retry the purchase\n"
+                            + e.getMessage(),
+                    Toast.LENGTH_LONG).show();
+        } catch (BadPaddingException | IllegalBlockSizeException | KeyStoreException |
+                CertificateException | UnrecoverableKeyException | IOException
+                | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Creates a symmetric key in the Android Key Store which can only be used after the user has
+     * authenticated with device credentials within the last X seconds.
+     */
+    private void createKey() {
+        // Generate a key to decrypt payment credentials, tokens, etc.
+        // This will most likely be a registration step for the user when they are setting up your app.
+        try {
+            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            KeyGenerator keyGenerator = KeyGenerator.getInstance(
+                    KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
+
+            // Set the alias of the entry in Android KeyStore where the key will appear
+            // and the constrains (purposes) in the constructor of the Builder
+            keyGenerator.init(new KeyGenParameterSpec.Builder(KEY_NAME,
+                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
+                    .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
+                    .setUserAuthenticationRequired(true)
+                            // Require that the user has unlocked in the last 30 seconds
+                    .setUserAuthenticationValidityDurationSeconds(AUTHENTICATION_DURATION_SECONDS)
+                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
+                    .build());
+            keyGenerator.generateKey();
+        } catch (NoSuchAlgorithmException | NoSuchProviderException
+                | InvalidAlgorithmParameterException | KeyStoreException
+                | CertificateException | IOException e) {
+            throw new RuntimeException("Failed to create a symmetric key", e);
+        }
+    }
+
+    private void showAuthenticationScreen() {
+        // Create the Confirm Credentials screen. You can customize the title and description. Or
+        // we will provide a generic one for you if you leave it null
+        Intent intent = mKeyguardManager.createConfirmDeviceCredentialIntent(null, null);
+        if (intent != null) {
+            startActivityForResult(intent, REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS);
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS) {
+            // Challenge completed, proceed with using cipher
+            if (resultCode == RESULT_OK) {
+                showPurchaseConfirmation();
+            } else {
+                // The user canceled or didn’t complete the lock screen
+                // operation. Go to error/cancellation flow.
+            }
+        }
+    }
+
+    private void showPurchaseConfirmation() {
+        findViewById(R.id.confirmation_message).setVisibility(View.VISIBLE);
+        findViewById(R.id.purchase_button).setEnabled(false);
+    }
+
+    private void showAlreadyAuthenticated() {
+        TextView textView = (TextView) findViewById(
+                R.id.already_has_valid_device_credential_message);
+        textView.setVisibility(View.VISIBLE);
+        textView.setText(getString(
+                R.string.already_confirmed_device_credentials_within_last_x_seconds,
+                AUTHENTICATION_DURATION_SECONDS));
+        findViewById(R.id.purchase_button).setEnabled(false);
+    }
+
+}
diff --git a/samples/browseable/FingerprintDialog/AndroidManifest.xml b/samples/browseable/FingerprintDialog/AndroidManifest.xml
new file mode 100644
index 0000000..5f754ad
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/AndroidManifest.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2015 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.example.android.fingerprintdialog"
+          android:versionCode="1"
+          android:versionName="1.0">
+
+    <uses-permission android:name="android.permission.USE_FINGERPRINT"/>
+
+    <application
+            android:name=".InjectedApplication"
+            android:allowBackup="true"
+            android:label="@string/app_name"
+            android:icon="@mipmap/ic_launcher"
+            android:theme="@style/AppTheme">
+
+        <activity android:name=".MainActivity"
+                  android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+    </application>
+
+
+</manifest>
diff --git a/samples/browseable/FingerprintDialog/_index.jd b/samples/browseable/FingerprintDialog/_index.jd
new file mode 100644
index 0000000..2044400
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/_index.jd
@@ -0,0 +1,11 @@
+
+page.tags="Fingerprint Dialog Sample"
+sample.group=security
+@jd:body
+
+<p>
+            
+This sample demonstrates how you can use registered fingerprints to authenticate the user
+before proceeding some actions such as purchasing an item.
+            
+        </p>
diff --git a/samples/browseable/FingerprintDialog/res/drawable-hdpi/ic_fp_40px.png b/samples/browseable/FingerprintDialog/res/drawable-hdpi/ic_fp_40px.png
new file mode 100644
index 0000000..48ebd8a
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/drawable-hdpi/ic_fp_40px.png
Binary files differ
diff --git a/samples/browseable/FingerprintDialog/res/drawable-hdpi/tile.9.png b/samples/browseable/FingerprintDialog/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/samples/browseable/FingerprintDialog/res/drawable-mdpi/ic_fp_40px.png b/samples/browseable/FingerprintDialog/res/drawable-mdpi/ic_fp_40px.png
new file mode 100644
index 0000000..122f442
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/drawable-mdpi/ic_fp_40px.png
Binary files differ
diff --git a/samples/browseable/FingerprintDialog/res/drawable-nodpi/android_robot.png b/samples/browseable/FingerprintDialog/res/drawable-nodpi/android_robot.png
new file mode 100644
index 0000000..40bf934
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/drawable-nodpi/android_robot.png
Binary files differ
diff --git a/samples/browseable/FingerprintDialog/res/drawable-xhdpi/ic_fp_40px.png b/samples/browseable/FingerprintDialog/res/drawable-xhdpi/ic_fp_40px.png
new file mode 100644
index 0000000..e1c9590
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/drawable-xhdpi/ic_fp_40px.png
Binary files differ
diff --git a/samples/browseable/FingerprintDialog/res/drawable-xxhdpi/ic_fp_40px.png b/samples/browseable/FingerprintDialog/res/drawable-xxhdpi/ic_fp_40px.png
new file mode 100644
index 0000000..f7e8724
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/drawable-xxhdpi/ic_fp_40px.png
Binary files differ
diff --git a/samples/browseable/FingerprintDialog/res/drawable-xxxhdpi/ic_fp_40px.png b/samples/browseable/FingerprintDialog/res/drawable-xxxhdpi/ic_fp_40px.png
new file mode 100644
index 0000000..0fb8545
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/drawable-xxxhdpi/ic_fp_40px.png
Binary files differ
diff --git a/samples/browseable/FingerprintDialog/res/drawable/card.xml b/samples/browseable/FingerprintDialog/res/drawable/card.xml
new file mode 100644
index 0000000..691a4c5
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/drawable/card.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 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
+  -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <solid
+        android:color="#fefefe"/>
+
+    <corners
+        android:radius="2dp" />
+</shape>
\ No newline at end of file
diff --git a/samples/browseable/FingerprintDialog/res/drawable/ic_fingerprint_error.xml b/samples/browseable/FingerprintDialog/res/drawable/ic_fingerprint_error.xml
new file mode 100644
index 0000000..be46116
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/drawable/ic_fingerprint_error.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 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
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="40.0dp"
+        android:height="40.0dp"
+        android:viewportWidth="40.0"
+        android:viewportHeight="40.0">
+    <path
+        android:pathData="M20.0,0.0C8.96,0.0 0.0,8.95 0.0,20.0s8.96,20.0 20.0,20.0c11.04,0.0 20.0,-8.95 20.0,-20.0S31.04,0.0 20.0,0.0z"
+        android:fillColor="#F4511E"/>
+    <path
+        android:pathData="M21.33,29.33l-2.67,0.0l0.0,-2.67l2.67,0.0L21.33,29.33zM21.33,22.67l-2.67,0.0l0.0,-12.0l2.67,0.0L21.33,22.67z"
+        android:fillColor="#FFFFFF"/>
+</vector>
diff --git a/samples/browseable/FingerprintDialog/res/drawable/ic_fingerprint_success.xml b/samples/browseable/FingerprintDialog/res/drawable/ic_fingerprint_success.xml
new file mode 100644
index 0000000..261f3e7
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/drawable/ic_fingerprint_success.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 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
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="40.0dp"
+        android:height="40.0dp"
+        android:viewportWidth="40.0"
+        android:viewportHeight="40.0">
+    <path
+        android:pathData="M20.0,20.0m-20.0,0.0a20.0,20.0 0.0,1.0 1.0,40.0 0.0a20.0,20.0 0.0,1.0 1.0,-40.0 0.0"
+        android:fillColor="#009688"/>
+    <path
+        android:pathData="M11.2,21.41l1.63,-1.619999 4.17,4.169998 10.59,-10.589999 1.619999,1.63 -12.209999,12.209999z"
+        android:fillColor="#FFFFFF"/>
+</vector>
diff --git a/samples/browseable/FingerprintDialog/res/layout/activity_main.xml b/samples/browseable/FingerprintDialog/res/layout/activity_main.xml
new file mode 100644
index 0000000..8f30557
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/layout/activity_main.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 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
+  -->
+<ScrollView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+    <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+
+        <ImageView
+                android:layout_width="150dp"
+                android:layout_height="150dp"
+                android:layout_marginTop="32dp"
+                android:layout_marginBottom="32dp"
+                android:layout_gravity="center_horizontal"
+                android:scaleType="fitCenter"
+                android:src="@drawable/android_robot"/>
+
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="8dp"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="8dp"
+                android:orientation="vertical"
+                android:background="@drawable/card"
+                android:elevation="4dp"
+                android:paddingTop="16dp"
+                android:paddingBottom="16dp"
+                android:paddingStart="16dp"
+                android:paddingEnd="16dp">
+
+            <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textAppearance="@android:style/TextAppearance.Material.Headline"
+                    android:text="@string/item_title"/>
+
+            <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textAppearance="@android:style/TextAppearance.Material.Body2"
+                    android:textColor="?android:attr/colorAccent"
+                    android:text="@string/item_price"/>
+
+            <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="16dp"
+                    android:textAppearance="@android:style/TextAppearance.Material.Body1"
+                    android:textColor="?android:attr/textColorSecondary"
+                    android:text="@string/item_description"/>
+
+        </LinearLayout>
+        <Button style="@android:style/Widget.Material.Button.Colored"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="8dp"
+                android:layout_marginEnd="4dp"
+                android:layout_gravity="end"
+                android:textColor="?android:attr/textColorPrimaryInverse"
+                android:text="@string/purchase"
+                android:id="@+id/purchase_button"
+                android:layout_alignParentEnd="true"/>
+
+        <TextView
+                android:id="@+id/confirmation_message"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="16dp"
+                android:paddingStart="16dp"
+                android:paddingEnd="16dp"
+                android:textAppearance="@android:style/TextAppearance.Material.Body2"
+                android:textColor="?android:attr/colorAccent"
+                android:text="@string/purchase_done"
+                android:visibility="gone"/>
+
+        <TextView
+                android:id="@+id/encrypted_message"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="16dp"
+                android:paddingStart="16dp"
+                android:paddingEnd="16dp"
+                android:textAppearance="@android:style/TextAppearance.Material.Body2"
+                android:textColor="?android:attr/colorAccent"
+                android:text="@string/purchase_done"
+                android:visibility="gone"/>
+    </LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/samples/browseable/FingerprintDialog/res/layout/fingerprint_dialog_backup.xml b/samples/browseable/FingerprintDialog/res/layout/fingerprint_dialog_backup.xml
new file mode 100644
index 0000000..0b88e33
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/layout/fingerprint_dialog_backup.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 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
+  -->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/backup_container"
+    android:layout_width="match_parent" android:layout_height="match_parent"
+    android:paddingTop="16dp"
+    android:paddingBottom="8dp">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+        android:text="@string/password_description"
+        android:id="@+id/description"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentStart="true"
+        android:layout_marginStart="24dp"
+        android:layout_marginEnd="24dp"
+        android:textColor="?android:attr/textColorSecondary"/>
+
+    <EditText
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:inputType="textPassword"
+        android:ems="10"
+        android:hint="@string/password"
+        android:imeOptions="actionGo"
+        android:id="@+id/password"
+        android:layout_below="@+id/description"
+        android:layout_marginTop="16dp"
+        android:layout_marginStart="20dp"
+        android:layout_marginEnd="20dp"
+        android:layout_alignParentStart="true" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/samples/browseable/FingerprintDialog/res/layout/fingerprint_dialog_container.xml b/samples/browseable/FingerprintDialog/res/layout/fingerprint_dialog_container.xml
new file mode 100644
index 0000000..08bb1bb
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/layout/fingerprint_dialog_container.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 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
+  -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <FrameLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+
+        <include layout="@layout/fingerprint_dialog_content" />
+
+        <include
+            layout="@layout/fingerprint_dialog_backup"
+            android:visibility="gone" />
+
+    </FrameLayout>
+
+    <LinearLayout
+        android:id="@+id/buttonPanel"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingStart="12dp"
+        android:paddingEnd="12dp"
+        android:paddingTop="4dp"
+        android:paddingBottom="4dp"
+        android:gravity="bottom"
+        style="?android:attr/buttonBarStyle">
+
+        <Space
+            android:id="@+id/spacer"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            android:visibility="invisible" />
+        <Button
+            android:id="@+id/cancel_button"
+            style="?android:attr/buttonBarNegativeButtonStyle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"/>
+
+        <Button
+            android:id="@+id/second_dialog_button"
+            style="?android:attr/buttonBarPositiveButtonStyle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"/>
+    </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/browseable/FingerprintDialog/res/layout/fingerprint_dialog_content.xml b/samples/browseable/FingerprintDialog/res/layout/fingerprint_dialog_content.xml
new file mode 100644
index 0000000..b56ccbb
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/layout/fingerprint_dialog_content.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 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
+  -->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/fingerprint_container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:paddingBottom="8dp"
+    android:paddingLeft="24dp"
+    android:paddingRight="24dp"
+    android:paddingTop="16dp">
+
+    <TextView
+        android:id="@+id/fingerprint_description"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentStart="true"
+        android:layout_alignParentTop="true"
+        android:text="@string/fingerprint_description"
+        android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+        android:textColor="?android:attr/textColorSecondary"/>
+
+
+    <ImageView
+        android:id="@+id/fingerprint_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentStart="true"
+        android:layout_below="@+id/fingerprint_description"
+        android:layout_marginTop="20dp"
+        android:src="@drawable/ic_fp_40px" />
+
+    <TextView
+        android:id="@+id/fingerprint_status"
+        style="@android:style/TextAppearance.Material.Body1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBottom="@+id/fingerprint_icon"
+        android:layout_alignTop="@+id/fingerprint_icon"
+        android:layout_marginLeft="16dp"
+        android:layout_toEndOf="@+id/fingerprint_icon"
+        android:gravity="center_vertical"
+        android:text="@string/fingerprint_hint"
+        android:textColor="@color/hint_color" />
+</RelativeLayout>
\ No newline at end of file
diff --git a/samples/browseable/FingerprintDialog/res/mipmap-hdpi/ic_launcher.png b/samples/browseable/FingerprintDialog/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..68c473a
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/FingerprintDialog/res/mipmap-mdpi/ic_launcher.png b/samples/browseable/FingerprintDialog/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..fd7e5f6
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/FingerprintDialog/res/mipmap-xhdpi/ic_launcher.png b/samples/browseable/FingerprintDialog/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..106c0d3
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/FingerprintDialog/res/mipmap-xxhdpi/ic_launcher.png b/samples/browseable/FingerprintDialog/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b319beb
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/FingerprintDialog/res/mipmap-xxxhdpi/ic_launcher.png b/samples/browseable/FingerprintDialog/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4dc0ddf
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/values/dimens.xml b/samples/browseable/FingerprintDialog/res/values-sw600dp/template-dimens.xml
similarity index 71%
copy from samples/ActionBarCompat/res/values/dimens.xml
copy to samples/browseable/FingerprintDialog/res/values-sw600dp/template-dimens.xml
index 67c8436..22074a2 100644
--- a/samples/ActionBarCompat/res/values/dimens.xml
+++ b/samples/browseable/FingerprintDialog/res/values-sw600dp/template-dimens.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -15,7 +15,10 @@
   -->
 
 <resources>
-    <dimen name="actionbar_compat_height">48dp</dimen>
-    <dimen name="actionbar_compat_button_width">48dp</dimen>
-    <dimen name="actionbar_compat_button_home_width">56dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
 </resources>
diff --git a/samples/ActionBarCompat/res/values-v13/styles.xml b/samples/browseable/FingerprintDialog/res/values-sw600dp/template-styles.xml
similarity index 67%
copy from samples/ActionBarCompat/res/values-v13/styles.xml
copy to samples/browseable/FingerprintDialog/res/values-sw600dp/template-styles.xml
index 8a042b4..03d1974 100644
--- a/samples/ActionBarCompat/res/values-v13/styles.xml
+++ b/samples/browseable/FingerprintDialog/res/values-sw600dp/template-styles.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -16,8 +16,10 @@
 
 <resources>
 
-    <style name="ActionBarTitle" parent="android:style/TextAppearance.Holo.Widget.ActionBar.Title">
-        <item name="android:textColor">@color/actionbar_title_color</item>
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceLarge</item>
+        <item name="android:lineSpacingMultiplier">1.2</item>
+        <item name="android:shadowDy">-6.5</item>
     </style>
 
 </resources>
diff --git a/samples/ActionBarCompat/res/values/colors.xml b/samples/browseable/FingerprintDialog/res/values-v11/template-styles.xml
similarity index 79%
copy from samples/ActionBarCompat/res/values/colors.xml
copy to samples/browseable/FingerprintDialog/res/values-v11/template-styles.xml
index 4edc6d6..8c1ea66 100644
--- a/samples/ActionBarCompat/res/values/colors.xml
+++ b/samples/browseable/FingerprintDialog/res/values-v11/template-styles.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -15,5 +15,8 @@
   -->
 
 <resources>
-    <color name="actionbar_title_color">#224894</color>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
 </resources>
diff --git a/samples/browseable/FingerprintDialog/res/values-v21/base-colors.xml b/samples/browseable/FingerprintDialog/res/values-v21/base-colors.xml
new file mode 100644
index 0000000..8b6ec3f
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/values-v21/base-colors.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+
+</resources>
diff --git a/samples/browseable/FingerprintDialog/res/values-v21/base-template-styles.xml b/samples/browseable/FingerprintDialog/res/values-v21/base-template-styles.xml
new file mode 100644
index 0000000..c778e4f
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/values-v21/base-template-styles.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Material.Light">
+    </style>
+
+</resources>
diff --git a/samples/browseable/FingerprintDialog/res/values/base-strings.xml b/samples/browseable/FingerprintDialog/res/values/base-strings.xml
new file mode 100644
index 0000000..f3545f5
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/values/base-strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+    <string name="app_name">Fingerprint Dialog Sample</string>
+    <string name="intro_message">
+        <![CDATA[
+        
+            
+This sample demonstrates how you can use registered fingerprints to authenticate the user
+before proceeding some actions such as purchasing an item.
+            
+        
+        ]]>
+    </string>
+</resources>
diff --git a/samples/browseable/FingerprintDialog/res/values/colors.xml b/samples/browseable/FingerprintDialog/res/values/colors.xml
new file mode 100644
index 0000000..a24f3c8
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/values/colors.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 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
+  -->
+<resources>
+    <color name="warning_color">#f4511e</color>
+    <color name="hint_color">#42000000</color>
+    <color name="success_color">#009688</color>
+</resources>
diff --git a/samples/browseable/FingerprintDialog/res/values/strings.xml b/samples/browseable/FingerprintDialog/res/values/strings.xml
new file mode 100644
index 0000000..8a6ecde
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/values/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 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
+  -->
+<resources>
+    <string name="action_settings">Settings</string>
+    <string name="cancel">Cancel</string>
+    <string name="use_password">Use password</string>
+    <string name="sign_in">Sign in</string>
+    <string name="ok">Ok</string>
+    <string name="password">Password</string>
+    <string name="fingerprint_description">Confirm fingerprint to continue</string>
+    <string name="fingerprint_hint">Touch sensor</string>
+    <string name="password_description">Enter your store password to continue</string>
+    <string name="purchase">Purchase</string>
+    <string name="fingerprint_not_recognized">Fingerprint not recognized. Try again</string>
+    <string name="fingerprint_success">Fingerprint recognized</string>
+    <string name="item_title">White Mesh Pluto Backpack</string>
+    <string name="item_price">$62.68</string>
+    <string name="item_description">Mesh backpack in white. Black textile trim throughout.</string>
+    <string name="purchase_done">Purchase successful</string>
+</resources>
diff --git a/samples/browseable/FingerprintDialog/res/values/template-dimens.xml b/samples/browseable/FingerprintDialog/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+  Copyright 2013 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.
+  -->
+
+<resources>
+
+    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+    <dimen name="margin_tiny">4dp</dimen>
+    <dimen name="margin_small">8dp</dimen>
+    <dimen name="margin_medium">16dp</dimen>
+    <dimen name="margin_large">32dp</dimen>
+    <dimen name="margin_huge">64dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/samples/browseable/FingerprintDialog/res/values/template-styles.xml b/samples/browseable/FingerprintDialog/res/values/template-styles.xml
new file mode 100644
index 0000000..6e7d593
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+  Copyright 2013 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.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+
+    <style name="Theme.Base" parent="android:Theme.Light" />
+
+    <style name="Theme.Sample" parent="Theme.Base" />
+
+    <style name="AppTheme" parent="Theme.Sample" />
+    <!-- Widget styling -->
+
+    <style name="Widget" />
+
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceMedium</item>
+        <item name="android:lineSpacingMultiplier">1.1</item>
+    </style>
+
+    <style name="Widget.SampleMessageTile">
+        <item name="android:background">@drawable/tile</item>
+        <item name="android:shadowColor">#7F000000</item>
+        <item name="android:shadowDy">-3.5</item>
+        <item name="android:shadowRadius">2</item>
+    </style>
+
+</resources>
diff --git a/samples/browseable/FingerprintDialog/src/com.example.android.fingerprintdialog/FingerprintAuthenticationDialogFragment.java b/samples/browseable/FingerprintDialog/src/com.example.android.fingerprintdialog/FingerprintAuthenticationDialogFragment.java
new file mode 100644
index 0000000..57c00de
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/src/com.example.android.fingerprintdialog/FingerprintAuthenticationDialogFragment.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2015 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.fingerprintdialog;
+
+import android.app.DialogFragment;
+import android.hardware.fingerprint.FingerprintManager;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import javax.inject.Inject;
+
+/**
+ * A dialog which uses fingerprint APIs to authenticate the user, and falls back to password
+ * authentication if fingerprint is not available.
+ */
+public class FingerprintAuthenticationDialogFragment extends DialogFragment
+        implements TextView.OnEditorActionListener, FingerprintUiHelper.Callback {
+
+    private Button mCancelButton;
+    private Button mSecondDialogButton;
+    private View mFingerprintContent;
+    private View mBackupContent;
+    private EditText mPassword;
+
+    private Stage mStage = Stage.FINGERPRINT;
+
+    private FingerprintManager.CryptoObject mCryptoObject;
+    private FingerprintUiHelper mFingerprintUiHelper;
+
+    @Inject FingerprintUiHelper.FingerprintUiHelperBuilder mFingerprintUiHelperBuilder;
+    @Inject InputMethodManager mInputMethodManager;
+
+    @Inject
+    public FingerprintAuthenticationDialogFragment() {}
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Do not create a new Fragment when the Activity is re-created such as orientation changes.
+        setRetainInstance(true);
+        setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Material_Light_Dialog);
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        getDialog().setTitle(getString(R.string.sign_in));
+        View v = inflater.inflate(R.layout.fingerprint_dialog_container, container, false);
+        mCancelButton = (Button) v.findViewById(R.id.cancel_button);
+        mCancelButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                dismiss();
+            }
+        });
+
+        mSecondDialogButton = (Button) v.findViewById(R.id.second_dialog_button);
+        mSecondDialogButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                if (mStage == Stage.FINGERPRINT) {
+                    goToBackup();
+                } else {
+                    verifyPassword();
+                }
+            }
+        });
+        mFingerprintContent = v.findViewById(R.id.fingerprint_container);
+        mBackupContent = v.findViewById(R.id.backup_container);
+        mPassword = (EditText) v.findViewById(R.id.password);
+        mPassword.setOnEditorActionListener(this);
+        mFingerprintUiHelper = mFingerprintUiHelperBuilder.build(
+                (ImageView) v.findViewById(R.id.fingerprint_icon),
+                (TextView) v.findViewById(R.id.fingerprint_status), this);
+        updateStage();
+
+        // If fingerprint authentication is not available, switch immediately to the backup
+        // (password) screen.
+        if (!mFingerprintUiHelper.isFingerprintAuthAvailable()) {
+            goToBackup();
+        }
+        return v;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        if (mStage == Stage.FINGERPRINT) {
+            mFingerprintUiHelper.startListening(mCryptoObject);
+        }
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mFingerprintUiHelper.stopListening();
+    }
+
+    /**
+     * Sets the crypto object to be passed in when authenticating with fingerprint.
+     */
+    public void setCryptoObject(FingerprintManager.CryptoObject cryptoObject) {
+        mCryptoObject = cryptoObject;
+    }
+
+    /**
+     * Switches to backup (password) screen. This either can happen when fingerprint is not
+     * available or the user chooses to use the password authentication method by pressing the
+     * button. This can also happen when the user had too many fingerprint attempts.
+     */
+    private void goToBackup() {
+        mStage = Stage.PASSWORD;
+        updateStage();
+        mPassword.requestFocus();
+
+        // Show the keyboard.
+        mPassword.postDelayed(mShowKeyboardRunnable, 500);
+
+        // Fingerprint is not used anymore. Stop listening for it.
+        mFingerprintUiHelper.stopListening();
+    }
+
+    /**
+     * Checks whether the current entered password is correct, and dismisses the the dialog and
+     * let's the activity know about the result.
+     */
+    private void verifyPassword() {
+        if (checkPassword(mPassword.getText().toString())) {
+            ((MainActivity) getActivity()).onPurchased(false /* without Fingerprint */);
+            dismiss();
+        } else {
+            // assume the password is always correct.
+        }
+    }
+
+    /**
+     * @return true if {@code password} is correct, false otherwise
+     */
+    private boolean checkPassword(String password) {
+        // Assume the password is always correct.
+        // In the real world situation, the password needs to be verified in the server side.
+        return password.length() > 0;
+    }
+
+    private final Runnable mShowKeyboardRunnable = new Runnable() {
+        @Override
+        public void run() {
+            mInputMethodManager.showSoftInput(mPassword, 0);
+        }
+    };
+
+    private void updateStage() {
+        switch (mStage) {
+            case FINGERPRINT:
+                mCancelButton.setText(R.string.cancel);
+                mSecondDialogButton.setText(R.string.use_password);
+                mFingerprintContent.setVisibility(View.VISIBLE);
+                mBackupContent.setVisibility(View.GONE);
+                break;
+            case PASSWORD:
+                mCancelButton.setText(R.string.cancel);
+                mSecondDialogButton.setText(R.string.ok);
+                mFingerprintContent.setVisibility(View.GONE);
+                mBackupContent.setVisibility(View.VISIBLE);
+                break;
+        }
+    }
+
+    @Override
+    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+        if (actionId == EditorInfo.IME_ACTION_GO) {
+            verifyPassword();
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void onAuthenticated() {
+        // Callback from FingerprintUiHelper. Let the activity know that authentication was
+        // successful.
+        ((MainActivity) getActivity()).onPurchased(true /* withFingerprint */);
+        dismiss();
+    }
+
+    @Override
+    public void onError() {
+        goToBackup();
+    }
+
+    /**
+     * Enumeration to indicate which authentication method the user is trying to authenticate with.
+     */
+    private enum Stage {
+        FINGERPRINT,
+        PASSWORD
+    }
+}
diff --git a/samples/browseable/FingerprintDialog/src/com.example.android.fingerprintdialog/FingerprintModule.java b/samples/browseable/FingerprintDialog/src/com.example.android.fingerprintdialog/FingerprintModule.java
new file mode 100644
index 0000000..16d5067
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/src/com.example.android.fingerprintdialog/FingerprintModule.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2015 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.fingerprintdialog;
+
+import android.app.KeyguardManager;
+import android.content.Context;
+import android.hardware.fingerprint.FingerprintManager;
+import android.view.inputmethod.InputMethodManager;
+
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * Dagger module for Fingerprint APIs.
+ */
+@Module(
+        library = true,
+        injects = {MainActivity.class}
+)
+public class FingerprintModule {
+
+    private final Context mContext;
+
+    public FingerprintModule(Context context) {
+        mContext = context;
+    }
+
+    @Provides
+    public Context providesContext() {
+        return mContext;
+    }
+
+    @Provides
+    public FingerprintManager providesFingerprintManager(Context context) {
+        return context.getSystemService(FingerprintManager.class);
+    }
+
+    @Provides
+    public KeyguardManager providesKeyguardManager(Context context) {
+        return context.getSystemService(KeyguardManager.class);
+    }
+
+    @Provides
+    public KeyStore providesKeystore() {
+        try {
+            return KeyStore.getInstance("AndroidKeyStore");
+        } catch (KeyStoreException e) {
+            throw new RuntimeException("Failed to get an instance of KeyStore", e);
+        }
+    }
+
+    @Provides
+    public KeyGenerator providesKeyGenerator() {
+        try {
+            return KeyGenerator.getInstance("AES", "AndroidKeyStore");
+        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
+            throw new RuntimeException("Failed to get an instance of KeyGenerator", e);
+        }
+    }
+
+    @Provides
+    public Cipher providesCipher(KeyStore keyStore) {
+        try {
+            return Cipher.getInstance("AES/CBC/PKCS7Padding");
+        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
+            throw new RuntimeException("Failed to get an instance of Cipher", e);
+        }
+    }
+
+    @Provides
+    public InputMethodManager providesInputMethodManager(Context context) {
+        return (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
+    }
+}
diff --git a/samples/browseable/FingerprintDialog/src/com.example.android.fingerprintdialog/FingerprintUiHelper.java b/samples/browseable/FingerprintDialog/src/com.example.android.fingerprintdialog/FingerprintUiHelper.java
new file mode 100644
index 0000000..ab7570c
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/src/com.example.android.fingerprintdialog/FingerprintUiHelper.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2015 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.fingerprintdialog;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import android.hardware.fingerprint.FingerprintManager;
+import android.os.CancellationSignal;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import javax.inject.Inject;
+
+/**
+ * Small helper class to manage text/icon around fingerprint authentication UI.
+ */
+public class FingerprintUiHelper extends FingerprintManager.AuthenticationCallback {
+
+    @VisibleForTesting static final long ERROR_TIMEOUT_MILLIS = 1600;
+    @VisibleForTesting static final long SUCCESS_DELAY_MILLIS = 1300;
+
+    private final FingerprintManager mFingerprintManager;
+    private final ImageView mIcon;
+    private final TextView mErrorTextView;
+    private final Callback mCallback;
+    private CancellationSignal mCancellationSignal;
+
+    @VisibleForTesting boolean mSelfCancelled;
+
+    /**
+     * Builder class for {@link FingerprintUiHelper} in which injected fields from Dagger
+     * holds its fields and takes other arguments in the {@link #build} method.
+     */
+    public static class FingerprintUiHelperBuilder {
+        private final FingerprintManager mFingerPrintManager;
+
+        @Inject
+        public FingerprintUiHelperBuilder(FingerprintManager fingerprintManager) {
+            mFingerPrintManager = fingerprintManager;
+        }
+
+        public FingerprintUiHelper build(ImageView icon, TextView errorTextView, Callback callback) {
+            return new FingerprintUiHelper(mFingerPrintManager, icon, errorTextView,
+                    callback);
+        }
+    }
+
+    /**
+     * Constructor for {@link FingerprintUiHelper}. This method is expected to be called from
+     * only the {@link FingerprintUiHelperBuilder} class.
+     */
+    private FingerprintUiHelper(FingerprintManager fingerprintManager,
+            ImageView icon, TextView errorTextView, Callback callback) {
+        mFingerprintManager = fingerprintManager;
+        mIcon = icon;
+        mErrorTextView = errorTextView;
+        mCallback = callback;
+    }
+
+    public boolean isFingerprintAuthAvailable() {
+        return mFingerprintManager.isHardwareDetected()
+                && mFingerprintManager.hasEnrolledFingerprints();
+    }
+
+    public void startListening(FingerprintManager.CryptoObject cryptoObject) {
+        if (!isFingerprintAuthAvailable()) {
+            return;
+        }
+        mCancellationSignal = new CancellationSignal();
+        mSelfCancelled = false;
+        mFingerprintManager.authenticate(cryptoObject, mCancellationSignal, this, 0 /* flags */);
+        mIcon.setImageResource(R.drawable.ic_fp_40px);
+    }
+
+    public void stopListening() {
+        if (mCancellationSignal != null) {
+            mSelfCancelled = true;
+            mCancellationSignal.cancel();
+            mCancellationSignal = null;
+        }
+    }
+
+    @Override
+    public void onAuthenticationError(int errMsgId, CharSequence errString) {
+        if (!mSelfCancelled) {
+            showError(errString);
+            mIcon.postDelayed(new Runnable() {
+                @Override
+                public void run() {
+                    mCallback.onError();
+                }
+            }, ERROR_TIMEOUT_MILLIS);
+        }
+    }
+
+    @Override
+    public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
+        showError(helpString);
+    }
+
+    @Override
+    public void onAuthenticationFailed() {
+        showError(mIcon.getResources().getString(
+                R.string.fingerprint_not_recognized));
+    }
+
+    @Override
+    public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
+        mErrorTextView.removeCallbacks(mResetErrorTextRunnable);
+        mIcon.setImageResource(R.drawable.ic_fingerprint_success);
+        mErrorTextView.setTextColor(
+                mErrorTextView.getResources().getColor(R.color.success_color, null));
+        mErrorTextView.setText(
+                mErrorTextView.getResources().getString(R.string.fingerprint_success));
+        mIcon.postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                mCallback.onAuthenticated();
+            }
+        }, SUCCESS_DELAY_MILLIS);
+    }
+
+    private void showError(CharSequence error) {
+        mIcon.setImageResource(R.drawable.ic_fingerprint_error);
+        mErrorTextView.setText(error);
+        mErrorTextView.setTextColor(
+                mErrorTextView.getResources().getColor(R.color.warning_color, null));
+        mErrorTextView.removeCallbacks(mResetErrorTextRunnable);
+        mErrorTextView.postDelayed(mResetErrorTextRunnable, ERROR_TIMEOUT_MILLIS);
+    }
+
+    @VisibleForTesting
+    Runnable mResetErrorTextRunnable = new Runnable() {
+        @Override
+        public void run() {
+            mErrorTextView.setTextColor(
+                    mErrorTextView.getResources().getColor(R.color.hint_color, null));
+            mErrorTextView.setText(
+                    mErrorTextView.getResources().getString(R.string.fingerprint_hint));
+            mIcon.setImageResource(R.drawable.ic_fp_40px);
+        }
+    };
+
+    public interface Callback {
+
+        void onAuthenticated();
+
+        void onError();
+    }
+}
diff --git a/samples/browseable/FingerprintDialog/src/com.example.android.fingerprintdialog/InjectedApplication.java b/samples/browseable/FingerprintDialog/src/com.example.android.fingerprintdialog/InjectedApplication.java
new file mode 100644
index 0000000..b7075a9
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/src/com.example.android.fingerprintdialog/InjectedApplication.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2015 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.fingerprintdialog;
+
+import android.app.Application;
+import android.util.Log;
+
+import dagger.ObjectGraph;
+
+/**
+ * The Application class of the sample which holds the ObjectGraph in Dagger and enables
+ * dependency injection.
+ */
+public class InjectedApplication extends Application {
+
+    private static final String TAG = InjectedApplication.class.getSimpleName();
+
+    private ObjectGraph mObjectGraph;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+
+        initObjectGraph(new FingerprintModule(this));
+    }
+
+    /**
+     * Initialize the Dagger module. Passing null or mock modules can be used for testing.
+     *
+     * @param module for Dagger
+     */
+    public void initObjectGraph(Object module) {
+        mObjectGraph = module != null ? ObjectGraph.create(module) : null;
+    }
+
+    public void inject(Object object) {
+        if (mObjectGraph == null) {
+            // This usually happens during tests.
+            Log.i(TAG, "Object graph is not initialized.");
+            return;
+        }
+        mObjectGraph.inject(object);
+    }
+
+}
diff --git a/samples/browseable/FingerprintDialog/src/com.example.android.fingerprintdialog/MainActivity.java b/samples/browseable/FingerprintDialog/src/com.example.android.fingerprintdialog/MainActivity.java
new file mode 100644
index 0000000..9d09765
--- /dev/null
+++ b/samples/browseable/FingerprintDialog/src/com.example.android.fingerprintdialog/MainActivity.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2015 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.fingerprintdialog;
+
+import android.Manifest;
+import android.app.Activity;
+import android.app.KeyguardManager;
+import android.content.pm.PackageManager;
+import android.hardware.fingerprint.FingerprintManager;
+import android.os.Bundle;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyPermanentlyInvalidatedException;
+import android.security.keystore.KeyProperties;
+import android.util.Base64;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.inject.Inject;
+
+/**
+ * Main entry point for the sample, showing a backpack and "Purchase" button.
+ */
+public class MainActivity extends Activity {
+
+    private static final String TAG = MainActivity.class.getSimpleName();
+
+    private static final String DIALOG_FRAGMENT_TAG = "myFragment";
+    private static final String SECRET_MESSAGE = "Very secret message";
+    /** Alias for our key in the Android Key Store */
+    private static final String KEY_NAME = "my_key";
+
+    @Inject KeyguardManager mKeyguardManager;
+    @Inject FingerprintAuthenticationDialogFragment mFragment;
+    @Inject KeyStore mKeyStore;
+    @Inject KeyGenerator mKeyGenerator;
+    @Inject Cipher mCipher;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        ((InjectedApplication) getApplication()).inject(this);
+
+        requestPermissions(new String[]{Manifest.permission.USE_FINGERPRINT}, 0);
+    }
+
+    @Override
+    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] state) {
+        if (requestCode == 0 && state[0] == PackageManager.PERMISSION_GRANTED) {
+            setContentView(R.layout.activity_main);
+            Button purchaseButton = (Button) findViewById(R.id.purchase_button);
+            if (!mKeyguardManager.isKeyguardSecure()) {
+                // Show a message that the user hasn't set up a fingerprint or lock screen.
+                Toast.makeText(this,
+                        "Secure lock screen hasn't set up.\n"
+                                + "Go to 'Settings -> Security -> Fingerprint' to set up a fingerprint",
+                        Toast.LENGTH_LONG).show();
+                purchaseButton.setEnabled(false);
+                return;
+            }
+            createKey();
+            purchaseButton.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+
+                    // Show the fingerprint dialog. The user has the option to use the fingerprint with
+                    // crypto, or you can fall back to using a server-side verified password.
+                    mFragment.setCryptoObject(new FingerprintManager.CryptoObject(mCipher));
+                    mFragment.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
+                }
+            });
+
+            // Set up the crypto object for later. The object will be authenticated by use
+            // of the fingerprint.
+            initCipher();
+        }
+    }
+
+    private void initCipher() {
+        try {
+            mKeyStore.load(null);
+            SecretKey key = (SecretKey) mKeyStore.getKey(KEY_NAME, null);
+            mCipher.init(Cipher.ENCRYPT_MODE, key);
+        } catch (KeyPermanentlyInvalidatedException e) {
+            // This happens if the lock screen has been disabled or reset after the key was
+            // generated, or if a fingerprint got enrolled after the key was generated.
+            Toast.makeText(this, "Keys are invalidated after created. Retry the purchase\n"
+                            + e.getMessage(),
+                    Toast.LENGTH_LONG).show();
+        } catch (KeyStoreException | CertificateException | UnrecoverableKeyException | IOException
+                | NoSuchAlgorithmException | InvalidKeyException e) {
+            throw new RuntimeException("Failed to init Cipher", e);
+        }
+    }
+
+    public void onPurchased(boolean withFingerprint) {
+        findViewById(R.id.purchase_button).setVisibility(View.GONE);
+        if (withFingerprint) {
+            // If the user has authenticated with fingerprint, verify that using cryptography and
+            // then show the confirmation message.
+            tryEncrypt();
+        } else {
+            // Authentication happened with backup password. Just show the confirmation message.
+            showConfirmation(null);
+        }
+    }
+
+    // Show confirmation, if fingerprint was used show crypto information.
+    private void showConfirmation(byte[] encrypted) {
+        findViewById(R.id.confirmation_message).setVisibility(View.VISIBLE);
+        if (encrypted != null) {
+            TextView v = (TextView) findViewById(R.id.encrypted_message);
+            v.setVisibility(View.VISIBLE);
+            v.setText(Base64.encodeToString(encrypted, 0 /* flags */));
+        }
+    }
+
+    /**
+     * Tries to encrypt some data with the generated key in {@link #createKey} which is
+     * only works if the user has just authenticated via fingerprint.
+     */
+    private void tryEncrypt() {
+        try {
+            byte[] encrypted = mCipher.doFinal(SECRET_MESSAGE.getBytes());
+            showConfirmation(encrypted);
+        } catch (BadPaddingException | IllegalBlockSizeException e) {
+            Toast.makeText(this, "Failed to encrypt the data with the generated key. "
+                    + "Retry the purchase", Toast.LENGTH_LONG).show();
+            Log.e(TAG, "Failed to encrypt the data with the generated key." + e.getMessage());
+        }
+    }
+
+    /**
+     * Creates a symmetric key in the Android Key Store which can only be used after the user has
+     * authenticated with fingerprint.
+     */
+    private void createKey() {
+        // The enrolling flow for fingerprint. This is where you ask the user to set up fingerprint
+        // for your flow. Use of keys is necessary if you need to know if the set of
+        // enrolled fingerprints has changed.
+        try {
+            mKeyStore.load(null);
+            // Set the alias of the entry in Android KeyStore where the key will appear
+            // and the constrains (purposes) in the constructor of the Builder
+            mKeyGenerator.init(new KeyGenParameterSpec.Builder(KEY_NAME,
+                    KeyProperties.PURPOSE_ENCRYPT |
+                            KeyProperties.PURPOSE_DECRYPT)
+                    .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
+                            // Require the user to authenticate with a fingerprint to authorize every use
+                            // of the key
+                    .setUserAuthenticationRequired(true)
+                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
+                    .build());
+            mKeyGenerator.generateKey();
+        } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException
+                | CertificateException | IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/samples/browseable/RuntimePermissions/AndroidManifest.xml b/samples/browseable/RuntimePermissions/AndroidManifest.xml
new file mode 100644
index 0000000..050b051
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/AndroidManifest.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2015 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.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.system.runtimepermissions" >
+
+    <!-- BEGIN_INCLUDE(manifest) -->
+
+    <!-- Note that all required permissions are declared here in the Android manifest.
+     On Android M and above, use of these permissions is only requested at run time. -->
+    <uses-permission android:name="android.permission.CAMERA"/>
+
+    <!-- The following permissions are only requested if the device is on M or above.
+     On older platforms these permissions are not requested and will not be available. -->
+    <uses-permission-sdk-m android:name="android.permission.READ_CONTACTS" />
+    <uses-permission-sdk-m android:name="android.permission.WRITE_CONTACTS" />
+
+    <!-- END_INCLUDE(manifest) -->
+
+    <application
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name=".MainActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+    </application>
+
+</manifest>
diff --git a/samples/browseable/RuntimePermissions/_index.jd b/samples/browseable/RuntimePermissions/_index.jd
new file mode 100644
index 0000000..75c6fee
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/_index.jd
@@ -0,0 +1,12 @@
+
+page.tags="RuntimePermissions"
+sample.group=System
+@jd:body
+
+<p>
+            
+            This sample shows runtime permissions available in the Android M and above.
+            Display the log to follow the execution.
+            If executed on an Android M device, an additional option to access contacts is shown.
+            
+        </p>
diff --git a/samples/browseable/RuntimePermissions/res/drawable-hdpi/tile.9.png b/samples/browseable/RuntimePermissions/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/samples/browseable/RuntimePermissions/res/layout-w720dp/activity_main.xml b/samples/browseable/RuntimePermissions/res/layout-w720dp/activity_main.xml
new file mode 100644
index 0000000..c9a52f6
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/res/layout-w720dp/activity_main.xml
@@ -0,0 +1,73 @@
+<!--
+  Copyright 2013 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.
+  -->
+<LinearLayout
+      xmlns:android="http://schemas.android.com/apk/res/android"
+      android:orientation="horizontal"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:id="@+id/sample_main_layout">
+
+    <LinearLayout
+          android:id="@+id/sample_output"
+          android:layout_width="0px"
+          android:layout_height="match_parent"
+          android:layout_weight="1"
+          android:orientation="vertical">
+
+        <FrameLayout
+              style="@style/Widget.SampleMessageTile"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content">
+
+            <TextView
+                  style="@style/Widget.SampleMessage"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:paddingLeft="@dimen/margin_medium"
+                  android:paddingRight="@dimen/margin_medium"
+                  android:paddingTop="@dimen/margin_large"
+                  android:paddingBottom="@dimen/margin_large"
+                  android:text="@string/intro_message" />
+        </FrameLayout>
+
+        <View
+              android:layout_width="match_parent"
+              android:layout_height="1dp"
+              android:background="@android:color/darker_gray" />
+
+        <fragment
+              android:name="com.example.android.common.logger.LogFragment"
+              android:id="@+id/log_fragment"
+              android:layout_width="match_parent"
+              android:layout_height="0px"
+              android:layout_weight="1" />
+
+    </LinearLayout>
+
+    <View
+          android:layout_width="1dp"
+          android:layout_height="match_parent"
+          android:background="@android:color/darker_gray" />
+
+    <FrameLayout
+          android:id="@+id/sample_content_fragment"
+          android:layout_weight="2"
+          android:layout_width="0px"
+          android:layout_height="match_parent" />
+
+</LinearLayout>
+
+
diff --git a/samples/browseable/RuntimePermissions/res/layout/activity_main.xml b/samples/browseable/RuntimePermissions/res/layout/activity_main.xml
new file mode 100644
index 0000000..64e8322
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/res/layout/activity_main.xml
@@ -0,0 +1,65 @@
+<!--
+  Copyright 2015 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.
+  -->
+<LinearLayout
+      xmlns:android="http://schemas.android.com/apk/res/android"
+      android:orientation="vertical"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:id="@+id/sample_main_layout">
+
+    <ViewAnimator
+          android:id="@+id/sample_output"
+          android:layout_width="match_parent"
+          android:layout_height="0px"
+          android:layout_weight="1">
+
+        <ScrollView
+              style="@style/Widget.SampleMessageTile"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+            <TextView
+                  style="@style/Widget.SampleMessage"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:paddingLeft="@dimen/horizontal_page_margin"
+                  android:paddingRight="@dimen/horizontal_page_margin"
+                  android:paddingTop="@dimen/vertical_page_margin"
+                  android:paddingBottom="@dimen/vertical_page_margin"
+                  android:text="@string/intro_message" />
+        </ScrollView>
+
+        <fragment
+              android:name="com.example.android.common.logger.LogFragment"
+              android:id="@+id/log_fragment"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent" />
+
+    </ViewAnimator>
+
+    <View
+          android:layout_width="match_parent"
+          android:layout_height="1dp"
+          android:background="@android:color/darker_gray" />
+
+    <FrameLayout
+          android:id="@+id/sample_content_fragment"
+          android:layout_weight="2"
+          android:layout_width="match_parent"
+          android:layout_height="0px" />
+
+</LinearLayout>
+
diff --git a/samples/browseable/RuntimePermissions/res/layout/fragment_camera.xml b/samples/browseable/RuntimePermissions/res/layout/fragment_camera.xml
new file mode 100644
index 0000000..ecdc54a
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/res/layout/fragment_camera.xml
@@ -0,0 +1,33 @@
+<!--
+ Copyright 2015 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/back"
+            android:onClick="onBackClick"
+            android:layout_gravity="center_horizontal"/>
+
+    <FrameLayout
+            android:id="@+id/camera_preview"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent"
+            android:layout_weight="1"
+            />
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/browseable/RuntimePermissions/res/layout/fragment_camera_unavailable.xml b/samples/browseable/RuntimePermissions/res/layout/fragment_camera_unavailable.xml
new file mode 100644
index 0000000..200ebbc
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/res/layout/fragment_camera_unavailable.xml
@@ -0,0 +1,43 @@
+<!--
+ Copyright 2015 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/back"
+            android:onClick="onBackClick"
+            android:layout_gravity="center_horizontal"/>
+
+    <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="fill_parent">
+
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingLeft="@dimen/horizontal_page_margin"
+                android:paddingRight="@dimen/horizontal_page_margin"
+                android:paddingTop="@dimen/vertical_page_margin"
+                android:paddingBottom="@dimen/vertical_page_margin"
+                android:text="@string/camera_unavailable"/>
+
+    </ScrollView>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/browseable/RuntimePermissions/res/layout/fragment_contacts.xml b/samples/browseable/RuntimePermissions/res/layout/fragment_contacts.xml
new file mode 100644
index 0000000..8a70fe2
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/res/layout/fragment_contacts.xml
@@ -0,0 +1,54 @@
+<!--
+ Copyright 2015 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:paddingLeft="@dimen/horizontal_page_margin"
+              android:paddingRight="@dimen/horizontal_page_margin"
+              android:paddingTop="@dimen/vertical_page_margin"
+              android:paddingBottom="@dimen/vertical_page_margin">
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/back"
+            android:onClick="onBackClick"
+            android:layout_gravity="center_horizontal"/>
+
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/contacts_intro"/>
+
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/contact_message"/>
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/add_contact"
+            android:id="@+id/contact_add"/>
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/show_contact"
+            android:id="@+id/contact_load"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/browseable/RuntimePermissions/res/layout/fragment_main.xml b/samples/browseable/RuntimePermissions/res/layout/fragment_main.xml
new file mode 100644
index 0000000..f9bfd5f
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/res/layout/fragment_main.xml
@@ -0,0 +1,48 @@
+<!--
+ Copyright 2015 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              xmlns:tools="http://schemas.android.com/tools"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:paddingLeft="@dimen/horizontal_page_margin"
+              android:paddingRight="@dimen/horizontal_page_margin"
+              android:paddingTop="@dimen/vertical_page_margin"
+              android:paddingBottom="@dimen/vertical_page_margin"
+              android:orientation="vertical"
+              tools:context=".MainActivityFragment">
+
+    <TextView
+            android:text="@string/main_introduction"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"/>
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/show_camera"
+            android:id="@+id/button_camera"
+            android:onClick="showCamera"/>
+
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/show_contacts"
+            android:id="@+id/button_contacts"
+            android:onClick="showContacts"/>
+
+</LinearLayout>
diff --git a/samples/ActionBarCompat/res/values/dimens.xml b/samples/browseable/RuntimePermissions/res/menu/main.xml
similarity index 67%
copy from samples/ActionBarCompat/res/values/dimens.xml
copy to samples/browseable/RuntimePermissions/res/menu/main.xml
index 67c8436..b49c2c5 100644
--- a/samples/ActionBarCompat/res/values/dimens.xml
+++ b/samples/browseable/RuntimePermissions/res/menu/main.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -14,8 +14,8 @@
   limitations under the License.
   -->
 
-<resources>
-    <dimen name="actionbar_compat_height">48dp</dimen>
-    <dimen name="actionbar_compat_button_width">48dp</dimen>
-    <dimen name="actionbar_compat_button_home_width">56dp</dimen>
-</resources>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/menu_toggle_log"
+          android:showAsAction="always"
+          android:title="@string/sample_show_log" />
+</menu>
diff --git a/samples/browseable/RuntimePermissions/res/mipmap-hdpi/ic_launcher.png b/samples/browseable/RuntimePermissions/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..3279054
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/RuntimePermissions/res/mipmap-mdpi/ic_launcher.png b/samples/browseable/RuntimePermissions/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..225fe42
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/RuntimePermissions/res/mipmap-xhdpi/ic_launcher.png b/samples/browseable/RuntimePermissions/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..c129dbb
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/RuntimePermissions/res/mipmap-xxhdpi/ic_launcher.png b/samples/browseable/RuntimePermissions/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b4ab118
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/RuntimePermissions/res/mipmap-xxxhdpi/ic_launcher.png b/samples/browseable/RuntimePermissions/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..99649fb
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/values/dimens.xml b/samples/browseable/RuntimePermissions/res/values-sw600dp/template-dimens.xml
similarity index 71%
copy from samples/ActionBarCompat/res/values/dimens.xml
copy to samples/browseable/RuntimePermissions/res/values-sw600dp/template-dimens.xml
index 67c8436..22074a2 100644
--- a/samples/ActionBarCompat/res/values/dimens.xml
+++ b/samples/browseable/RuntimePermissions/res/values-sw600dp/template-dimens.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -15,7 +15,10 @@
   -->
 
 <resources>
-    <dimen name="actionbar_compat_height">48dp</dimen>
-    <dimen name="actionbar_compat_button_width">48dp</dimen>
-    <dimen name="actionbar_compat_button_home_width">56dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
 </resources>
diff --git a/samples/ActionBarCompat/res/values-v13/styles.xml b/samples/browseable/RuntimePermissions/res/values-sw600dp/template-styles.xml
similarity index 67%
copy from samples/ActionBarCompat/res/values-v13/styles.xml
copy to samples/browseable/RuntimePermissions/res/values-sw600dp/template-styles.xml
index 8a042b4..03d1974 100644
--- a/samples/ActionBarCompat/res/values-v13/styles.xml
+++ b/samples/browseable/RuntimePermissions/res/values-sw600dp/template-styles.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -16,8 +16,10 @@
 
 <resources>
 
-    <style name="ActionBarTitle" parent="android:style/TextAppearance.Holo.Widget.ActionBar.Title">
-        <item name="android:textColor">@color/actionbar_title_color</item>
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceLarge</item>
+        <item name="android:lineSpacingMultiplier">1.2</item>
+        <item name="android:shadowDy">-6.5</item>
     </style>
 
 </resources>
diff --git a/samples/ActionBarCompat/res/values/colors.xml b/samples/browseable/RuntimePermissions/res/values-v11/template-styles.xml
similarity index 79%
copy from samples/ActionBarCompat/res/values/colors.xml
copy to samples/browseable/RuntimePermissions/res/values-v11/template-styles.xml
index 4edc6d6..8c1ea66 100644
--- a/samples/ActionBarCompat/res/values/colors.xml
+++ b/samples/browseable/RuntimePermissions/res/values-v11/template-styles.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -15,5 +15,8 @@
   -->
 
 <resources>
-    <color name="actionbar_title_color">#224894</color>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
 </resources>
diff --git a/samples/browseable/RuntimePermissions/res/values-v21/base-colors.xml b/samples/browseable/RuntimePermissions/res/values-v21/base-colors.xml
new file mode 100644
index 0000000..8b6ec3f
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/res/values-v21/base-colors.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+
+</resources>
diff --git a/samples/browseable/RuntimePermissions/res/values-v21/base-template-styles.xml b/samples/browseable/RuntimePermissions/res/values-v21/base-template-styles.xml
new file mode 100644
index 0000000..c778e4f
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/res/values-v21/base-template-styles.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Material.Light">
+    </style>
+
+</resources>
diff --git a/samples/browseable/RuntimePermissions/res/values/base-strings.xml b/samples/browseable/RuntimePermissions/res/values/base-strings.xml
new file mode 100644
index 0000000..58d75f9
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/res/values/base-strings.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+    <string name="app_name">RuntimePermissions</string>
+    <string name="intro_message">
+        <![CDATA[
+        
+            
+            This sample shows runtime permissions available in the Android M and above.
+            Display the log to follow the execution.
+            If executed on an Android M device, an additional option to access contacts is shown.
+            
+        
+        ]]>
+    </string>
+</resources>
diff --git a/samples/ActionBarCompat/res/values/colors.xml b/samples/browseable/RuntimePermissions/res/values/fragmentview_strings.xml
similarity index 77%
copy from samples/ActionBarCompat/res/values/colors.xml
copy to samples/browseable/RuntimePermissions/res/values/fragmentview_strings.xml
index 4edc6d6..7b9d9ec 100644
--- a/samples/ActionBarCompat/res/values/colors.xml
+++ b/samples/browseable/RuntimePermissions/res/values/fragmentview_strings.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -12,8 +12,8 @@
   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.
-  -->
-
+-->
 <resources>
-    <color name="actionbar_title_color">#224894</color>
+    <string name="sample_show_log">Show Log</string>
+    <string name="sample_hide_log">Hide Log</string>
 </resources>
diff --git a/samples/browseable/RuntimePermissions/res/values/strings.xml b/samples/browseable/RuntimePermissions/res/values/strings.xml
new file mode 100644
index 0000000..941f059
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="contacts_string">Total number of contacts: %1$,d\nFirst contact:<b>%2$s</b></string>
+    <string name="contacts_none">No contacts stored on device.</string>
+    <string name="contacts_empty">Contacts not loaded.</string>
+    <string name="add_contact">Add a contact</string>
+    <string name="show_contact">Show first contact</string>
+    <string name="contacts_intro">This fragment demonstrates access to the contact database on the device.\n
+            Clicking \"Add a contact\" adds a new contact named "__DUMMY ENTRY" directly into the database.\n
+    Clicking \"Show first contact\" accesses the contact database to display the name of the first contact.</string>
+    <string name="camera_unavailable"><b>Camera could not be opened.</b>\nThis occurs when the camera is not available (for example it is already in use) or if the system has denied access (for example when camera access has been disabled).</string>
+    <string name="back">Back</string>
+    <string name="show_camera">Show camera preview</string>
+    <string name="show_contacts">Show and add contacts</string>
+    <string name="main_introduction">Click the buttons below to show a camera preview or access the contacts database.\nNote that the contacts option is only available on Android M to illustrate the use of optional, M-only permissions that are not requested on lower SDK platforms.</string>
+    <string name="permision_available_camera">Camera Permission has been granted. Preview can now be opened.</string>
+    <string name="permision_available_contacts">Contacts Permissions have been granted. Contacts screen can now be opened.</string>
+    <string name="permissions_not_granted">Permissions were not granted.</string>
+</resources>
\ No newline at end of file
diff --git a/samples/browseable/RuntimePermissions/res/values/template-dimens.xml b/samples/browseable/RuntimePermissions/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+  Copyright 2013 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.
+  -->
+
+<resources>
+
+    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+    <dimen name="margin_tiny">4dp</dimen>
+    <dimen name="margin_small">8dp</dimen>
+    <dimen name="margin_medium">16dp</dimen>
+    <dimen name="margin_large">32dp</dimen>
+    <dimen name="margin_huge">64dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/samples/browseable/RuntimePermissions/res/values/template-styles.xml b/samples/browseable/RuntimePermissions/res/values/template-styles.xml
new file mode 100644
index 0000000..6e7d593
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+  Copyright 2013 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.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+
+    <style name="Theme.Base" parent="android:Theme.Light" />
+
+    <style name="Theme.Sample" parent="Theme.Base" />
+
+    <style name="AppTheme" parent="Theme.Sample" />
+    <!-- Widget styling -->
+
+    <style name="Widget" />
+
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceMedium</item>
+        <item name="android:lineSpacingMultiplier">1.1</item>
+    </style>
+
+    <style name="Widget.SampleMessageTile">
+        <item name="android:background">@drawable/tile</item>
+        <item name="android:shadowColor">#7F000000</item>
+        <item name="android:shadowDy">-3.5</item>
+        <item name="android:shadowRadius">2</item>
+    </style>
+
+</resources>
diff --git a/samples/browseable/RuntimePermissions/src/com.example.android.common/activities/SampleActivityBase.java b/samples/browseable/RuntimePermissions/src/com.example.android.common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/src/com.example.android.common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 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.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+    public static final String TAG = "SampleActivityBase";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    protected  void onStart() {
+        super.onStart();
+        initializeLogging();
+    }
+
+    /** Set up targets to receive log data */
+    public void initializeLogging() {
+        // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+        // Wraps Android's native log framework
+        LogWrapper logWrapper = new LogWrapper();
+        Log.setLogNode(logWrapper);
+
+        Log.i(TAG, "Ready");
+    }
+}
diff --git a/samples/browseable/RuntimePermissions/src/com.example.android.common/logger/Log.java b/samples/browseable/RuntimePermissions/src/com.example.android.common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/src/com.example.android.common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+    // Grabbing the native values from Android's native logging facilities,
+    // to make for easy migration and interop.
+    public static final int NONE = -1;
+    public static final int VERBOSE = android.util.Log.VERBOSE;
+    public static final int DEBUG = android.util.Log.DEBUG;
+    public static final int INFO = android.util.Log.INFO;
+    public static final int WARN = android.util.Log.WARN;
+    public static final int ERROR = android.util.Log.ERROR;
+    public static final int ASSERT = android.util.Log.ASSERT;
+
+    // Stores the beginning of the LogNode topology.
+    private static LogNode mLogNode;
+
+    /**
+     * Returns the next LogNode in the linked list.
+     */
+    public static LogNode getLogNode() {
+        return mLogNode;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to.
+     */
+    public static void setLogNode(LogNode node) {
+        mLogNode = node;
+    }
+
+    /**
+     * Instructs the LogNode to print the log data provided. Other LogNodes can
+     * be chained to the end of the LogNode as desired.
+     *
+     * @param priority Log level of the data being logged. Verbose, Error, etc.
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void println(int priority, String tag, String msg, Throwable tr) {
+        if (mLogNode != null) {
+            mLogNode.println(priority, tag, msg, tr);
+        }
+    }
+
+    /**
+     * Instructs the LogNode to print the log data provided. Other LogNodes can
+     * be chained to the end of the LogNode as desired.
+     *
+     * @param priority Log level of the data being logged. Verbose, Error, etc.
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     */
+    public static void println(int priority, String tag, String msg) {
+        println(priority, tag, msg, null);
+    }
+
+   /**
+     * Prints a message at VERBOSE priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void v(String tag, String msg, Throwable tr) {
+        println(VERBOSE, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at VERBOSE priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void v(String tag, String msg) {
+        v(tag, msg, null);
+    }
+
+
+    /**
+     * Prints a message at DEBUG priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void d(String tag, String msg, Throwable tr) {
+        println(DEBUG, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at DEBUG priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void d(String tag, String msg) {
+        d(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at INFO priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void i(String tag, String msg, Throwable tr) {
+        println(INFO, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at INFO priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void i(String tag, String msg) {
+        i(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void w(String tag, String msg, Throwable tr) {
+        println(WARN, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void w(String tag, String msg) {
+        w(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void w(String tag, Throwable tr) {
+        w(tag, null, tr);
+    }
+
+    /**
+     * Prints a message at ERROR priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void e(String tag, String msg, Throwable tr) {
+        println(ERROR, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at ERROR priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void e(String tag, String msg) {
+        e(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void wtf(String tag, String msg, Throwable tr) {
+        println(ASSERT, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void wtf(String tag, String msg) {
+        wtf(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void wtf(String tag, Throwable tr) {
+        wtf(tag, null, tr);
+    }
+}
diff --git a/samples/browseable/RuntimePermissions/src/com.example.android.common/logger/LogFragment.java b/samples/browseable/RuntimePermissions/src/com.example.android.common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/src/com.example.android.common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+    private LogView mLogView;
+    private ScrollView mScrollView;
+
+    public LogFragment() {}
+
+    public View inflateViews() {
+        mScrollView = new ScrollView(getActivity());
+        ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT);
+        mScrollView.setLayoutParams(scrollParams);
+
+        mLogView = new LogView(getActivity());
+        ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+        logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+        mLogView.setLayoutParams(logParams);
+        mLogView.setClickable(true);
+        mLogView.setFocusable(true);
+        mLogView.setTypeface(Typeface.MONOSPACE);
+
+        // Want to set padding as 16 dips, setPadding takes pixels.  Hooray math!
+        int paddingDips = 16;
+        double scale = getResources().getDisplayMetrics().density;
+        int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+        mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+        mLogView.setCompoundDrawablePadding(paddingPixels);
+
+        mLogView.setGravity(Gravity.BOTTOM);
+        mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+        mScrollView.addView(mLogView);
+        return mScrollView;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+
+        View result = inflateViews();
+
+        mLogView.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+            }
+        });
+        return result;
+    }
+
+    public LogView getLogView() {
+        return mLogView;
+    }
+}
\ No newline at end of file
diff --git a/samples/browseable/RuntimePermissions/src/com.example.android.common/logger/LogNode.java b/samples/browseable/RuntimePermissions/src/com.example.android.common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/src/com.example.android.common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 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.example.android.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+    /**
+     * Instructs first LogNode in the list to print the log data provided.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/samples/browseable/RuntimePermissions/src/com.example.android.common/logger/LogView.java b/samples/browseable/RuntimePermissions/src/com.example.android.common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/src/com.example.android.common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+    public LogView(Context context) {
+        super(context);
+    }
+
+    public LogView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public LogView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    /**
+     * Formats the log data and prints it out to the LogView.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+
+        
+        String priorityStr = null;
+
+        // For the purposes of this View, we want to print the priority as readable text.
+        switch(priority) {
+            case android.util.Log.VERBOSE:
+                priorityStr = "VERBOSE";
+                break;
+            case android.util.Log.DEBUG:
+                priorityStr = "DEBUG";
+                break;
+            case android.util.Log.INFO:
+                priorityStr = "INFO";
+                break;
+            case android.util.Log.WARN:
+                priorityStr = "WARN";
+                break;
+            case android.util.Log.ERROR:
+                priorityStr = "ERROR";
+                break;
+            case android.util.Log.ASSERT:
+                priorityStr = "ASSERT";
+                break;
+            default:
+                break;
+        }
+
+        // Handily, the Log class has a facility for converting a stack trace into a usable string.
+        String exceptionStr = null;
+        if (tr != null) {
+            exceptionStr = android.util.Log.getStackTraceString(tr);
+        }
+
+        // Take the priority, tag, message, and exception, and concatenate as necessary
+        // into one usable line of text.
+        final StringBuilder outputBuilder = new StringBuilder();
+
+        String delimiter = "\t";
+        appendIfNotNull(outputBuilder, priorityStr, delimiter);
+        appendIfNotNull(outputBuilder, tag, delimiter);
+        appendIfNotNull(outputBuilder, msg, delimiter);
+        appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+        // In case this was originally called from an AsyncTask or some other off-UI thread,
+        // make sure the update occurs within the UI thread.
+        ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+            @Override
+            public void run() {
+                // Display the text we just generated within the LogView.
+                appendToLog(outputBuilder.toString());
+            }
+        })));
+
+        if (mNext != null) {
+            mNext.println(priority, tag, msg, tr);
+        }
+    }
+
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+    /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+     * the logger takes so many arguments that might be null, this method helps cut out some of the
+     * agonizing tedium of writing the same 3 lines over and over.
+     * @param source StringBuilder containing the text to append to.
+     * @param addStr The String to append
+     * @param delimiter The String to separate the source and appended strings. A tab or comma,
+     *                  for instance.
+     * @return The fully concatenated String as a StringBuilder
+     */
+    private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+        if (addStr != null) {
+            if (addStr.length() == 0) {
+                delimiter = "";
+            }
+
+            return source.append(addStr).append(delimiter);
+        }
+        return source;
+    }
+
+    // The next LogNode in the chain.
+    LogNode mNext;
+
+    /** Outputs the string as a new line of log data in the LogView. */
+    public void appendToLog(String s) {
+        append("\n" + s);
+    }
+
+
+}
diff --git a/samples/browseable/RuntimePermissions/src/com.example.android.common/logger/LogWrapper.java b/samples/browseable/RuntimePermissions/src/com.example.android.common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/src/com.example.android.common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 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.example.android.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface.  This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+    // For piping:  The next node to receive Log data after this one has done its work.
+    private LogNode mNext;
+
+    /**
+     * Returns the next LogNode in the linked list.
+     */
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to..
+     */
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+    /**
+     * Prints data out to the console using Android's native log mechanism.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+        // There actually are log methods that don't take a msg parameter.  For now,
+        // if that's the case, just convert null to the empty string and move on.
+        String useMsg = msg;
+        if (useMsg == null) {
+            useMsg = "";
+        }
+
+        // If an exeption was provided, convert that exception to a usable string and attach
+        // it to the end of the msg method.
+        if (tr != null) {
+            msg += "\n" + Log.getStackTraceString(tr);
+        }
+
+        // This is functionally identical to Log.x(tag, useMsg);
+        // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+        Log.println(priority, tag, useMsg);
+
+        // If this isn't the last node in the chain, move things along.
+        if (mNext != null) {
+            mNext.println(priority, tag, msg, tr);
+        }
+    }
+}
diff --git a/samples/browseable/RuntimePermissions/src/com.example.android.common/logger/MessageOnlyLogFilter.java b/samples/browseable/RuntimePermissions/src/com.example.android.common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/src/com.example.android.common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+    LogNode mNext;
+
+    /**
+     * Takes the "next" LogNode as a parameter, to simplify chaining.
+     *
+     * @param next The next LogNode in the pipeline.
+     */
+    public MessageOnlyLogFilter(LogNode next) {
+        mNext = next;
+    }
+
+    public MessageOnlyLogFilter() {
+    }
+
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+        if (mNext != null) {
+            getNext().println(Log.NONE, null, msg, null);
+        }
+    }
+
+    /**
+     * Returns the next LogNode in the chain.
+     */
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to..
+     */
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+}
diff --git a/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/MainActivity.java b/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/MainActivity.java
new file mode 100644
index 0000000..43436aa
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/MainActivity.java
@@ -0,0 +1,279 @@
+/*
+* Copyright 2015 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.system.runtimepermissions;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+import com.example.android.system.runtimepermissions.camera.CameraPreviewFragment;
+import com.example.android.system.runtimepermissions.contacts.ContactsFragment;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.Toast;
+import android.widget.ViewAnimator;
+
+/**
+ * Launcher Activity that demonstrates the use of runtime permissions for Android M.
+ * It contains a summary sample description, sample log and a Fragment that calls callbacks on this
+ * Activity to illustrate parts of the runtime permissions API.
+ * <p>
+ * This Activity requests permissions to access the camera ({@link android.Manifest.permission#CAMERA})
+ * when the 'Show Camera' button is clicked to display the camera preview.
+ * Contacts permissions (({@link android.Manifest.permission#READ_CONTACTS} and ({@link
+ * android.Manifest.permission#WRITE_CONTACTS})) are requested when the 'Show and Add Contacts'
+ * button is
+ * clicked to display the first contact in the contacts database and to add a dummy contact
+ * directly
+ * to it. First, permissions are checked if they have already been granted through {@link
+ * android.app.Activity#checkSelfPermission(String)} (wrapped in {@link
+ * PermissionUtil#hasSelfPermission(Activity, String)} and {@link PermissionUtil#hasSelfPermission(Activity,
+ * String[])} for compatibility). If permissions have not been granted, they are requested through
+ * {@link Activity#requestPermissions(String[], int)} and the return value checked in {@link
+ * Activity#onRequestPermissionsResult(int, String[], int[])}.
+ * <p>
+ * If this sample is executed on a device running a platform version below M, all permissions
+ * declared
+ * in the Android manifest file are always granted at install time and cannot be requested at run
+ * time.
+ * <p>
+ * This sample targets the M platform and must therefore request permissions at runtime. Change the
+ * targetSdk in the file 'Application/build.gradle' to 22 to run the application in compatibility
+ * mode.
+ * Now, if a permission has been disable by the system through the application settings, disabled
+ * APIs provide compatibility data.
+ * For example the camera cannot be opened or an empty list of contacts is returned. No special
+ * action is required in this case.
+ * <p>
+ * (This class is based on the MainActivity used in the SimpleFragment sample template.)
+ */
+public class MainActivity extends SampleActivityBase {
+
+    public static final String TAG = "MainActivity";
+
+    /**
+     * Id to identify a camera permission request.
+     */
+    private static final int REQUEST_CAMERA = 0;
+
+    /**
+     * Id to identify a contacts permission request.
+     */
+    private static final int REQUEST_CONTACTS = 1;
+
+    /**
+     * Permissions required to read and write contacts. Used by the {@link ContactsFragment}.
+     */
+    private static String[] PERMISSIONS_CONTACT = {Manifest.permission.READ_CONTACTS,
+            Manifest.permission.WRITE_CONTACTS};
+
+    // Whether the Log Fragment is currently shown.
+    private boolean mLogShown;
+
+
+    /**
+     * Called when the 'show camera' button is clicked.
+     * Callback is defined in resource layout definition.
+     */
+    public void showCamera(View view) {
+        Log.i(TAG, "Show camera button pressed. Checking permission.");
+        // BEGIN_INCLUDE(camera_permission)
+        // Check if the Camera permission is already available.
+        if (PermissionUtil.hasSelfPermission(this, Manifest.permission.CAMERA)) {
+            Log.i(TAG,
+                    "CAMERA permission has already been granted. Displaying camera preview.");
+            // Camera permissions is already available, show the camera preview.
+            showCameraPreview();
+        } else {
+            Log.i(TAG, "CAMERA permission has NOT been granted. Requesting permission.");
+            // Camera permission has not been granted. Request it.
+            requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA);
+        }
+        // END_INCLUDE(camera_permission)
+
+    }
+
+    /**
+     * Called when the 'show camera' button is clicked.
+     * Callback is defined in resource layout definition.
+     */
+    public void showContacts(View v) {
+        Log.i(TAG, "Show contacts button pressed. Checking permissions.");
+        // Verify that all required contact permissions have been granted.
+        if (PermissionUtil.hasSelfPermission(this, PERMISSIONS_CONTACT)) {
+            Log.i(TAG,
+                    "Contact permissions have already been granted. Displaying contact details.");
+            // Contact permissions have been granted. Show the contacts fragment.
+            showContactDetails();
+        } else {
+            Log.i(TAG, "Contact permissions has NOT been granted. Requesting permission.");
+            // contact permissions has not been granted (read and write contacts). Request them.
+            requestPermissions(PERMISSIONS_CONTACT, REQUEST_CONTACTS);
+        }
+    }
+
+    /**
+     * Display the {@link CameraPreviewFragment} in the content area if the required Camera
+     * permission has been granted.
+     */
+    private void showCameraPreview() {
+        getSupportFragmentManager().beginTransaction()
+                .replace(R.id.sample_content_fragment, CameraPreviewFragment.newInstance())
+                .addToBackStack("contacts")
+                .commit();
+    }
+
+    /**
+     * Display the {@link ContactsFragment} in the content area if the required contacts
+     * permissions
+     * have been granted.
+     */
+    private void showContactDetails() {
+        getSupportFragmentManager().beginTransaction()
+                .replace(R.id.sample_content_fragment, ContactsFragment.newInstance())
+                .addToBackStack("contacts")
+                .commit();
+    }
+
+
+    /**
+     * Callback received when a permissions request has been completed.
+     */
+    @Override
+    public void onRequestPermissionsResult(int requestCode, String[] permissions,
+            int[] grantResults) {
+
+        if (requestCode == REQUEST_CAMERA) {
+            // BEGIN_INCLUDE(permission_result)
+            // Received permission result for camera permission.
+            Log.i(TAG, "Received response for Camera permission request.");
+
+            // Check if the only required permission has been granted
+            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+                // Camera permission has been granted, preview can be displayed
+                Log.i(TAG, "CAMERA permission has now been granted. Showing preview.");
+                Toast.makeText(this, R.string.permision_available_camera, Toast.LENGTH_SHORT)
+                        .show();
+            } else {
+                Log.i(TAG, "CAMERA permission was NOT granted.");
+                Toast.makeText(this, R.string.permissions_not_granted, Toast.LENGTH_SHORT).show();
+
+            }
+            // END_INCLUDE(permission_result)
+
+        } else if (requestCode == REQUEST_CONTACTS) {
+            Log.i(TAG, "Received response for contact permissions request.");
+
+            // We have requested multiple permissions for contacts, so all of them need to be
+            // checked.
+            if (PermissionUtil.verifyPermissions(grantResults)) {
+                // All required permissions have been granted, display contacts fragment.
+                Toast.makeText(this, R.string.permision_available_contacts, Toast.LENGTH_SHORT)
+                        .show();
+            } else {
+                Log.i(TAG, "Contacts permissions were NOT granted.");
+                Toast.makeText(this, R.string.permissions_not_granted, Toast.LENGTH_SHORT).show();
+            }
+
+        } else {
+            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+        }
+    }
+
+    /* Note: Methods and definitions below are only used to provide the UI for this sample and are
+    not relevant for the execution of the runtime permissions API. */
+
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.main, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        MenuItem logToggle = menu.findItem(R.id.menu_toggle_log);
+        logToggle.setVisible(findViewById(R.id.sample_output) instanceof ViewAnimator);
+        logToggle.setTitle(mLogShown ? R.string.sample_hide_log : R.string.sample_show_log);
+
+        return super.onPrepareOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.menu_toggle_log:
+                mLogShown = !mLogShown;
+                ViewAnimator output = (ViewAnimator) findViewById(R.id.sample_output);
+                if (mLogShown) {
+                    output.setDisplayedChild(1);
+                } else {
+                    output.setDisplayedChild(0);
+                }
+                supportInvalidateOptionsMenu();
+                return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    /** Create a chain of targets that will receive log data */
+    @Override
+    public void initializeLogging() {
+        // Wraps Android's native log framework.
+        LogWrapper logWrapper = new LogWrapper();
+        // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+        Log.setLogNode(logWrapper);
+
+        // Filter strips out everything except the message text.
+        MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+        logWrapper.setNext(msgFilter);
+
+        // On screen logging via a fragment with a TextView.
+        LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+                .findFragmentById(R.id.log_fragment);
+        msgFilter.setNext(logFragment.getLogView());
+    }
+
+    public void onBackClick(View view) {
+        getSupportFragmentManager().popBackStack();
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        if (savedInstanceState == null) {
+            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+            RuntimePermissionsFragment fragment = new RuntimePermissionsFragment();
+            transaction.replace(R.id.sample_content_fragment, fragment);
+            transaction.commit();
+        }
+
+        // This method sets up our custom logger, which will print all log messages to the device
+        // screen, as well as to adb logcat.
+        initializeLogging();
+    }
+}
diff --git a/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/PermissionUtil.java b/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/PermissionUtil.java
new file mode 100644
index 0000000..ba2370f
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/PermissionUtil.java
@@ -0,0 +1,90 @@
+/*
+* Copyright 2015 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.system.runtimepermissions;
+
+import android.app.Activity;
+import android.content.pm.PackageManager;
+import android.os.Build;
+
+/**
+ * Utility class that wraps access to the runtime permissions API in M and provides basic helper
+ * methods.
+ */
+public abstract class PermissionUtil {
+
+    /**
+     * Check that all given permissions have been granted by verifying that each entry in the
+     * given array is of the value {@link PackageManager#PERMISSION_GRANTED}.
+     *
+     * @see Activity#onRequestPermissionsResult(int, String[], int[])
+     */
+    public static boolean verifyPermissions(int[] grantResults) {
+        // Verify that each required permission has been granted, otherwise return false.
+        for (int result : grantResults) {
+            if (result != PackageManager.PERMISSION_GRANTED) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns true if the Activity has access to all given permissions.
+     * Always returns true on platforms below M.
+     *
+     * @see Activity#checkSelfPermission(String)
+     */
+    public static boolean hasSelfPermission(Activity activity, String[] permissions) {
+        // Below Android M all permissions are granted at install time and are already available.
+        if (!isMNC()) {
+            return true;
+        }
+
+        // Verify that all required permissions have been granted
+        for (String permission : permissions) {
+            if (activity.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns true if the Activity has access to a given permission.
+     * Always returns true on platforms below M.
+     *
+     * @see Activity#checkSelfPermission(String)
+     */
+    public static boolean hasSelfPermission(Activity activity, String permission) {
+        // Below Android M all permissions are granted at install time and are already available.
+        if (!isMNC()) {
+            return true;
+        }
+
+        return activity.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED;
+    }
+
+    public static boolean isMNC() {
+        /*
+         TODO: In the Android M Preview release, checking if the platform is M is done through
+         the codename, not the version code. Once the API has been finalised, the following check
+         should be used: */
+        // return Build.VERSION.SDK_INT == Build.VERSION_CODES.MNC
+
+        return "MNC".equals(Build.VERSION.CODENAME);
+    }
+}
diff --git a/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/RuntimePermissionsFragment.java b/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/RuntimePermissionsFragment.java
new file mode 100644
index 0000000..b35bfeb
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/RuntimePermissionsFragment.java
@@ -0,0 +1,50 @@
+/*
+* Copyright 2015 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.system.runtimepermissions;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+public class RuntimePermissionsFragment extends Fragment {
+
+    @Nullable
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        View root = inflater.inflate(R.layout.fragment_main, null);
+
+        // BEGIN_INCLUDE(m_only_permission)
+        if (!PermissionUtil.isMNC()) {
+            /*
+            The contacts permissions have been declared in the AndroidManifest for Android M only.
+            They are not available on older platforms, so we are hiding the button to access the
+            contacts database.
+            This shows how new runtime-only permissions can be added, that do not apply to older
+            platform versions. This can be useful for automated updates where additional
+            permissions might prompt the user on upgrade.
+             */
+            root.findViewById(R.id.button_camera).setVisibility(View.GONE);
+        }
+        // END_INCLUDE(m_only_permission)
+
+        return root;
+    }
+}
diff --git a/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/camera/CameraPreview.java b/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/camera/CameraPreview.java
new file mode 100644
index 0000000..1d25b51
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/camera/CameraPreview.java
@@ -0,0 +1,142 @@
+/*
+* Copyright 2015 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.system.runtimepermissions.camera;
+
+import android.content.Context;
+import android.hardware.Camera;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import java.io.IOException;
+
+/**
+ * Camera preview that displays a {@link Camera}.
+ *
+ * Handles basic lifecycle methods to display and stop the preview.
+ * <p>
+ * Implementation is based directly on the documentation at
+ * http://developer.android.com/guide/topics/media/camera.html
+ */
+public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
+
+    private static final String TAG = "CameraPreview";
+    private SurfaceHolder mHolder;
+    private Camera mCamera;
+    private Camera.CameraInfo mCameraInfo;
+    private int mDisplayOrientation;
+
+    public CameraPreview(Context context, Camera camera, Camera.CameraInfo cameraInfo,
+            int displayOrientation) {
+        super(context);
+
+        // Do not initialise if no camera has been set
+        if (camera == null || cameraInfo == null) {
+            return;
+        }
+        mCamera = camera;
+        mCameraInfo = cameraInfo;
+        mDisplayOrientation = displayOrientation;
+
+        // Install a SurfaceHolder.Callback so we get notified when the
+        // underlying surface is created and destroyed.
+        mHolder = getHolder();
+        mHolder.addCallback(this);
+    }
+
+    public void surfaceCreated(SurfaceHolder holder) {
+        // The Surface has been created, now tell the camera where to draw the preview.
+        try {
+            mCamera.setPreviewDisplay(holder);
+            mCamera.startPreview();
+            Log.d(TAG, "Camera preview started.");
+        } catch (IOException e) {
+            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
+        }
+    }
+
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        // empty. Take care of releasing the Camera preview in your activity.
+    }
+
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        // If your preview can change or rotate, take care of those events here.
+        // Make sure to stop the preview before resizing or reformatting it.
+
+        if (mHolder.getSurface() == null) {
+            // preview surface does not exist
+            Log.d(TAG, "Preview surface does not exist");
+            return;
+        }
+
+        // stop preview before making changes
+        try {
+            mCamera.stopPreview();
+            Log.d(TAG, "Preview stopped.");
+        } catch (Exception e) {
+            // ignore: tried to stop a non-existent preview
+            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
+        }
+
+        int orientation = calculatePreviewOrientation(mCameraInfo, mDisplayOrientation);
+        mCamera.setDisplayOrientation(orientation);
+
+        try {
+            mCamera.setPreviewDisplay(mHolder);
+            mCamera.startPreview();
+            Log.d(TAG, "Camera preview started.");
+        } catch (Exception e) {
+            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Calculate the correct orientation for a {@link Camera} preview that is displayed on screen.
+     *
+     * Implementation is based on the sample code provided in
+     * {@link Camera#setDisplayOrientation(int)}.
+     */
+    public static int calculatePreviewOrientation(Camera.CameraInfo info, int rotation) {
+        int degrees = 0;
+
+        switch (rotation) {
+            case Surface.ROTATION_0:
+                degrees = 0;
+                break;
+            case Surface.ROTATION_90:
+                degrees = 90;
+                break;
+            case Surface.ROTATION_180:
+                degrees = 180;
+                break;
+            case Surface.ROTATION_270:
+                degrees = 270;
+                break;
+        }
+
+        int result;
+        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
+            result = (info.orientation + degrees) % 360;
+            result = (360 - result) % 360;  // compensate the mirror
+        } else {  // back-facing
+            result = (info.orientation - degrees + 360) % 360;
+        }
+
+        return result;
+    }
+}
diff --git a/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/camera/CameraPreviewFragment.java b/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/camera/CameraPreviewFragment.java
new file mode 100644
index 0000000..d0938f6
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/camera/CameraPreviewFragment.java
@@ -0,0 +1,112 @@
+/*
+* Copyright 2015 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.system.runtimepermissions.camera;
+
+import com.example.android.common.logger.Log;
+import com.example.android.system.runtimepermissions.R;
+
+import android.hardware.Camera;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.Toast;
+
+/**
+ * Displays a {@link CameraPreview} of the first {@link Camera}.
+ * An error message is displayed if the Camera is not available.
+ * <p>
+ * This Fragment is only used to illustrate that access to the Camera API has been granted (or
+ * denied) as part of the runtime permissions model. It is not relevant for the use of the
+ * permissions API.
+ * <p>
+ * Implementation is based directly on the documentation at
+ * http://developer.android.com/guide/topics/media/camera.html
+ */
+public class CameraPreviewFragment extends Fragment {
+
+    private static final String TAG = "CameraPreview";
+
+    /**
+     * Id of the camera to access. 0 is the first camera.
+     */
+    private static final int CAMERA_ID = 0;
+
+    private CameraPreview mPreview;
+    private Camera mCamera;
+
+    public static CameraPreviewFragment newInstance() {
+        return new CameraPreviewFragment();
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+
+        // Open an instance of the first camera and retrieve its info.
+        mCamera = getCameraInstance(CAMERA_ID);
+        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
+        Camera.getCameraInfo(CAMERA_ID, cameraInfo);
+
+        if (mCamera == null || cameraInfo == null) {
+            // Camera is not available, display error message
+            Toast.makeText(getActivity(), "Camera is not available.", Toast.LENGTH_SHORT).show();
+            return inflater.inflate(R.layout.fragment_camera_unavailable, null);
+        }
+
+        View root = inflater.inflate(R.layout.fragment_camera, null);
+
+        // Get the rotation of the screen to adjust the preview image accordingly.
+        final int displayRotation = getActivity().getWindowManager().getDefaultDisplay()
+                .getRotation();
+
+        // Create the Preview view and set it as the content of this Activity.
+        mPreview = new CameraPreview(getActivity(), mCamera, cameraInfo, displayRotation);
+        FrameLayout preview = (FrameLayout) root.findViewById(R.id.camera_preview);
+        preview.addView(mPreview);
+
+        return root;
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        // Stop camera access
+        releaseCamera();
+    }
+
+    /** A safe way to get an instance of the Camera object. */
+    public static Camera getCameraInstance(int cameraId) {
+        Camera c = null;
+        try {
+            c = Camera.open(cameraId); // attempt to get a Camera instance
+        } catch (Exception e) {
+            // Camera is not available (in use or does not exist)
+            Log.d(TAG, "Camera " + cameraId + " is not available: " + e.getMessage());
+        }
+        return c; // returns null if camera is unavailable
+    }
+
+    private void releaseCamera() {
+        if (mCamera != null) {
+            mCamera.release();        // release the camera for other applications
+            mCamera = null;
+        }
+    }
+}
diff --git a/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/contacts/ContactsFragment.java b/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/contacts/ContactsFragment.java
new file mode 100644
index 0000000..19f54fb
--- /dev/null
+++ b/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/contacts/ContactsFragment.java
@@ -0,0 +1,189 @@
+/*
+* Copyright 2015 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.system.runtimepermissions.contacts;
+
+import com.example.android.common.logger.Log;
+import com.example.android.system.runtimepermissions.R;
+
+import android.content.ContentProviderOperation;
+import android.content.ContentResolver;
+import android.content.OperationApplicationException;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.provider.ContactsContract;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+/**
+ * Displays the first contact stored on the device and contains an option to add a dummy contact.
+ * <p>
+ * This Fragment is only used to illustrate that access to the Contacts ContentProvider API has
+ * been granted (or denied) as part of the runtime permissions model. It is not relevant for the
+ * use
+ * of the permissions API.
+ * <p>
+ * This fragments demonstrates a basic use case for accessing the Contacts Provider. The
+ * implementation is based on the training guide available here:
+ * https://developer.android.com/training/contacts-provider/retrieve-names.html
+ */
+public class ContactsFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
+
+    private static final String TAG = "Contacts";
+    private TextView mMessageText = null;
+
+    private static String DUMMY_CONTACT_NAME = "__DUMMY CONTACT from runtime permissions sample";
+
+    /**
+     * Projection for the content provider query includes the id and primary name of a contact.
+     */
+    private static final String[] PROJECTION = {ContactsContract.Contacts._ID,
+            ContactsContract.Contacts.DISPLAY_NAME_PRIMARY};
+    /**
+     * Sort order for the query. Sorted by primary name in ascending order.
+     */
+    private static final String ORDER = ContactsContract.Contacts.DISPLAY_NAME_PRIMARY + " ASC";
+
+
+    /**
+     * Creates a new instance of a ContactsFragment.
+     */
+    public static ContactsFragment newInstance() {
+        return new ContactsFragment();
+    }
+
+
+    @Nullable
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        View rootView = inflater.inflate(R.layout.fragment_contacts, container, false);
+
+        mMessageText = (TextView) rootView.findViewById(R.id.contact_message);
+
+        // Register a listener to add a dummy contact when a button is clicked.
+        Button button = (Button) rootView.findViewById(R.id.contact_add);
+        button.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                insertDummyContact();
+            }
+        });
+
+        // Register a listener to display the first contact when a button is clicked.
+        button = (Button) rootView.findViewById(R.id.contact_load);
+        button.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                loadContact();
+            }
+        });
+        return rootView;
+    }
+
+    /**
+     * Restart the Loader to query the Contacts content provider to display the first contact.
+     */
+    private void loadContact() {
+        getLoaderManager().restartLoader(0, null, this);
+    }
+
+    /**
+     * Initialises a new {@link CursorLoader} that queries the {@link ContactsContract}.
+     */
+    @Override
+    public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
+        return new CursorLoader(getActivity(), ContactsContract.Contacts.CONTENT_URI, PROJECTION,
+                null, null, ORDER);
+    }
+
+
+    /**
+     * Dislays either the name of the first contact or a message.
+     */
+    @Override
+    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
+
+        if (cursor != null) {
+            final int totalCount = cursor.getCount();
+            if (totalCount > 0) {
+                cursor.moveToFirst();
+                String name = cursor
+                        .getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
+                mMessageText.setText(
+                        getResources().getString(R.string.contacts_string, totalCount, name));
+                Log.d(TAG, "First contact loaded: " + name);
+                Log.d(TAG, "Total number of contacts: " + totalCount);
+                Log.d(TAG, "Total number of contacts: " + totalCount);
+            } else {
+                Log.d(TAG, "List of contacts is empty.");
+                mMessageText.setText(R.string.contacts_empty);
+            }
+        }
+    }
+
+    @Override
+    public void onLoaderReset(Loader<Cursor> loader) {
+        mMessageText.setText(R.string.contacts_empty);
+    }
+
+    /**
+     * Accesses the Contacts content provider directly to insert a new contact.
+     * <p>
+     * The contact is called "__DUMMY ENTRY" and only contains a name.
+     */
+    private void insertDummyContact() {
+        // Two operations are needed to insert a new contact.
+        ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(2);
+
+        // First, set up a new raw contact.
+        ContentProviderOperation.Builder op =
+                ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
+                        .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
+                        .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null);
+        operations.add(op.build());
+
+        // Next, set the name for the contact.
+        op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
+                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
+                .withValue(ContactsContract.Data.MIMETYPE,
+                        ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
+                .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
+                        DUMMY_CONTACT_NAME);
+        operations.add(op.build());
+
+        // Apply the operations.
+        ContentResolver resolver = getActivity().getContentResolver();
+        try {
+            resolver.applyBatch(ContactsContract.AUTHORITY, operations);
+        } catch (RemoteException e) {
+            Log.d(TAG, "Could not add a new contact: " + e.getMessage());
+        } catch (OperationApplicationException e) {
+            Log.d(TAG, "Could not add a new contact: " + e.getMessage());
+        }
+    }
+}
diff --git a/samples/browseable/RuntimePermissionsBasic/AndroidManifest.xml b/samples/browseable/RuntimePermissionsBasic/AndroidManifest.xml
new file mode 100644
index 0000000..1f7ea6a
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/AndroidManifest.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2015 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.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.example.android.basicpermissions">
+
+    <!-- BEGIN_INCLUDE(manifest) -->
+
+    <!-- Note that all required permissions are declared here in the Android manifest.
+     On Android M and above, use of these permissions is only requested at run time. -->
+    <uses-permission android:name="android.permission.CAMERA"/>
+    <!-- END_INCLUDE(manifest) -->
+
+    <application
+            android:allowBackup="true"
+            android:icon="@mipmap/ic_launcher"
+            android:label="@string/app_name"
+            android:theme="@style/AppTheme">
+        <activity
+                android:name=".MainActivity"
+                android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+
+        <!-- Activity that only displays the camera preview. -->
+        <activity
+                android:name=".camera.CameraPreviewActivity"
+                android:exported="false"/>
+
+    </application>
+
+</manifest>
diff --git a/samples/browseable/RuntimePermissionsBasic/_index.jd b/samples/browseable/RuntimePermissionsBasic/_index.jd
new file mode 100644
index 0000000..c4b5d4c
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/_index.jd
@@ -0,0 +1,12 @@
+
+page.tags="RuntimePermissionsBasic"
+sample.group=System
+@jd:body
+
+<p>
+            
+            This sample shows runtime permissions available in the Android M and above.
+            This sample shows a basic implementation for requesting permissions at runtime. Click the button to request the Camera permission and open a full-screen camera preview.
+Note: The "RuntimePermissions" sample provides a more complete overview over the runtime permission features available.
+            
+        </p>
diff --git a/samples/browseable/RuntimePermissionsBasic/res/drawable-hdpi/tile.9.png b/samples/browseable/RuntimePermissionsBasic/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/samples/browseable/RuntimePermissionsBasic/res/layout/activity_camera.xml b/samples/browseable/RuntimePermissionsBasic/res/layout/activity_camera.xml
new file mode 100644
index 0000000..b12eee1
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/res/layout/activity_camera.xml
@@ -0,0 +1,22 @@
+<!--
+ Copyright 2015 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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+             android:id="@+id/camera_preview"
+             android:layout_width="fill_parent"
+             android:layout_height="fill_parent"
+             android:layout_weight="1"
+        />
diff --git a/samples/browseable/RuntimePermissionsBasic/res/layout/activity_camera_unavailable.xml b/samples/browseable/RuntimePermissionsBasic/res/layout/activity_camera_unavailable.xml
new file mode 100644
index 0000000..af0efe5
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/res/layout/activity_camera_unavailable.xml
@@ -0,0 +1,37 @@
+<!--
+ Copyright 2015 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:paddingLeft="@dimen/horizontal_page_margin"
+              android:paddingRight="@dimen/horizontal_page_margin"
+              android:paddingTop="@dimen/vertical_page_margin"
+              android:paddingBottom="@dimen/vertical_page_margin">
+
+    <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="fill_parent">
+
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/camera_unavailable"/>
+
+    </ScrollView>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/browseable/RuntimePermissionsBasic/res/layout/activity_main.xml b/samples/browseable/RuntimePermissionsBasic/res/layout/activity_main.xml
new file mode 100644
index 0000000..c3bf99c
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/res/layout/activity_main.xml
@@ -0,0 +1,40 @@
+<!--
+ Copyright 2015 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              xmlns:tools="http://schemas.android.com/tools"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:paddingLeft="@dimen/horizontal_page_margin"
+              android:paddingRight="@dimen/horizontal_page_margin"
+              android:paddingTop="@dimen/vertical_page_margin"
+              android:paddingBottom="@dimen/vertical_page_margin"
+              android:orientation="vertical"
+              tools:context=".MainActivity">
+
+    <TextView
+            android:text="@string/intro"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="@dimen/horizontal_page_margin"/>
+
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Open Camera Preview"
+            android:id="@+id/button_open_camera"/>
+</LinearLayout>
diff --git a/samples/browseable/RuntimePermissionsBasic/res/mipmap-hdpi/ic_launcher.png b/samples/browseable/RuntimePermissionsBasic/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..a7cee76
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/RuntimePermissionsBasic/res/mipmap-mdpi/ic_launcher.png b/samples/browseable/RuntimePermissionsBasic/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..378d029
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/RuntimePermissionsBasic/res/mipmap-xhdpi/ic_launcher.png b/samples/browseable/RuntimePermissionsBasic/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..c898742
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/RuntimePermissionsBasic/res/mipmap-xxhdpi/ic_launcher.png b/samples/browseable/RuntimePermissionsBasic/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..ad4f1df
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/RuntimePermissionsBasic/res/mipmap-xxxhdpi/ic_launcher.png b/samples/browseable/RuntimePermissionsBasic/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..484f298
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/values/dimens.xml b/samples/browseable/RuntimePermissionsBasic/res/values-sw600dp/template-dimens.xml
similarity index 71%
copy from samples/ActionBarCompat/res/values/dimens.xml
copy to samples/browseable/RuntimePermissionsBasic/res/values-sw600dp/template-dimens.xml
index 67c8436..22074a2 100644
--- a/samples/ActionBarCompat/res/values/dimens.xml
+++ b/samples/browseable/RuntimePermissionsBasic/res/values-sw600dp/template-dimens.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -15,7 +15,10 @@
   -->
 
 <resources>
-    <dimen name="actionbar_compat_height">48dp</dimen>
-    <dimen name="actionbar_compat_button_width">48dp</dimen>
-    <dimen name="actionbar_compat_button_home_width">56dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
 </resources>
diff --git a/samples/ActionBarCompat/res/values-v13/styles.xml b/samples/browseable/RuntimePermissionsBasic/res/values-sw600dp/template-styles.xml
similarity index 67%
copy from samples/ActionBarCompat/res/values-v13/styles.xml
copy to samples/browseable/RuntimePermissionsBasic/res/values-sw600dp/template-styles.xml
index 8a042b4..03d1974 100644
--- a/samples/ActionBarCompat/res/values-v13/styles.xml
+++ b/samples/browseable/RuntimePermissionsBasic/res/values-sw600dp/template-styles.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -16,8 +16,10 @@
 
 <resources>
 
-    <style name="ActionBarTitle" parent="android:style/TextAppearance.Holo.Widget.ActionBar.Title">
-        <item name="android:textColor">@color/actionbar_title_color</item>
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceLarge</item>
+        <item name="android:lineSpacingMultiplier">1.2</item>
+        <item name="android:shadowDy">-6.5</item>
     </style>
 
 </resources>
diff --git a/samples/ActionBarCompat/res/values/colors.xml b/samples/browseable/RuntimePermissionsBasic/res/values-v11/template-styles.xml
similarity index 79%
copy from samples/ActionBarCompat/res/values/colors.xml
copy to samples/browseable/RuntimePermissionsBasic/res/values-v11/template-styles.xml
index 4edc6d6..8c1ea66 100644
--- a/samples/ActionBarCompat/res/values/colors.xml
+++ b/samples/browseable/RuntimePermissionsBasic/res/values-v11/template-styles.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2011 The Android Open Source Project
+  Copyright 2013 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.
@@ -15,5 +15,8 @@
   -->
 
 <resources>
-    <color name="actionbar_title_color">#224894</color>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
 </resources>
diff --git a/samples/browseable/RuntimePermissionsBasic/res/values-v21/base-colors.xml b/samples/browseable/RuntimePermissionsBasic/res/values-v21/base-colors.xml
new file mode 100644
index 0000000..8b6ec3f
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/res/values-v21/base-colors.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+
+</resources>
diff --git a/samples/browseable/RuntimePermissionsBasic/res/values-v21/base-template-styles.xml b/samples/browseable/RuntimePermissionsBasic/res/values-v21/base-template-styles.xml
new file mode 100644
index 0000000..c778e4f
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/res/values-v21/base-template-styles.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Material.Light">
+    </style>
+
+</resources>
diff --git a/samples/browseable/RuntimePermissionsBasic/res/values/base-strings.xml b/samples/browseable/RuntimePermissionsBasic/res/values/base-strings.xml
new file mode 100644
index 0000000..1a6b6be
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/res/values/base-strings.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+    <string name="app_name">RuntimePermissionsBasic</string>
+    <string name="intro_message">
+        <![CDATA[
+        
+            
+            This sample shows runtime permissions available in the Android M and above.
+            This sample shows a basic implementation for requesting permissions at runtime. Click the button to request the Camera permission and open a full-screen camera preview.
+Note: The "RuntimePermissions" sample provides a more complete overview over the runtime permission features available.
+            
+        
+        ]]>
+    </string>
+</resources>
diff --git a/samples/browseable/RuntimePermissionsBasic/res/values/strings.xml b/samples/browseable/RuntimePermissionsBasic/res/values/strings.xml
new file mode 100644
index 0000000..eb0b7c4
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/res/values/strings.xml
@@ -0,0 +1,6 @@
+<resources>
+    <string name="show_camera">Show camera preview</string>
+    <string name="camera_unavailable"><b>Camera could not be opened.</b>\nThis occurs when the camera is not available (for example it is already in use) or if the system has denied access (for example when camera access has been disabled).</string>
+    <string name="intro">This sample shows a basic implementation for requesting permissions at runtime.\nClick the button below to request the Camera permission and open a full-screen camera preview.</string>
+
+</resources>
diff --git a/samples/browseable/RuntimePermissionsBasic/res/values/template-dimens.xml b/samples/browseable/RuntimePermissionsBasic/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+  Copyright 2013 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.
+  -->
+
+<resources>
+
+    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+    <dimen name="margin_tiny">4dp</dimen>
+    <dimen name="margin_small">8dp</dimen>
+    <dimen name="margin_medium">16dp</dimen>
+    <dimen name="margin_large">32dp</dimen>
+    <dimen name="margin_huge">64dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/samples/browseable/RuntimePermissionsBasic/res/values/template-styles.xml b/samples/browseable/RuntimePermissionsBasic/res/values/template-styles.xml
new file mode 100644
index 0000000..6e7d593
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+  Copyright 2013 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.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+
+    <style name="Theme.Base" parent="android:Theme.Light" />
+
+    <style name="Theme.Sample" parent="Theme.Base" />
+
+    <style name="AppTheme" parent="Theme.Sample" />
+    <!-- Widget styling -->
+
+    <style name="Widget" />
+
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceMedium</item>
+        <item name="android:lineSpacingMultiplier">1.1</item>
+    </style>
+
+    <style name="Widget.SampleMessageTile">
+        <item name="android:background">@drawable/tile</item>
+        <item name="android:shadowColor">#7F000000</item>
+        <item name="android:shadowDy">-3.5</item>
+        <item name="android:shadowRadius">2</item>
+    </style>
+
+</resources>
diff --git a/samples/browseable/RuntimePermissionsBasic/src/com.example.android.basicpermissions/MainActivity.java b/samples/browseable/RuntimePermissionsBasic/src/com.example.android.basicpermissions/MainActivity.java
new file mode 100644
index 0000000..9de3b01
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/src/com.example.android.basicpermissions/MainActivity.java
@@ -0,0 +1,135 @@
+/*
+* Copyright 2015 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.basicpermissions;
+
+import com.example.android.basicpermissions.camera.CameraPreviewActivity;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.Toast;
+
+/**
+ * Launcher Activity that demonstrates the use of runtime permissions for Android M.
+ * This Activity requests permissions to access the camera
+ * ({@link android.Manifest.permission#CAMERA})
+ * when the 'Show Camera Preview' button is clicked to start  {@link CameraPreviewActivity} once
+ * the permission has been granted.
+ * <p>
+ * First, the status of the Camera permission is checked using {@link
+ * Activity#checkSelfPermission(String)}.
+ * If it has not been granted ({@link PackageManager#PERMISSION_GRANTED}), it is requested by
+ * calling
+ * {@link Activity#requestPermissions(String[], int)}. The result of the request is returned in
+ * {@link Activity#onRequestPermissionsResult(int, String[], int[])}, which starts {@link
+ * CameraPreviewActivity}
+ * if the permission has been granted.
+ */
+public class MainActivity extends Activity {
+
+    private static final int PERMISSION_REQUEST_CAMERA = 0;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        // Register a listener for the 'Show Camera Preview' button.
+        Button b = (Button) findViewById(R.id.button_open_camera);
+        b.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                showCameraPreview();
+            }
+        });
+    }
+
+    @Override
+    public void onRequestPermissionsResult(int requestCode, String[] permissions,
+            int[] grantResults) {
+        // BEGIN_INCLUDE(onRequestPermissionsResult)
+        if (requestCode == PERMISSION_REQUEST_CAMERA) {
+            // Request for camera permission.
+            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+                // Permission has been granted. Start camera preview Activity.
+                Toast.makeText(this, "Camera permission was granted. Starting preview.",
+                        Toast.LENGTH_SHORT)
+                        .show();
+                startCamera();
+            } else {
+                // Permission request was denied.
+                Toast.makeText(this, "Camera permission request was denied.", Toast.LENGTH_SHORT)
+                        .show();
+            }
+        }
+        // END_INCLUDE(onRequestPermissionsResult)
+    }
+
+    private void showCameraPreview() {
+        // BEGIN_INCLUDE(startCamera)
+        if (isMNC()) {
+            // On Android M and above, need to check if permission has been granted at runtime.
+            if (checkSelfPermission(Manifest.permission.CAMERA)
+                    == PackageManager.PERMISSION_GRANTED) {
+                // Permission is available, start camera preview
+                startCamera();
+                Toast.makeText(this,
+                        "Camera permission has already been granted. Starting preview.",
+                        Toast.LENGTH_SHORT).show();
+            } else {
+                // Permission has not been granted and must be requested.
+                Toast.makeText(this,
+                        "Permission is not available. Requesting camera permission.",
+                        Toast.LENGTH_SHORT).show();
+                requestPermissions(new String[]{Manifest.permission.CAMERA},
+                        PERMISSION_REQUEST_CAMERA);
+            }
+        } else {
+            /*
+             Below Android M all permissions have already been grated at install time and do not
+             need to verified or requested.
+             If a permission has been disabled in the system settings, the API will return
+             unavailable or empty data instead. */
+            Toast.makeText(this,
+                    "Requested permissions are granted at install time below M and are always "
+                            + "available at runtime.",
+                    Toast.LENGTH_SHORT).show();
+            startCamera();
+        }
+        // END_INCLUDE(startCamera)
+    }
+
+    private void startCamera() {
+        Intent intent = new Intent(this, CameraPreviewActivity.class);
+        startActivity(intent);
+    }
+
+    public static boolean isMNC() {
+        /*
+         TODO: In the Android M Preview release, checking if the platform is M is done through
+         the codename, not the version code. Once the API has been finalised, the following check
+         should be used: */
+        // return Build.VERSION.SDK_INT >= Build.VERSION_CODES.MNC
+
+        return "MNC".equals(Build.VERSION.CODENAME);
+    }
+}
diff --git a/samples/browseable/RuntimePermissionsBasic/src/com.example.android.basicpermissions/camera/CameraPreview.java b/samples/browseable/RuntimePermissionsBasic/src/com.example.android.basicpermissions/camera/CameraPreview.java
new file mode 100644
index 0000000..7abf2d8
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/src/com.example.android.basicpermissions/camera/CameraPreview.java
@@ -0,0 +1,142 @@
+/*
+* Copyright 2015 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.basicpermissions.camera;
+
+import android.content.Context;
+import android.hardware.Camera;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import java.io.IOException;
+
+/**
+ * Camera preview that displays a {@link Camera}.
+ *
+ * Handles basic lifecycle methods to display and stop the preview.
+ * <p>
+ * Implementation is based directly on the documentation at
+ * http://developer.android.com/guide/topics/media/camera.html
+ */
+public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
+
+    private static final String TAG = "CameraPreview";
+    private SurfaceHolder mHolder;
+    private Camera mCamera;
+    private Camera.CameraInfo mCameraInfo;
+    private int mDisplayOrientation;
+
+    public CameraPreview(Context context, Camera camera, Camera.CameraInfo cameraInfo,
+            int displayOrientation) {
+        super(context);
+
+        // Do not initialise if no camera has been set
+        if (camera == null || cameraInfo == null) {
+            return;
+        }
+        mCamera = camera;
+        mCameraInfo = cameraInfo;
+        mDisplayOrientation = displayOrientation;
+
+        // Install a SurfaceHolder.Callback so we get notified when the
+        // underlying surface is created and destroyed.
+        mHolder = getHolder();
+        mHolder.addCallback(this);
+    }
+
+    public void surfaceCreated(SurfaceHolder holder) {
+        // The Surface has been created, now tell the camera where to draw the preview.
+        try {
+            mCamera.setPreviewDisplay(holder);
+            mCamera.startPreview();
+            Log.d(TAG, "Camera preview started.");
+        } catch (IOException e) {
+            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
+        }
+    }
+
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        // empty. Take care of releasing the Camera preview in your activity.
+    }
+
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        // If your preview can change or rotate, take care of those events here.
+        // Make sure to stop the preview before resizing or reformatting it.
+
+        if (mHolder.getSurface() == null) {
+            // preview surface does not exist
+            Log.d(TAG, "Preview surface does not exist");
+            return;
+        }
+
+        // stop preview before making changes
+        try {
+            mCamera.stopPreview();
+            Log.d(TAG, "Preview stopped.");
+        } catch (Exception e) {
+            // ignore: tried to stop a non-existent preview
+            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
+        }
+
+        int orientation = calculatePreviewOrientation(mCameraInfo, mDisplayOrientation);
+        mCamera.setDisplayOrientation(orientation);
+
+        try {
+            mCamera.setPreviewDisplay(mHolder);
+            mCamera.startPreview();
+            Log.d(TAG, "Camera preview started.");
+        } catch (Exception e) {
+            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Calculate the correct orientation for a {@link Camera} preview that is displayed on screen.
+     *
+     * Implementation is based on the sample code provided in
+     * {@link Camera#setDisplayOrientation(int)}.
+     */
+    public static int calculatePreviewOrientation(Camera.CameraInfo info, int rotation) {
+        int degrees = 0;
+
+        switch (rotation) {
+            case Surface.ROTATION_0:
+                degrees = 0;
+                break;
+            case Surface.ROTATION_90:
+                degrees = 90;
+                break;
+            case Surface.ROTATION_180:
+                degrees = 180;
+                break;
+            case Surface.ROTATION_270:
+                degrees = 270;
+                break;
+        }
+
+        int result;
+        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
+            result = (info.orientation + degrees) % 360;
+            result = (360 - result) % 360;  // compensate the mirror
+        } else {  // back-facing
+            result = (info.orientation - degrees + 360) % 360;
+        }
+
+        return result;
+    }
+}
diff --git a/samples/browseable/RuntimePermissionsBasic/src/com.example.android.basicpermissions/camera/CameraPreviewActivity.java b/samples/browseable/RuntimePermissionsBasic/src/com.example.android.basicpermissions/camera/CameraPreviewActivity.java
new file mode 100644
index 0000000..ee589d9
--- /dev/null
+++ b/samples/browseable/RuntimePermissionsBasic/src/com.example.android.basicpermissions/camera/CameraPreviewActivity.java
@@ -0,0 +1,104 @@
+/*
+* Copyright 2015 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.basicpermissions.camera;
+
+import com.example.android.basicpermissions.R;
+
+import android.app.Activity;
+import android.hardware.Camera;
+import android.os.Bundle;
+import android.widget.FrameLayout;
+import android.widget.Toast;
+
+/**
+ * Displays a {@link CameraPreview} of the first {@link Camera}.
+ * An error message is displayed if the Camera is not available.
+ * <p>
+ * This Activity is only used to illustrate that access to the Camera API has been granted (or
+ * denied) as part of the runtime permissions model. It is not relevant for the use of the
+ * permissions API.
+ * <p>
+ * Implementation is based directly on the documentation at
+ * http://developer.android.com/guide/topics/media/camera.html
+ */
+public class CameraPreviewActivity extends Activity {
+
+    private static final String TAG = "CameraPreview";
+
+    /**
+     * Id of the camera to access. 0 is the first camera.
+     */
+    private static final int CAMERA_ID = 0;
+
+    private CameraPreview mPreview;
+    private Camera mCamera;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Open an instance of the first camera and retrieve its info.
+        mCamera = getCameraInstance(CAMERA_ID);
+        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
+        Camera.getCameraInfo(CAMERA_ID, cameraInfo);
+
+        if (mCamera == null || cameraInfo == null) {
+            // Camera is not available, display error message
+            Toast.makeText(this, "Camera is not available.", Toast.LENGTH_SHORT).show();
+            setContentView(R.layout.activity_camera_unavailable);
+        } else {
+
+            setContentView(R.layout.activity_camera);
+
+            // Get the rotation of the screen to adjust the preview image accordingly.
+            final int displayRotation = getWindowManager().getDefaultDisplay()
+                    .getRotation();
+
+            // Create the Preview view and set it as the content of this Activity.
+            mPreview = new CameraPreview(this, mCamera, cameraInfo, displayRotation);
+            FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
+            preview.addView(mPreview);
+        }
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        // Stop camera access
+        releaseCamera();
+    }
+
+    /** A safe way to get an instance of the Camera object. */
+    private Camera getCameraInstance(int cameraId) {
+        Camera c = null;
+        try {
+            c = Camera.open(cameraId); // attempt to get a Camera instance
+        } catch (Exception e) {
+            // Camera is not available (in use or does not exist)
+            Toast.makeText(this, "Camera " + cameraId + " is not available: " + e.getMessage(),
+                    Toast.LENGTH_SHORT).show();
+        }
+        return c; // returns null if camera is unavailable
+    }
+
+    private void releaseCamera() {
+        if (mCamera != null) {
+            mCamera.release();        // release the camera for other applications
+            mCamera = null;
+        }
+    }
+}
diff --git a/samples/devbytes/telephony/SmsSampleProject/.gitignore b/samples/devbytes/telephony/SmsSampleProject/.gitignore
new file mode 100644
index 0000000..9c4de58
--- /dev/null
+++ b/samples/devbytes/telephony/SmsSampleProject/.gitignore
@@ -0,0 +1,7 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
diff --git a/samples/devbytes/telephony/SmsSampleProject/.idea/.name b/samples/devbytes/telephony/SmsSampleProject/.idea/.name
new file mode 100644
index 0000000..1c26a73
--- /dev/null
+++ b/samples/devbytes/telephony/SmsSampleProject/.idea/.name
@@ -0,0 +1 @@
+smssample
\ No newline at end of file
diff --git a/samples/devbytes/telephony/SmsSampleProject/.idea/compiler.xml b/samples/devbytes/telephony/SmsSampleProject/.idea/compiler.xml
new file mode 100644
index 0000000..96cc43e
--- /dev/null
+++ b/samples/devbytes/telephony/SmsSampleProject/.idea/compiler.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <resourceExtensions />
+    <wildcardResourcePatterns>
+      <entry name="!?*.java" />
+      <entry name="!?*.form" />
+      <entry name="!?*.class" />
+      <entry name="!?*.groovy" />
+      <entry name="!?*.scala" />
+      <entry name="!?*.flex" />
+      <entry name="!?*.kt" />
+      <entry name="!?*.clj" />
+      <entry name="!?*.aj" />
+    </wildcardResourcePatterns>
+    <annotationProcessing>
+      <profile default="true" name="Default" enabled="false">
+        <processorPath useClasspath="true" />
+      </profile>
+    </annotationProcessing>
+  </component>
+</project>
\ No newline at end of file
diff --git a/samples/devbytes/telephony/SmsSampleProject/.idea/copyright/profiles_settings.xml b/samples/devbytes/telephony/SmsSampleProject/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/samples/devbytes/telephony/SmsSampleProject/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+<component name="CopyrightManager">
+  <settings default="" />
+</component>
\ No newline at end of file
diff --git a/samples/devbytes/telephony/SmsSampleProject/.idea/gradle.xml b/samples/devbytes/telephony/SmsSampleProject/.idea/gradle.xml
new file mode 100644
index 0000000..1bbc21d
--- /dev/null
+++ b/samples/devbytes/telephony/SmsSampleProject/.idea/gradle.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="GradleSettings">
+    <option name="linkedExternalProjectsSettings">
+      <GradleProjectSettings>
+        <option name="distributionType" value="DEFAULT_WRAPPED" />
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="gradleJvm" value="1.7" />
+        <option name="modules">
+          <set>
+            <option value="$PROJECT_DIR$" />
+            <option value="$PROJECT_DIR$/app" />
+          </set>
+        </option>
+      </GradleProjectSettings>
+    </option>
+  </component>
+</project>
\ No newline at end of file
diff --git a/samples/devbytes/telephony/SmsSampleProject/.idea/misc.xml b/samples/devbytes/telephony/SmsSampleProject/.idea/misc.xml
new file mode 100644
index 0000000..e930905
--- /dev/null
+++ b/samples/devbytes/telephony/SmsSampleProject/.idea/misc.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="EntryPointsManager">
+    <entry_points version="2.0" />
+  </component>
+  <component name="ProjectLevelVcsManager" settingsEditedManually="false">
+    <OptionsSetting value="true" id="Add" />
+    <OptionsSetting value="true" id="Remove" />
+    <OptionsSetting value="true" id="Checkout" />
+    <OptionsSetting value="true" id="Update" />
+    <OptionsSetting value="true" id="Status" />
+    <OptionsSetting value="true" id="Edit" />
+    <ConfirmationsSetting value="0" id="Add" />
+    <ConfirmationsSetting value="0" id="Remove" />
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/build/classes" />
+  </component>
+  <component name="ProjectType">
+    <option name="id" value="Android" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/samples/devbytes/telephony/SmsSampleProject/.idea/modules.xml b/samples/devbytes/telephony/SmsSampleProject/.idea/modules.xml
new file mode 100644
index 0000000..3c327c4
--- /dev/null
+++ b/samples/devbytes/telephony/SmsSampleProject/.idea/modules.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/SmsSampleProject.iml" filepath="$PROJECT_DIR$/SmsSampleProject.iml" />
+      <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
+    </modules>
+  </component>
+</project>
\ No newline at end of file
diff --git a/samples/devbytes/telephony/SmsSampleProject/.idea/vcs.xml b/samples/devbytes/telephony/SmsSampleProject/.idea/vcs.xml
new file mode 100644
index 0000000..6564d52
--- /dev/null
+++ b/samples/devbytes/telephony/SmsSampleProject/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/samples/devbytes/telephony/SmsSampleProject/README b/samples/devbytes/telephony/SmsSampleProject/README
deleted file mode 100644
index a26768c..0000000
--- a/samples/devbytes/telephony/SmsSampleProject/README
+++ /dev/null
@@ -1,7 +0,0 @@
-This is an Android Studio project:
-http://developer.android.com/sdk/installing/studio.html
-
-To build you should first copy local.properties.sample to
-local.properties and set your SDK path.
-
-Then use Android Studio to import the project.
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/build.gradle b/samples/devbytes/telephony/SmsSampleProject/SmsSample/build.gradle
deleted file mode 100644
index d0f9b97..0000000
--- a/samples/devbytes/telephony/SmsSampleProject/SmsSample/build.gradle
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-buildscript {
-    repositories {
-        mavenCentral()
-    }
-    dependencies {
-        classpath 'com.android.tools.build:gradle:0.6.+'
-    }
-}
-apply plugin: 'android'
-
-repositories {
-    mavenCentral()
-}
-
-android {
-    compileSdkVersion 19
-    buildToolsVersion "18.1.1"
-
-    defaultConfig {
-        minSdkVersion 10
-        targetSdkVersion 19
-    }
-}
-
-dependencies {
-    compile 'com.android.support:support-v4:18.0.0'
-}
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSampleProject.iml b/samples/devbytes/telephony/SmsSampleProject/SmsSampleProject.iml
new file mode 100644
index 0000000..4954b7e
--- /dev/null
+++ b/samples/devbytes/telephony/SmsSampleProject/SmsSampleProject.iml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id="SmsSampleProject" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="java-gradle" name="Java-Gradle">
+      <configuration>
+        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
+        <option name="BUILDABLE" value="false" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/samples/devbytes/telephony/SmsSampleProject/app/.gitignore b/samples/devbytes/telephony/SmsSampleProject/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/samples/devbytes/telephony/SmsSampleProject/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/samples/devbytes/telephony/SmsSampleProject/app/app.iml b/samples/devbytes/telephony/SmsSampleProject/app/app.iml
new file mode 100644
index 0000000..4951e43
--- /dev/null
+++ b/samples/devbytes/telephony/SmsSampleProject/app/app.iml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="SmsSampleProject" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="android-gradle" name="Android-Gradle">
+      <configuration>
+        <option name="GRADLE_PROJECT_PATH" value=":app" />
+      </configuration>
+    </facet>
+    <facet type="android" name="Android">
+      <configuration>
+        <option name="SELECTED_BUILD_VARIANT" value="debug" />
+        <option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
+        <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
+        <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
+        <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
+        <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
+        <option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" />
+        <option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugAndroidTestSources" />
+        <option name="ALLOW_USER_CONFIGURATION" value="false" />
+        <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
+        <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
+        <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
+        <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
+    <output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/22.2.0/jars" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/22.2.0/jars" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
+      <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
+    </content>
+    <orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" exported="" name="support-annotations-22.2.0" level="project" />
+    <orderEntry type="library" exported="" name="support-v4-22.2.0" level="project" />
+    <orderEntry type="library" exported="" name="appcompat-v7-22.2.0" level="project" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/samples/devbytes/telephony/SmsSampleProject/app/build.gradle b/samples/devbytes/telephony/SmsSampleProject/app/build.gradle
new file mode 100644
index 0000000..01b041e
--- /dev/null
+++ b/samples/devbytes/telephony/SmsSampleProject/app/build.gradle
@@ -0,0 +1,25 @@
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 22
+    buildToolsVersion "23.0.0 rc2"
+
+    defaultConfig {
+        applicationId "android.example.com.smssample"
+        minSdkVersion 15
+        targetSdkVersion 22
+        versionCode 1
+        versionName "1.0"
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+}
+
+dependencies {
+    compile fileTree(dir: 'libs', include: ['*.jar'])
+    compile 'com.android.support:appcompat-v7:22.2.0'
+}
diff --git a/samples/devbytes/telephony/SmsSampleProject/app/proguard-rules.pro b/samples/devbytes/telephony/SmsSampleProject/app/proguard-rules.pro
new file mode 100644
index 0000000..f7d1389
--- /dev/null
+++ b/samples/devbytes/telephony/SmsSampleProject/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /usr/local/google/home/omakoto/Android/Sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/AndroidManifest.xml b/samples/devbytes/telephony/SmsSampleProject/app/src/main/AndroidManifest.xml
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/AndroidManifest.xml
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/AndroidManifest.xml
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/java/com/example/android/smssample/MainActivity.java b/samples/devbytes/telephony/SmsSampleProject/app/src/main/java/com/example/android/smssample/MainActivity.java
similarity index 94%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/java/com/example/android/smssample/MainActivity.java
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/java/com/example/android/smssample/MainActivity.java
index c949397..8321181 100644
--- a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/java/com/example/android/smssample/MainActivity.java
+++ b/samples/devbytes/telephony/SmsSampleProject/app/src/main/java/com/example/android/smssample/MainActivity.java
@@ -16,6 +16,7 @@
 
 package com.example.android.smssample;
 
+import android.content.Context;
 import android.content.Intent;
 import android.database.Cursor;
 import android.net.Uri;
@@ -26,6 +27,7 @@
 import android.support.v4.content.CursorLoader;
 import android.support.v4.content.Loader;
 import android.support.v4.widget.SimpleCursorAdapter;
+import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.view.Menu;
 import android.view.View;
@@ -147,6 +149,14 @@
                 });
             }
         }
+        String phoneNumberToast = "Unable to obtain phone number (not default SMS app?)";
+        final TelephonyManager telephony =
+                (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
+        try {
+            phoneNumberToast = "Phone number: " + telephony.getLine1Number();
+        } catch (SecurityException e) {
+        }
+        Toast.makeText(this, phoneNumberToast, Toast.LENGTH_SHORT).show();
     }
 
     @Override
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/java/com/example/android/smssample/Utils.java b/samples/devbytes/telephony/SmsSampleProject/app/src/main/java/com/example/android/smssample/Utils.java
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/java/com/example/android/smssample/Utils.java
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/java/com/example/android/smssample/Utils.java
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/java/com/example/android/smssample/receiver/MessagingReceiver.java b/samples/devbytes/telephony/SmsSampleProject/app/src/main/java/com/example/android/smssample/receiver/MessagingReceiver.java
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/java/com/example/android/smssample/receiver/MessagingReceiver.java
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/java/com/example/android/smssample/receiver/MessagingReceiver.java
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/java/com/example/android/smssample/receiver/MmsReceiver.java b/samples/devbytes/telephony/SmsSampleProject/app/src/main/java/com/example/android/smssample/receiver/MmsReceiver.java
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/java/com/example/android/smssample/receiver/MmsReceiver.java
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/java/com/example/android/smssample/receiver/MmsReceiver.java
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/java/com/example/android/smssample/receiver/MmsReceiverLegacy.java b/samples/devbytes/telephony/SmsSampleProject/app/src/main/java/com/example/android/smssample/receiver/MmsReceiverLegacy.java
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/java/com/example/android/smssample/receiver/MmsReceiverLegacy.java
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/java/com/example/android/smssample/receiver/MmsReceiverLegacy.java
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/java/com/example/android/smssample/receiver/SmsReceiver.java b/samples/devbytes/telephony/SmsSampleProject/app/src/main/java/com/example/android/smssample/receiver/SmsReceiver.java
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/java/com/example/android/smssample/receiver/SmsReceiver.java
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/java/com/example/android/smssample/receiver/SmsReceiver.java
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/java/com/example/android/smssample/receiver/SmsReceiverLegacy.java b/samples/devbytes/telephony/SmsSampleProject/app/src/main/java/com/example/android/smssample/receiver/SmsReceiverLegacy.java
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/java/com/example/android/smssample/receiver/SmsReceiverLegacy.java
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/java/com/example/android/smssample/receiver/SmsReceiverLegacy.java
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/java/com/example/android/smssample/service/MessagingService.java b/samples/devbytes/telephony/SmsSampleProject/app/src/main/java/com/example/android/smssample/service/MessagingService.java
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/java/com/example/android/smssample/service/MessagingService.java
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/java/com/example/android/smssample/service/MessagingService.java
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/java/com/example/android/smssample/service/RespondService.java b/samples/devbytes/telephony/SmsSampleProject/app/src/main/java/com/example/android/smssample/service/RespondService.java
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/java/com/example/android/smssample/service/RespondService.java
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/java/com/example/android/smssample/service/RespondService.java
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/drawable-hdpi/ic_launcher.png b/samples/devbytes/telephony/SmsSampleProject/app/src/main/res/drawable-hdpi/ic_launcher.png
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/drawable-hdpi/ic_launcher.png
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/drawable-mdpi/ic_launcher.png b/samples/devbytes/telephony/SmsSampleProject/app/src/main/res/drawable-mdpi/ic_launcher.png
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/drawable-mdpi/ic_launcher.png
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/drawable-xhdpi/ic_launcher.png b/samples/devbytes/telephony/SmsSampleProject/app/src/main/res/drawable-xhdpi/ic_launcher.png
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/drawable-xhdpi/ic_launcher.png
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/samples/devbytes/telephony/SmsSampleProject/app/src/main/res/drawable-xxhdpi/ic_launcher.png
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/drawable-xxhdpi/ic_launcher.png
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/layout/activity_main.xml b/samples/devbytes/telephony/SmsSampleProject/app/src/main/res/layout/activity_main.xml
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/layout/activity_main.xml
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/res/layout/activity_main.xml
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/menu/main.xml b/samples/devbytes/telephony/SmsSampleProject/app/src/main/res/menu/main.xml
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/menu/main.xml
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/res/menu/main.xml
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/values-v11/styles.xml b/samples/devbytes/telephony/SmsSampleProject/app/src/main/res/values-v11/styles.xml
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/values-v11/styles.xml
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/res/values-v11/styles.xml
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/values-v19/bools.xml b/samples/devbytes/telephony/SmsSampleProject/app/src/main/res/values-v19/bools.xml
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/values-v19/bools.xml
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/res/values-v19/bools.xml
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/values/bools.xml b/samples/devbytes/telephony/SmsSampleProject/app/src/main/res/values/bools.xml
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/values/bools.xml
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/res/values/bools.xml
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/values/colors.xml b/samples/devbytes/telephony/SmsSampleProject/app/src/main/res/values/colors.xml
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/values/colors.xml
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/res/values/colors.xml
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/values/dimens.xml b/samples/devbytes/telephony/SmsSampleProject/app/src/main/res/values/dimens.xml
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/values/dimens.xml
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/res/values/dimens.xml
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/values/strings.xml b/samples/devbytes/telephony/SmsSampleProject/app/src/main/res/values/strings.xml
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/values/strings.xml
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/res/values/strings.xml
diff --git a/samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/values/styles.xml b/samples/devbytes/telephony/SmsSampleProject/app/src/main/res/values/styles.xml
similarity index 100%
rename from samples/devbytes/telephony/SmsSampleProject/SmsSample/src/main/res/values/styles.xml
rename to samples/devbytes/telephony/SmsSampleProject/app/src/main/res/values/styles.xml
diff --git a/samples/devbytes/telephony/SmsSampleProject/build.gradle b/samples/devbytes/telephony/SmsSampleProject/build.gradle
index 495c503..9405f3f 100644
--- a/samples/devbytes/telephony/SmsSampleProject/build.gradle
+++ b/samples/devbytes/telephony/SmsSampleProject/build.gradle
@@ -1 +1,19 @@
 // Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+    repositories {
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:1.2.3'
+
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        jcenter()
+    }
+}
diff --git a/samples/devbytes/telephony/SmsSampleProject/gradle.properties b/samples/devbytes/telephony/SmsSampleProject/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/samples/devbytes/telephony/SmsSampleProject/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/samples/devbytes/telephony/SmsSampleProject/gradle/wrapper/gradle-wrapper.jar b/samples/devbytes/telephony/SmsSampleProject/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/samples/devbytes/telephony/SmsSampleProject/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/samples/devbytes/telephony/SmsSampleProject/gradle/wrapper/gradle-wrapper.properties b/samples/devbytes/telephony/SmsSampleProject/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/samples/devbytes/telephony/SmsSampleProject/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/samples/devbytes/telephony/SmsSampleProject/gradlew b/samples/devbytes/telephony/SmsSampleProject/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/samples/devbytes/telephony/SmsSampleProject/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/samples/devbytes/telephony/SmsSampleProject/gradlew.bat b/samples/devbytes/telephony/SmsSampleProject/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/samples/devbytes/telephony/SmsSampleProject/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off

+@rem ##########################################################################

+@rem

+@rem  Gradle startup script for Windows

+@rem

+@rem ##########################################################################

+

+@rem Set local scope for the variables with windows NT shell

+if "%OS%"=="Windows_NT" setlocal

+

+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.

+set DEFAULT_JVM_OPTS=

+

+set DIRNAME=%~dp0

+if "%DIRNAME%" == "" set DIRNAME=.

+set APP_BASE_NAME=%~n0

+set APP_HOME=%DIRNAME%

+

+@rem Find java.exe

+if defined JAVA_HOME goto findJavaFromJavaHome

+

+set JAVA_EXE=java.exe

+%JAVA_EXE% -version >NUL 2>&1

+if "%ERRORLEVEL%" == "0" goto init

+

+echo.

+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:findJavaFromJavaHome

+set JAVA_HOME=%JAVA_HOME:"=%

+set JAVA_EXE=%JAVA_HOME%/bin/java.exe

+

+if exist "%JAVA_EXE%" goto init

+

+echo.

+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:init

+@rem Get command-line arguments, handling Windowz variants

+

+if not "%OS%" == "Windows_NT" goto win9xME_args

+if "%@eval[2+2]" == "4" goto 4NT_args

+

+:win9xME_args

+@rem Slurp the command line arguments.

+set CMD_LINE_ARGS=

+set _SKIP=2

+

+:win9xME_args_slurp

+if "x%~1" == "x" goto execute

+

+set CMD_LINE_ARGS=%*

+goto execute

+

+:4NT_args

+@rem Get arguments from the 4NT Shell from JP Software

+set CMD_LINE_ARGS=%$

+

+:execute

+@rem Setup the command line

+

+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

+

+@rem Execute Gradle

+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

+

+:end

+@rem End local scope for the variables with windows NT shell

+if "%ERRORLEVEL%"=="0" goto mainEnd

+

+:fail

+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of

+rem the _cmd.exe /c_ return code!

+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1

+exit /b 1

+

+:mainEnd

+if "%OS%"=="Windows_NT" endlocal

+

+:omega

diff --git a/samples/devbytes/telephony/SmsSampleProject/local.properties.sample b/samples/devbytes/telephony/SmsSampleProject/local.properties.sample
deleted file mode 100644
index 37317f4..0000000
--- a/samples/devbytes/telephony/SmsSampleProject/local.properties.sample
+++ /dev/null
@@ -1,7 +0,0 @@
-# This file should be copied to local.properties and path set to point
-# to your Android SDK.
-
-# Location of the SDK. This is only used by Gradle.
-# For customization when using a Version Control System, please read the
-# header note.
-sdk.dir=/usr/local/lib/android-sdk
\ No newline at end of file
diff --git a/samples/devbytes/telephony/SmsSampleProject/settings.gradle b/samples/devbytes/telephony/SmsSampleProject/settings.gradle
index e0867f0..e7b4def 100644
--- a/samples/devbytes/telephony/SmsSampleProject/settings.gradle
+++ b/samples/devbytes/telephony/SmsSampleProject/settings.gradle
@@ -1 +1 @@
-include ':SmsSample'
\ No newline at end of file
+include ':app'
diff --git a/samples/samples_source.prop_template b/samples/samples_source.prop_template
index 9e33a6c..523d6bd 100644
--- a/samples/samples_source.prop_template
+++ b/samples/samples_source.prop_template
@@ -1,4 +1,4 @@
 Pkg.UserSrc=false
-Pkg.Revision=6
+Pkg.Revision=2
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
diff --git a/scripts/gdbclient b/scripts/gdbclient
index 5113977..b74a8f0 100755
--- a/scripts/gdbclient
+++ b/scripts/gdbclient
@@ -13,16 +13,16 @@
 source $ANDROID_BUILD_TOP/build/envsetup.sh
 
 function adb_get_product_device() {
-  local candidate=`adb shell getprop ro.product.device | sed s/.$//`
+  local candidate=`adb shell getprop ro.product.device | tr -d '\r\n'`
   if [ -z $candidate ]; then
-    candidate=`adb shell getprop ro.hardware | sed s/.$//`
+    candidate=`adb shell getprop ro.hardware | tr -d '\r\n'`
   fi
   echo $candidate
 }
 
 # returns 0 when process is not traced
 function adb_get_traced_by() {
-  echo `adb shell cat /proc/$1/status | grep -e "^TracerPid:" | sed "s/^TracerPid:\t//" | sed s/.$//`
+  echo `adb shell cat /proc/$1/status | grep -e "^TracerPid:" | sed "s/^TracerPid:\t//" | tr -d '\r\n'`
 }
 
 function get_symbols_directory()
@@ -95,7 +95,7 @@
     fi
   fi
 
-  local EXE=`adb shell readlink /proc/$PID/exe | sed s/.$//`
+  local EXE=`adb shell readlink /proc/$PID/exe | tr -d '\r\n'`
 
   if [ -z "$EXE" ]; then
     echo "Error: no such pid=$PID - is process still alive?"
@@ -126,7 +126,7 @@
 
   local GDB=
   local GDB64=
-  local CPU_ABI=`adb shell getprop ro.product.cpu.abilist | sed s/.$//`
+  local CPU_ABI=`adb shell getprop ro.product.cpu.abilist | tr -d '\r\n'`
   # TODO: Derive this differently to correctly support multi-arch. We could try to parse
   #       /proc/pid/exe. Right now, we prefer 64bit by checking those entries first.
   # TODO: Correctly support native bridge, which makes parsing abilist very brittle.
diff --git a/scripts/stack_core.py b/scripts/stack_core.py
index 9b7ff23..5a6fd48 100755
--- a/scripts/stack_core.py
+++ b/scripts/stack_core.py
@@ -53,6 +53,7 @@
     "arm": "r0|r1|r2|r3|r4|r5|r6|r7|r8|r9|sl|fp|ip|sp|lr|pc|cpsr",
     "arm64": "x0|x1|x2|x3|x4|x5|x6|x7|x8|x9|x10|x11|x12|x13|x14|x15|x16|x17|x18|x19|x20|x21|x22|x23|x24|x25|x26|x27|x28|x29|x30|sp|pc|pstate",
     "mips": "zr|at|v0|v1|a0|a1|a2|a3|t0|t1|t2|t3|t4|t5|t6|t7|s0|s1|s2|s3|s4|s5|s6|s7|t8|t9|k0|k1|gp|sp|s8|ra|hi|lo|bva|epc",
+    "mips64": "zr|at|v0|v1|a0|a1|a2|a3|a4|a5|a6|a7|t0|t1|t2|t3|s0|s1|s2|s3|s4|s5|s6|s7|t8|t9|k0|k1|gp|sp|s8|ra|hi|lo|bva|epc",
     "x86": "eax|ebx|ecx|edx|esi|edi|x?cs|x?ds|x?es|x?fs|x?ss|eip|ebp|esp|flags",
     "x86_64": "rax|rbx|rcx|rdx|rsi|rdi|r8|r9|r10|r11|r12|r13|r14|r15|cs|ss|rip|rbp|rsp|eflags",
   }
diff --git a/sdk/build_tools_source.prop_template b/sdk/build_tools_source.prop_template
index c9bfc2f..06a2ff8 100644
--- a/sdk/build_tools_source.prop_template
+++ b/sdk/build_tools_source.prop_template
@@ -1,3 +1,5 @@
 Pkg.UserSrc=false
-Pkg.Revision=${PLATFORM_SDK_VERSION}.0.2
+// due to the codename this resolve to 22 instead of 23, so replace it with hardcoded version for now.
+//Pkg.Revision=${PLATFORM_SDK_VERSION}.0.0
+Pkg.Revision=23.0.0 rc3
 
diff --git a/sdk/doc_source.prop_template b/sdk/doc_source.prop_template
index d3cdfd5..523d6bd 100644
--- a/sdk/doc_source.prop_template
+++ b/sdk/doc_source.prop_template
@@ -1,4 +1,4 @@
 Pkg.UserSrc=false
-Pkg.Revision=1
+Pkg.Revision=2
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
diff --git a/sdk/plat_tools_source.prop_template b/sdk/plat_tools_source.prop_template
index 5d62307..4c98e9a 100644
--- a/sdk/plat_tools_source.prop_template
+++ b/sdk/plat_tools_source.prop_template
@@ -1,3 +1,4 @@
 Pkg.UserSrc=false
-Pkg.Revision=${PLATFORM_SDK_VERSION}.0.0
-
+// due to the codename this resolve to 22 instead of 23, so replace it with hardcoded version for now.
+//Pkg.Revision=${PLATFORM_SDK_VERSION}.0.0
+Pkg.Revision=23.0.0 rc4
diff --git a/sdk/platform_source.prop_template b/sdk/platform_source.prop_template
index 0eb8dd2..a611014 100644
--- a/sdk/platform_source.prop_template
+++ b/sdk/platform_source.prop_template
@@ -1,10 +1,10 @@
 Pkg.Desc=Android SDK Platform ${PLATFORM_VERSION}
 Pkg.UserSrc=false
 Platform.Version=${PLATFORM_VERSION}
-Platform.CodeName=LOLLIPOP_MR1
+Platform.CodeName=MNC
 Pkg.Revision=2
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
-Layoutlib.Api=14
-Layoutlib.Revision=2
+Layoutlib.Api=15
+Layoutlib.Revision=1
 Platform.MinToolsRev=22
diff --git a/sdk/source_source.prop_template b/sdk/source_source.prop_template
index d3cdfd5..523d6bd 100644
--- a/sdk/source_source.prop_template
+++ b/sdk/source_source.prop_template
@@ -1,4 +1,4 @@
 Pkg.UserSrc=false
-Pkg.Revision=1
+Pkg.Revision=2
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
diff --git a/sdk/support_source.prop_template b/sdk/support_source.prop_template
index 03d6962..f5b217e 100644
--- a/sdk/support_source.prop_template
+++ b/sdk/support_source.prop_template
@@ -1,5 +1,5 @@
 Pkg.UserSrc=false
-Pkg.Revision=${PLATFORM_SDK_VERSION}.1.1
+Pkg.Revision=${PLATFORM_SDK_VERSION}.0.0
 Extra.Vendor=android
 Extra.VendorId=android
 Extra.VendorDisplay=Android
diff --git a/sys-img/images_arm64-v8a_source.prop_template b/sys-img/images_arm64-v8a_source.prop_template
index 1a18cf8..d5f5610 100644
--- a/sys-img/images_arm64-v8a_source.prop_template
+++ b/sys-img/images_arm64-v8a_source.prop_template
@@ -1,6 +1,6 @@
 Pkg.Desc=Android SDK Platform ${PLATFORM_VERSION}
 Pkg.UserSrc=false
-Pkg.Revision=1
+Pkg.Revision=2
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
 SystemImage.Abi=${TARGET_CPU_ABI}
diff --git a/sys-img/images_armeabi-v7a_source.prop_template b/sys-img/images_armeabi-v7a_source.prop_template
index 9c7a332..7d13fce 100644
--- a/sys-img/images_armeabi-v7a_source.prop_template
+++ b/sys-img/images_armeabi-v7a_source.prop_template
@@ -1,6 +1,6 @@
 Pkg.Desc=Android SDK Platform ${PLATFORM_VERSION}
 Pkg.UserSrc=false
-Pkg.Revision=1
+Pkg.Revision=2
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
 SystemImage.Abi=armeabi-v7a
diff --git a/sys-img/images_armeabi_source.prop_template b/sys-img/images_armeabi_source.prop_template
index 91e9d21..ef17ea6 100644
--- a/sys-img/images_armeabi_source.prop_template
+++ b/sys-img/images_armeabi_source.prop_template
@@ -1,6 +1,6 @@
 Pkg.Desc=Android SDK Platform ${PLATFORM_VERSION}
 Pkg.UserSrc=false
-Pkg.Revision=1
+Pkg.Revision=2
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
 SystemImage.Abi=armeabi
diff --git a/sys-img/images_mips64_source.prop_template b/sys-img/images_mips64_source.prop_template
new file mode 100644
index 0000000..157746d
--- /dev/null
+++ b/sys-img/images_mips64_source.prop_template
@@ -0,0 +1,9 @@
+Pkg.Desc=Android SDK Platform ${PLATFORM_VERSION}
+Pkg.UserSrc=false
+Pkg.Revision=2
+AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
+AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
+SystemImage.Abi=mips64
+SystemImage.GpuSupport=true
+SystemImage.TagId=default
+
diff --git a/sys-img/images_mips_source.prop_template b/sys-img/images_mips_source.prop_template
index b891152..dcca286 100644
--- a/sys-img/images_mips_source.prop_template
+++ b/sys-img/images_mips_source.prop_template
@@ -1,6 +1,6 @@
 Pkg.Desc=Android SDK Platform ${PLATFORM_VERSION}
 Pkg.UserSrc=false
-Pkg.Revision=1
+Pkg.Revision=2
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
 SystemImage.Abi=mips
diff --git a/sys-img/images_x86_64_source.prop_template b/sys-img/images_x86_64_source.prop_template
index 1a18cf8..d5f5610 100644
--- a/sys-img/images_x86_64_source.prop_template
+++ b/sys-img/images_x86_64_source.prop_template
@@ -1,6 +1,6 @@
 Pkg.Desc=Android SDK Platform ${PLATFORM_VERSION}
 Pkg.UserSrc=false
-Pkg.Revision=1
+Pkg.Revision=2
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
 SystemImage.Abi=${TARGET_CPU_ABI}
diff --git a/sys-img/images_x86_source.prop_template b/sys-img/images_x86_source.prop_template
index 1a18cf8..d5f5610 100644
--- a/sys-img/images_x86_source.prop_template
+++ b/sys-img/images_x86_source.prop_template
@@ -1,6 +1,6 @@
 Pkg.Desc=Android SDK Platform ${PLATFORM_VERSION}
 Pkg.UserSrc=false
-Pkg.Revision=1
+Pkg.Revision=2
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
 SystemImage.Abi=${TARGET_CPU_ABI}
diff --git a/testrunner/adb_interface.py b/testrunner/adb_interface.py
index dc43a93..cd39480 100755
--- a/testrunner/adb_interface.py
+++ b/testrunner/adb_interface.py
@@ -51,7 +51,7 @@
     """Direct all future commands to Android target with the given serial."""
     self._target_arg = "-s %s" % serial
 
-  def SendCommand(self, command_string, timeout_time=20, retry_count=3):
+  def SendCommand(self, command_string, timeout_time=60, retry_count=3):
     """Send a command via adb.
 
     Args:
@@ -131,16 +131,17 @@
       logger.Log("ADB Pull Failed: Source file %s does not exist." % src)
       return False
 
-  def Install(self, apk_path):
+  def Install(self, apk_path, extra_flags):
     """Installs apk on device.
 
     Args:
       apk_path: file path to apk file on host
+      extra_flags: Additional flags to use with adb install
 
     Returns:
       output of install command
     """
-    return self.SendCommand("install -r %s" % apk_path)
+    return self.SendCommand("install -r %s %s" % (extra_flags, apk_path))
 
   def DoesFileExist(self, src):
     """Checks if the given path exists on device target.
diff --git a/testrunner/runtest.py b/testrunner/runtest.py
index 761652f..9b011a6 100755
--- a/testrunner/runtest.py
+++ b/testrunner/runtest.py
@@ -153,6 +153,10 @@
     parser.add_option("--coverage-target", dest="coverage_target_path",
                       default=None,
                       help="Path to app to collect code coverage target data for.")
+    parser.add_option("-k", "--skip-permissions", dest="skip_permissions",
+                      default=False, action="store_true",
+                      help="Do not grant runtime permissions during test package"
+                      " installation.")
     parser.add_option("-x", "--path", dest="test_path",
                       help="Run test(s) at given file system path")
     parser.add_option("-t", "--all-tests", dest="all_tests",
@@ -247,19 +251,27 @@
 
   def _DoBuild(self):
     logger.SilentLog("Building tests...")
-
     tests = self._GetTestsToRun()
+
+    # Build and install tests that do not get granted permissions
+    self._DoPermissionAwareBuild(tests, False)
+
+    # Build and install tests that require granted permissions
+    self._DoPermissionAwareBuild(tests, True)
+
+  def _DoPermissionAwareBuild(self, tests, test_requires_permissions):
     # turn off dalvik verifier if necessary
     # TODO: skip turning off verifier for now, since it puts device in bad
     # state b/14088982
     #self._TurnOffVerifier(tests)
-    self._DoFullBuild(tests)
+    self._DoFullBuild(tests, test_requires_permissions)
 
     target_tree = make_tree.MakeTree()
 
     extra_args_set = []
     for test_suite in tests:
-      self._AddBuildTarget(test_suite, target_tree, extra_args_set)
+      if test_suite.IsGrantedPermissions() == test_requires_permissions:
+        self._AddBuildTarget(test_suite, target_tree, extra_args_set)
 
     if not self._options.preview:
       self._adb.EnableAdbRoot()
@@ -301,9 +313,9 @@
           output = run_command.RunCommand(cmd, return_output=True, timeout_time=600)
         run_command.SetAbortOnError(False)
         logger.SilentLog(output)
-        self._DoInstall(output)
+        self._DoInstall(output, test_requires_permissions)
 
-  def _DoInstall(self, make_output):
+  def _DoInstall(self, make_output, test_requires_permissions):
     """Install artifacts from build onto device.
 
     Looks for 'install:' text from make output to find artifacts to install.
@@ -323,8 +335,11 @@
         for install_path in re.split(r'\s+', install_paths):
           if install_path.endswith(".apk"):
             abs_install_path = os.path.join(self._root_path, install_path)
-            logger.Log("adb install -r %s" % abs_install_path)
-            logger.Log(self._adb.Install(abs_install_path))
+            extra_flags = ""
+            if test_requires_permissions and not self._options.skip_permissions:
+              extra_flags = "-g"
+            logger.Log("adb install -r %s %s" % (extra_flags, abs_install_path))
+            logger.Log(self._adb.Install(abs_install_path, extra_flags))
           else:
             self._PushInstallFileToDevice(install_path)
 
@@ -341,12 +356,12 @@
     else:
       logger.Log("Error: Failed to recognize path of file to install %s" % install_path)
 
-  def _DoFullBuild(self, tests):
+  def _DoFullBuild(self, tests, test_requires_permissions):
     """If necessary, run a full 'make' command for the tests that need it."""
     extra_args_set = Set()
 
     for test in tests:
-      if test.IsFullMake():
+      if test.IsFullMake() and test.IsGrantedPermissions() == test_requires_permissions:
         if test.GetExtraBuildArgs():
           # extra args contains the args to pass to 'make'
           extra_args_set.add(test.GetExtraBuildArgs())
@@ -365,7 +380,7 @@
         output = run_command.RunCommand(cmd, return_output=True)
         logger.SilentLog(output)
         os.chdir(old_dir)
-        self._DoInstall(output)
+        self._DoInstall(output, test_requires_permissions)
 
   def _AddBuildTarget(self, test_suite, target_tree, extra_args_set):
     if not test_suite.IsFullMake():
diff --git a/testrunner/test_defs.xml b/testrunner/test_defs.xml
index 19cba74..07bb9a4 100644
--- a/testrunner/test_defs.xml
+++ b/testrunner/test_defs.xml
@@ -356,6 +356,13 @@
     coverage_target="framework"
     suite="cts" />
 
+<test name="cts-telecom"
+    build_path="cts/tests/tests/telecom"
+    package="com.android.cts.telecom"
+    runner="android.support.test.runner.AndroidJUnitRunner"
+    coverage_target="framework"
+    suite="cts" />
+
 <test name="cts-telephony"
     build_path="cts/tests/tests/telephony"
     package="com.android.cts.telephony"
@@ -506,7 +513,7 @@
     continuous="true"
     coverage_target="Phone" />
 
-<test name="telecomm-unit"
+<test name="telecom-unit"
     build_path="packages/services/Telecomm"
     package="com.android.server.telecom.tests"
     continuous="true"
@@ -554,6 +561,11 @@
     build_path="external/android-clat"
     description="clatd unit tests." />
 
+<!-- dhcpcd -->
+<test-native name="dhcpcd"
+    build_path="external/dhcpcd"
+    description="dhcpcd unit tests." />
+
 <!-- Libjingle -->
 <test-native name="libjingle"
     build_path="vendor/google/libraries/libjingle"
diff --git a/testrunner/test_defs/test_suite.py b/testrunner/test_defs/test_suite.py
index d0bd9ee..5bd9a19 100644
--- a/testrunner/test_defs/test_suite.py
+++ b/testrunner/test_defs/test_suite.py
@@ -33,6 +33,7 @@
     self._description = ''
     self._extra_build_args = ''
     self._is_full_make = False
+    self._is_granted_permissions = True
 
   def GetName(self):
     return self._name
@@ -65,6 +66,14 @@
     self._is_continuous = continuous
     return self._is_continuous
 
+  def IsGrantedPermissions(self):
+    """Return true if the test should be granted runtime permissions on install."""
+    return self._is_granted_permissions
+
+  def SetIsGrantedPermissions(self, is_granted_permissions):
+    self._is_granted_permissions = is_granted_permissions
+    return self._is_granted_permissions
+
   def GetSuite(self):
     """Returns the name of test' suite, or None."""
     return self._suite
diff --git a/testrunner/test_defs/xml_suite_helper.py b/testrunner/test_defs/xml_suite_helper.py
index 6cf2e6c..6805fcd 100644
--- a/testrunner/test_defs/xml_suite_helper.py
+++ b/testrunner/test_defs/xml_suite_helper.py
@@ -40,6 +40,7 @@
   _DESCRIPTION_ATTR = 'description'
   _EXTRA_BUILD_ARGS_ATTR = 'extra_build_args'
   _FULL_MAKE_ATTR = 'full_make'
+  _GRANTED_PERMISSIONS_ATTR = 'granted_permissions'
 
   def Parse(self, element):
     """Populates common suite attributes from given suite xml element.
@@ -72,6 +73,9 @@
     test_suite.SetContinuous(self._ParseAttribute(suite_element,
                                                   self._CONTINUOUS_ATTR,
                                                   False, default_value=False))
+    test_suite.SetIsGrantedPermissions(self._ParseAttribute(suite_element,
+                                                  self._GRANTED_PERMISSIONS_ATTR,
+                                                  False, default_value=True))
     test_suite.SetSuite(self._ParseAttribute(suite_element, self._SUITE_ATTR, False,
                                            default_value=None))
     test_suite.SetDescription(self._ParseAttribute(suite_element,
@@ -88,6 +92,8 @@
                       default_value=None):
     if suite_element.hasAttribute(attribute_name):
       value = suite_element.getAttribute(attribute_name)
+      if default_value in (True, False):
+        value = value.lower() == "true"
     elif mandatory:
       error_msg = ('Could not find attribute %s in %s' %
                    (attribute_name, self.TAG_NAME))
diff --git a/tools/btsnooz/Android.mk b/tools/btsnooz/Android.mk
new file mode 100644
index 0000000..5364b0f
--- /dev/null
+++ b/tools/btsnooz/Android.mk
@@ -0,0 +1,37 @@
+# Copyright (C) 2014 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)
+
+supported_platforms := linux # For now... Needs to be tested on MacOS/Windows
+cur_platform := $(filter $(HOST_OS),$(supported_platforms))
+
+ifdef cur_platform
+
+# Host executable
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := btsnooz
+LOCAL_SRC_FILES := btsnooz.cpp btsnooz_utils.cpp
+LOCAL_C_INCLUDES := external/zlib system/bt
+LOCAL_CFLAGS += -std=c++11 -W -Wall
+LOCAL_STATIC_LIBRARIES := libz
+
+ifeq ($(HOST_OS),linux)
+  LOCAL_LDLIBS += -lresolv
+endif
+
+include $(BUILD_HOST_EXECUTABLE)
+
+endif #cur_platform
diff --git a/tools/btsnooz/btsnooz.cpp b/tools/btsnooz/btsnooz.cpp
new file mode 100644
index 0000000..567a0ea
--- /dev/null
+++ b/tools/btsnooz/btsnooz.cpp
@@ -0,0 +1,87 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2015 Google, Inc.
+ *
+ *  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 <iostream>
+#include <iomanip>
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "btsnooz_utils.h"
+
+int main(int argc, char *argv[]) {
+  if (argc > 3) {
+    std::cerr << "Usage: " << argv[0] << " [input_file] [output_file]\n";
+    return 1;
+  }
+
+  std::vector<char> buffer;
+
+  int read = 0;
+  if (argc < 3) {
+    std::cerr << "<Reading from stdin>\n";
+    read = readLog(std::cin, buffer);
+
+  } else {
+    std::cerr << "<Reading " << argv[1] << ">\n";
+    std::ifstream ff(argv[1]);
+    read = readLog(ff, buffer);
+    ff.close();
+  }
+
+  if (read == 0) {
+    std::cerr << "File not found or not BTSNOOP data block....\n";
+    return 2;
+  }
+
+  std::cerr << std::setw(8) << read << " bytes of base64 data read\n";
+
+  read = base64Decode(buffer);
+  if (read <= 0) {
+    std::cerr << "Decoding base64 data failed...\n";
+    return 3;
+  }
+
+  std::cerr << std::setw(8) << read << " bytes of compressed data decoded\n";
+
+  std::vector<uint8_t> uncompressed;
+  read = inflate(buffer, uncompressed);
+  if (read <= 0) {
+    std::cerr << "Error inflating data...\n";
+    return 4;
+  }
+
+  std::cerr << std::setw(8) << read << " bytes of data inflated\n";
+
+  if (argc < 2) {
+    std::cerr << "<Writing to stdout>\n";
+    read = writeBtSnoop(std::cout, uncompressed);
+
+  } else {
+    const int arg = argc > 2 ? 2 : 1;
+    std::cerr << "<Writing " << argv[arg] << ">\n";
+    std::ofstream ff(argv[arg]);
+    read = writeBtSnoop(ff, uncompressed);
+    ff.close();
+  }
+
+  std::cerr << std::setw(8) << read << " btsnoop packets written\n";
+
+  return 0;
+}
diff --git a/tools/btsnooz/btsnooz_utils.cpp b/tools/btsnooz/btsnooz_utils.cpp
new file mode 100644
index 0000000..b743997
--- /dev/null
+++ b/tools/btsnooz/btsnooz_utils.cpp
@@ -0,0 +1,244 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2015 Google, Inc.
+ *
+ *  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 <iostream>
+#include <iomanip>
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <string.h> // for memcpy
+#include <vector>
+#include <resolv.h>
+#include <zlib.h>
+
+extern "C" {
+#include "btif/include/btif_debug_btsnoop.h"
+#include "hci/include/bt_hci_bdroid.h"
+#include "stack/include/bt_types.h"
+#include "stack/include/hcidefs.h"
+}
+
+// Epoch in microseconds since 01/01/0000.
+#define BTSNOOP_EPOCH_DELTA 0x00dcddb30f2f8000ULL
+
+#define INITIAL_BUFFER_SIZE 131072
+#define INFLATE_BUFFER  16384
+
+#define LOG_PREFIX  "--- BEGIN:BTSNOOP_LOG_SUMMARY"
+#define LOG_POSTFIX  "--- END:BTSNOOP_LOG_SUMMARY"
+
+#define H4_DIRECTION_SENT  0
+#define H4_DIRECTION_RECEIVED  1
+
+static uint8_t packetTypeToFlags(const uint8_t type) {
+  switch (type << 8) {
+    case MSG_HC_TO_STACK_HCI_ERR:
+    case MSG_HC_TO_STACK_HCI_ACL:
+    case MSG_HC_TO_STACK_HCI_SCO:
+    case MSG_HC_TO_STACK_HCI_EVT:
+    case MSG_HC_TO_STACK_L2C_SEG_XMIT:
+      return H4_DIRECTION_RECEIVED;
+
+    case MSG_STACK_TO_HC_HCI_ACL:
+    case MSG_STACK_TO_HC_HCI_SCO:
+    case MSG_STACK_TO_HC_HCI_CMD:
+      return H4_DIRECTION_SENT;
+
+    default:
+      break;
+  }
+  return 0;
+}
+
+static uint8_t packetTypeToHciType(const uint8_t type) {
+  switch (type << 8 & 0xFF00) {
+    case MSG_STACK_TO_HC_HCI_CMD:
+      return HCIT_TYPE_COMMAND;
+
+    case MSG_HC_TO_STACK_HCI_EVT:
+      return HCIT_TYPE_EVENT;
+
+    case MSG_STACK_TO_HC_HCI_ACL:
+    case MSG_HC_TO_STACK_HCI_ACL:
+      return HCIT_TYPE_ACL_DATA;
+
+    case MSG_STACK_TO_HC_HCI_SCO:
+    case MSG_HC_TO_STACK_HCI_SCO:
+      return HCIT_TYPE_SCO_DATA;
+
+    default:
+      break;
+  }
+  return 0;
+}
+
+size_t writeBtSnoop(std::ostream &out, std::vector<uint8_t> &in) {
+  if (in.size() < sizeof(btsnooz_preamble_t))
+    return 0;
+
+  // Get preamble
+
+  uint8_t *p = in.data();
+  btsnooz_preamble_t *preamble = reinterpret_cast<btsnooz_preamble_t*>(p);
+  if (preamble->version != BTSNOOZ_CURRENT_VERSION)
+    return 0;
+
+  // Write header
+
+  const uint8_t header[] = {
+    0x62, 0x74, 0x73, 0x6e, 0x6f, 0x6f, 0x70, 0x00,
+    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0xea
+  };
+
+  out.write(reinterpret_cast<const char*>(header), sizeof(header));
+
+  // Calculate first timestamp
+
+  uint64_t first_ts = preamble->last_timestamp_ms + BTSNOOP_EPOCH_DELTA;
+  size_t left = in.size() - sizeof(btsnooz_preamble_t);
+  p = in.data() + sizeof(btsnooz_preamble_t);
+
+  while (left > sizeof(btsnooz_header_t)) {
+    btsnooz_header_t *p_hdr = reinterpret_cast<btsnooz_header_t*>(p);
+    p += sizeof(btsnooz_header_t) + (p_hdr->length - 1);
+    left -= sizeof(btsnooz_header_t) + (p_hdr->length - 1);
+
+    first_ts -= p_hdr->delta_time_ms;
+  }
+
+  // Process packets
+
+  size_t packets = 0;
+  left = in.size() - sizeof(btsnooz_preamble_t);
+  p = in.data() + sizeof(btsnooz_preamble_t);
+
+  while (left > sizeof(btsnooz_header_t)) {
+    btsnooz_header_t *p_hdr = reinterpret_cast<btsnooz_header_t*>(p);
+    p += sizeof(btsnooz_header_t);
+    left -= sizeof(btsnooz_header_t);
+
+    const uint32_t h_length = htonl(p_hdr->length);
+    out.write(reinterpret_cast<const char*>(&h_length), 4);
+    out.write(reinterpret_cast<const char*>(&h_length), 4);
+
+    const uint32_t h_flags = htonl(packetTypeToFlags(p_hdr->type));
+    out.write(reinterpret_cast<const char*>(&h_flags), 4);
+
+    const uint32_t h_dropped = 0;
+    out.write(reinterpret_cast<const char*>(&h_dropped), 4);
+
+    first_ts += p_hdr->delta_time_ms;
+    const uint32_t h_time_hi = htonl(first_ts >> 32);
+    const uint32_t h_time_lo = htonl(first_ts & 0xFFFFFFFF);
+    out.write(reinterpret_cast<const char*>(&h_time_hi), 4);
+    out.write(reinterpret_cast<const char*>(&h_time_lo), 4);
+
+    const uint8_t type = packetTypeToHciType(p_hdr->type);
+    out.write(reinterpret_cast<const char*>(&type), 1);
+
+    out.write(reinterpret_cast<const char*>(p), p_hdr->length - 1);
+
+    p += p_hdr->length - 1;
+    left -= p_hdr->length - 1;
+
+    ++packets;
+  }
+
+  return packets;
+}
+
+int readLog(std::istream &in, std::vector<char> &buffer) {
+  buffer.reserve(INITIAL_BUFFER_SIZE);
+
+  std::string line;
+
+  const std::string log_prefix(LOG_PREFIX);
+  const std::string log_postfix(LOG_POSTFIX);
+
+  bool in_block = false;
+
+  while (std::getline(in, line)) {
+    // Ensure line endings aren't wonky...
+
+    if (!line.empty() && line[line.size() - 1] == '\r')
+      line.erase(line.end() - 1);
+
+    // Detect block
+
+    if (!in_block) {
+      if (line.compare(0, log_prefix.length(), log_prefix) == 0)
+        in_block = true;
+      continue;
+    }
+
+    if (line.compare(0, log_postfix.length(), log_postfix) == 0)
+      break;
+
+    // Process data
+
+    buffer.insert(buffer.end(), line.begin(), line.end());
+  }
+
+  if (buffer.size() != 0)
+    buffer.push_back(0);
+
+  return buffer.size();
+}
+
+int base64Decode(std::vector<char> &buffer) {
+  char *p = buffer.data();
+  return b64_pton(p, reinterpret_cast<uint8_t*>(p), buffer.size());
+}
+
+int inflate(std::vector<char> &in, std::vector<uint8_t> &out) {
+  out.reserve(in.size());
+
+  uint8_t buffer[INFLATE_BUFFER];
+  z_stream zs;
+
+  int ret = inflateInit(&zs);
+  if (Z_OK != ret)
+    return -1;
+
+  // Copy preamble as-is
+
+  for (size_t i = 0; i != sizeof(btsnooz_preamble_t); ++i) {
+    out.push_back(in[i]);
+  }
+
+  // De-compress data
+
+  zs.avail_in = in.size() - sizeof(btsnooz_preamble_t);;
+  zs.next_in = reinterpret_cast<uint8_t*>(in.data()) + sizeof(btsnooz_preamble_t);
+
+  do {
+    zs.avail_out = INFLATE_BUFFER;
+    zs.next_out = buffer;
+
+    ret = inflate(&zs, Z_NO_FLUSH);
+
+    size_t read = INFLATE_BUFFER - zs.avail_out;
+    uint8_t *p = buffer;
+    while (read--)
+      out.push_back(*p++);
+  } while (zs.avail_out == 0);
+
+  inflateEnd(&zs);
+
+  return out.size();
+}
diff --git a/tools/btsnooz/btsnooz_utils.h b/tools/btsnooz/btsnooz_utils.h
new file mode 100644
index 0000000..94ada83
--- /dev/null
+++ b/tools/btsnooz/btsnooz_utils.h
@@ -0,0 +1,27 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2015 Google, Inc.
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+#pragma once
+
+#include <iostream>
+#include <vector>
+
+size_t writeBtSnoop(std::ostream &out, std::vector<uint8_t> &in);
+int readLog(std::istream &in, std::vector<char> &buffer);
+int base64Decode(std::vector<char> &buffer);
+int inflate(std::vector<char> &in, std::vector<uint8_t> &out);
diff --git a/tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/sms/SmsTest.java b/tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/sms/SmsTest.java
index 2e18cc4..6b99ea5 100644
--- a/tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/sms/SmsTest.java
+++ b/tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/sms/SmsTest.java
@@ -21,7 +21,7 @@
 import android.database.Cursor;
 import android.os.Bundle;
 import android.os.HandlerThread;
-import android.support.test.InjectContext;
+import android.support.test.InstrumentationRegistry;
 
 import org.junit.Assert;
 import static junit.framework.Assert.assertEquals;
@@ -42,8 +42,6 @@
     public final static String BODY = "test sms";
     private final static int SMS_POLL_TIME_MS = 10 * 1000;
     private final static int SIXY_SECONDS_OF_LOOPS = 6;
-    @InjectContext
-    public Context mContext;
 
     /**
      * Verify that an SMS has been received with the correct number and body
@@ -63,7 +61,7 @@
     }
 
     private Cursor getSmsCursor() throws java.lang.InterruptedException {
-        ContentResolver r = mContext.getContentResolver();
+        ContentResolver r = InstrumentationRegistry.getTargetContext().getContentResolver();
         Uri message = Uri.parse("content://sms/");
         Cursor c;
 
diff --git a/tools/idegen/src/Configuration.java b/tools/idegen/src/Configuration.java
index c09be1a..bd643b9 100644
--- a/tools/idegen/src/Configuration.java
+++ b/tools/idegen/src/Configuration.java
@@ -123,16 +123,27 @@
          */
 
         boolean firstJavaFile = true;
-	File[] files = directory.listFiles();
-	if (files == null) {
-	    return;
-	}
+        File[] files = directory.listFiles();
+        if (files == null) {
+            return;
+        }
         for (File file : files) {
             // Trim preceding "./" from path.
             String path = file.getPath().substring(2);
 
-            // Keep track of source roots for .java files.
-            if (path.endsWith(".java") && !file.isDirectory()) {
+            if (file.isDirectory()) {
+                // Traverse nested directories.
+                if (excludes.exclude(path)) {
+                    // Don't recurse into excluded dirs.
+                    Log.debug("Excluding: " + path);
+                    excludedDirs.add(file);
+                } else {
+                    traverse(file, sourceRoots, jarFiles, excludedDirs,
+                            excludes);
+                }
+            } else if (path.endsWith(".java")) {
+                // Keep track of source roots for .java files.
+                // Do not check excludes in this branch.
                 if (firstJavaFile) {
                     // Only parse one .java file per directory.
                     firstJavaFile = false;
@@ -142,30 +153,12 @@
                         sourceRoots.add(sourceRoot);
                     }
                 }
-                                
-                continue;
-            }
-
-            // Keep track of .jar files.
-            if (path.endsWith(".jar")) {
-                if (!excludes.exclude(path)) {
-                    jarFiles.add(file);
-                } else {
-                    Log.debug("Skipped: " + file);
-                }
-
-                continue;
-            }
-
-            // Traverse nested directories.
-            if (file.isDirectory()) {
+            } else if (path.endsWith(".jar")) {
+                // Keep track of .jar files.
                 if (excludes.exclude(path)) {
-                    // Don't recurse into excluded dirs.
-                    Log.debug("Excluding: " + path);
-                    excludedDirs.add(file);
+                    Log.debug("Skipped: " + file);
                 } else {
-                    traverse(file, sourceRoots, jarFiles, excludedDirs,
-                            excludes);
+                    jarFiles.add(file);
                 }
             }
         }
diff --git a/tools/recovery_l10n/res/values-en-rAU/strings.xml b/tools/recovery_l10n/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..b70d678c
--- /dev/null
+++ b/tools/recovery_l10n/res/values-en-rAU/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="recovery_installing" msgid="7864047928003865598">"Installing system update…"</string>
+    <string name="recovery_erasing" msgid="4612809744968710197">"Erasing…"</string>
+    <string name="recovery_no_command" msgid="1915703879031023455">"No command."</string>
+    <string name="recovery_error" msgid="4550265746256727080">"Error!"</string>
+</resources>
diff --git a/tools/recovery_l10n/res/values-gu-rIN/strings.xml b/tools/recovery_l10n/res/values-gu-rIN/strings.xml
new file mode 100644
index 0000000..a364b52
--- /dev/null
+++ b/tools/recovery_l10n/res/values-gu-rIN/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="recovery_installing" msgid="7864047928003865598">"સિસ્ટમ અપડેટ ઇન્સ્ટોલ કરી રહ્યાં છે…"</string>
+    <string name="recovery_erasing" msgid="4612809744968710197">"કાઢી નાખી રહ્યાં છે…"</string>
+    <string name="recovery_no_command" msgid="1915703879031023455">"કોઈ આદેશ નથી."</string>
+    <string name="recovery_error" msgid="4550265746256727080">"ભૂલ!"</string>
+</resources>
diff --git a/tools/recovery_l10n/res/values-pa-rIN/strings.xml b/tools/recovery_l10n/res/values-pa-rIN/strings.xml
new file mode 100644
index 0000000..39ef32f
--- /dev/null
+++ b/tools/recovery_l10n/res/values-pa-rIN/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="recovery_installing" msgid="7864047928003865598">"ਸਿਸਟਮ ਅਪਡੇਟ ਇੰਸਟੌਲ ਕਰ ਰਿਹਾ ਹੈ…"</string>
+    <string name="recovery_erasing" msgid="4612809744968710197">"ਹਟਾ ਰਿਹਾ ਹੈ…"</string>
+    <string name="recovery_no_command" msgid="1915703879031023455">"ਕੋਈ ਕਮਾਂਡ ਨਹੀਂ।"</string>
+    <string name="recovery_error" msgid="4550265746256727080">"ਅਸ਼ੁੱਧੀ!"</string>
+</resources>
diff --git a/tools/recovery_l10n/res/values-sk/strings.xml b/tools/recovery_l10n/res/values-sk/strings.xml
index e55f83f..cae6bce 100644
--- a/tools/recovery_l10n/res/values-sk/strings.xml
+++ b/tools/recovery_l10n/res/values-sk/strings.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="recovery_installing" msgid="7864047928003865598">"Prebieha inštalácia aktualizácie systému..."</string>
+    <string name="recovery_installing" msgid="7864047928003865598">"Inštalácia aktualizácie systému..."</string>
     <string name="recovery_erasing" msgid="4612809744968710197">"Prebieha mazanie..."</string>
     <string name="recovery_no_command" msgid="1915703879031023455">"Žiadny príkaz."</string>
     <string name="recovery_error" msgid="4550265746256727080">"Chyba!"</string>
diff --git a/tools/recovery_l10n/res/values-sq-rAL/strings.xml b/tools/recovery_l10n/res/values-sq-rAL/strings.xml
new file mode 100644
index 0000000..29f8ef5
--- /dev/null
+++ b/tools/recovery_l10n/res/values-sq-rAL/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="recovery_installing" msgid="7864047928003865598">"Po instalon përditësimin e sistemit..."</string>
+    <string name="recovery_erasing" msgid="4612809744968710197">"Po spastron..."</string>
+    <string name="recovery_no_command" msgid="1915703879031023455">"Nuk ka komanda."</string>
+    <string name="recovery_error" msgid="4550265746256727080">"Gabim!"</string>
+</resources>