Merge "add preview functionality to the bug report sender. lets users preview system logs, memory info, cpu info, and procrank."
diff --git a/build/sdk.atree b/build/sdk.atree
index 845ddea..f3bd0c6 100644
--- a/build/sdk.atree
+++ b/build/sdk.atree
@@ -72,7 +72,10 @@
# emacs support from sdk.git
sdk/files/android.el tools/lib/android.el
-# samples
+# samples to include in the sdk samples package
+#
+# the list here should match the list of samples that we generate docs for,
+# (see web_docs_sample_code_flags in frameworks/base/Android.mk)
development/samples/source.properties samples/${PLATFORM_NAME}/source.properties
development/apps/GestureBuilder samples/${PLATFORM_NAME}/GestureBuilder
development/samples/BluetoothChat samples/${PLATFORM_NAME}/BluetoothChat
@@ -80,6 +83,7 @@
development/samples/LunarLander samples/${PLATFORM_NAME}/LunarLander
development/samples/NotePad samples/${PLATFORM_NAME}/NotePad
development/samples/ApiDemos samples/${PLATFORM_NAME}/ApiDemos
+development/samples/SampleSyncAdapter samples/${PLATFORM_NAME}/SampleSyncAdapter
development/samples/SkeletonApp samples/${PLATFORM_NAME}/SkeletonApp
development/samples/Snake samples/${PLATFORM_NAME}/Snake
development/samples/SoftKeyboard samples/${PLATFORM_NAME}/SoftKeyboard
diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml
index e45e19c..fb416ed 100644
--- a/samples/ApiDemos/AndroidManifest.xml
+++ b/samples/ApiDemos/AndroidManifest.xml
@@ -28,6 +28,7 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SET_WALLPAPER" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- We will request access to the camera, saying we require a camera
of some sort but not one with autofocus capability. -->
@@ -588,6 +589,14 @@
<!-- CONTENT PACKAGE SAMPLES -->
<!-- ************************************* -->
+ <activity android:name=".content.ExternalStorage" android:label="@string/activity_external_storage">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.SAMPLE_CODE" />
+ <category android:name="android.intent.category.EMBED" />
+ </intent-filter>
+ </activity>
+
<activity android:name=".content.StyledText" android:label="@string/activity_styled_text">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
diff --git a/samples/ApiDemos/res/layout/external_storage.xml b/samples/ApiDemos/res/layout/external_storage.xml
new file mode 100644
index 0000000..28105a3
--- /dev/null
+++ b/samples/ApiDemos/res/layout/external_storage.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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="wrap_content"
+ android:scrollbars="none">
+
+ <LinearLayout
+ android:id="@+id/layout"
+ android:orientation="vertical"
+ android:layout_width="match_parent" android:layout_height="wrap_content">
+ </LinearLayout>
+</ScrollView>
diff --git a/samples/ApiDemos/res/layout/external_storage_item.xml b/samples/ApiDemos/res/layout/external_storage_item.xml
new file mode 100644
index 0000000..6ba058b
--- /dev/null
+++ b/samples/ApiDemos/res/layout/external_storage_item.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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="wrap_content">
+ <TextView android:id="@+id/label" style="?android:attr/textAppearanceMediumInverse"
+ android:layout_width="match_parent" android:layout_height="wrap_content"
+ android:layout_weight="0"
+ android:padding="4dip"
+ android:singleLine="true"
+ android:color="?android:attr/textColorPrimaryInverse"
+ android:background="#888" />
+ <TextView android:id="@+id/path" style="?android:attr/textAppearanceSmall"
+ android:layout_width="match_parent" android:layout_height="wrap_content"
+ android:layout_weight="0"
+ android:padding="4dip"
+ android:singleLine="true" />
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent" android:layout_height="wrap_content">
+ <View
+ android:layout_width="0dip"
+ android:layout_height="0dip"
+ android:layout_weight="1" />
+ <Button android:id="@+id/create"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/create" />
+ <View
+ android:layout_width="0dip"
+ android:layout_height="0dip"
+ android:layout_weight="1" />
+ <Button android:id="@+id/delete"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/delete" />
+ <View
+ android:layout_width="0dip"
+ android:layout_height="0dip"
+ android:layout_weight="1" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/samples/ApiDemos/res/values/strings.xml b/samples/ApiDemos/res/values/strings.xml
index 415e681..3ab923b 100644
--- a/samples/ApiDemos/res/values/strings.xml
+++ b/samples/ApiDemos/res/values/strings.xml
@@ -228,6 +228,10 @@
<!-- app/content examples strings -->
<!-- ============================== -->
+ <string name="activity_external_storage">Content/Storage/External Storage</string>
+ <string name="create">Create</string>
+ <string name="delete">Delete</string>
+
<string name="activity_styled_text">Content/Resources/<i>Styled</i> <b>Text</b></string>
<string name="styled_text_rsrc">Initialized from a resource:</string>
<string name="styled_text">Plain, <b>bold</b>, <i>italic</i>, <b><i>bold-italic</i></b></string>
diff --git a/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java b/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
new file mode 100644
index 0000000..d950a2c
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2010 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;
+
+//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.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.MediaScannerConnection;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+
+/**
+* Demonstration of styled text resources.
+*/
+public class ExternalStorage extends Activity {
+ ViewGroup mLayout;
+
+ static class Item {
+ View mRoot;
+ Button mCreate;
+ Button mDelete;
+ }
+
+ Item mExternalStoragePublicPicture;
+ Item mExternalStoragePrivatePicture;
+ Item mExternalStoragePrivateFile;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.external_storage);
+ mLayout = (ViewGroup)findViewById(R.id.layout);
+ mExternalStoragePublicPicture = createStorageControls(
+ "Picture: getExternalStoragePublicDirectory",
+ Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES),
+ new View.OnClickListener() {
+ public void onClick(View v) {
+ createExternalStoragePublicPicture();
+ updateExternalStorageState();
+ }
+ },
+ new View.OnClickListener() {
+ public void onClick(View v) {
+ deleteExternalStoragePublicPicture();
+ updateExternalStorageState();
+ }
+ });
+ mLayout.addView(mExternalStoragePublicPicture.mRoot);
+ mExternalStoragePrivatePicture = createStorageControls(
+ "Picture getExternalFilesDir",
+ getExternalFilesDir(Environment.DIRECTORY_PICTURES),
+ new View.OnClickListener() {
+ public void onClick(View v) {
+ createExternalStoragePrivatePicture();
+ updateExternalStorageState();
+ }
+ },
+ new View.OnClickListener() {
+ public void onClick(View v) {
+ deleteExternalStoragePrivatePicture();
+ updateExternalStorageState();
+ }
+ });
+ mLayout.addView(mExternalStoragePrivatePicture.mRoot);
+ mExternalStoragePrivateFile = createStorageControls(
+ "File getExternalFilesDir",
+ getExternalFilesDir(null),
+ new View.OnClickListener() {
+ public void onClick(View v) {
+ createExternalStoragePrivateFile();
+ updateExternalStorageState();
+ }
+ },
+ new View.OnClickListener() {
+ public void onClick(View v) {
+ deleteExternalStoragePrivateFile();
+ updateExternalStorageState();
+ }
+ });
+ mLayout.addView(mExternalStoragePrivateFile.mRoot);
+
+ startWatchingExternalStorage();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ stopWatchingExternalStorage();
+ }
+
+ void handleExternalStorageState(boolean available, boolean writeable) {
+ boolean has = hasExternalStoragePublicPicture();
+ mExternalStoragePublicPicture.mCreate.setEnabled(writeable && !has);
+ mExternalStoragePublicPicture.mDelete.setEnabled(writeable && has);
+ has = hasExternalStoragePrivatePicture();
+ mExternalStoragePrivatePicture.mCreate.setEnabled(writeable && !has);
+ mExternalStoragePrivatePicture.mDelete.setEnabled(writeable && has);
+ has = hasExternalStoragePrivateFile();
+ mExternalStoragePrivateFile.mCreate.setEnabled(writeable && !has);
+ mExternalStoragePrivateFile.mDelete.setEnabled(writeable && has);
+ }
+
+// BEGIN_INCLUDE(monitor_storage)
+ BroadcastReceiver mExternalStorageReceiver;
+ boolean mExternalStorageAvailable = false;
+ boolean mExternalStorageWriteable = false;
+
+ void updateExternalStorageState() {
+ String state = Environment.getExternalStorageState();
+ if (Environment.MEDIA_MOUNTED.equals(state)) {
+ mExternalStorageAvailable = mExternalStorageWriteable = true;
+ } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+ mExternalStorageAvailable = true;
+ mExternalStorageWriteable = false;
+ } else {
+ mExternalStorageAvailable = mExternalStorageWriteable = false;
+ }
+ handleExternalStorageState(mExternalStorageAvailable,
+ mExternalStorageWriteable);
+ }
+
+ void startWatchingExternalStorage() {
+ mExternalStorageReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.i("test", "Storage: " + intent.getData());
+ updateExternalStorageState();
+ }
+ };
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
+ filter.addAction(Intent.ACTION_MEDIA_REMOVED);
+ registerReceiver(mExternalStorageReceiver, filter);
+ updateExternalStorageState();
+ }
+
+ void stopWatchingExternalStorage() {
+ unregisterReceiver(mExternalStorageReceiver);
+ }
+ // END_INCLUDE(monitor_storage)
+
+ // BEGIN_INCLUDE(public_picture)
+ void createExternalStoragePublicPicture() {
+ // Create a path where we will place our picture in the user's
+ // public pictures directory. Note that you should be careful about
+ // what you place here, since the user often manages these files. For
+ // pictures and other media owned by the application, consider
+ // Context.getExternalMediaDir().
+ File path = Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES);
+ File file = new File(path, "DemoPicture.jpg");
+
+ try {
+ // Make sure the Pictures directory exists.
+ path.mkdirs();
+
+ // Very simple code to copy a picture from the application's
+ // resource into the external file. Note that this code does
+ // no error checking, and assumes the picture is small (does not
+ // try to copy it in chunks). Note that if external storage is
+ // not currently mounted this will silently fail.
+ InputStream is = getResources().openRawResource(R.drawable.balloons);
+ OutputStream os = new FileOutputStream(file);
+ byte[] data = new byte[is.available()];
+ is.read(data);
+ os.write(data);
+ is.close();
+ os.close();
+
+ // Tell the media scanner about the new file so that it is
+ // immediately available to the user.
+ MediaScannerConnection.scanFile(this,
+ new String[] { file.toString() }, null,
+ new MediaScannerConnection.ScanResultListener() {
+ public void onScanCompleted(String path, Uri uri) {
+ Log.i("ExternalStorage", "Scanned " + path + ":");
+ Log.i("ExternalStorage", "-> uri=" + uri);
+ }
+ });
+ } catch (IOException e) {
+ // Unable to create file, likely because external storage is
+ // not currently mounted.
+ Log.w("ExternalStorage", "Error writing " + file, e);
+ }
+ }
+
+ void deleteExternalStoragePublicPicture() {
+ // Create a path where we will place our picture in the user's
+ // public pictures directory and delete the file. If external
+ // storage is not currently mounted this will fail.
+ File path = Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES);
+ File file = new File(path, "DemoPicture.jpg");
+ file.delete();
+ }
+
+ boolean hasExternalStoragePublicPicture() {
+ // Create a path where we will place our picture in the user's
+ // public pictures directory and check if the file exists. If
+ // external storage is not currently mounted this will think the
+ // picture doesn't exist.
+ File path = Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES);
+ File file = new File(path, "DemoPicture.jpg");
+ return file.exists();
+ }
+// END_INCLUDE(public_picture)
+
+// BEGIN_INCLUDE(private_picture)
+ void createExternalStoragePrivatePicture() {
+ // Create a path where we will place our picture in our own private
+ // pictures directory. Note that we don't really need to place a
+ // picture in DIRECTORY_PICTURES, since the media scanner will see
+ // all media in these directories; this may be useful with other
+ // media types such as DIRECTORY_MUSIC however to help it classify
+ // your media for display to the user.
+ File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
+ File file = new File(path, "DemoPicture.jpg");
+
+ try {
+ // Very simple code to copy a picture from the application's
+ // resource into the external file. Note that this code does
+ // no error checking, and assumes the picture is small (does not
+ // try to copy it in chunks). Note that if external storage is
+ // not currently mounted this will silently fail.
+ InputStream is = getResources().openRawResource(R.drawable.balloons);
+ OutputStream os = new FileOutputStream(file);
+ byte[] data = new byte[is.available()];
+ is.read(data);
+ os.write(data);
+ is.close();
+ os.close();
+
+ // Tell the media scanner about the new file so that it is
+ // immediately available to the user.
+ MediaScannerConnection.scanFile(this,
+ new String[] { file.toString() }, null,
+ new MediaScannerConnection.ScanResultListener() {
+ public void onScanCompleted(String path, Uri uri) {
+ Log.i("ExternalStorage", "Scanned " + path + ":");
+ Log.i("ExternalStorage", "-> uri=" + uri);
+ }
+ });
+ } catch (IOException e) {
+ // Unable to create file, likely because external storage is
+ // not currently mounted.
+ Log.w("ExternalStorage", "Error writing " + file, e);
+ }
+ }
+
+ void deleteExternalStoragePrivatePicture() {
+ // Create a path where we will place our picture in the user's
+ // public pictures directory and delete the file. If external
+ // storage is not currently mounted this will fail.
+ File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
+ if (path != null) {
+ File file = new File(path, "DemoPicture.jpg");
+ file.delete();
+ }
+ }
+
+ boolean hasExternalStoragePrivatePicture() {
+ // Create a path where we will place our picture in the user's
+ // public pictures directory and check if the file exists. If
+ // external storage is not currently mounted this will think the
+ // picture doesn't exist.
+ File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
+ if (path != null) {
+ File file = new File(path, "DemoPicture.jpg");
+ return file.exists();
+ }
+ return false;
+ }
+// END_INCLUDE(private_picture)
+
+// BEGIN_INCLUDE(private_file)
+ void createExternalStoragePrivateFile() {
+ // Create a path where we will place our private file on external
+ // storage.
+ File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
+
+ try {
+ // Very simple code to copy a picture from the application's
+ // resource into the external file. Note that this code does
+ // no error checking, and assumes the picture is small (does not
+ // try to copy it in chunks). Note that if external storage is
+ // not currently mounted this will silently fail.
+ InputStream is = getResources().openRawResource(R.drawable.balloons);
+ OutputStream os = new FileOutputStream(file);
+ byte[] data = new byte[is.available()];
+ is.read(data);
+ os.write(data);
+ is.close();
+ os.close();
+ } catch (IOException e) {
+ // Unable to create file, likely because external storage is
+ // not currently mounted.
+ Log.w("ExternalStorage", "Error writing " + file, e);
+ }
+ }
+
+ void deleteExternalStoragePrivateFile() {
+ // Get path for the file on external storage. If external
+ // storage is not currently mounted this will fail.
+ File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
+ if (file != null) {
+ file.delete();
+ }
+ }
+
+ boolean hasExternalStoragePrivateFile() {
+ // Get path for the file on external storage. If external
+ // storage is not currently mounted this will fail.
+ File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
+ if (file != null) {
+ return file.exists();
+ }
+ return false;
+ }
+ // END_INCLUDE(private_file)
+
+ Item createStorageControls(CharSequence label, File path,
+ View.OnClickListener createClick,
+ View.OnClickListener deleteClick) {
+ LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
+ Item item = new Item();
+ item.mRoot = inflater.inflate(R.layout.external_storage_item, null);
+ TextView tv = (TextView)item.mRoot.findViewById(R.id.label);
+ tv.setText(label);
+ if (path != null) {
+ tv = (TextView)item.mRoot.findViewById(R.id.path);
+ tv.setText(path.toString());
+ }
+ item.mCreate = (Button)item.mRoot.findViewById(R.id.create);
+ item.mCreate.setOnClickListener(createClick);
+ item.mDelete = (Button)item.mRoot.findViewById(R.id.delete);
+ item.mDelete.setOnClickListener(deleteClick);
+ return item;
+ }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/content/_index.html b/samples/ApiDemos/src/com/example/android/apis/content/_index.html
index 1aa52b3..769a927 100644
--- a/samples/ApiDemos/src/com/example/android/apis/content/_index.html
+++ b/samples/ApiDemos/src/com/example/android/apis/content/_index.html
@@ -1,5 +1,8 @@
<h3>Resources</h3>
<dl>
+ <dt><a href="StyledText.html">External Storage</a></dt>
+ <dd>Demonstrates reading and writing files in external storage. </dd>
+
<dt><a href="StyledText.html">Styled Text</a></dt>
<dd>Demonstrates loading styled text (bold, italic) defined in a resource file. </dd>
diff --git a/samples/CubeLiveWallpaper/AndroidManifest.xml b/samples/CubeLiveWallpaper/AndroidManifest.xml
index c317fe2..8a7d527 100644
--- a/samples/CubeLiveWallpaper/AndroidManifest.xml
+++ b/samples/CubeLiveWallpaper/AndroidManifest.xml
@@ -21,6 +21,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.livecubes">
+ <uses-sdk android:minSdkVersion="7" />
<uses-feature android:name="android.software.live_wallpaper" />
<uses-feature android:name="android.software.live_wallpaper" />
diff --git a/samples/CubeLiveWallpaper/_index.html b/samples/CubeLiveWallpaper/_index.html
new file mode 100644
index 0000000..f6aa931
--- /dev/null
+++ b/samples/CubeLiveWallpaper/_index.html
@@ -0,0 +1,83 @@
+<p>This sample demonstrates how to create a live wallpaper and bundle it in an
+<code>.apk</code> that users can install on their devices.</p>
+
+<p>In terms of implementation, a live wallpaper is very similar to a regular
+Android <a href="../../../reference/android/app/Service.html">service</a>. The
+only difference is the addition of a new method, <a
+href="../../../reference/android/service/wallpaper/WallpaperService.
+html#onCreateEngine()"><code>onCreateEngine()</code></a>, whose goal is to
+create a <a
+href="../../../reference/android/service/wallpaper/WallpaperService.Engine.html">
+<code>WallpaperService.Engine</code></a>. The engine is responsible for
+handling the lifecycle and drawing of a wallpaper. The system provides a surface
+on which you can draw, just like you would with a <a
+href="../../../reference/android/view/SurfaceView.html"><code>SurfaceView</code></a>.
+The wallpapers you create can respond to touch events on the screen and
+have access to all the facilities of the platform: SGL (2D drawing), OpenGL (3D
+drawing), GPS, accelerometers, network access, and so on. </p>
+
+<p>The examples in this application show how to set up a wallpaper service that
+creates a <code>WallpaperService.Engine</code> to manage the service lifecycle,
+render the wallpaper, handle touch events, and so on. The examples also show how
+a wallpaper should stop drawing when its visibility changes, for example, when
+the user launches an application that covers the home screen. Drawing only when
+visible is an important implementation guideline for live wallpapers because it
+minimizes the wallpaper's impact on system performance and battery life.
+</p>
+
+<p>The application includes two wallpaper services and a wallpaper settings
+activity:<p>
+
+<ul>
+<li><a
+href="src/com/example/android/livecubes/cube1/CubeWallpaper1.html"><code>
+CubeWallpaper1</code></a> — a wallpaper service that draws and animates a
+wire-frame cube to a <a
+href="../../../reference/android/graphics/Canvas.html"><code>Canvas</code></a>.
+</li>
+<li><a
+href="src/com/example/android/livecubes/cube2/CubeWallpaper2.html"><code>CubeWallpaper2</code></a>
+— a wallpaper service that draws and animates a
+wire-frame shape to a <code>Canvas</code>. The shape is set by the user, by means
+of the <code>cube2.CubeWallpaper2Settings</code> settings activity (see below). The
+wallpaper service implements a listener callback method that captures the user's
+wallpaper shape preference. </li>
+<li><a
+href="src/com/example/android/livecubes/cube2/CubeWallpaper2Settings.html"><code>CubeWallpaper2Settings</code></a>
+— a wallpaper service that draws and
+animates a wire-frame shape to a <code>Canvas</code>. The shape is set by the
+user through a simple settings activity,
+<code>cube2.CubeWallpaper2Settings</code>, also included in the app. The
+wallpaper service implements a listener callback method that captures the user's
+wallpaper shape preference. </li>
+</ul>
+
+<p>If you are developing a live wallpaper, remember that the feature is
+supported only on Android 2.1 (API level 7) and higher versions of the platform.
+To ensure that your application can only be installed on devices that support
+live wallpapers, remember to add the following to the application's manifest
+before publishing to Android Market:</p>
+
+<ul>
+<li><code><uses-sdk android:minSdkVersion="7" /></code>, which indicates
+to Android Market and the platform that your application requires Android 2.1 or
+higher. For more information, see the <a href="../../../guide/appendix/api-levels.html">API Levels</a>
+and the documentation for the
+<a href="../../../guide/topics/manifest/uses-sdk-element.html"><code><uses-sdk></code></a>
+element.</li>
+<li><code><uses-feature android:name="android.software.live_wallpaper" /></code>,
+which tells Android Market that your application includes a live wallpaper.
+Android Market uses this feature as a filter, when presenting users lists of
+available applications. When you declaring this feature, Android Market
+displays your application only to users whose devices support live wallpapers,
+while hiding it from other devices on which it would not be able to run. For
+more information, see the documentation for the
+<a href="../../../guide/topics/manifest/uses-feature-element.html"><code><uses-feature></code></a>
+element.</li>
+</ul>
+
+<p>For more information about live wallpapers, see the
+<a href="../../articles/live-wallpapers.html">Live Wallpapers</a> article. </p>
+
+<img alt="Screenshot 1" src="../images/CubeLiveWallpaper1.png" />
+<img alt="Screenshot 3" src="../images/CubeLiveWallpaper3.png" />
diff --git a/samples/MarketLicensing/src/com/android/vending/licensing/ILicenseResultListener.aidl b/samples/MarketLicensing/src/com/android/vending/licensing/ILicenseResultListener.aidl
deleted file mode 100755
index 869cb16..0000000
--- a/samples/MarketLicensing/src/com/android/vending/licensing/ILicenseResultListener.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2010 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.vending.licensing;
-
-oneway interface ILicenseResultListener {
- void verifyLicense(int responseCode, String signedData, String signature);
-}
diff --git a/samples/MarketLicensing/src/com/android/vending/licensing/ILicensingService.aidl b/samples/MarketLicensing/src/com/android/vending/licensing/ILicensingService.aidl
deleted file mode 100755
index 9541a20..0000000
--- a/samples/MarketLicensing/src/com/android/vending/licensing/ILicensingService.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2010 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.vending.licensing;
-
-import com.android.vending.licensing.ILicenseResultListener;
-
-oneway interface ILicensingService {
- void checkLicense(long nonce, String packageName, in ILicenseResultListener listener);
-}
diff --git a/samples/MarketLicensing/src/com/android/vending/licensing/LicenseChecker.java b/samples/MarketLicensing/src/com/android/vending/licensing/LicenseChecker.java
deleted file mode 100755
index 773b8cd..0000000
--- a/samples/MarketLicensing/src/com/android/vending/licensing/LicenseChecker.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2010 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.vending.licensing;
-
-import java.security.SecureRandom;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.vending.licensing.LicenseCheckerCallback.ApplicationErrorCode;
-import com.android.vending.licensing.Policy.LicenseResponse;
-
-/**
- * Client library for Android Market license verifications.
- *
- * The LicenseChecker is configured via a {@link Policy} which contains the
- * logic to determine whether a user should have access to the application.
- * For example, the Policy can define a threshold for allowable number of
- * server or client failures before the library reports the user as not having
- * access.
- *
- * This library is not thread-safe. Multiple, concurrent checks will result in
- * an error.
- */
-public class LicenseChecker implements ServiceConnection {
- private static final String TAG = "LicenseChecker";
-
- private static final SecureRandom RANDOM = new SecureRandom();
-
- private ILicensingService mService;
-
- /** Validator for the request in progress. */
- private LicenseValidator mValidator;
-
- private final Context mContext;
- private final Policy mPolicy;
- /** Listener for service (IPC) calls. */
- private final ResultListener mListener;
- private final String mPackageName;
- private final String mVersionCode;
-
- public LicenseChecker(Context context, Policy policy) {
- mContext = context;
- mPolicy = policy;
- mListener = new ResultListener();
- mPackageName = mContext.getPackageName();
- mVersionCode = getVersionCode(context, mPackageName);
- }
-
- private boolean isInProgress() {
- return mValidator != null;
- }
-
- /**
- * Checks if the user should have access to the app.
- *
- * @param callback
- */
- public synchronized void checkAccess(LicenseCheckerCallback callback) {
- if (isInProgress()) {
- callback.applicationError(ApplicationErrorCode.CHECK_IN_PROGRESS);
- }
-
- mValidator = new LicenseValidator(mPolicy, callback, generateNonce(), mPackageName,
- mVersionCode);
-
- Log.i(TAG, "Binding to licensing service.");
- boolean bindResult = mContext.bindService(new Intent(ILicensingService.class.getName()),
- this, // ServiceConnection.
- Context.BIND_AUTO_CREATE);
-
- if (!bindResult) {
- Log.e(TAG, "Could not bind to service.");
- callback.dontAllow();
- // No need to unbind at this point.
- return;
- }
- }
-
- private class ResultListener extends ILicenseResultListener.Stub {
- public void verifyLicense(int responseCode, String signedData, String signature) {
- mValidator.verify(responseCode, signedData, signature);
- cleanup();
- }
- }
-
- public void onServiceConnected(ComponentName name, IBinder service) {
- mService = ILicensingService.Stub.asInterface(service);
-
- try {
- Log.i(TAG, "Calling checkLicense on service for " + mValidator.getPackageName());
- mService.checkLicense(mValidator.getNonce(), mValidator.getPackageName(), mListener);
- } catch (RemoteException e) {
- Log.w(TAG, "RemoteException in checkLicense call.", e);
- handleServiceConnectionError();
- // cleanup unbinds service.
- cleanup();
- }
- }
-
- public void onServiceDisconnected(ComponentName name) {
- // Called when the connection with the service has been
- // unexpectedly disconnected. That is, Market crashed.
- Log.w(TAG, "Service unexpectedly disconnected.");
- handleServiceConnectionError();
- // cleanup unbinds service.
- cleanup();
- }
-
- private void handleServiceConnectionError() {
- if (mPolicy.allowAccess(LicenseResponse.CLIENT_RETRY)) {
- mValidator.getCallback().allow();
- } else {
- mValidator.getCallback().dontAllow();
- }
- }
-
- /** Resets request state. */
- private synchronized void cleanup() {
- mContext.unbindService(this);
- mValidator = null;
- }
-
- /** Generates a nonce (number used once). */
- private int generateNonce() {
- return RANDOM.nextInt();
- }
-
- /**
- * Get version code for the application package name.
- *
- * @param context
- * @param packageName application package name
- * @return the version code or empty string if package not found
- */
- private static String getVersionCode(Context context, String packageName) {
- try {
- return String.valueOf(context.getPackageManager().getPackageInfo(packageName, 0).
- versionCode);
- } catch (NameNotFoundException e) {
- Log.e(TAG, "Package not found. could not get version code.");
- return "";
- }
- }
-}
diff --git a/samples/MarketLicensing/src/com/android/vending/licensing/LicenseCheckerCallback.java b/samples/MarketLicensing/src/com/android/vending/licensing/LicenseCheckerCallback.java
deleted file mode 100755
index 1567497..0000000
--- a/samples/MarketLicensing/src/com/android/vending/licensing/LicenseCheckerCallback.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2010 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.vending.licensing;
-
-/**
- * Callback for the license checker library.
- *
- * Upon checking with the Market server and conferring with the policy, the
- * library calls a appropriate callback method to communicate the result.
- */
-public interface LicenseCheckerCallback {
-
- /**
- * Allow use. App should proceed as normal.
- */
- public void allow();
-
- /**
- * Don't allow use. App should inform user and take appropriate action.
- */
- public void dontAllow();
-
- /** Application error codes. */
- public enum ApplicationErrorCode {
- /** Package is not installed. */
- INVALID_PACKAGE_NAME,
- /** Requested for a package that is not the current app. */
- NON_MATCHING_UID,
- /** Market does not know about the package. */
- NOT_MARKET_MANAGED,
- /** A previous check request is already in progress.
- * Only one check is allowed at a time. */
- CHECK_IN_PROGRESS
- }
-
- /**
- * Error in application code. Caller did not call or set up license
- * checker correctly. Should be considered fatal.
- */
- public void applicationError(ApplicationErrorCode errorCode);
-}
diff --git a/samples/MarketLicensing/src/com/android/vending/licensing/LicenseValidator.java b/samples/MarketLicensing/src/com/android/vending/licensing/LicenseValidator.java
deleted file mode 100755
index 135d98e..0000000
--- a/samples/MarketLicensing/src/com/android/vending/licensing/LicenseValidator.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2010 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.vending.licensing;
-
-import android.util.Log;
-
-import com.android.vending.licensing.LicenseCheckerCallback.ApplicationErrorCode;
-import com.android.vending.licensing.Policy.LicenseResponse;
-
-/**
- * Contains data related to a licensing request and methods to verify
- * and process the response.
- */
-class LicenseValidator {
- private static final String TAG = "LicenseValidator";
-
- // Server response codes.
- private static final int LICENSED = 0x0;
- private static final int NOT_LICENSED = 0x1;
- private static final int LICENSED_OLD_KEY = 0x2;
- private static final int ERROR_NOT_MARKET_MANAGED = 0x3;
- private static final int ERROR_INVALID_KEYS = 0x4;
- private static final int ERROR_OVER_QUOTA = 0x5;
-
- private static final int ERROR_CONTACTING_SERVER = 0x101;
- private static final int ERROR_INVALID_PACKAGE_NAME = 0x102;
- private static final int ERROR_NON_MATCHING_UID = 0x103;
-
- private final Policy mPolicy;
- private final LicenseCheckerCallback mCallback;
- private final int mNonce;
- private final String mPackageName;
- private final String mVersionCode;
-
- LicenseValidator(Policy policy, LicenseCheckerCallback callback, int nonce, String packageName,
- String versionCode) {
- mPolicy = policy;
- mCallback = callback;
- mNonce = nonce;
- mPackageName = packageName;
- mVersionCode = versionCode;
- }
-
- public LicenseCheckerCallback getCallback() {
- return mCallback;
- }
-
- public int getNonce() {
- return mNonce;
- }
-
- public String getPackageName() {
- return mPackageName;
- }
-
- /**
- * Verifies the response from server and calls appropriate callback method.
- *
- * @param responseCode server response code
- * @param signedData signed data from server
- * @param signature server signature
- */
- public void verify(int responseCode, String signedData, String signature) {
- // Parse and validate response.
- // TODO(jyum): decode data with signature.
- // TODO(jyum): verify timestamp is within reason. However, relying
- // on device clock may lead to problems?
- ResponseData data;
- try {
- data = ResponseData.parse(signedData);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Could not parse response.");
- handleInvalidResponse();
- return;
- }
-
- if (data.responseCode != responseCode) {
- Log.e(TAG, "Response codes don't match.");
- handleInvalidResponse();
- return;
- }
-
- if (data.nonce != mNonce) {
- Log.e(TAG, "Nonce doesn't match.");
- handleInvalidResponse();
- return;
- }
-
- if (!data.packageName.equals(mPackageName)) {
- Log.e(TAG, "Package name doesn't match.");
- handleInvalidResponse();
- return;
- }
-
- if (!data.versionCode.equals(mVersionCode)) {
- Log.e(TAG, "Version codes don't match.");
- handleInvalidResponse();
- return;
- }
-
- switch (responseCode) {
- case LICENSED:
- case LICENSED_OLD_KEY:
- handleResponse(LicenseResponse.LICENSED);
- break;
- case NOT_LICENSED:
- handleResponse(LicenseResponse.NOT_LICENSED);
- break;
- case ERROR_CONTACTING_SERVER:
- handleResponse(LicenseResponse.CLIENT_RETRY);
- break;
- case ERROR_INVALID_KEYS:
- case ERROR_OVER_QUOTA:
- handleResponse(LicenseResponse.SERVER_RETRY);
- break;
- case ERROR_INVALID_PACKAGE_NAME:
- handleApplicationError(ApplicationErrorCode.INVALID_PACKAGE_NAME);
- break;
- case ERROR_NON_MATCHING_UID:
- handleApplicationError(ApplicationErrorCode.NON_MATCHING_UID);
- break;
- case ERROR_NOT_MARKET_MANAGED:
- handleApplicationError(ApplicationErrorCode.NOT_MARKET_MANAGED);
- break;
- default:
- Log.e(TAG, "Unknown response code for license check.");
- handleInvalidResponse();
- }
- }
-
- /**
- * Confers with policy and calls appropriate callback method.
- *
- * @param response
- */
- private void handleResponse(LicenseResponse response) {
- if (mPolicy.allowAccess(response)) {
- mCallback.allow();
- } else {
- mCallback.dontAllow();
- }
- }
-
- private void handleApplicationError(ApplicationErrorCode code) {
- mCallback.applicationError(code);
- }
-
- private void handleInvalidResponse() {
- mCallback.dontAllow();
- }
-}
diff --git a/samples/MarketLicensing/src/com/android/vending/licensing/Policy.java b/samples/MarketLicensing/src/com/android/vending/licensing/Policy.java
deleted file mode 100755
index 461c08e..0000000
--- a/samples/MarketLicensing/src/com/android/vending/licensing/Policy.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2010 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.vending.licensing;
-
-/**
- * Policy used by {@link LicenseChecker} to determine whether a user should
- * have access to the application.
- */
-public interface Policy {
-
- /**
- * Result of a license check.
- */
- public enum LicenseResponse {
- /**
- * User is licensed to use the app.
- */
- LICENSED,
- /**
- * User is not licensed to use the app.
- */
- NOT_LICENSED,
- /**
- * Retryable error on the client side e.g. no network.
- */
- CLIENT_RETRY,
- /**
- * Retryable error on the server side e.g. application is over request
- * quota.
- */
- SERVER_RETRY,
- }
-
- /**
- * Determines whether the user should be allowed access.
- *
- * @param response result of the license check request
- * @return true iff access should be allowed
- */
- boolean allowAccess(LicenseResponse response);
-}
diff --git a/samples/MarketLicensing/src/com/android/vending/licensing/ResponseData.java b/samples/MarketLicensing/src/com/android/vending/licensing/ResponseData.java
deleted file mode 100755
index 3882d56..0000000
--- a/samples/MarketLicensing/src/com/android/vending/licensing/ResponseData.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2010 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.vending.licensing;
-
-import java.util.Iterator;
-import java.util.regex.Pattern;
-
-import android.text.TextUtils;
-
-/**
- * ResponseData from licensing server.
- */
-class ResponseData {
-
- public int responseCode;
- public int nonce;
- public String packageName;
- public String versionCode;
- public String userId;
- public long timestamp;
- /** Response-specific data. */
- public String extra;
-
- /**
- * Parses response string into ResponseData.
- *
- * @param responseData response data string
- * @throws IllegalArgumentException upon parsing error
- * @return ResponseData object
- */
- public static ResponseData parse(String responseData) {
- // Must parse out main response data and response-specific data.
- TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(':');
- splitter.setString(responseData);
- Iterator<String> it = splitter.iterator();
- if (!it.hasNext()) {
- throw new IllegalArgumentException("Blank response.");
- }
- final String mainData = it.next();
-
- // Response-specific (extra) data is optional.
- String extraData = "";
- if (it.hasNext()) {
- extraData = it.next();
- }
-
- String [] fields = TextUtils.split(mainData, Pattern.quote("|"));
- if (fields.length < 5) {
- throw new IllegalArgumentException("Wrong number of fields.");
- }
-
- ResponseData data = new ResponseData();
- data.extra = extraData;
- data.responseCode = Integer.parseInt(fields[0]);
- data.nonce = Integer.parseInt(fields[1]);
- data.packageName = fields[2];
- data.versionCode = fields[3];
- // TODO(jyum): userId is not there yet.
- // data.userId = fields[4];
- data.timestamp = Long.parseLong(fields[4]);
-
- return data;
- }
-
- @Override
- public String toString() {
- return TextUtils.join("|", new Object [] { responseCode, nonce, packageName, versionCode,
- userId, timestamp });
- }
-}
diff --git a/samples/MarketLicensing/src/com/android/vending/licensing/StrictPolicy.java b/samples/MarketLicensing/src/com/android/vending/licensing/StrictPolicy.java
deleted file mode 100755
index ddff8e9..0000000
--- a/samples/MarketLicensing/src/com/android/vending/licensing/StrictPolicy.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2010 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.vending.licensing;
-
-/**
- * Strict policy.
- *
- * Should never be used in a real application as it strictly disallows access
- * upon retryable errors such as no connection present.
- */
-public class StrictPolicy implements Policy {
-
- public boolean allowAccess(LicenseResponse response) {
- return LicenseResponse.LICENSED == response;
- }
-}
diff --git a/samples/SampleSyncAdapter/_index.html b/samples/SampleSyncAdapter/_index.html
index b0fbd4a..4191ba5 100644
--- a/samples/SampleSyncAdapter/_index.html
+++ b/samples/SampleSyncAdapter/_index.html
@@ -1,26 +1,37 @@
-<p>A sample that demonstrates how an application can communicate with cloud-based services and synchronize their data with data stored locally in a content provider.
-The sample uses two related parts of the Android framework — the account manager and the synchronization manager (through a sync adapter).</p>
+<p>This sample demonstrates how an application can communicate with a
+cloud-based service and synchronize its data with data stored locally in a
+content provider. The sample uses two related parts of the Android framework
+— the account manager and the synchronization manager (through a sync
+adapter).</p>
-<p> The <a href="../../../android/accounts/AccountManager">account manager</a> allows sharing of credentials across multiple applications and services.
-Users enter the credentials for each account only once — applications with the <code>USE_CREDENTIALS</code> permission can then query the account manager
- to obtain an auth token for the account.The authenticator (a pluggable component of account manager) requests credentials from the user, validates them
- with an authentication server running in the cloud, and then stores them to the AccountManager.
-This sample demonstrates how to write an authenticator for your
-service by extending the new <code><a href="../../../android/accounts/AbstractAccountAuthenticator.html">AbstractAccountAuthenticator</a></code> abstract class.
-</p>
+<p> The <a
+href="../../../reference/android/accounts/AccountManager.html">account
+manager</a> allows sharing of credentials across multiple applications and
+services. Users enter the credentials for each account only once —
+applications with the <code>USE_CREDENTIALS</code> permission can then query the
+account manager to obtain an auth token for the account. An authenticator (a
+pluggable component of account manager) requests credentials from the user,
+validates them with an authentication server running in the cloud, and then
+stores them to the account manager. This sample demonstrates how to write an
+authenticator for your service by extending the new <code><a
+href="../../../reference/android/accounts/AbstractAccountAuthenticator.html">
+AbstractAccountAuthenticator</a></code> abstract class. </p>
-<p>The sync adapter (essential to the synchronization service) declares the account type and ContentProvider authority to the sync manager.
-This sample demosntrates how to write your own sync adapters by extending the <code><a href="../../../android/content/AbstractThreadedSyncAdapter.html">AbstractThreadedSyncAdapter</a></code>
-abstract class and implementing the onPerformSync() method that gets called whenever the sync manager issues a sync operation for that sync adapter.
-</p>
+<p>The sync adapter (essential to the synchronization service) declares the
+account type and ContentProvider authority to the sync manager. This sample
+demosntrates how to write your own sync adapters by extending the <code><a
+href="../../../reference/android/content/AbstractThreadedSyncAdapter.html">
+AbstractThreadedSyncAdapter</a></code> abstract class and implementing the
+<code>onPerformSync()</code> method, which gets called whenever the sync manager
+issues a sync operation for that sync adapter. </p>
-<p> The service for this sample application is running at: <br>
-http://samplesyncadapter.appspot.com/users
-</p>
+<p> The cloud-based service for this sample application is running at: </p>
+<p style="margin-left:2em;">http://samplesyncadapter.appspot.com/users</p>
-<p class="note">When you install this sample application, a new syncable "SampleSyncAdapter" account will be added to your phone's account manager.
-You can go to "Settings | Accounts & sync" to view the accounts that are stored in the account manager and to change their sync settings. </p>
+<p>When you install this sample application, a new syncable "SampleSyncAdapter"
+account will be added to your phone's account manager. You can go to "Settings |
+Accounts & Sync" to view the account and change its sync settings. </p>
<img alt="Screenshot 1" src="../images/SampleSyncAdapter1.png" />
<img alt="Screenshot 2" src="../images/SampleSyncAdapter2.png" />
-<img alt="Screenshot 3" src="../images/SampleSyncAdapter3.png" />
\ No newline at end of file
+<img alt="Screenshot 3" src="../images/SampleSyncAdapter3.png" />
diff --git a/testrunner/test_defs.xml b/testrunner/test_defs.xml
index 2307cfa..68eab5d 100644
--- a/testrunner/test_defs.xml
+++ b/testrunner/test_defs.xml
@@ -561,12 +561,12 @@
description="Android STL."
extra_build_args="ASTL_TESTS=1" />
-<!-- pending patch 820
+<!-- Google Test -->
<test-native name="gtest"
build_path="external/gtest"
description="Google test."
extra_build_args="GTEST_TESTS=1" />
--->
+
<!-- host java tests -->
<test-host name="cts-appsecurity"
diff --git a/testrunner/test_defs/native_test.py b/testrunner/test_defs/native_test.py
index e6917c9..dc26c73 100644
--- a/testrunner/test_defs/native_test.py
+++ b/testrunner/test_defs/native_test.py
@@ -86,7 +86,7 @@
# Single quotes are needed to prevent the shell splitting it.
output = adb.SendShellCommand("'%s 2>&1;echo -n exit code:$?'" %
- full_path,
+ "(cd /sdcard;%s)" % full_path,
int(options.timeout))
success = output.endswith("exit code:0")
logger.Log("%s... %s" % (f, success and "ok" or "failed"))