Merge "Add mProperSigningKeySet to PackageKeySetData constructor." into lmp-dev
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 68606836..1e1a613 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -80,6 +80,9 @@
private final static boolean DEBUG = false;
private final static boolean DEBUG_ICONS = false;
+ // Default flags to use with PackageManager when no flags are given.
+ private final static int sDefaultFlags = PackageManager.GET_SHARED_LIBRARY_FILES;
+
private final Object mLock = new Object();
@GuardedBy("mLock")
@@ -730,7 +733,7 @@
}
if (appInfo == null) {
try {
- appInfo = getApplicationInfo(packageName, 0);
+ appInfo = getApplicationInfo(packageName, sDefaultFlags);
} catch (NameNotFoundException e) {
return null;
}
@@ -770,7 +773,7 @@
@Override public Drawable getActivityIcon(ComponentName activityName)
throws NameNotFoundException {
- return getActivityInfo(activityName, 0).loadIcon(this);
+ return getActivityInfo(activityName, sDefaultFlags).loadIcon(this);
}
@Override public Drawable getActivityIcon(Intent intent)
@@ -799,13 +802,13 @@
@Override public Drawable getApplicationIcon(String packageName)
throws NameNotFoundException {
- return getApplicationIcon(getApplicationInfo(packageName, 0));
+ return getApplicationIcon(getApplicationInfo(packageName, sDefaultFlags));
}
@Override
public Drawable getActivityBanner(ComponentName activityName)
throws NameNotFoundException {
- return getActivityInfo(activityName, 0).loadBanner(this);
+ return getActivityInfo(activityName, sDefaultFlags).loadBanner(this);
}
@Override
@@ -832,13 +835,13 @@
@Override
public Drawable getApplicationBanner(String packageName)
throws NameNotFoundException {
- return getApplicationBanner(getApplicationInfo(packageName, 0));
+ return getApplicationBanner(getApplicationInfo(packageName, sDefaultFlags));
}
@Override
public Drawable getActivityLogo(ComponentName activityName)
throws NameNotFoundException {
- return getActivityInfo(activityName, 0).loadLogo(this);
+ return getActivityInfo(activityName, sDefaultFlags).loadLogo(this);
}
@Override
@@ -865,7 +868,7 @@
@Override
public Drawable getApplicationLogo(String packageName)
throws NameNotFoundException {
- return getApplicationLogo(getApplicationInfo(packageName, 0));
+ return getApplicationLogo(getApplicationInfo(packageName, sDefaultFlags));
}
@Override
@@ -914,7 +917,7 @@
@Override public Resources getResourcesForActivity(
ComponentName activityName) throws NameNotFoundException {
return getResourcesForApplication(
- getActivityInfo(activityName, 0).applicationInfo);
+ getActivityInfo(activityName, sDefaultFlags).applicationInfo);
}
@Override public Resources getResourcesForApplication(
@@ -926,7 +929,8 @@
Resources r = mContext.mMainThread.getTopLevelResources(
sameUid ? app.sourceDir : app.publicSourceDir,
sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
- app.resourceDirs, null, Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo);
+ app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
+ null, mContext.mPackageInfo);
if (r != null) {
return r;
}
@@ -936,7 +940,7 @@
@Override public Resources getResourcesForApplication(
String appPackageName) throws NameNotFoundException {
return getResourcesForApplication(
- getApplicationInfo(appPackageName, 0));
+ getApplicationInfo(appPackageName, sDefaultFlags));
}
/** @hide */
@@ -951,7 +955,7 @@
return mContext.mMainThread.getSystemContext().getResources();
}
try {
- ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, 0, userId);
+ ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, sDefaultFlags, userId);
if (ai != null) {
return getResourcesForApplication(ai);
}
@@ -1136,7 +1140,7 @@
}
if (appInfo == null) {
try {
- appInfo = getApplicationInfo(packageName, 0);
+ appInfo = getApplicationInfo(packageName, sDefaultFlags);
} catch (NameNotFoundException e) {
return null;
}
@@ -1164,7 +1168,7 @@
ApplicationInfo appInfo) {
if (appInfo == null) {
try {
- appInfo = getApplicationInfo(packageName, 0);
+ appInfo = getApplicationInfo(packageName, sDefaultFlags);
} catch (NameNotFoundException e) {
return null;
}
diff --git a/core/java/android/app/backup/WallpaperBackupHelper.java b/core/java/android/app/backup/WallpaperBackupHelper.java
index b8575d7..68ea9e9 100644
--- a/core/java/android/app/backup/WallpaperBackupHelper.java
+++ b/core/java/android/app/backup/WallpaperBackupHelper.java
@@ -39,6 +39,11 @@
private static final String TAG = "WallpaperBackupHelper";
private static final boolean DEBUG = false;
+ // If 'true', then apply an acceptable-size heuristic at restore time, dropping back
+ // to the factory default wallpaper if the restored one differs "too much" from the
+ // device's preferred wallpaper image dimensions.
+ private static final boolean REJECT_OUTSIZED_RESTORE = false;
+
// This path must match what the WallpaperManagerService uses
// TODO: Will need to change if backing up non-primary user's wallpaper
public static final String WALLPAPER_IMAGE =
@@ -130,27 +135,36 @@
if (DEBUG) Slog.d(TAG, "Restoring wallpaper image w=" + options.outWidth
+ " h=" + options.outHeight);
- // We accept any wallpaper that is at least as wide as our preference
- // (i.e. wide enough to fill the screen), and is within a comfortable
- // factor of the target height, to avoid significant clipping/scaling/
- // letterboxing.
- final double heightRatio = mDesiredMinHeight / options.outHeight;
- if (options.outWidth >= mDesiredMinWidth
- && heightRatio > 0 && heightRatio < 1.33) {
- // sufficiently close to our resolution; go ahead and use it
- Slog.d(TAG, "Applying restored wallpaper image.");
- f.renameTo(new File(WALLPAPER_IMAGE));
- // TODO: spin a service to copy the restored image to sd/usb storage,
- // since it does not exist anywhere other than the private wallpaper
- // file.
- } else {
- Slog.i(TAG, "Restored image dimensions (w="
- + options.outWidth + ", h=" + options.outHeight
- + ") too far off target (tw="
- + mDesiredMinWidth + ", th=" + mDesiredMinHeight
- + "); falling back to default wallpaper.");
- f.delete();
+ if (REJECT_OUTSIZED_RESTORE) {
+ // We accept any wallpaper that is at least as wide as our preference
+ // (i.e. wide enough to fill the screen), and is within a comfortable
+ // factor of the target height, to avoid significant clipping/scaling/
+ // letterboxing.
+ final double heightRatio = mDesiredMinHeight / options.outHeight;
+ if (options.outWidth < mDesiredMinWidth
+ || heightRatio <= 0
+ || heightRatio >= 1.33) {
+ // Not wide enough for the screen, or too short/tall to be a good fit
+ // for the height of the screen, broken image file, or the system's
+ // desires for wallpaper size are in a bad state. Probably one of the
+ // first two.
+ Slog.i(TAG, "Restored image dimensions (w="
+ + options.outWidth + ", h=" + options.outHeight
+ + ") too far off target (tw="
+ + mDesiredMinWidth + ", th=" + mDesiredMinHeight
+ + "); falling back to default wallpaper.");
+ f.delete();
+ return;
+ }
}
+
+ // We passed the acceptable-dimensions test (if any), so we're going to
+ // use the restored image.
+ // TODO: spin a service to copy the restored image to sd/usb storage,
+ // since it does not exist anywhere other than the private wallpaper
+ // file.
+ Slog.d(TAG, "Applying restored wallpaper image.");
+ f.renameTo(new File(WALLPAPER_IMAGE));
}
} else if (key.equals(WALLPAPER_INFO_KEY)) {
// XML file containing wallpaper info
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index 9129121..5b926ad 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -26,7 +26,6 @@
import android.nfc.INfcAdapterExtras;
import android.nfc.INfcTag;
import android.nfc.INfcCardEmulation;
-import android.nfc.INfcLockscreenDispatch;
import android.nfc.INfcUnlockHandler;
import android.os.Bundle;
diff --git a/docs/html/sdk/download.jd b/docs/html/sdk/download.jd
index 4329102..52432cf 100644
--- a/docs/html/sdk/download.jd
+++ b/docs/html/sdk/download.jd
@@ -14,9 +14,9 @@
if (location.indexOf('?v=') != -1) {
var filename = location.substring(location.indexOf('=')+1,location.length);
if (document.getElementById('checkbox').checked) {
- document.location = "http://dl.google.com/android/" + filename;
+ document.location = "https://dl.google.com/android/" + filename;
}
- document.getElementById('click-download').setAttribute("href", "http://dl.google.com/android/"
+ document.getElementById('click-download').setAttribute("href", "https://dl.google.com/android/"
+ filename);
$("#terms-form").hide(500);
$("#next-steps").show(500);
diff --git a/docs/html/tools/sdk/eclipse-adt.jd b/docs/html/tools/sdk/eclipse-adt.jd
index 469d11f..deafed5 100644
--- a/docs/html/tools/sdk/eclipse-adt.jd
+++ b/docs/html/tools/sdk/eclipse-adt.jd
@@ -70,8 +70,8 @@
<li>Java 1.6 or higher is required if you are targeting other releases.</li>
<li>Eclipse Indigo (Version 3.7.2) or higher is required.</li>
<li>This version of ADT is designed for use with
- <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r23.0.4</a>.
- If you haven't already installed SDK Tools r23.0.4 into your SDK, use the
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r23.0.2</a>.
+ If you haven't already installed SDK Tools r23.0.2 into your SDK, use the
Android SDK Manager to do so.</li>
</ul>
</dd>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index 4dd57ab..5443c56 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -784,6 +784,34 @@
<li class="nav-section">
<div class="nav-section-header">
+ <a href="<?cs var:toroot ?>training/wearables/ui/index.html"
+ description="How to create custom user interfaces for wearable apps."
+ >Creating Custom UIs</a>
+ </div>
+ <ul>
+ <li>
+ <a href="<?cs var:toroot ?>training/wearables/ui/layouts.html">Defining Layouts</a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/wearables/ui/cards.html">Creating Cards</a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/wearables/ui/lists.html">Creating Lists</a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/wearables/ui/2d-picker.html">Creating a 2D Picker</a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/wearables/ui/confirm.html">Showing Confirmations</a>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>training/wearables/ui/exit.html">Exiting Full-Screen Activities</a>
+ </li>
+ </ul>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header">
<a href="<?cs var:toroot ?>training/wearables/data-layer/index.html"
description="How to sync data between handhelds and wearables."
>Sending and Syncing Data</a>
diff --git a/docs/html/training/wearables/ui/2d-picker.jd b/docs/html/training/wearables/ui/2d-picker.jd
new file mode 100644
index 0000000..8f4d8af
--- /dev/null
+++ b/docs/html/training/wearables/ui/2d-picker.jd
@@ -0,0 +1,181 @@
+page.title=Creating a 2D Picker
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#add-page-grid">Add a Page Grid</a></li>
+ <li><a href="#implement-adapter">Implement a Page Adapter</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}design/wear/index.html">Android Wear Design Principles</a></li>
+</ul>
+</div>
+</div>
+
+<p>The <a href="{@docRoot}design/wear/structure.html#2DPicker">2D Picker</a> pattern in Android
+Wear allows users to navigate and choose from a set of items shown as pages. The Wearable UI
+Library lets you easily implement this pattern using a page grid, which is a layout manager
+that allows users to scroll vertically and horizontally through pages of data.</p>
+
+<p>To implement this pattern, you add a <code>GridViewPager</code> element to the layout
+of your activity and implement an adapter that provides a set of pages by extending
+the <code>FragmentGridPagerAdapter</code> class.</p>
+
+<p class="note"><strong>Note:</strong> The <em>GridViewPager</em> sample in the Android SDK
+demonstrates how to use the <code>GridViewPager</code> layout in your apps. This sample is
+located in the <code>android-sdk/samples/android-20/wearable/GridViewPager</code> directory.</p>
+
+
+<h2 id="add-page-grid">Add a Page Grid</h2>
+
+<p>Add a <code>GridViewPager</code> element to your layout definition as follows:</p>
+
+<pre>
+<android.support.wearable.view.GridViewPager
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/pager"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+</pre>
+
+<p>You can use any of the techniques described in
+<a href="{@docRoot}training/wearables/ui/layouts.html">Defining Layouts</a> to ensure that
+your 2D picker works on both round and square devices.</p>
+
+
+<h2 id="implement-adapter">Implement a Page Adapter</h2>
+
+<p>A page adapter provides a set of pages to populate a <code>GridViewPager</code> component. To
+implement this adapter, you extend the <code>FragmentGridPageAdapter</code> class from the
+Wearable UI Library</p>
+
+<p>For example, the <em>GridViewPager</em> sample in the Android SDK contains
+the following adapter implementation that provides a set of static cards with custom background
+images:</p>
+
+<pre>
+public class SampleGridPagerAdapter extends FragmentGridPagerAdapter {
+
+ private final Context mContext;
+
+ public SampleGridPagerAdapter(Context ctx, FragmentManager fm) {
+ super(fm);
+ mContext = ctx;
+ }
+
+ static final int[] BG_IMAGES = new int[] {
+ R.drawable.debug_background_1, ...
+ R.drawable.debug_background_5
+ };
+
+ // A simple container for static data in each page
+ private static class Page {
+ // static resources
+ int titleRes;
+ int textRes;
+ int iconRes;
+ ...
+ }
+
+ // Create a static set of pages in a 2D array
+ private final Page[][] PAGES = { ... };
+
+ // Override methods in FragmentGridPagerAdapter
+ ...
+}
+</pre>
+
+<p>The picker calls <code>getFragment</code> and <code>getBackground</code> to retrieve the content
+to display at each position of the grid:</p>
+
+<pre>
+// Obtain the UI fragment at the specified position
+@Override
+public Fragment getFragment(int row, int col) {
+ Page page = PAGES[row][col];
+ String title =
+ page.titleRes != 0 ? mContext.getString(page.titleRes) : null;
+ String text =
+ page.textRes != 0 ? mContext.getString(page.textRes) : null;
+ CardFragment fragment = CardFragment.create(title, text, page.iconRes);
+
+ // Advanced settings (card gravity, card expansion/scrolling)
+ fragment.setCardGravity(page.cardGravity);
+ fragment.setExpansionEnabled(page.expansionEnabled);
+ fragment.setExpansionDirection(page.expansionDirection);
+ fragment.setExpansionFactor(page.expansionFactor);
+ return fragment;
+}
+
+// Obtain the background image for the page at the specified position
+@Override
+public ImageReference getBackground(int row, int column) {
+ return ImageReference.forDrawable(BG_IMAGES[row % BG_IMAGES.length]);
+}
+</pre>
+
+<p>The <code>getRowCount</code> method tells the picker how many rows of content are
+available, and the <code>getColumnCount</code> method tells the picker how many columns
+of content are available for each of the rows.</p>
+
+<pre>
+// Obtain the number of pages (vertical)
+@Override
+public int getRowCount() {
+ return PAGES.length;
+}
+
+// Obtain the number of pages (horizontal)
+@Override
+public int getColumnCount(int rowNum) {
+ return PAGES[rowNum].length;
+}
+</pre>
+
+<p>The adapter implementation details depend on your particular set of pages. Each page provided
+by the adapter is of type <code>Fragment</code>. In this example, each page is a
+<code>CardFragment</code> instance that uses one of the default card layouts. However, you can
+combine different types of pages in the same 2D picker, such as cards, action icons, and custom
+layouts depending on your use cases.</p>
+
+<div style="float:right;margin-left:25px;width:250px">
+<img src="{@docRoot}wear/images/07_uilib.png" width="250" height="250" alt=""/>
+<p class="img-caption" style="text-align:center"><strong>Figure 1:</strong>
+The <em>GridViewPager</em> sample.</p>
+</div>
+
+<p>Not all rows need to have the same number of pages. Notice that in this example the number of
+colums is different for each row. You can also use a <code>GridViewPager</code> component to
+implement a 1D picker with only one row or only one column.</p>
+
+<p><code>GridViewPager</code> provides support for scrolling in cards whose content does not fit
+the device screen. This example configures each card to expand as required, so users can scroll
+through the card's content. When users reach the end of a scrollable card, a swipe in the same
+direction shows the next page on the grid, if one is available.</p>
+
+<p>You can specify a custom background for each page with the <code>getBackground()</code> method.
+When users swipe to navigate across pages, <code>GridViewPager</code> applies parallax
+and crossfade effects between different backgrounds automatically.</p>
+
+<h3>Assign an adapter instance to the page grid</h3>
+
+<p>In your activity, assign an instance of your adapter implementation to the
+<code>GridViewPager</code> component:</p>
+
+<pre>
+public class MainActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ ...
+ final GridViewPager pager = (GridViewPager) findViewById(R.id.pager);
+ pager.setAdapter(new SampleGridPagerAdapter(this, getFragmentManager()));
+ }
+}
+</pre>
diff --git a/docs/html/training/wearables/ui/cards.jd b/docs/html/training/wearables/ui/cards.jd
new file mode 100644
index 0000000..0633720
--- /dev/null
+++ b/docs/html/training/wearables/ui/cards.jd
@@ -0,0 +1,169 @@
+page.title=Creating Cards
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#card-fragment">Create a Card Fragment</a></li>
+ <li><a href="#card-layout">Add a Card to Your Layout</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}design/wear/index.html">Android Wear Design Principles</a></li>
+</ul>
+</div>
+</div>
+
+
+<p>Cards present information to users with a consistent look and feel across different apps.
+This lesson shows you how to create cards in your Android Wear apps.</p>
+
+<p>The Wearable UI Library provides implementations of cards specifically designed for wearable
+devices. This library contains the <code>CardFrame</code> class, which wraps views inside
+a card-styled frame with a white background, rounded corners, and a light-drop shadow.
+<code>CardFrame</code> can only contain one direct child, usually a layout manager, to which
+you can add other views to customize the content inside the card.</p>
+
+<p>You can add cards to your app in two ways:</p>
+
+<ul>
+ <li>Use or extend the <code>CardFragment</code> class.</li>
+ <li>Add a card inside a <code>CardScrollView</code> in your layout.</li>
+</ul>
+
+<p class="note"><strong>Note:</strong> This lesson shows you how to add cards to Android Wear
+activities. Android notifications on wearable devices are also displayed as cards. For more
+information, see <a href="{@docRoot}training/wearables/notifications/index.html">Adding Wearable
+Features to Notifications</a>.</p>
+
+
+<h2 id="card-fragment">Create a Card Fragment</h2>
+
+<p>The <code>CardFragment</code> class provides a default card layout with a title, a
+description, and an icon. Use this approach to add cards to your app if the default card layout
+shown in figure 1 meets your needs.</p>
+
+<img src="{@docRoot}wear/images/05_uilib.png" width="500" height="245" alt=""/>
+<p class="img-caption"><strong>Figure 1.</strong> The default <code>CardFragment</code> layout.</p>
+
+<p>To add a <code>CardFragment</code> to your app:</p>
+
+<ol>
+<li>In your layout, assign an ID to the element that contains the card</li>
+<li>Create a <code>CardFragment</code> instance in your activity</li>
+<li>Use the fragment manager to add the <code>CardFragment</code> instance to its container</li>
+</ol>
+
+<p>The following sample code shows the code for the screen display shown in Figure 1:</p>
+
+<pre>
+<android.support.wearable.view.BoxInsetLayout
+xmlns:android="http://schemas.android.com/apk/res/android"
+xmlns:app="http://schemas.android.com/apk/res-auto"
+android:background="@drawable/robot_background"
+android:layout_height="match_parent"
+android:layout_width="match_parent">
+
+ <FrameLayout
+ <strong>android:id="@+id/frame_layout"</strong>
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ app:layout_box="bottom">
+
+ </FrameLayout>
+</android.support.wearable.view.BoxInsetLayout>
+</pre>
+
+<p>The following code adds the <code>CardFragment</code> instance to the activity in Figure 1:</p>
+
+<pre>
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_wear_activity2);
+
+ FragmentManager fragmentManager = getFragmentManager();
+ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+ CardFragment cardFragment = CardFragment.create(getString(R.string.cftitle),
+ getString(R.string.cfdesc),
+ R.drawable.p);
+ fragmentTransaction.add(R.id.frame_layout, cardFragment);
+ fragmentTransaction.commit();
+}
+</pre>
+
+<p>To create a card with a custom layout using <code>CardFragment</code>, extend this class
+and override its <code>onCreateContentView</code> method.</p>
+
+
+<h2 id="card-layout">Add a CardFrame to Your Layout</h2>
+
+<p>You can also add a card directly to your layout definition, as shown in figure 2. Use this
+approach when you want to define a custom layout for the card inside a layout definition file.</p>
+
+<img src="{@docRoot}wear/images/04_uilib.png" width="500" height="248" alt=""/>
+<p class="img-caption"><strong>Figure 2.</strong> Adding a <code>CardFrame</code> to your
+layout.</p>
+
+<p>The following layout code sample demonstrates a vertical linear layout with two elements. You
+can create more complex layouts to fit the needs of your app.</p>
+
+<pre>
+<android.support.wearable.view.BoxInsetLayout
+xmlns:android="http://schemas.android.com/apk/res/android"
+xmlns:app="http://schemas.android.com/apk/res-auto"
+android:background="@drawable/robot_background"
+android:layout_height="match_parent"
+android:layout_width="match_parent">
+
+ <<strong>android.support.wearable.view.CardScrollView</strong>
+ android:id="@+id/card_scroll_view"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ app:layout_box="bottom">
+
+ <<strong>android.support.wearable.view.CardFrame</strong>
+ android:layout_height="wrap_content"
+ android:layout_width="fill_parent">
+
+ <LinearLayout
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:orientation="vertical"
+ android:paddingLeft="5dp">
+ <TextView
+ android:fontFamily="sans-serif-light"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:text="@string/custom_card"
+ android:textColor="@color/black"
+ android:textSize="20sp"/>
+ <TextView
+ android:fontFamily="sans-serif-light"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:text="@string/description"
+ android:textColor="@color/black"
+ android:textSize="14sp"/>
+ </LinearLayout>
+ </android.support.wearable.view.CardFrame>
+ </android.support.wearable.view.CardScrollView>
+</android.support.wearable.view.BoxInsetLayout>
+</pre>
+
+<p>The <code>CardScrollView</code> element in the example layout above lets you assign gravity to
+the card when its content is smaller than the container. This example aligns the card to the
+bottom of the screen:</p>
+
+<pre>
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_wear_activity2);
+
+ CardScrollView cardScrollView =
+ (CardScrollView) findViewById(R.id.card_scroll_view);
+ cardScrollView.setCardGravity(Gravity.BOTTOM);
+}
+</pre>
diff --git a/docs/html/training/wearables/ui/confirm.jd b/docs/html/training/wearables/ui/confirm.jd
new file mode 100644
index 0000000..36330a6
--- /dev/null
+++ b/docs/html/training/wearables/ui/confirm.jd
@@ -0,0 +1,166 @@
+page.title=Showing Confirmations
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#confirmation-timers">Use Automatic Confirmation Timers</a></li>
+ <li><a href="#show-confirmation">Show Confirmation Animations</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}design/wear/index.html">Android Wear Design Principles</a></li>
+</ul>
+</div>
+</div>
+
+
+<p><a href="{@docRoot}design/wear/patterns.html#Countdown">Confirmations</a> in Android Wear apps
+use the whole screen or a larger portion of it than those in handheld apps. This ensures that
+users can see these confirmations by just glancing at the screen and that they have large enough
+touch targets to cancel an action.</p>
+
+<p>The Wearable UI Library helps you show confirmation animations and timers in your
+Android Wear apps:</p>
+
+<dl>
+<dt><em>Confirmation timers</em></dt>
+ <dd>Automatic confirmation timers show users an animated timer that lets them cancel an action
+ they just performed.</dd>
+<dt><em>Confirmation animations</em></dt>
+ <dd>Confirmation animations give users visual feedback when they complete an action.</dd>
+</dl>
+
+<p>The following sections show you how to implement these patterns.</p>
+
+
+<h2 id="confirmation-timers">Use Automatic Confirmation Timers</h2>
+
+<div style="float:right;margin-left:25px;width:230px;margin-top:10px">
+<img src="{@docRoot}wear/images/09_uilib.png" width="230" height="230" alt=""/>
+<p class="img-caption" style="text-align:center"><strong>Figure 1:</strong>
+A confirmation timer.</p>
+</div>
+
+<p>Automatic confirmation timers let users cancel an action they just performed. When the user
+performs the action, your app shows a button to cancel the action with a timer animation and
+starts the timer. The user has the option to cancel the action until the timer finishes. Your app
+gets notified if the user cancels the action and when the timer expires.</p>
+
+<p>To show a confirmation timer when users complete an action in your app:</p>
+
+<ol>
+<li>Add a <code>DelayedConfirmationView</code> element to your layout.</li>
+<li>Implement the <code>DelayedConfirmationListener</code> interface in your activity.</li>
+<li>Set the duration of the timer and start it when the user completes an action.</li>
+</ol>
+
+<p>Add the <code>DelayedConfirmationView</code> element to your layout as follows:</p>
+
+<pre>
+<android.support.wearable.view.DelayedConfirmationView
+ android:id="@+id/delayed_confirm"
+ android:layout_width="40dp"
+ android:layout_height="40dp"
+ android:src="@drawable/cancel_circle"
+ app:circle_border_color="@color/lightblue"
+ app:circle_border_width="4dp"
+ app:circle_radius="16dp">
+</android.support.wearable.view.DelayedConfirmationView>
+</pre>
+
+<p>You can assign a drawable resource to display inside the circle with the
+<code>android:src</code> attribute and configure the parameters of the circle directly on the
+layout definition.</p>
+
+<p>To be notified when the timer finishes or when users tap on it, implement the corresponding
+listener methods in your activity:</p>
+
+<pre>
+public class WearActivity extends Activity implements
+ DelayedConfirmationView.DelayedConfirmationListener {
+
+ private DelayedConfirmationView mDelayedView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_wear_activity);
+
+ mDelayedView =
+ (DelayedConfirmationView) findViewById(R.id.delayed_confirm);
+ mDelayedView.setListener(this);
+ }
+
+ @Override
+ public void onTimerFinished(View view) {
+ // User didn't cancel, perform the action
+ }
+
+ @Override
+ public void onTimerSelected(View view) {
+ // User canceled, abort the action
+ }
+}
+</pre>
+
+<p>To start the timer, add the following code to the point in your activity where users select
+an action:</p>
+
+<pre>
+// Two seconds to cancel the action
+mDelayedView.setTotalTimeMs(2000);
+// Start the timer
+mDelayedView.start();
+</pre>
+
+
+<h2 id="show-confirmation">Show Confirmation Animations</h2>
+
+<div style="float:right;margin-left:25px;width:200px">
+<img src="{@docRoot}wear/images/08_uilib.png" width="200" height="200" alt=""/>
+<p class="img-caption" style="text-align:center"><strong>Figure 2:</strong>
+A confirmation animation.</p>
+</div>
+
+<p>To show a confirmation animation when users complete an action in your app, create an intent
+that starts <code>ConfirmationActivity</code> from one of your activities. You can specify
+one of the these animations with the <code>EXTRA_ANIMATION_TYPE</code> intent extra:</p>
+
+<ul>
+<li><code>SUCCESS_ANIMATION</code></li>
+<li><code>FAILURE_ANIMATION</code></li>
+<li><code>OPEN_ON_PHONE_ANIMATION</code></li>
+</ul>
+
+<p>You can also add a message that appears under the confirmation icon.</p>
+
+<p>To use the <code>ConfirmationActivity</code> in your app, first declare this activity in your
+manifest file:</p>
+
+<pre>
+<manifest>
+ <application>
+ ...
+ <activity
+ android:name="android.support.wearable.activity.ConfirmationActivity">
+ </activity>
+ </application>
+</manifest>
+</pre>
+
+<p>Then determine the result of the user action and start the activity with an intent:</p>
+
+<pre>
+Intent intent = new Intent(this, ConfirmationActivity.class);
+intent.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE,
+ ConfirmationActivity.SUCCESS_ANIMATION);
+intent.putExtra(ConfirmationActivity.EXTRA_MESSAGE,
+ getString(R.string.msg_sent));
+startActivity(intent);
+</pre>
+
+<p>After showing the confirmation animation, <code>ConfirmationActivity</code> finishes and your
+activity resumes.</p>
diff --git a/docs/html/training/wearables/ui/exit.jd b/docs/html/training/wearables/ui/exit.jd
new file mode 100644
index 0000000..b89711a
--- /dev/null
+++ b/docs/html/training/wearables/ui/exit.jd
@@ -0,0 +1,110 @@
+page.title=Exiting Full-Screen Activities
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#disable-swipe">Disable the Swipe-To-Dismiss Gesture</a></li>
+ <li><a href="#long-press">Implement the Long Press to Dismiss Pattern</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}design/wear/index.html">Android Wear Design Principles</a></li>
+</ul>
+</div>
+</div>
+
+
+<p>By default, users exit Android Wear activities by swiping from left to right. If the app
+contains horizontally scrollable content, users first have to navigate to the edge of the
+content and then swipe again from left to right to exit the app.</p>
+
+<p>For more immersive experiences, like an app that can scroll a map in any direction, you can
+disable the swipe to exit gesture in your app. However, if you disable it, you must implement
+the long-press-to-dismiss UI pattern to let users exit your app using the
+<code>DismissOverlayView</code> class from the Wearable UI Library.
+You must also inform your users the first time they run your app that they can exit using
+a long press.</p>
+
+<p>For design guidelines on exiting Android Wear activities, see
+<a href="{@docRoot}design/wear/structure.html#Custom">Breaking out of the card</a>.</p>
+
+
+<h2 id="disable-swipe">Disable the Swipe-To-Dismiss Gesture</h2>
+
+<p>If the user interaction model of your app interferes with the swipe-to-dismiss gesture,
+you can disable it for your app. To disable the swipe-to-dismiss gesture in your app, extend
+the default theme and set the <code>android:windowSwipeToDismiss</code> attribute to
+<code>false</code>:</p>
+
+<pre>
+<style name="AppTheme" parent="Theme.DeviceDefault">
+ <item name="android:windowSwipeToDismiss">false</item>
+</style>
+</pre>
+
+<p>If you disable this gesture, you must implement the long-press-to-dismiss UI pattern to let users
+exit your app, as described in the next section.</p>
+
+
+<h2 id="long-press">Implement the Long Press to Dismiss Pattern</h2>
+
+<p>To use the <code>DissmissOverlayView</code> class in your activity, add this element to
+your layout definition such that it covers the whole screen and is placed above all other views.
+For example:</p>
+
+<pre>
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent">
+
+ <!-- other views go here -->
+
+ <android.support.wearable.view.DismissOverlayView
+ android:id="@+id/dismiss_overlay"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"/>
+<FrameLayout>
+</pre>
+
+<p>In your activity, obtain the <code>DismissOverlayView</code> element and set some introductory
+text. This text is shown to users the first time they run your app to inform them that they
+can exit the app using a long press gesture. Then use a <code>GestureDetector</code> to detect
+a long press:</p>
+
+<pre>
+public class WearActivity extends Activity {
+
+ private DismissOverlayView mDismissOverlay;
+ private GestureDetector mDetector;
+
+ public void onCreate(Bundle savedState) {
+ super.onCreate(savedState);
+ setContentView(R.layout.wear_activity);
+
+ // Obtain the DismissOverlayView element
+ mDismissOverlay = (DismissOverlayView) findViewById(R.id.dismiss_overlay);
+ mDismissOverlay.setIntroText(R.string.long_press_intro);
+ mDismissOverlay.showIntroIfNecessary();
+
+ // Configure a gesture detector
+ mDetector = new GestureDetector(this, new SimpleOnGestureListener() {
+ public void onLongPress(MotionEvent ev) {
+ mDismissOverlay.show();
+ }
+ });
+ }
+
+ // Capture long presses
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ return mDetector.onTouchEvent(ev) || super.onTouchEvent(ev);
+ }
+}
+</pre>
+
+<p>When the system detects a long press gesture, <code>DismissOverlayView</code> shows an
+<strong>Exit</strong> button, which terminates your activity if the user presses it.</p>
\ No newline at end of file
diff --git a/docs/html/training/wearables/ui/index.jd b/docs/html/training/wearables/ui/index.jd
new file mode 100644
index 0000000..8ef6fe7
--- /dev/null
+++ b/docs/html/training/wearables/ui/index.jd
@@ -0,0 +1,57 @@
+page.title=Creating Custom UIs for Wear Devices
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>Dependencies and Prerequisites</h2>
+ <ul>
+ <li>Android Studio 0.8 or later and Gradle 0.12 or later</li>
+ </ul>
+</div>
+</div>
+
+<p>User interfaces for wearable apps differ significantly from those built for handheld devices.
+Apps for wearables should follow the Android Wear <a href="{@docRoot}design/wear/index.html">design
+principles</a> and implement the recommended <a href="{@docRoot}design/wear/patterns.html">UI
+patterns</a>, which ensure a consistent user experience across apps that is optimized for
+wearables.</a>
+
+<p>This class teaches you how to create custom UIs for your
+<a href="{@docRoot}training/wearables/apps/creating.html">wearable apps</a> and
+<a href="{@docRoot}training/wearables/apps/layouts.html#CustomNotifications">custom
+notifications</a> that look good on any Android Wear device by implementing these
+UI patterns:</p>
+
+<ul>
+<li>Cards</li>
+<li>Countdowns and confirmations</li>
+<li>Long press to dismiss</li>
+<li>2D Pickers</li>
+<li>Selection lists</li>
+</ul>
+
+<p>The Wearable UI Library, which is part of the Google Repository in the Android SDK,
+provides classes that help you implement these patterns and create layouts that work on
+both round and square Android Wear devices.</p>
+
+<p class="note"><b>Note:</b> We recommend using Android Studio for Android Wear development
+as it provides project setup, library inclusion, and packaging conveniences that aren't available
+in ADT. This training assumes you are using Android Studio.</p>
+
+<h2>Lessons</h2>
+
+<dl>
+ <dt><a href="{@docRoot}training/wearables/ui/layouts.html">Defining Layouts</a></dt>
+ <dd>Learn how to create layouts that look good on round and square Android Wear devices.</dd>
+ <dt><a href="{@docRoot}training/wearables/ui/cards.html">Creating Cards</a></dt>
+ <dd>Learn how to create cards with custom layouts.</dd>
+ <dt><a href="{@docRoot}training/wearables/ui/lists.html">Creating Lists</a></dt>
+ <dd>Learn how to create lists that are optimized for wearable devices.</dd>
+ <dt><a href="{@docRoot}training/wearables/ui/2d-picker.html">Creating a 2D Picker</a></dt>
+ <dd>Learn how to implement the 2D Picker UI pattern to navigate through pages of data.</dd>
+ <dt><a href="{@docRoot}training/wearables/ui/confirm.html">Showing Confirmations</a></dt>
+ <dd>Learn how to display confirmation animations when users complete actions.</dd>
+ <dt><a href="{@docRoot}training/wearables/ui/exit.html">Exiting Full-Screen Activities</a></dt>
+ <dd>Learn how to implement the long-press-to-dismiss UI pattern to exit full-screen activities.</dd>
+</dl>
\ No newline at end of file
diff --git a/docs/html/training/wearables/ui/layouts.jd b/docs/html/training/wearables/ui/layouts.jd
new file mode 100644
index 0000000..14b9403
--- /dev/null
+++ b/docs/html/training/wearables/ui/layouts.jd
@@ -0,0 +1,261 @@
+page.title=Defining Layouts
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#add-library">Add the Wearable UI Library</a></li>
+ <li><a href="#different-layouts">Specify Different Layouts for Square and Round Screens</a></li>
+ <li><a href="#same-layout">Use a Shape-Aware Layout</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}design/wear/index.html">Android Wear Design Principles</a></li>
+</ul>
+<h2>Video</h2>
+<ul>
+ <li><a href="https://www.youtube.com/watch?v=naf_WbtFAlY">Full Screen Apps for Android Wear</a></li>
+</ul>
+</div>
+</div>
+
+<p>Wearables use the same layout techniques as handheld Android devices, but need to be designed
+with specific constraints. Do not port functionality and the UI from a handheld app and expect a
+good experience. For more information on how to design great wearable apps, read the
+<a href="{@docRoot}design/wear/index.html">Android Wear Design Guidelines</a>.</p>
+
+<p>When you create layouts for Android Wear apps, you need to account for devices with square
+and round screens. Any content placed near the corners of the screen may be cropped on round
+Android Wear devices, so layouts designed for square screens do not work well on round devices.
+For a demonstration of this type of problem, see the video
+<a href="https://www.youtube.com/watch?v=naf_WbtFAlY">Full Screen Apps for Android Wear</a>.</p>
+
+<p>For example, figure 1 shows how the following layout looks on square and round screens:</p>
+
+<img src="{@docRoot}wear/images/01_uilib.png" alt="" width="500" height="261"/>
+<p class="img-caption"><strong>Figure 1.</strong> Demonstration of how a layout designed for
+square screens does not work well on round screens.</p>
+
+<pre>
+<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:orientation="vertical">
+
+ <TextView
+ android:id="@+id/text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/hello_square" />
+</LinearLayout>
+</pre>
+
+<p>The text does not display correctly on devices with round screens.</p>
+
+<p>The Wearable UI Library provides two different approaches to solve this problem:</p>
+
+<ul>
+<li>Define different layouts for square and round devices. Your app detects the shape
+ of the device screen and inflates the correct layout at runtime.</li>
+<li>Use a special layout included in the library for both square and round devices. This layout
+ applies different window insets depending on the shape of the device screen.</li>
+</ul>
+
+<p>You typically use the first approach when you want your app to look different depending on
+the shape of the device screen. You use the second approach when you want to use a similar layout
+on both screen shapes without having views cropped near the edges of round screens.</p>
+
+
+<h2 id="add-library">Add the Wearable UI Library</h2>
+
+<p>Android Studio includes the Wearable UI Library on your <code>wear</code> module by default
+when you use the Project Wizard. To compile your project with this library, ensure that the
+<em>Extras</em> > <em>Google Repository</em> package is installed in
+the Android SDK manager and that the following dependency is included in the
+<code>build.gradle</code> file of your <code>wear</code> module:</p>
+
+<pre>
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ <strong>compile 'com.google.android.support:wearable:+'</strong>
+ compile 'com.google.android.gms:play-services-wearable:+'
+}
+</pre>
+
+<p>The <code>'com.google.android.support:wearable'</code> dependency is required to implement
+the layout techniques shown in the following sections.</p>
+
+<p><a href="/shareables/training/wearable-support-docs.zip">Download the full API
+reference documentation</a> for the Wearable UI Library classes.</p>
+
+
+<h2 id="different-layouts">Specify Different Layouts for Square and Round Screens</h2>
+
+<p>The <code>WatchViewStub</code> class included in the Wearable UI Library lets you specify
+different layout definitions for square and round screens. This class detects the screen shape
+at runtime and inflates the corresponding layout.</p>
+
+<p>To use this class for handling different screen shapes in your app:</p>
+
+<ol>
+<li>Add <code>WatchViewStub</code> as the main element of your activity's layout.</li>
+<li>Specify a layout definition file for square screens with the <code>rectLayout</code>
+ attribute.</li>
+<li>Specify a layout definition file for round screens with the <code>roundLayout</code>
+ attribute.</li>
+</ol>
+
+<p>Define your activity's layout as follows:</p>
+
+<pre>
+<android.support.wearable.view.WatchViewStub
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/watch_view_stub"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ <strong>app:rectLayout="@layout/rect_activity_wear"</strong>
+ <strong>app:roundLayout="@layout/round_activity_wear"</strong>>
+</android.support.wearable.view.WatchViewStub>
+</pre>
+
+<p>Inflate this layout in your activity:</p>
+
+<pre>
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_wear);
+}
+</pre>
+
+<p>Then create different layout definition files for square and round screens. In this example,
+you need to create the files <code>res/layout/rect_activity_wear.xml</code> and
+<code>res/layout/round_activity_wear.xml</code>. You define these layouts in the same way that
+you create layouts for handheld apps, but taking into account the constraints of wearable devices.
+The system inflates the correct layout at runtime depending on the screen shape.</p>
+
+<h3>Accessing layout views</h3>
+
+<p>The layouts that you specify for square or round screens are not inflated until
+<code>WatchViewStub</code> detects the shape of the screen, so your app cannot access their views
+immediately. To access these views, set a listener in your activity to be notified when
+the shape-specific layout has been inflated:</p>
+
+<pre>
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_wear);
+
+ WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
+ stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
+ @Override public void onLayoutInflated(WatchViewStub stub) {
+ // Now you can access your views
+ TextView tv = (TextView) stub.findViewById(R.id.text);
+ ...
+ }
+ });
+}
+</pre>
+
+
+<h2 id="same-layout">Use a Shape-Aware Layout</h2>
+
+<div style="float:right;margin-left:25px;width:250px">
+<img src="{@docRoot}wear/images/02_uilib.png" width="250" height="250" alt=""/>
+<p class="img-caption"><strong>Figure 2.</strong> Window insets on a round screen.</p>
+</div>
+
+<p>The <code>BoxInsetLayout</code> class included in the Wearable UI Library extends
+{@link android.widget.FrameLayout} and lets you define a single layout that works for both square
+and round screens. This class applies the required window insets depending on the screen shape
+and lets you easily align views on the center or near the edges of the screen.</p>
+
+<p>The gray square in figure 2 shows the area where <code>BoxInsetLayout</code> can automatically
+place its child views on round screens after applying the required window insets. To be displayed
+inside this area, children views specify the <code>layout_box</code> atribute with these values:
+</p>
+
+<ul>
+<li>A combination of <code>top</code>, <code>bottom</code>, <code>left</code>, and
+ <code>right</code>. For example, <code>"left|top"</code> positions the child's left and top
+ edges inside the gray square in figure 2.</li>
+<li>The <code>all</code> value positions all the child's content inside the gray square in
+ figure 2.</li>
+</ul>
+
+<p>On square screens, the window insets are zero and the <code>layout_box</code> attribute is
+ignored.</p>
+
+<img src="{@docRoot}wear/images/03_uilib.png" width="500" height="253" alt=""/>
+<p class="img-caption"><strong>Figure 3.</strong> A layout definition that works on both
+square and round screens.</p>
+
+<p>The layout shown in figure 3 uses <code>BoxInsetLayout</code> and works on square and
+round screens:</p>
+
+<pre>
+<<strong>android.support.wearable.view.BoxInsetLayout</strong>
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ <strong>android:background="@drawable/robot_background"</strong>
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ <strong>android:padding="15dp"</strong>>
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ <strong>android:padding="5dp"</strong>
+ <strong>app:layout_box="all"</strong>>
+
+ <TextView
+ android:gravity="center"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:text="@string/sometext"
+ android:textColor="@color/black" />
+
+ <ImageButton
+ android:background="@null"
+ android:layout_gravity="bottom|left"
+ android:layout_height="50dp"
+ android:layout_width="50dp"
+ android:src="@drawable/ok" />
+
+ <ImageButton
+ android:background="@null"
+ android:layout_gravity="bottom|right"
+ android:layout_height="50dp"
+ android:layout_width="50dp"
+ android:src="@drawable/cancel" />
+ </FrameLayout>
+</android.support.wearable.view.BoxInsetLayout>
+</pre>
+
+<p>Notice the parts of the layout marked in bold:</p>
+
+<ul>
+<li>
+ <p><code>android:padding="15dp"</code></p>
+ <p>This line assigns padding to the <code>BoxInsetLayout</code> element. Because the window
+ insets on round devices are larger than 15dp, this padding only applies to square screens.</p>
+</li>
+<li>
+ <p><code>android:padding="5dp"</code></p>
+ <p>This line assigns padding to the inner <code>FrameLayout</code> element. This padding applies
+ to both square and round screens. The total padding between the buttons and the window insets
+ is 20 dp on square screens (15+5) and 5 dp on round screens.</p>
+</li>
+<li>
+ <p><code>app:layout_box="all"</code></p>
+ <p>This line ensures that the <code>FrameLayout</code> element and its children are boxed inside
+ the area defined by the window insets on round screens. This line has no effect on square
+ screens.</p>
+</li>
+</ul>
\ No newline at end of file
diff --git a/docs/html/training/wearables/ui/lists.jd b/docs/html/training/wearables/ui/lists.jd
new file mode 100644
index 0000000..5458541
--- /dev/null
+++ b/docs/html/training/wearables/ui/lists.jd
@@ -0,0 +1,304 @@
+page.title=Creating Lists
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#add-list">Add a List View</a></li>
+ <li><a href="#layout-impl">Create a Layout Implementation for List Items</a></li>
+ <li><a href="#layout-def">Create a Layout Definition for Items</a></li>
+ <li><a href="#adapter">Create an Adapter to Populate the List</a></li>
+ <li><a href="#adapter-listener">Associate the Adapter and Set a Click Listener</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}design/wear/index.html">Android Wear Design Principles</a></li>
+</ul>
+</div>
+</div>
+
+
+<p>Lists let users select an item from a set of choices easily on wearable devices. This lesson
+shows you how to create lists in your Android Wear apps.</p>
+
+<p>The Wearable UI Library includes the <code>WearableListView</code> class, which is a list
+implementation optimized for wearable devices..</p>
+
+<p class="note"><strong>Note:</strong> The <em>Notifications</em> sample in the Android SDK
+demonstrates how to use <code>WearableListView</code> in your apps. This sample is located in
+the <code>android-sdk/samples/android-20/wearable/Notifications</code> directory.</p>
+
+<p>To create a list in your Android Wear apps:</p>
+
+<ol>
+<li>Add a <code>WearableListView</code> element to your activity's layout definition.</li>
+<li>Create a custom layout implementation for your list items.</li>
+<li>Use this implementation to create a layout definition file for your list items.</li>
+<div style="float:right;margin-left:25px;width:215px;margin-top:-20px">
+<img src="{@docRoot}wear/images/06_uilib.png" width="200" height="200" alt=""/>
+<p class="img-caption" style="text-align:center"><strong>Figure 3:</strong>
+A list view on Android Wear.</p>
+</div>
+<li>Create an adapter to populate the list.</li>
+<li>Assign the adapter to the <code>WearableListView</code> element.</li>
+</ol>
+
+<p>These steps are described in detail in the following sections.</p>
+
+
+<h2 id="add-list">Add a List View</h2>
+
+<p>The following layout adds a list view to an activity using a <code>BoxInsetLayout</code>, so
+the list is displayed properly on both round and square devices:</p>
+
+<pre>
+<android.support.wearable.view.BoxInsetLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:background="@drawable/robot_background"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent">
+
+ <FrameLayout
+ android:id="@+id/frame_layout"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ app:layout_box="left|bottom|right">
+
+ <<strong>android.support.wearable.view.WearableListView</strong>
+ android:id="@+id/wearable_list"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent">
+ </android.support.wearable.view.WearableListView>
+ </FrameLayout>
+</android.support.wearable.view.BoxInsetLayout>
+</pre>
+
+
+<h2 id="layout-impl">Create a Layout Implementation for List Items</h2>
+
+<p>In many cases, each list item consists of an icon and a description. The
+<em>Notifications</em> sample from the Android SDK implements a custom layout that extends
+{@link android.widget.LinearLayout} to incorporate these two elements inside each list item.
+This layout also implements the methods in the <code>WearableListView.Item</code> interface
+to animate the item's icon and fade the text in response to events from
+<code>WearableListView</code> as the user scrolls through the list.</p>
+
+<pre>
+public class WearableListItemLayout extends LinearLayout
+ implements WearableListView.Item {
+
+ private final float mFadedTextAlpha;
+ private final int mFadedCircleColor;
+ private final int mChosenCircleColor;
+ private ImageView mCircle;
+ private float mScale;
+ private TextView mName;
+
+ public WearableListItemLayout(Context context) {
+ this(context, null);
+ }
+
+ public WearableListItemLayout(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public WearableListItemLayout(Context context, AttributeSet attrs,
+ int defStyle) {
+ super(context, attrs, defStyle);
+ mFadedTextAlpha = getResources()
+ .getInteger(R.integer.action_text_faded_alpha) / 100f;
+ mFadedCircleColor = getResources().getColor(R.color.grey);
+ mChosenCircleColor = getResources().getColor(R.color.blue);
+ }
+
+ // Get references to the icon and text in the item layout definition
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ // These are defined in the layout file for list items
+ // (see next section)
+ mCircle = (ImageView) findViewById(R.id.circle);
+ mName = (TextView) findViewById(R.id.name);
+ }
+
+ // Provide scaling values for WearableListView animations
+ @Override
+ public float getProximityMinValue() {
+ return 1f;
+ }
+
+ @Override
+ public float getProximityMaxValue() {
+ return 1.6f;
+ }
+
+ @Override
+ public float getCurrentProximityValue() {
+ return mScale;
+ }
+
+ // Scale the icon for WearableListView animations
+ @Override
+ public void setScalingAnimatorValue(float scale) {
+ mScale = scale;
+ mCircle.setScaleX(scale);
+ mCircle.setScaleY(scale);
+ }
+
+ // Change color of the icon, remove fading from the text
+ @Override
+ public void onScaleUpStart() {
+ mName.setAlpha(1f);
+ ((GradientDrawable) mCircle.getDrawable()).setColor(mChosenCircleColor);
+ }
+
+ // Change the color of the icon, fade the text
+ @Override
+ public void onScaleDownStart() {
+ ((GradientDrawable) mCircle.getDrawable()).setColor(mFadedCircleColor);
+ mName.setAlpha(mFadedTextAlpha);
+ }
+}
+</pre>
+
+
+<h2 id="layout-def">Create a Layout Definition for Items</h2>
+
+<p>After you implement a custom layout for list items, you provide a layout definition file that
+specifies the layout parameters of each of the components inside a list item. The following layout
+definition uses the custom layout implementation from the previous section and defines an icon
+and a text view whose IDs match those in the layout implementation class:</p>
+
+<pre>
+<-- res/layout/list_item.xml -->
+<com.example.android.support.wearable.notifications.WearableListItemLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:gravity="center_vertical"
+ android:layout_width="match_parent"
+ android:layout_height="80dp">
+ <ImageView
+ android:id="@+id/circle"
+ android:layout_height="20dp"
+ android:layout_margin="16dp"
+ android:layout_width="20dp"
+ android:src="@drawable/wl_circle"/>
+ <TextView
+ android:id="@+id/name"
+ android:gravity="center_vertical|left"
+ android:layout_width="wrap_content"
+ android:layout_marginRight="16dp"
+ android:layout_height="match_parent"
+ android:fontFamily="sans-serif-condensed-light"
+ android:lineSpacingExtra="-4sp"
+ android:textColor="@color/text_color"
+ android:textSize="16sp"/>
+</com.example.android.support.wearable.notifications.WearableListItemLayout>
+</pre>
+
+
+<h2 id="adapter">Create an Adapter to Populate the List</h2>
+
+<p>The adapter populates the <code>WearableListView</code> with content. The following simple
+adapter populates the list with elements based on an array of strings:</p>
+
+<pre>
+private static final class Adapter extends WearableListView.Adapter {
+ private String[] mDataset;
+ private final Context mContext;
+ private final LayoutInflater mInflater;
+
+ // Provide a suitable constructor (depends on the kind of dataset)
+ public Adapter(Context context, String[] dataset) {
+ mContext = context;
+ mInflater = LayoutInflater.from(context);
+ mDataset = dataset;
+ }
+
+ // Provide a reference to the type of views you're using
+ public static class ItemViewHolder extends WearableListView.ViewHolder {
+ private TextView textView;
+ public ItemViewHolder(View itemView) {
+ super(itemView);
+ // find the text view within the custom item's layout
+ textView = (TextView) itemView.findViewById(R.id.name);
+ }
+ }
+
+ // Create new views for list items
+ // (invoked by the WearableListView's layout manager)
+ @Override
+ public WearableListView.ViewHolder onCreateViewHolder(ViewGroup parent,
+ int viewType) {
+ // Inflate our custom layout for list items
+ return new ItemViewHolder(mInflater.inflate(R.layout.list_item, null));
+ }
+
+ // Replace the contents of a list item
+ // Instead of creating new views, the list tries to recycle existing ones
+ // (invoked by the WearableListView's layout manager)
+ @Override
+ public void onBindViewHolder(WearableListView.ViewHolder holder,
+ int position) {
+ // retrieve the text view
+ ItemViewHolder itemHolder = (ItemViewHolder) holder;
+ TextView view = itemHolder.textView;
+ // replace text contents
+ view.setText(mDataset[position]);
+ // replace list item's metadata
+ holder.itemView.setTag(position);
+ }
+
+ // Return the size of your dataset
+ // (invoked by the WearableListView's layout manager)
+ @Override
+ public int getItemCount() {
+ return mDataset.length;
+ }
+}
+</pre>
+
+
+<h2 id="adapter-listener">Associate the Adapter and Set a Click Listener</h2>
+
+<p>In your activity, obtain a reference to the <code>WearableListView</code> element from
+your layout, assign an instance of the adapter to populate the list, and set a click listener
+to complete an action when the user selects a particular list item.</p>
+
+<pre>
+public class WearActivity extends Activity
+ implements WearableListView.ClickListener {
+
+ // Sample dataset for the list
+ String[] elements = { "List Item 1", "List Item 2", ... };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.my_list_activity);
+
+ // Get the list component from the layout of the activity
+ WearableListView listView =
+ (WearableListView) findViewById(R.id.wearable_list);
+
+ // Assign an adapter to the list
+ listView.setAdapter(new Adapter(this, elements));
+
+ // Set a click listener
+ listView.setClickListener(this);
+ }
+
+ // WearableListView click listener
+ @Override
+ public void onClick(WearableListView.ViewHolder v) {
+ Integer tag = (Integer) v.itemView.getTag();
+ // use this data to complete some action ...
+ }
+
+ @Override
+ public void onTopEmptyRegionClick() {
+ }
+}
+</pre>
diff --git a/docs/html/wear/images/01_uilib.png b/docs/html/wear/images/01_uilib.png
new file mode 100644
index 0000000..14484d6
--- /dev/null
+++ b/docs/html/wear/images/01_uilib.png
Binary files differ
diff --git a/docs/html/wear/images/02_uilib.png b/docs/html/wear/images/02_uilib.png
new file mode 100644
index 0000000..39896a1
--- /dev/null
+++ b/docs/html/wear/images/02_uilib.png
Binary files differ
diff --git a/docs/html/wear/images/03_uilib.png b/docs/html/wear/images/03_uilib.png
new file mode 100644
index 0000000..ebf635d
--- /dev/null
+++ b/docs/html/wear/images/03_uilib.png
Binary files differ
diff --git a/docs/html/wear/images/04_uilib.png b/docs/html/wear/images/04_uilib.png
new file mode 100644
index 0000000..e5a29a0
--- /dev/null
+++ b/docs/html/wear/images/04_uilib.png
Binary files differ
diff --git a/docs/html/wear/images/05_uilib.png b/docs/html/wear/images/05_uilib.png
new file mode 100644
index 0000000..25d2e34
--- /dev/null
+++ b/docs/html/wear/images/05_uilib.png
Binary files differ
diff --git a/docs/html/wear/images/06_uilib.png b/docs/html/wear/images/06_uilib.png
new file mode 100644
index 0000000..257bb82
--- /dev/null
+++ b/docs/html/wear/images/06_uilib.png
Binary files differ
diff --git a/docs/html/wear/images/07_uilib.png b/docs/html/wear/images/07_uilib.png
new file mode 100644
index 0000000..ce1a80c
--- /dev/null
+++ b/docs/html/wear/images/07_uilib.png
Binary files differ
diff --git a/docs/html/wear/images/08_uilib.png b/docs/html/wear/images/08_uilib.png
new file mode 100644
index 0000000..b44522b
--- /dev/null
+++ b/docs/html/wear/images/08_uilib.png
Binary files differ
diff --git a/docs/html/wear/images/09_uilib.png b/docs/html/wear/images/09_uilib.png
new file mode 100644
index 0000000..f8234e1
--- /dev/null
+++ b/docs/html/wear/images/09_uilib.png
Binary files differ
diff --git a/location/java/android/location/package.html b/location/java/android/location/package.html
index 81fcea4..2355e72 100644
--- a/location/java/android/location/package.html
+++ b/location/java/android/location/package.html
@@ -1,22 +1,20 @@
<html>
<body>
-<p>Contains the framework API classes that define Android location-based and related services.</p>
-<p class="note">
- <strong>Note:</strong> The Google Location Services API, part of Google Play
- Services, provides a more powerful, high-level framework that automates tasks such as
- location provider choice and power management. Location Services also provides new
- features such as activity detection that aren't available in the framework API. Developers who
- are using the framework API, as well as developers who are just now adding location-awareness
- to their apps, should strongly consider using the Location Services API.
-<br/>
- To learn more about the Location Services API, see
- <a href="{@docRoot}google/play-services/location.html">Location APIs</a>.
+<p>Contains the framework API classes that define Android location-based and
+ related services.</p>
+<p class="warning">
+<strong>This API is not the recommended method for accessing Android location.</strong><br>
+The
+<a href="{@docRoot}reference/com/google/android/gms/location/package-summary.html">Google Location Services API</a>,
+part of Google Play services, is the preferred way to add location-awareness to
+your app. It offers a simpler API, higher accuracy, low-power geofencing, and
+more. If you are currently using the android.location API, you are strongly
+encouraged to switch to the Google Location Services API as soon as
+possible.
+<br><br>
+To learn more about the Google Location Services API, see the
+<a href="{@docRoot}google/play-services/location.html">Location API overview</a>.
</p>
-
-<p>For more information about the framework API, see the
-<a href="{@docRoot}guide/topics/location/index.html">Location and Maps</a> guide.</p>
-{@more}
-
</body>
</html>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index 9984fca..ce99cc3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -66,7 +66,8 @@
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
- state.visible = mController.isHotspotSupported() && mUsageTracker.isRecentlyUsed();
+ state.visible = mController.isHotspotSupported() && mUsageTracker.isRecentlyUsed()
+ && !mController.isProvisioningNeeded();
state.label = mContext.getString(R.string.quick_settings_hotspot_label);
state.value = mController.isHotspotEnabled();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java
index 7ca91a5..0863c86 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java
@@ -22,6 +22,7 @@
boolean isHotspotEnabled();
boolean isHotspotSupported();
void setHotspotEnabled(boolean enabled);
+ boolean isProvisioningNeeded();
public interface Callback {
void onHotspotChanged(boolean enabled);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
index dd706bb9..63c1100 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -24,6 +24,7 @@
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
@@ -74,6 +75,20 @@
}
@Override
+ public boolean isProvisioningNeeded() {
+ // Keep in sync with other usage of config_mobile_hotspot_provision_app.
+ // TetherSettings#isProvisioningNeeded and
+ // ConnectivityManager#enforceTetherChangePermission
+ String[] provisionApp = mContext.getResources().getStringArray(
+ com.android.internal.R.array.config_mobile_hotspot_provision_app);
+ if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)
+ || provisionApp == null) {
+ return false;
+ }
+ return (provisionApp.length == 2);
+ }
+
+ @Override
public void setHotspotEnabled(boolean enabled) {
final ContentResolver cr = mContext.getContentResolver();
// This needs to be kept up to date with Settings (WifiApEnabler.setSoftapEnabled)
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 86cfdb9..fca13f8 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -2207,9 +2207,15 @@
private List<ResolveInfo> queryIntentReceivers(Intent intent, int userId) {
final long identity = Binder.clearCallingIdentity();
try {
+ int flags = PackageManager.GET_META_DATA;
+
+ // Widgets referencing shared libraries need to have their
+ // dependencies loaded.
+ flags |= PackageManager.GET_SHARED_LIBRARY_FILES;
+
return mPackageManager.queryIntentReceivers(intent,
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
- PackageManager.GET_META_DATA, userId);
+ flags, userId);
} catch (RemoteException re) {
return Collections.emptyList();
} finally {
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index a71161a..f934963 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -81,6 +81,13 @@
public static final int STATE_CONNECTING = 9;
/**
+ * The state of a {@code Call} when the user has initiated a disconnection of the call, but the
+ * call has not yet been disconnected by the underlying {@code ConnectionService}. The next
+ * state of the call is (potentially) {@link #STATE_DISCONNECTED}.
+ */
+ public static final int STATE_DISCONNECTING = 10;
+
+ /**
* The key to retrieve the optional {@code PhoneAccount}s Telecom can bundle with its Call
* extras. Used to pass the phone accounts to display on the front end to the user in order to
* select phone accounts to (for example) place a call.
@@ -828,6 +835,8 @@
return STATE_DISCONNECTED;
case CallState.ABORTED:
return STATE_DISCONNECTED;
+ case CallState.DISCONNECTING:
+ return STATE_DISCONNECTING;
default:
Log.wtf(this, "Unrecognized CallState %s", parcelableCallState);
return STATE_NEW;
diff --git a/telecomm/java/android/telecom/CallState.java b/telecomm/java/android/telecom/CallState.java
index 7690847..bd9223a 100644
--- a/telecomm/java/android/telecom/CallState.java
+++ b/telecomm/java/android/telecom/CallState.java
@@ -100,6 +100,16 @@
*/
public static final int ABORTED = 8;
+ /**
+ * Indicates that the call is in the process of being disconnected and will transition next
+ * to a {@link #DISCONNECTED} state.
+ * <p>
+ * This state is not expected to be communicated from the Telephony layer, but will be reported
+ * to the InCall UI for calls where disconnection has been initiated by the user but the
+ * ConnectionService has confirmed the call as disconnected.
+ */
+ public static final int DISCONNECTING = 9;
+
public static String toString(int callState) {
switch (callState) {
case NEW:
@@ -120,6 +130,8 @@
return "DISCONNECTED";
case ABORTED:
return "ABORTED";
+ case DISCONNECTING:
+ return "DISCONNECTING";
default:
return "UNKNOWN";
}
diff --git a/tests/SharedLibrary/client/AndroidManifest.xml b/tests/SharedLibrary/client/AndroidManifest.xml
index a39c754..d1167fa 100644
--- a/tests/SharedLibrary/client/AndroidManifest.xml
+++ b/tests/SharedLibrary/client/AndroidManifest.xml
@@ -25,5 +25,13 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
+
+ <receiver android:name="DependentAppwidgetProvider">
+ <intent-filter>
+ <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+ </intent-filter>
+ <meta-data android:name="android.appwidget.provider"
+ android:resource="@xml/dependent_appwidget_info" />
+ </receiver>
</application>
</manifest>
diff --git a/tests/SharedLibrary/client/res/layout/dependent_appwidget.xml b/tests/SharedLibrary/client/res/layout/dependent_appwidget.xml
new file mode 100644
index 0000000..13beafa
--- /dev/null
+++ b/tests/SharedLibrary/client/res/layout/dependent_appwidget.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView android:id="@+id/label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@com.google.android.test.shared_library:string/shared_string"
+ style="@com.google.android.test.shared_library:style/CodeFont"/>
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@com.google.android.test.shared_library:drawable/size_48x48"/>
+</LinearLayout>
diff --git a/tests/SharedLibrary/client/res/xml/dependent_appwidget_info.xml b/tests/SharedLibrary/client/res/xml/dependent_appwidget_info.xml
new file mode 100644
index 0000000..452e010
--- /dev/null
+++ b/tests/SharedLibrary/client/res/xml/dependent_appwidget_info.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
+ android:minWidth="40dp"
+ android:minHeight="40dp"
+ android:updatePeriodMillis="0"
+ android:initialLayout="@layout/dependent_appwidget"
+ android:resizeMode="horizontal|vertical" />
diff --git a/tests/SharedLibrary/client/src/com/google/android/test/lib_client/DependentAppwidgetProvider.java b/tests/SharedLibrary/client/src/com/google/android/test/lib_client/DependentAppwidgetProvider.java
new file mode 100644
index 0000000..4e9b26b
--- /dev/null
+++ b/tests/SharedLibrary/client/src/com/google/android/test/lib_client/DependentAppwidgetProvider.java
@@ -0,0 +1,29 @@
+/*
+ * 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.google.android.test.lib_client;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class DependentAppwidgetProvider extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+
+ }
+}
diff --git a/tests/SharedLibrary/lib/res/values/public.xml b/tests/SharedLibrary/lib/res/values/public.xml
index 37b1ec9..23d307e 100644
--- a/tests/SharedLibrary/lib/res/values/public.xml
+++ b/tests/SharedLibrary/lib/res/values/public.xml
@@ -13,5 +13,7 @@
<public type="attr" name="zip" id="0x00010005" />
<public type="attr" name="country" id="0x00010006" />
+ <public type="drawable" name="size_48x48" id="0x00030000" />
+
<public type="array" name="animals" id="0x02050000" />
</resources>