Merge "Generate /data/system/packages.list in the PackageManager"
diff --git a/Android.mk b/Android.mk
index ec6f96b..7bb5b5f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -33,6 +33,9 @@
# FRAMEWORKS_BASE_SUBDIRS comes from build/core/pathmap.mk
LOCAL_SRC_FILES := $(call find-other-java-files,$(FRAMEWORKS_BASE_SUBDIRS))
+# EventLogTags files.
+LOCAL_SRC_FILES += core/java/android/content/EventLogTags.logtags
+
# The following filters out code we are temporarily not including at all.
# TODO: Move AWT and beans (and associated harmony code) back into libcore.
# TODO: Maybe remove javax.microedition entirely?
@@ -367,6 +370,8 @@
sample_dir := development/samples
+# the list here should match the list of samples included in the sdk samples package
+# (see development/build/sdk.atree)
web_docs_sample_code_flags := \
-hdf android.hasSamples 1 \
-samplecode $(sample_dir)/ApiDemos \
@@ -377,6 +382,8 @@
resources/samples/BusinessCard "Business Card" \
-samplecode $(sample_dir)/ContactManager \
resources/samples/ContactManager "Contact Manager" \
+ -samplecode $(sample_dir)/CubeLiveWallpaper \
+ resources/samples/CubeLiveWallpaper "Live Wallpaper" \
-samplecode $(sample_dir)/Home \
resources/samples/Home "Home" \
-samplecode $(sample_dir)/JetBoy \
@@ -387,6 +394,8 @@
resources/samples/MultiResolution "Multiple Resolutions" \
-samplecode $(sample_dir)/NotePad \
resources/samples/NotePad "Note Pad" \
+ -samplecode $(sample_dir)/SampleSyncAdapter \
+ resources/samples/SampleSyncAdapter "Sample Sync Adapter" \
-samplecode $(sample_dir)/SearchableDictionary \
resources/samples/SearchableDictionary "Searchable Dictionary" \
-samplecode $(sample_dir)/Snake \
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index b33be23..bdbe341 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -16,6 +16,8 @@
package android.content;
+import android.accounts.Account;
+import android.app.ActivityThread;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
@@ -30,8 +32,8 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.text.TextUtils;
-import android.accounts.Account;
import android.util.Config;
+import android.util.EventLog;
import android.util.Log;
import java.io.File;
@@ -41,6 +43,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
+import java.util.Random;
import java.util.ArrayList;
@@ -163,6 +166,11 @@
/** @hide */
public static final int SYNC_OBSERVER_TYPE_ALL = 0x7fffffff;
+ // Always log queries which take 100ms+; shorter queries are
+ // sampled accordingly.
+ private static final int SLOW_THRESHOLD_MILLIS = 100;
+ private final Random mRandom = new Random(); // guarded by itself
+
public ContentResolver(Context context) {
mContext = context;
}
@@ -235,12 +243,15 @@
return null;
}
try {
+ long startTime = System.currentTimeMillis();
Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder);
- if(qCursor == null) {
+ if (qCursor == null) {
releaseProvider(provider);
return null;
}
- //Wrap the cursor object into CursorWrapperInner object
+ long durationMillis = System.currentTimeMillis() - startTime;
+ maybeLogQueryToEventLog(durationMillis, uri, projection, selection, sortOrder);
+ // Wrap the cursor object into CursorWrapperInner object
return new CursorWrapperInner(qCursor, provider);
} catch (RemoteException e) {
releaseProvider(provider);
@@ -572,7 +583,11 @@
throw new IllegalArgumentException("Unknown URL " + url);
}
try {
- return provider.insert(url, values);
+ long startTime = System.currentTimeMillis();
+ Uri createdRow = provider.insert(url, values);
+ long durationMillis = System.currentTimeMillis() - startTime;
+ maybeLogUpdateToEventLog(durationMillis, url, "insert", null /* where */);
+ return createdRow;
} catch (RemoteException e) {
return null;
} finally {
@@ -627,7 +642,11 @@
throw new IllegalArgumentException("Unknown URL " + url);
}
try {
- return provider.bulkInsert(url, values);
+ long startTime = System.currentTimeMillis();
+ int rowsCreated = provider.bulkInsert(url, values);
+ long durationMillis = System.currentTimeMillis() - startTime;
+ maybeLogUpdateToEventLog(durationMillis, url, "bulkinsert", null /* where */);
+ return rowsCreated;
} catch (RemoteException e) {
return 0;
} finally {
@@ -652,7 +671,11 @@
throw new IllegalArgumentException("Unknown URL " + url);
}
try {
- return provider.delete(url, where, selectionArgs);
+ long startTime = System.currentTimeMillis();
+ int rowsDeleted = provider.delete(url, where, selectionArgs);
+ long durationMillis = System.currentTimeMillis() - startTime;
+ maybeLogUpdateToEventLog(durationMillis, url, "delete", where);
+ return rowsDeleted;
} catch (RemoteException e) {
return -1;
} finally {
@@ -680,7 +703,11 @@
throw new IllegalArgumentException("Unknown URI " + uri);
}
try {
- return provider.update(uri, values, where, selectionArgs);
+ long startTime = System.currentTimeMillis();
+ int rowsUpdated = provider.update(uri, values, where, selectionArgs);
+ long durationMillis = System.currentTimeMillis() - startTime;
+ maybeLogUpdateToEventLog(durationMillis, uri, "update", where);
+ return rowsUpdated;
} catch (RemoteException e) {
return -1;
} finally {
@@ -1217,6 +1244,78 @@
}
}
+ /**
+ * Returns sampling percentage for a given duration.
+ *
+ * Always returns at least 1%.
+ */
+ private int samplePercentForDuration(long durationMillis) {
+ if (durationMillis >= SLOW_THRESHOLD_MILLIS) {
+ return 100;
+ }
+ return (int) (100 * durationMillis / SLOW_THRESHOLD_MILLIS) + 1;
+ }
+
+ private void maybeLogQueryToEventLog(long durationMillis,
+ Uri uri, String[] projection,
+ String selection, String sortOrder) {
+ int samplePercent = samplePercentForDuration(durationMillis);
+ if (samplePercent < 100) {
+ synchronized (mRandom) {
+ if (mRandom.nextInt(100) >= samplePercent) {
+ return;
+ }
+ }
+ }
+
+ StringBuilder projectionBuffer = new StringBuilder(100);
+ if (projection != null) {
+ for (int i = 0; i < projection.length; ++i) {
+ // Note: not using a comma delimiter here, as the
+ // multiple arguments to EventLog.writeEvent later
+ // stringify with a comma delimiter, which would make
+ // parsing uglier later.
+ if (i != 0) projectionBuffer.append('/');
+ projectionBuffer.append(projection[i]);
+ }
+ }
+
+ // ActivityThread.currentPackageName() only returns non-null if the
+ // current thread is an application main thread. This parameter tells
+ // us whether an event loop is blocked, and if so, which app it is.
+ String blockingPackage = ActivityThread.currentPackageName();
+
+ EventLog.writeEvent(
+ EventLogTags.CONTENT_QUERY_OPERATION,
+ uri.toString(),
+ projectionBuffer.toString(),
+ selection != null ? selection : "",
+ sortOrder != null ? sortOrder : "",
+ durationMillis,
+ blockingPackage != null ? blockingPackage : "",
+ samplePercent);
+ }
+
+ private void maybeLogUpdateToEventLog(
+ long durationMillis, Uri uri, String operation, String selection) {
+ int samplePercent = samplePercentForDuration(durationMillis);
+ if (samplePercent < 100) {
+ synchronized (mRandom) {
+ if (mRandom.nextInt(100) >= samplePercent) {
+ return;
+ }
+ }
+ }
+ String blockingPackage = ActivityThread.currentPackageName();
+ EventLog.writeEvent(
+ EventLogTags.CONTENT_UPDATE_OPERATION,
+ uri.toString(),
+ operation,
+ selection != null ? selection : "",
+ durationMillis,
+ blockingPackage != null ? blockingPackage : "",
+ samplePercent);
+ }
private final class CursorWrapperInner extends CursorWrapper {
private IContentProvider mContentProvider;
diff --git a/core/java/android/content/EventLogTags.logtags b/core/java/android/content/EventLogTags.logtags
new file mode 100644
index 0000000..a815b95
--- /dev/null
+++ b/core/java/android/content/EventLogTags.logtags
@@ -0,0 +1,6 @@
+# See system/core/logcat/event.logtags for a description of the format of this file.
+
+option java_package android.content;
+
+52002 content_query_operation (uri|3),(projection|3),(selection|3),(sortorder|3),(time|1|3),(blocking_package|3),(sample_percent|1|6)
+52003 content_update_operation (uri|3),(operation|3),(selection|3),(time|1|3),(blocking_package|3),(sample_percent|1|6)
diff --git a/core/java/android/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java
index 9581080..9a8ee02 100644
--- a/core/java/android/view/VelocityTracker.java
+++ b/core/java/android/view/VelocityTracker.java
@@ -61,6 +61,7 @@
float mYVelocity[] = new float[MotionEvent.BASE_AVAIL_POINTERS];
float mXVelocity[] = new float[MotionEvent.BASE_AVAIL_POINTERS];
+ int mLastTouch;
private VelocityTracker mNext;
@@ -105,8 +106,11 @@
* Reset the velocity tracker back to its initial state.
*/
public void clear() {
- for (int i = 0; i < MotionEvent.BASE_AVAIL_POINTERS; i++) {
- mPastTime[i][0] = 0;
+ final long[][] pastTime = mPastTime;
+ for (int p = 0; p < MotionEvent.BASE_AVAIL_POINTERS; p++) {
+ for (int i = 0; i < NUM_PAST; i++) {
+ pastTime[p][i] = 0;
+ }
}
}
@@ -133,42 +137,11 @@
}
private void addPoint(int pos, float x, float y, long time) {
- int drop = -1;
- int i;
- if (localLOGV) Log.v(TAG, "Adding past y=" + y + " time=" + time);
- final long[] pastTime = mPastTime[pos];
- for (i=0; i<NUM_PAST; i++) {
- if (pastTime[i] == 0) {
- break;
- } else if (pastTime[i] < time-LONGEST_PAST_TIME) {
- if (localLOGV) Log.v(TAG, "Dropping past too old at "
- + i + " time=" + pastTime[i]);
- drop = i;
- }
- }
- if (localLOGV) Log.v(TAG, "Add index: " + i);
- if (i == NUM_PAST && drop < 0) {
- drop = 0;
- }
- if (drop == i) drop--;
- final float[] pastX = mPastX[pos];
- final float[] pastY = mPastY[pos];
- if (drop >= 0) {
- if (localLOGV) Log.v(TAG, "Dropping up to #" + drop);
- final int start = drop+1;
- final int count = NUM_PAST-drop-1;
- System.arraycopy(pastX, start, pastX, 0, count);
- System.arraycopy(pastY, start, pastY, 0, count);
- System.arraycopy(pastTime, start, pastTime, 0, count);
- i -= (drop+1);
- }
- pastX[i] = x;
- pastY[i] = y;
- pastTime[i] = time;
- i++;
- if (i < NUM_PAST) {
- pastTime[i] = 0;
- }
+ final int lastTouch = (mLastTouch + 1) % NUM_PAST;
+ mPastX[pos][lastTouch] = x;
+ mPastY[pos][lastTouch] = y;
+ mPastTime[pos][lastTouch] = time;
+ mLastTouch = lastTouch;
}
/**
@@ -199,36 +172,41 @@
final float[] pastX = mPastX[pos];
final float[] pastY = mPastY[pos];
final long[] pastTime = mPastTime[pos];
-
+ final int lastTouch = mLastTouch;
+
+ // find oldest acceptable time
+ int oldestTouch = lastTouch;
+ if (pastTime[lastTouch] > 0) { // cleared ?
+ oldestTouch = (lastTouch + 1) % NUM_PAST;
+ final float acceptableTime = pastTime[lastTouch] - LONGEST_PAST_TIME;
+ while (pastTime[oldestTouch] < acceptableTime) {
+ oldestTouch = (oldestTouch + 1) % NUM_PAST;
+ }
+ }
+
// Kind-of stupid.
- final float oldestX = pastX[0];
- final float oldestY = pastY[0];
- final long oldestTime = pastTime[0];
+ final float oldestX = pastX[oldestTouch];
+ final float oldestY = pastY[oldestTouch];
+ final long oldestTime = pastTime[oldestTouch];
float accumX = 0;
float accumY = 0;
- int N=0;
- while (N < NUM_PAST) {
- if (pastTime[N] == 0) {
- break;
- }
- N++;
- }
+ float N = (lastTouch - oldestTouch + NUM_PAST) % NUM_PAST + 1;
// Skip the last received event, since it is probably pretty noisy.
if (N > 3) N--;
for (int i=1; i < N; i++) {
- final int dur = (int)(pastTime[i] - oldestTime);
+ final int j = (oldestTouch + i) % NUM_PAST;
+ final int dur = (int)(pastTime[j] - oldestTime);
if (dur == 0) continue;
- float dist = pastX[i] - oldestX;
+ float dist = pastX[j] - oldestX;
float vel = (dist/dur) * units; // pixels/frame.
- if (accumX == 0) accumX = vel;
- else accumX = (accumX + vel) * .5f;
-
- dist = pastY[i] - oldestY;
+ accumX = (accumX == 0) ? vel : (accumX + vel) * .5f;
+
+ dist = pastY[j] - oldestY;
vel = (dist/dur) * units; // pixels/frame.
- if (accumY == 0) accumY = vel;
- else accumY = (accumY + vel) * .5f;
+ accumY = (accumY == 0) ? vel : (accumY + vel) * .5f;
}
+
mXVelocity[pos] = accumX < 0.0f ? Math.max(accumX, -maxVelocity)
: Math.min(accumX, maxVelocity);
mYVelocity[pos] = accumY < 0.0f ? Math.max(accumY, -maxVelocity)
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 889985a..fb19dcf 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8282,7 +8282,7 @@
*/
public void clearAnimation() {
if (mCurrentAnimation != null) {
- mCurrentAnimation.cancel();
+ mCurrentAnimation.detach();
}
mCurrentAnimation = null;
}
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index ad98259..337fe58 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -277,6 +277,16 @@
}
/**
+ * @hide
+ */
+ public void detach() {
+ if (mStarted && !mEnded) {
+ if (mListener != null) mListener.onAnimationEnd(this);
+ mEnded = true;
+ }
+ }
+
+ /**
* Whether or not the animation has been initialized.
*
* @return Has this animation been initialized.
diff --git a/docs/html/resources/articles/images/live_wallpapers_small.png b/docs/html/resources/articles/images/live_wallpapers_small.png
new file mode 100644
index 0000000..3b49b24
--- /dev/null
+++ b/docs/html/resources/articles/images/live_wallpapers_small.png
Binary files differ
diff --git a/docs/html/resources/articles/index.jd b/docs/html/resources/articles/index.jd
index 4fda6d7..d2f0996 100644
--- a/docs/html/resources/articles/index.jd
+++ b/docs/html/resources/articles/index.jd
@@ -77,6 +77,11 @@
</dl>
<dl>
+ <dt><a href="{@docRoot}resources/articles/live-wallpapers.html">Live Wallpapers</a></dt>
+ <dd>Live wallpapers are richer, animated, interactive backgrounds that users can display in their home screens. Learn how to create a live wallpaper and bundle it in an application that users can install on their devices.</dd>
+</dl>
+
+<dl>
<dt><a href="{@docRoot}resources/articles/on-screen-inputs.html">Onscreen Input Methods</a></dt>
<dd>The Input Method Framework (IMF) allows users to take advantage of on-screen input methods, such as software keyboards. This article provides an overview of Input Method Editors (IMEs) and how applications interact with them.</dd>
</dl>
diff --git a/docs/html/resources/articles/live-wallpapers.jd b/docs/html/resources/articles/live-wallpapers.jd
new file mode 100644
index 0000000..8dda879
--- /dev/null
+++ b/docs/html/resources/articles/live-wallpapers.jd
@@ -0,0 +1,84 @@
+page.title=Live Wallpapers
+@jd:body
+
+<p>Starting with Android 2.1 (API Level 7), users can now enjoy <em>live
+wallpapers</em> — richer, animated, interactive backgrounds — on
+their home screens. A live wallpaper is very similar to a normal Android
+application and has access to all the facilities of the platform: SGL (2D
+drawing), OpenGL (3D drawing), GPS, accelerometers, network access, etc. The
+live wallpapers included on Nexus One demonstrate the use of some of these APIs
+to create fun and interesting user experiences. For instance, the Grass
+wallpaper uses the phone's location to compute sunrise and sunset times in order
+to display the appropriate sky.</p>
+
+<img src="images/live_wallpapers_small.png" style="align:center" />
+
+<p>Creating your own live wallpaper is easy, especially if you have had
+previous experience with <a
+href="../../../reference/android/view/SurfaceView.html"><code>SurfaceView</code></a> or <a
+href="../../../reference/android/graphics/Canvas.html"><code>Canvas</code></a>.
+To learn how to create a live wallpaper, you should check out the <a
+href="../samples/CubeLiveWallpaper/index.html">CubeLiveWallpaper sample code</a>.</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 <code>SurfaceView</code></a>.
+Drawing a wallpaper can be very expensive so you should optimize your code
+as much as possible to avoid using too much CPU, not only for battery life
+but also to avoid slowing down the rest of the system. That is also why the
+most important part of the lifecycle of a wallpaper is <a href="../../../reference/android/service/wallpaper/WallpaperService.Engine.html#onVisibilityChanged%28boolean%29">when it becomes invisible</a>.
+When invisible, such as when the user launches an application that covers
+the home screen, a wallpaper must stop all activity.</p>
+
+<p>The engine can also implement several methods to interact with the user
+or the home application. For instance, if you want your wallpaper to scroll
+along when the user swipes from one home screen to another, you can use <a href="../../../reference/android/service/wallpaper/WallpaperService.Engine.html#onOffsetsChanged%28float,%20float,%20float,%20float,%20int,%20int%29"><code>onOffsetsChanged()</code></a>.
+To react to touch events, simply implement <a href="../../../reference/android/service/wallpaper/WallpaperService.Engine.html#onTouchEvent%28android.view.MotionEvent%29"><code>onTouchEvent(MotionEvent)</code></a>.
+Finally, applications can send arbitrary commands to the live wallpaper.
+Currently, only the standard home application sends commands to the <a
+href="../../../reference/android/service/wallpaper/WallpaperService.Engine.html#onCommand%28java.lang.String,%20int,%20int,%20int,%20android.os.Bundle,%20boolean%29"><code>onCommand()</code></a>
+method of the live wallpaper:</p>
+
+<ul>
+<li><code>android.wallpaper.tap</code>: When the user taps an empty space
+on the workspace. This command is interpreted by the Nexus and Water live
+wallpapers to make the wallpaper react to user interaction. For instance,
+if you tap an empty space on the Water live wallpaper, new ripples appear
+under your finger.</li>
+<li><code>android.home.drop</code>: When the user drops an icon or a widget
+on the workspace. This command is also interpreted by the Nexus and Water
+live wallpapers.</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>Many great live wallpapers are already available on Android Market and
+we can't wait to see more!</p>
diff --git a/docs/html/resources/resources_toc.cs b/docs/html/resources/resources_toc.cs
index e337e38..0972029 100644
--- a/docs/html/resources/resources_toc.cs
+++ b/docs/html/resources/resources_toc.cs
@@ -83,6 +83,9 @@
<li><a href="<?cs var:toroot ?>resources/articles/live-folders.html">
<span class="en">Live Folders</span>
</a></li>
+ <li><a href="<?cs var:toroot ?>resources/articles/live-wallpapers.html">
+ <span class="en">Live Wallpapers</span>
+ </a> <span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>resources/articles/on-screen-inputs.html">
<span class="en">Onscreen Input Methods</span>
</a></li>
@@ -178,28 +181,34 @@
</a></li>
<li><a href="<?cs var:toroot ?>resources/samples/BluetoothChat/index.html">
<span class="en">Bluetooth Chat</span>
- </a> <span class="new">new!</span></li>
+ </a></li>
<li><a href="<?cs var:toroot ?>resources/samples/BusinessCard/index.html">
<span class="en">Business Card</span>
- </a> <span class="new">new!</span></li>
+ </a></li>
<li><a href="<?cs var:toroot ?>resources/samples/ContactManager/index.html">
<span class="en">Contact Manager</span>
- </a> <span class="new">new!</span></li>
+ </a></li>
<li><a href="<?cs var:toroot ?>resources/samples/Home/index.html">
<span class="en">Home</span>
</a></li>
<li><a href="<?cs var:toroot ?>resources/samples/JetBoy/index.html">
<span class="en">JetBoy</span>
</a></li>
+ <li><a href="<?cs var:toroot ?>resources/samples/CubeLiveWallpaper/index.html">
+ <span class="en">Live Wallpaper</span>
+ </a> <span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>resources/samples/LunarLander/index.html">
<span class="en">Lunar Lander</span>
</a></li>
<li><a href="<?cs var:toroot ?>resources/samples/MultiResolution/index.html">
<span class="en">Multiple Resolutions</span>
- </a> <span class="new">new!</span></li>
+ </a></li>
<li><a href="<?cs var:toroot ?>resources/samples/NotePad/index.html">
<span class="en">Note Pad</span>
</a></li>
+ <li><a href="<?cs var:toroot ?>resources/samples/SampleSyncAdapter/index.html">
+ <span class="en">Sample Sync Adapter</span>
+ </a> <span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>resources/samples/SearchableDictionary/index.html">
<span class="en">Searchable Dictionary</span>
</a></li>
@@ -211,10 +220,10 @@
</a></li>
<li><a href="<?cs var:toroot ?>resources/samples/Wiktionary/index.html">
<span class="en">Wiktionary</span>
- </a> <span class="new">new!</span></li>
+ </a></li>
<li><a href="<?cs var:toroot ?>resources/samples/WiktionarySimple/index.html">
<span class="en">Wiktionary (Simplified)</span>
- </a> <span class="new">new!</span></li>
+ </a></li>
</ul>
</li>
</ul>
diff --git a/docs/html/resources/samples/images/CubeLiveWallpaper1.png b/docs/html/resources/samples/images/CubeLiveWallpaper1.png
new file mode 100644
index 0000000..55bc1e9
--- /dev/null
+++ b/docs/html/resources/samples/images/CubeLiveWallpaper1.png
Binary files differ
diff --git a/docs/html/resources/samples/images/CubeLiveWallpaper3.png b/docs/html/resources/samples/images/CubeLiveWallpaper3.png
new file mode 100644
index 0000000..2747a88
--- /dev/null
+++ b/docs/html/resources/samples/images/CubeLiveWallpaper3.png
Binary files differ
diff --git a/docs/html/resources/samples/index.jd b/docs/html/resources/samples/index.jd
index 0beb781..5ebf41c 100644
--- a/docs/html/resources/samples/index.jd
+++ b/docs/html/resources/samples/index.jd
@@ -27,10 +27,10 @@
platforms) and allow you to view the source files in your browser. </p>
<div class="special">
- <p>Some of the samples in this listing are not yet available in the
- SDK. While we work to update the SDK, you can
- <a href="{@docRoot}shareables/latest_samples.zip">download the latest samples</a> as a ZIP
- archive.</p>
+ <p>Some of the samples in this listing may not yet be available in the
+ SDK. To ensure that you have the latest versions of the samples, you can
+ <a href="{@docRoot}shareables/latest_samples.zip">download the samples pack</a>
+ as a .zip archive.</p>
</div>
<dl>
@@ -55,11 +55,15 @@
<dt><a href="Home/index.html">Home</a></dt>
<dd>A home screen replacement application.</dd>
-
+
<dt><a href="JetBoy/index.html">JetBoy</a></dt>
<dd>A game that demonstrates the SONiVOX JET interactive music technology,
with {@link android.media.JetPlayer}.</dd>
-
+
+ <dt><a href="CubeLiveWallpaper/index.html">Live Wallpaper</a></dt>
+ <dd>An application that demonstrates how to create a live wallpaper and
+ bundle it in an application that users can install on their devices.</dd>
+
<dt><a href="LunarLander/index.html">Lunar Lander</a></dt>
<dd>A classic Lunar Lander game.</dd>
@@ -70,14 +74,21 @@
<dt><a href="NotePad/index.html">Note Pad</a></dt>
<dd>An application for saving notes. Similar (but not identical) to the
<a href="{@docRoot}resources/tutorials/notepad/index.html">Notepad tutorial</a>.</dd>
-
+
+ <dt><a href="SampleSyncAdapter/index.html">SampleSyncAdapter</a></dt>
+ <dd>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).</dd>
+
<dt><a href="SearchableDictionary/index.html">Searchable Dictionary</a></dt>
<dd>A sample application that demonstrates Android's search framework,
including how to provide search suggestions for Quick Search Box.</dd>
-
+
<dt><a href="Snake/index.html">Snake</a></dt>
<dd>An implementation of the classic game "Snake."</dd>
-
+
<dt><a href="SoftKeyboard/index.html">Soft Keyboard</a></dt>
<dd>An example of writing an input method for a software keyboard.</dd>