Adds simple complication sample from I/O code lab (w/o use of Oli's library)
for public release after code lab.

Change-Id: I19ec97231800d362701b2f45bd0a0d7f39770875
diff --git a/wearable/wear/WatchFace/Wearable/src/main/AndroidManifest.xml b/wearable/wear/WatchFace/Wearable/src/main/AndroidManifest.xml
index 88bb033..a922297 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/AndroidManifest.xml
+++ b/wearable/wear/WatchFace/Wearable/src/main/AndroidManifest.xml
@@ -132,6 +132,42 @@
                 <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
             </intent-filter>
         </service>
+
+        <service
+            android:name=".ComplicationSimpleWatchFaceService"
+            android:enabled="true"
+            android:label="@string/complication_simple"
+            android:permission="android.permission.BIND_WALLPAPER">
+            <meta-data
+                android:name="android.service.wallpaper"
+                android:resource="@xml/watch_face"/>
+            <meta-data
+                android:name="com.google.android.wearable.watchface.preview"
+                android:resource="@drawable/preview_complication_simple"/>
+            <meta-data
+                android:name="com.google.android.wearable.watchface.preview_circular"
+                android:resource="@drawable/preview_complication_simple"/>
+            <meta-data
+                android:name="com.google.android.wearable.watchface.wearableConfigurationAction"
+                android:value="com.example.android.wearable.watchface.CONFIG_COMPLICATION_SIMPLE"/>
+
+            <intent-filter>
+                <action android:name="android.service.wallpaper.WallpaperService"/>
+
+                <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE"/>
+            </intent-filter>
+        </service>
+        <activity
+            android:name=".ComplicationSimpleConfigActivity"
+            android:label="@string/complication_simple">
+            <intent-filter>
+                <action android:name="com.example.android.wearable.watchface.CONFIG_COMPLICATION_SIMPLE"/>
+
+                <category android:name="com.google.android.wearable.watchface.category.WEARABLE_CONFIGURATION"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+            </intent-filter>
+        </activity>
+
         <service
             android:name=".InteractiveWatchFaceService"
             android:label="@string/interactive_name"
@@ -270,6 +306,35 @@
             android:name=".CalendarWatchFacePermissionActivity"
             android:label="@string/title_activity_calendar_watch_face_permission" >
         </activity>
+
+        <service
+            android:name=".provider.RandomNumberProviderService"
+            android:label="@string/complications_provider_random_number"
+            android:icon="@drawable/ic_launcher">
+
+            <intent-filter>
+                <action android:name="android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST"/>
+            </intent-filter>
+
+            <meta-data
+                android:name="android.support.wearable.complications.SUPPORTED_TYPES"
+                android:value="RANGED_VALUE,SHORT_TEXT,LONG_TEXT"/>
+            <!--
+            When your complication data provider is active, UPDATE_PERIOD_SECONDS specifies how
+            often you want the system to check for updates to the data. In this case, the time is
+            specified to a relatively short 120 seconds, so we can observe the result of this code
+            lab. In everyday use, developers should consider intervals in the order of minutes.
+            Also, remember that this is only a guidance for the system. Android Wear may update less
+            frequently.
+
+            If your app needs to push updates instead of updating on a regular schedule, you should
+            set this value to 0 and use ProviderUpdateRequester.requestUpdate() to trigger an update
+            request when you need one.
+            -->
+            <meta-data
+                android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS"
+                android:value="120"/>
+        </service>
     </application>
 
 </manifest>
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/ComplicationSimpleConfigActivity.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/ComplicationSimpleConfigActivity.java
new file mode 100644
index 0000000..66e208c
--- /dev/null
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/ComplicationSimpleConfigActivity.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.wearable.watchface;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.support.wearable.complications.ProviderChooserIntent;
+import android.support.wearable.view.WearableListView;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The watch-side config activity for {@link ComplicationSimpleWatchFaceService}, which
+ * allows for setting complications on the left and right of watch face.
+ */
+public class ComplicationSimpleConfigActivity extends Activity implements
+        WearableListView.ClickListener {
+
+    private static final String TAG = "CompSimpleConfig";
+
+    private static final int PROVIDER_CHOOSER_REQUEST_CODE = 1;
+
+    private WearableListView mWearableConfigListView;
+    private ConfigurationAdapter mAdapter;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_complication_simple_config);
+
+        mAdapter = new ConfigurationAdapter(getApplicationContext(), getComplicationItems());
+
+        mWearableConfigListView = (WearableListView) findViewById(R.id.wearable_list);
+        mWearableConfigListView.setAdapter(mAdapter);
+        mWearableConfigListView.setClickListener(this);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == PROVIDER_CHOOSER_REQUEST_CODE
+                && resultCode == RESULT_OK) {
+            finish();
+        }
+    }
+
+    @Override
+    public void onClick(WearableListView.ViewHolder viewHolder) {
+        if (Log.isLoggable(TAG, Log.DEBUG)) {
+            Log.d(TAG, "onClick()");
+        }
+
+        Integer tag = (Integer) viewHolder.itemView.getTag();
+        ComplicationItem complicationItem = mAdapter.getItem(tag);
+
+        startActivityForResult(ProviderChooserIntent.createProviderChooserIntent(
+                complicationItem.watchFace,
+                complicationItem.complicationId,
+                complicationItem.supportedTypes), PROVIDER_CHOOSER_REQUEST_CODE);
+    }
+
+    private List<ComplicationItem> getComplicationItems() {
+        ComponentName watchFace = new ComponentName(
+                getApplicationContext(), ComplicationSimpleWatchFaceService.class);
+
+        String[] complicationNames =
+                getResources().getStringArray(R.array.complication_simple_names);
+
+        int[] complicationIds = ComplicationSimpleWatchFaceService.COMPLICATION_IDS;
+
+        TypedArray icons = getResources().obtainTypedArray(R.array.complication_simple_icons);
+
+        List<ComplicationItem> items = new ArrayList<>();
+        for (int i = 0; i < complicationIds.length; i++) {
+            items.add(new ComplicationItem(watchFace,
+                    complicationIds[i],
+                    ComplicationSimpleWatchFaceService.COMPLICATION_SUPPORTED_TYPES[i],
+                    icons.getDrawable(i),
+                    complicationNames[i]));
+        }
+        return items;
+    }
+
+    @Override
+    public void onTopEmptyRegionClick() {
+        if (Log.isLoggable(TAG, Log.DEBUG)) {
+            Log.d(TAG, "onTopEmptyRegionClick()");
+        }
+    }
+
+    /*
+     * Inner class representing items of the ConfigurationAdapter (WearableListView.Adapter) class.
+     */
+    private final class ComplicationItem {
+        ComponentName watchFace;
+        int complicationId;
+        int[] supportedTypes;
+        Drawable icon;
+        String title;
+
+        public ComplicationItem(ComponentName watchFace, int complicationId, int[] supportedTypes,
+                                Drawable icon, String title) {
+            this.watchFace = watchFace;
+            this.complicationId = complicationId;
+            this.supportedTypes = supportedTypes;
+            this.icon = icon;
+            this.title = title;
+        }
+    }
+
+    private static class ConfigurationAdapter extends WearableListView.Adapter {
+
+        private Context mContext;
+        private final LayoutInflater mInflater;
+        private List<ComplicationItem> mItems;
+
+
+        public ConfigurationAdapter (Context context, List<ComplicationItem> items) {
+            mContext = context;
+            mInflater = LayoutInflater.from(mContext);
+            mItems = items;
+        }
+
+        // Provides a reference to the type of views you're using
+        public static class ItemViewHolder extends WearableListView.ViewHolder {
+            private ImageView iconImageView;
+            private TextView textView;
+            public ItemViewHolder(View itemView) {
+                super(itemView);
+                iconImageView = (ImageView) itemView.findViewById(R.id.icon);
+                textView = (TextView) itemView.findViewById(R.id.name);
+            }
+        }
+
+        @Override
+        public WearableListView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+
+            // Inflate custom layout for list items.
+            return new ItemViewHolder(
+                    mInflater.inflate(R.layout.activity_complication_simple_list_item, null));
+        }
+
+        @Override
+        public void onBindViewHolder(WearableListView.ViewHolder holder, int position) {
+
+            ItemViewHolder itemHolder = (ItemViewHolder) holder;
+
+            ImageView imageView = itemHolder.iconImageView;
+            imageView.setImageDrawable(mItems.get(position).icon);
+
+            TextView textView = itemHolder.textView;
+            textView.setText(mItems.get(position).title);
+
+            holder.itemView.setTag(position);
+        }
+
+        @Override
+        public int getItemCount() {
+            return mItems.size();
+        }
+
+        public ComplicationItem getItem(int position) {
+            return mItems.get(position);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/ComplicationSimpleWatchFaceService.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/ComplicationSimpleWatchFaceService.java
new file mode 100644
index 0000000..9eca2c3
--- /dev/null
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/ComplicationSimpleWatchFaceService.java
@@ -0,0 +1,744 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.wearable.watchface;
+
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.support.v7.graphics.Palette;
+import android.support.wearable.complications.ComplicationData;
+import android.support.wearable.complications.ComplicationText;
+import android.support.wearable.watchface.CanvasWatchFaceService;
+import android.support.wearable.watchface.WatchFaceService;
+import android.support.wearable.watchface.WatchFaceStyle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.SurfaceHolder;
+
+import java.util.Calendar;
+import java.util.TimeZone;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Demonstrates two simple complications in a watch face.
+ */
+public class ComplicationSimpleWatchFaceService extends CanvasWatchFaceService {
+    private static final String TAG = "SimpleComplicationWF";
+
+    // Unique IDs for each complication.
+    private static final int LEFT_DIAL_COMPLICATION = 0;
+    private static final int RIGHT_DIAL_COMPLICATION = 1;
+
+    // Left and right complication IDs as array for Complication API.
+    public static final int[] COMPLICATION_IDS = {LEFT_DIAL_COMPLICATION, RIGHT_DIAL_COMPLICATION};
+
+    // Left and right dial supported types.
+    public static final int[][] COMPLICATION_SUPPORTED_TYPES = {
+            {ComplicationData.TYPE_SHORT_TEXT},
+            {ComplicationData.TYPE_SHORT_TEXT}
+    };
+
+    /*
+     * Update rate in milliseconds for interactive mode. We update once a second to advance the
+     * second hand.
+     */
+    private static final long INTERACTIVE_UPDATE_RATE_MS = TimeUnit.SECONDS.toMillis(1);
+
+    @Override
+    public Engine onCreateEngine() {
+        return new Engine();
+    }
+
+    private class Engine extends CanvasWatchFaceService.Engine {
+        private static final int MSG_UPDATE_TIME = 0;
+
+        private static final float COMPLICATION_TEXT_SIZE = 38f;
+        private static final int COMPLICATION_TAP_BUFFER = 40;
+
+        private static final float HOUR_STROKE_WIDTH = 5f;
+        private static final float MINUTE_STROKE_WIDTH = 3f;
+        private static final float SECOND_TICK_STROKE_WIDTH = 2f;
+
+        private static final float CENTER_GAP_AND_CIRCLE_RADIUS = 4f;
+
+        private static final int SHADOW_RADIUS = 6;
+
+        private Calendar mCalendar;
+        private boolean mRegisteredTimeZoneReceiver = false;
+        private boolean mMuteMode;
+
+        private int mWidth;
+        private int mHeight;
+        private float mCenterX;
+        private float mCenterY;
+
+        private float mSecondHandLength;
+        private float mMinuteHandLength;
+        private float mHourHandLength;
+
+        // Colors for all hands (hour, minute, seconds, ticks) based on photo loaded.
+        private int mWatchHandColor;
+        private int mWatchHandHighlightColor;
+        private int mWatchHandShadowColor;
+
+        private Paint mHourPaint;
+        private Paint mMinutePaint;
+        private Paint mSecondPaint;
+        private Paint mTickAndCirclePaint;
+
+        private Paint mBackgroundPaint;
+        private Bitmap mBackgroundBitmap;
+        private Bitmap mGrayBackgroundBitmap;
+
+        // Variables for painting Complications
+        private Paint mComplicationPaint;
+
+        /* To properly place each complication, we need their x and y coordinates. While the width
+         * may change from moment to moment based on the time, the height will not change, so we
+         * store it as a local variable and only calculate it only when the surface changes
+         * (onSurfaceChanged()).
+         */
+        private int mComplicationsY;
+
+        /* Maps active complication ids to the data for that complication. Note: Data will only be
+         * present if the user has chosen a provider via the settings activity for the watch face.
+         */
+        private SparseArray<ComplicationData> mActiveComplicationDataSparseArray;
+
+        private boolean mAmbient;
+        private boolean mLowBitAmbient;
+        private boolean mBurnInProtection;
+
+        private Rect mPeekCardBounds = new Rect();
+
+        private final BroadcastReceiver mTimeZoneReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                mCalendar.setTimeZone(TimeZone.getDefault());
+                invalidate();
+            }
+        };
+
+        // Handler to update the time once a second in interactive mode.
+        private final Handler mUpdateTimeHandler = new Handler() {
+            @Override
+            public void handleMessage(Message message) {
+
+                if (Log.isLoggable(TAG, Log.DEBUG)) {
+                    Log.d(TAG, "updating time");
+                }
+                invalidate();
+                if (shouldTimerBeRunning()) {
+                    long timeMs = System.currentTimeMillis();
+                    long delayMs = INTERACTIVE_UPDATE_RATE_MS
+                            - (timeMs % INTERACTIVE_UPDATE_RATE_MS);
+                    mUpdateTimeHandler.sendEmptyMessageDelayed(MSG_UPDATE_TIME, delayMs);
+                }
+
+            }
+        };
+
+        @Override
+        public void onCreate(SurfaceHolder holder) {
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "onCreate");
+            }
+            super.onCreate(holder);
+
+            mCalendar = Calendar.getInstance();
+
+            setWatchFaceStyle(new WatchFaceStyle.Builder(ComplicationSimpleWatchFaceService.this)
+                    .setCardPeekMode(WatchFaceStyle.PEEK_MODE_SHORT)
+                    .setAcceptsTapEvents(true)
+                    .setBackgroundVisibility(WatchFaceStyle.BACKGROUND_VISIBILITY_INTERRUPTIVE)
+                    .setShowSystemUiTime(false)
+                    .build());
+
+            initializeBackground();
+            initializeComplication();
+            initializeWatchFace();
+        }
+
+        private void initializeBackground() {
+            mBackgroundPaint = new Paint();
+            mBackgroundPaint.setColor(Color.BLACK);
+            mBackgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
+        }
+
+        private void initializeComplication() {
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "initializeComplications()");
+            }
+            mActiveComplicationDataSparseArray = new SparseArray<>(COMPLICATION_IDS.length);
+
+            mComplicationPaint = new Paint();
+            mComplicationPaint.setColor(Color.WHITE);
+            mComplicationPaint.setTextSize(COMPLICATION_TEXT_SIZE);
+            mComplicationPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
+            mComplicationPaint.setAntiAlias(true);
+
+            setActiveComplications(COMPLICATION_IDS);
+        }
+
+        private void initializeWatchFace() {
+            /* Set defaults for colors */
+            mWatchHandColor = Color.WHITE;
+            mWatchHandHighlightColor = Color.RED;
+            mWatchHandShadowColor = Color.BLACK;
+
+            mHourPaint = new Paint();
+            mHourPaint.setColor(mWatchHandColor);
+            mHourPaint.setStrokeWidth(HOUR_STROKE_WIDTH);
+            mHourPaint.setAntiAlias(true);
+            mHourPaint.setStrokeCap(Paint.Cap.ROUND);
+            mHourPaint.setShadowLayer(SHADOW_RADIUS, 0, 0, mWatchHandShadowColor);
+
+            mMinutePaint = new Paint();
+            mMinutePaint.setColor(mWatchHandColor);
+            mMinutePaint.setStrokeWidth(MINUTE_STROKE_WIDTH);
+            mMinutePaint.setAntiAlias(true);
+            mMinutePaint.setStrokeCap(Paint.Cap.ROUND);
+            mMinutePaint.setShadowLayer(SHADOW_RADIUS, 0, 0, mWatchHandShadowColor);
+
+            mSecondPaint = new Paint();
+            mSecondPaint.setColor(mWatchHandHighlightColor);
+            mSecondPaint.setStrokeWidth(SECOND_TICK_STROKE_WIDTH);
+            mSecondPaint.setAntiAlias(true);
+            mSecondPaint.setStrokeCap(Paint.Cap.ROUND);
+            mSecondPaint.setShadowLayer(SHADOW_RADIUS, 0, 0, mWatchHandShadowColor);
+
+            mTickAndCirclePaint = new Paint();
+            mTickAndCirclePaint.setColor(mWatchHandColor);
+            mTickAndCirclePaint.setStrokeWidth(SECOND_TICK_STROKE_WIDTH);
+            mTickAndCirclePaint.setAntiAlias(true);
+            mTickAndCirclePaint.setStyle(Paint.Style.STROKE);
+            mTickAndCirclePaint.setShadowLayer(SHADOW_RADIUS, 0, 0, mWatchHandShadowColor);
+
+            // Asynchronous call extract colors from background image to improve watch face style.
+            Palette.from(mBackgroundBitmap).generate(
+                    new Palette.PaletteAsyncListener() {
+                        public void onGenerated(Palette palette) {
+                            /*
+                             * Sometimes, palette is unable to generate a color palette
+                             * so we need to check that we have one.
+                             */
+                            if (palette != null) {
+                                Log.d("onGenerated", palette.toString());
+                                mWatchHandColor = palette.getVibrantColor(Color.WHITE);
+                                mWatchHandShadowColor = palette.getDarkMutedColor(Color.BLACK);
+                                updateWatchHandStyle();
+                            }
+                        }
+                    });
+        }
+
+        @Override
+        public void onDestroy() {
+            mUpdateTimeHandler.removeMessages(MSG_UPDATE_TIME);
+            super.onDestroy();
+        }
+
+        @Override
+        public void onPropertiesChanged(Bundle properties) {
+            super.onPropertiesChanged(properties);
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "onPropertiesChanged: low-bit ambient = " + mLowBitAmbient);
+            }
+
+            mLowBitAmbient = properties.getBoolean(PROPERTY_LOW_BIT_AMBIENT, false);
+            mBurnInProtection = properties.getBoolean(PROPERTY_BURN_IN_PROTECTION, false);
+        }
+
+        /*
+         * Called when there is updated data for a complication id.
+         */
+        @Override
+        public void onComplicationDataUpdate(
+                int complicationId, ComplicationData complicationData) {
+            Log.d(TAG, "onComplicationDataUpdate() id: " + complicationId);
+
+            // Adds/updates active complication data in the array.
+            mActiveComplicationDataSparseArray.put(complicationId, complicationData);
+            invalidate();
+        }
+
+        @Override
+        public void onTapCommand(int tapType, int x, int y, long eventTime) {
+            Log.d(TAG, "OnTapCommand()");
+            switch (tapType) {
+                case TAP_TYPE_TAP:
+                    int tappedComplicationId = getTappedComplicationId(x, y);
+                    if (tappedComplicationId != -1) {
+                        onComplicationTap(tappedComplicationId);
+                    }
+                    break;
+            }
+        }
+
+        /*
+         * Determines if tap inside a complication area or returns -1.
+         */
+        private int getTappedComplicationId(int x, int y) {
+            ComplicationData complicationData;
+            long currentTimeMillis = System.currentTimeMillis();
+
+            for (int i = 0; i < COMPLICATION_IDS.length; i++) {
+                complicationData = mActiveComplicationDataSparseArray.get(COMPLICATION_IDS[i]);
+
+                if ((complicationData != null)
+                        && (complicationData.isActive(currentTimeMillis))
+                        && (complicationData.getType() != ComplicationData.TYPE_NOT_CONFIGURED)
+                        && (complicationData.getType() != ComplicationData.TYPE_EMPTY)) {
+
+                    Rect complicationBoundingRect = new Rect(0, 0, 0, 0);
+
+                    switch (COMPLICATION_IDS[i]) {
+                        case LEFT_DIAL_COMPLICATION:
+                            complicationBoundingRect.set(
+                                    0,                                          // left
+                                    mComplicationsY - COMPLICATION_TAP_BUFFER,  // top
+                                    (mWidth / 2),                               // right
+                                    ((int) COMPLICATION_TEXT_SIZE               // bottom
+                                            + mComplicationsY
+                                            + COMPLICATION_TAP_BUFFER));
+                            break;
+
+                        case RIGHT_DIAL_COMPLICATION:
+                            complicationBoundingRect.set(
+                                    (mWidth / 2),                               // left
+                                    mComplicationsY - COMPLICATION_TAP_BUFFER,  // top
+                                    mWidth,                                     // right
+                                    ((int) COMPLICATION_TEXT_SIZE               // bottom
+                                            + mComplicationsY
+                                            + COMPLICATION_TAP_BUFFER));
+                            break;
+                    }
+
+                    if (complicationBoundingRect.width() > 0) {
+                        if (complicationBoundingRect.contains(x, y)) {
+                            return COMPLICATION_IDS[i];
+                        }
+                    } else {
+                        Log.e(TAG, "Not a recognized complication id.");
+                    }
+                }
+            }
+            return -1;
+        }
+
+        /*
+         * Fires PendingIntent associated with complication (if it has one).
+         */
+        private void onComplicationTap(int complicationId) {
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "onComplicationTap()");
+            }
+            ComplicationData complicationData =
+                    mActiveComplicationDataSparseArray.get(complicationId);
+
+            if ((complicationData != null) && (complicationData.getTapAction() != null)) {
+                try {
+                    complicationData.getTapAction().send();
+                } catch (PendingIntent.CanceledException e) {
+                    Log.e(TAG, "On complication tap action error " + e);
+                }
+                invalidate();
+            } else {
+                if (Log.isLoggable(TAG, Log.DEBUG)) {
+                    Log.d(TAG, "No PendingIntent for complication " + complicationId + ".");
+                }
+            }
+        }
+
+        @Override
+        public void onTimeTick() {
+            super.onTimeTick();
+            invalidate();
+        }
+
+        @Override
+        public void onAmbientModeChanged(boolean inAmbientMode) {
+            super.onAmbientModeChanged(inAmbientMode);
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "onAmbientModeChanged: " + inAmbientMode);
+            }
+            mAmbient = inAmbientMode;
+
+            updateWatchHandStyle();
+
+            // Updates complication style
+            mComplicationPaint.setAntiAlias(!inAmbientMode);
+
+            // Check and trigger whether or not timer should be running (only in active mode).
+            updateTimer();
+        }
+
+        private void updateWatchHandStyle(){
+            if (mAmbient){
+                mHourPaint.setColor(Color.WHITE);
+                mMinutePaint.setColor(Color.WHITE);
+                mSecondPaint.setColor(Color.WHITE);
+                mTickAndCirclePaint.setColor(Color.WHITE);
+
+                mHourPaint.setAntiAlias(false);
+                mMinutePaint.setAntiAlias(false);
+                mSecondPaint.setAntiAlias(false);
+                mTickAndCirclePaint.setAntiAlias(false);
+
+                mHourPaint.clearShadowLayer();
+                mMinutePaint.clearShadowLayer();
+                mSecondPaint.clearShadowLayer();
+                mTickAndCirclePaint.clearShadowLayer();
+
+            } else {
+                mHourPaint.setColor(mWatchHandColor);
+                mMinutePaint.setColor(mWatchHandColor);
+                mSecondPaint.setColor(mWatchHandHighlightColor);
+                mTickAndCirclePaint.setColor(mWatchHandColor);
+
+                mHourPaint.setAntiAlias(true);
+                mMinutePaint.setAntiAlias(true);
+                mSecondPaint.setAntiAlias(true);
+                mTickAndCirclePaint.setAntiAlias(true);
+
+                mHourPaint.setShadowLayer(SHADOW_RADIUS, 0, 0, mWatchHandShadowColor);
+                mMinutePaint.setShadowLayer(SHADOW_RADIUS, 0, 0, mWatchHandShadowColor);
+                mSecondPaint.setShadowLayer(SHADOW_RADIUS, 0, 0, mWatchHandShadowColor);
+                mTickAndCirclePaint.setShadowLayer(SHADOW_RADIUS, 0, 0, mWatchHandShadowColor);
+            }
+        }
+
+        @Override
+        public void onInterruptionFilterChanged(int interruptionFilter) {
+            super.onInterruptionFilterChanged(interruptionFilter);
+            boolean inMuteMode = (interruptionFilter == WatchFaceService.INTERRUPTION_FILTER_NONE);
+
+            /* Dim display in mute mode. */
+            if (mMuteMode != inMuteMode) {
+                mMuteMode = inMuteMode;
+                mHourPaint.setAlpha(inMuteMode ? 100 : 255);
+                mMinutePaint.setAlpha(inMuteMode ? 100 : 255);
+                mSecondPaint.setAlpha(inMuteMode ? 80 : 255);
+                invalidate();
+            }
+        }
+
+        @Override
+        public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+            super.onSurfaceChanged(holder, format, width, height);
+
+            // Used for complications
+            mWidth = width;
+            mHeight = height;
+
+            /*
+             * Find the coordinates of the center point on the screen, and ignore the window
+             * insets, so that, on round watches with a "chin", the watch face is centered on the
+             * entire screen, not just the usable portion.
+             */
+            mCenterX = mWidth / 2f;
+            mCenterY = mHeight / 2f;
+
+            /*
+             * Since the height of the complications text does not change, we only have to
+             * recalculate when the surface changes.
+             */
+            mComplicationsY = (int) ((mHeight / 2) + (mComplicationPaint.getTextSize() / 2));
+
+            /*
+             * Calculate lengths of different hands based on watch screen size.
+             */
+            mSecondHandLength = (float) (mCenterX * 0.875);
+            mMinuteHandLength = (float) (mCenterX * 0.75);
+            mHourHandLength = (float) (mCenterX * 0.5);
+
+
+            /* Scale loaded background image (more efficient) if surface dimensions change. */
+            float scale = ((float) width) / (float) mBackgroundBitmap.getWidth();
+
+            mBackgroundBitmap = Bitmap.createScaledBitmap(mBackgroundBitmap,
+                    (int) (mBackgroundBitmap.getWidth() * scale),
+                    (int) (mBackgroundBitmap.getHeight() * scale), true);
+
+            /*
+             * Create a gray version of the image only if it will look nice on the device in
+             * ambient mode. That means we don't want devices that support burn-in
+             * protection (slight movements in pixels, not great for images going all the way to
+             * edges) and low ambient mode (degrades image quality).
+             *
+             * Also, if your watch face will know about all images ahead of time (users aren't
+             * selecting their own photos for the watch face), it will be more
+             * efficient to create a black/white version (png, etc.) and load that when you need it.
+             */
+            if (!mBurnInProtection && !mLowBitAmbient) {
+                initGrayBackgroundBitmap();
+            }
+        }
+
+        private void initGrayBackgroundBitmap() {
+            mGrayBackgroundBitmap = Bitmap.createBitmap(
+                    mBackgroundBitmap.getWidth(),
+                    mBackgroundBitmap.getHeight(),
+                    Bitmap.Config.ARGB_8888);
+            Canvas canvas = new Canvas(mGrayBackgroundBitmap);
+            Paint grayPaint = new Paint();
+            ColorMatrix colorMatrix = new ColorMatrix();
+            colorMatrix.setSaturation(0);
+            ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrix);
+            grayPaint.setColorFilter(filter);
+            canvas.drawBitmap(mBackgroundBitmap, 0, 0, grayPaint);
+        }
+
+        @Override
+        public void onDraw(Canvas canvas, Rect bounds) {
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "onDraw");
+            }
+            long now = System.currentTimeMillis();
+            mCalendar.setTimeInMillis(now);
+
+            drawBackground(canvas);
+            drawComplications(canvas, now);
+            drawWatchFace(canvas);
+
+
+        }
+
+        private void drawBackground(Canvas canvas) {
+            if (mAmbient && (mLowBitAmbient || mBurnInProtection)) {
+                canvas.drawColor(Color.BLACK);
+            } else if (mAmbient) {
+                canvas.drawBitmap(mGrayBackgroundBitmap, 0, 0, mBackgroundPaint);
+            } else {
+                canvas.drawBitmap(mBackgroundBitmap, 0, 0, mBackgroundPaint);
+            }
+        }
+
+        private void drawComplications(Canvas canvas, long currentTimeMillis) {
+            ComplicationData complicationData;
+
+            for (int i = 0; i < COMPLICATION_IDS.length; i++) {
+
+                complicationData = mActiveComplicationDataSparseArray.get(COMPLICATION_IDS[i]);
+
+                if ((complicationData != null)
+                        && (complicationData.isActive(currentTimeMillis))
+                        && (complicationData.getType() == ComplicationData.TYPE_SHORT_TEXT)) {
+
+                    ComplicationText mainText = complicationData.getShortText();
+                    ComplicationText subText = complicationData.getShortTitle();
+
+                    CharSequence complicationMessage =
+                            mainText.getText(getApplicationContext(), currentTimeMillis);
+
+                    /* In most cases you would want the subText (Title) under the mainText (Text),
+                     * but to keep it simple for the code lab, we are concatenating them all on one
+                     * line.
+                     */
+                    if (subText != null) {
+                        complicationMessage = TextUtils.concat(
+                                complicationMessage,
+                                " ",
+                                subText.getText(getApplicationContext(), currentTimeMillis));
+                    }
+
+                    //Log.d(TAG, "Comp id: " + COMPLICATION_IDS[i] + "\t" + complicationMessage);
+                    double textWidth =
+                            mComplicationPaint.measureText(
+                                    complicationMessage,
+                                    0,
+                                    complicationMessage.length());
+
+                    int complicationsX;
+
+                    if (COMPLICATION_IDS[i] == LEFT_DIAL_COMPLICATION) {
+                        complicationsX = (int) ((mWidth / 2) - textWidth) / 2;
+                    } else {
+                        // RIGHT_DIAL_COMPLICATION calculations
+                        int offset = (int) ((mWidth / 2) - textWidth) / 2;
+                        complicationsX = (mWidth / 2) + offset;
+                    }
+
+                    canvas.drawText(
+                            complicationMessage,
+                            0,
+                            complicationMessage.length(),
+                            complicationsX,
+                            mComplicationsY,
+                            mComplicationPaint);
+                }
+            }
+        }
+
+        private void drawWatchFace(Canvas canvas) {
+            /*
+             * Draw ticks. Usually you will want to bake this directly into the photo, but in
+             * cases where you want to allow users to select their own photos, this dynamically
+             * creates them on top of the photo.
+             */
+            float innerTickRadius = mCenterX - 10;
+            float outerTickRadius = mCenterX;
+            for (int tickIndex = 0; tickIndex < 12; tickIndex++) {
+                float tickRot = (float) (tickIndex * Math.PI * 2 / 12);
+                float innerX = (float) Math.sin(tickRot) * innerTickRadius;
+                float innerY = (float) -Math.cos(tickRot) * innerTickRadius;
+                float outerX = (float) Math.sin(tickRot) * outerTickRadius;
+                float outerY = (float) -Math.cos(tickRot) * outerTickRadius;
+                canvas.drawLine(mCenterX + innerX, mCenterY + innerY,
+                        mCenterX + outerX, mCenterY + outerY, mTickAndCirclePaint);
+            }
+
+            /*
+             * These calculations reflect the rotation in degrees per unit of time, e.g.,
+             * 360 / 60 = 6 and 360 / 12 = 30.
+             */
+            final float seconds =
+                    (mCalendar.get(Calendar.SECOND) + mCalendar.get(Calendar.MILLISECOND) / 1000f);
+            final float secondsRotation = seconds * 6f;
+
+            final float minutesRotation = mCalendar.get(Calendar.MINUTE) * 6f;
+
+            final float hourHandOffset = mCalendar.get(Calendar.MINUTE) / 2f;
+            final float hoursRotation = (mCalendar.get(Calendar.HOUR) * 30) + hourHandOffset;
+
+            /*
+             * Save the canvas state before we can begin to rotate it.
+             */
+            canvas.save();
+
+            canvas.rotate(hoursRotation, mCenterX, mCenterY);
+            canvas.drawLine(
+                    mCenterX,
+                    mCenterY - CENTER_GAP_AND_CIRCLE_RADIUS,
+                    mCenterX,
+                    mCenterY - mHourHandLength,
+                    mHourPaint);
+
+            canvas.rotate(minutesRotation - hoursRotation, mCenterX, mCenterY);
+            canvas.drawLine(
+                    mCenterX,
+                    mCenterY - CENTER_GAP_AND_CIRCLE_RADIUS,
+                    mCenterX,
+                    mCenterY - mMinuteHandLength,
+                    mMinutePaint);
+
+            /*
+             * Ensure the "seconds" hand is drawn only when we are in interactive mode.
+             * Otherwise, we only update the watch face once a minute.
+             */
+            if (!mAmbient) {
+                canvas.rotate(secondsRotation - minutesRotation, mCenterX, mCenterY);
+                canvas.drawLine(
+                        mCenterX,
+                        mCenterY - CENTER_GAP_AND_CIRCLE_RADIUS,
+                        mCenterX,
+                        mCenterY - mSecondHandLength,
+                        mSecondPaint);
+
+            }
+            canvas.drawCircle(
+                    mCenterX,
+                    mCenterY,
+                    CENTER_GAP_AND_CIRCLE_RADIUS,
+                    mTickAndCirclePaint);
+
+            /* Restore the canvas' original orientation. */
+            canvas.restore();
+
+            /* Draw rectangle behind peek card in ambient mode to improve readability. */
+            if (mAmbient) {
+                canvas.drawRect(mPeekCardBounds, mBackgroundPaint);
+            }
+        }
+
+        @Override
+        public void onVisibilityChanged(boolean visible) {
+            super.onVisibilityChanged(visible);
+
+            if (visible) {
+                registerReceiver();
+                // Update time zone in case it changed while we weren't visible.
+                mCalendar.setTimeZone(TimeZone.getDefault());
+                invalidate();
+            } else {
+                unregisterReceiver();
+            }
+
+            /* Check and trigger whether or not timer should be running (only in active mode). */
+            updateTimer();
+        }
+
+        @Override
+        public void onPeekCardPositionUpdate(Rect rect) {
+            super.onPeekCardPositionUpdate(rect);
+            mPeekCardBounds.set(rect);
+        }
+
+        private void registerReceiver() {
+            if (mRegisteredTimeZoneReceiver) {
+                return;
+            }
+            mRegisteredTimeZoneReceiver = true;
+            IntentFilter filter = new IntentFilter(Intent.ACTION_TIMEZONE_CHANGED);
+            ComplicationSimpleWatchFaceService.this.registerReceiver(mTimeZoneReceiver, filter);
+        }
+
+        private void unregisterReceiver() {
+            if (!mRegisteredTimeZoneReceiver) {
+                return;
+            }
+            mRegisteredTimeZoneReceiver = false;
+            ComplicationSimpleWatchFaceService.this.unregisterReceiver(mTimeZoneReceiver);
+        }
+
+        /**
+         * Starts/stops the {@link #mUpdateTimeHandler} timer based on the state of the watch face.
+         */
+        private void updateTimer() {
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "updateTimer");
+            }
+            mUpdateTimeHandler.removeMessages(MSG_UPDATE_TIME);
+            if (shouldTimerBeRunning()) {
+                mUpdateTimeHandler.sendEmptyMessage(MSG_UPDATE_TIME);
+            }
+        }
+
+        /**
+         * Returns whether the {@link #mUpdateTimeHandler} timer should be running. The timer
+         * should only run in active mode.
+         */
+        private boolean shouldTimerBeRunning() {
+            return isVisible() && !mAmbient;
+        }
+    }
+}
\ No newline at end of file
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/provider/RandomNumberProviderService.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/provider/RandomNumberProviderService.java
new file mode 100644
index 0000000..916f90f
--- /dev/null
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/provider/RandomNumberProviderService.java
@@ -0,0 +1,96 @@
+package com.example.android.wearable.watchface.provider;
+
+import android.support.wearable.complications.ComplicationData;
+import android.support.wearable.complications.ComplicationManager;
+import android.support.wearable.complications.ComplicationProviderService;
+import android.support.wearable.complications.ComplicationText;
+import android.util.Log;
+
+import java.util.Locale;
+
+/**
+ * Example Watch Face Complication data provider provides a random number on every update.
+ */
+public class RandomNumberProviderService extends ComplicationProviderService {
+
+    private static final String TAG = "RandomNumberProvider";
+
+    /*
+     * Called when a complication has been activated. The method is for any one-time
+     * (per complication) set-up.
+     *
+     * You can continue sending data for the active complicationId until onComplicationDeactivated()
+     * is called.
+     */
+    @Override
+    public void onComplicationActivated(
+            int complicationId, int dataType, ComplicationManager complicationManager) {
+        Log.d(TAG, "onComplicationActivated(): " + complicationId);
+        super.onComplicationActivated(complicationId, dataType, complicationManager);
+    }
+
+    /*
+     * Called when the complication needs updated data from your provider. There are four scenarios
+     * when this will happen:
+     *
+     *   1. An active watch face complication is changed to use this provider
+     *   2. A complication using this provider becomes active
+     *   3. The period of time you specified in the manifest has elapsed (UPDATE_PERIOD_SECONDS)
+     *   4. You triggered an update from your own class via the
+     *       ProviderUpdateRequester.requestUpdate() method.
+     */
+    @Override
+    public void onComplicationUpdate(
+            int complicationId, int dataType, ComplicationManager complicationManager) {
+        Log.d(TAG, "onComplicationUpdate()");
+
+
+        // Retrieve your data, in this case, we simply create a random number to display.
+        int randomNumber = (int) Math.floor(Math.random() * 10);
+
+        String randomNumberText =
+                String.format(Locale.getDefault(), "%d!", randomNumber);
+
+        ComplicationData complicationData = null;
+
+        switch (dataType) {
+            case ComplicationData.TYPE_RANGED_VALUE:
+                complicationData = new ComplicationData.Builder(ComplicationData.TYPE_RANGED_VALUE)
+                        .setValue(randomNumber)
+                        .setMinValue(0)
+                        .setMaxValue(10)
+                        .setShortText(ComplicationText.plainText(randomNumberText))
+                        .build();
+                break;
+            case ComplicationData.TYPE_SHORT_TEXT:
+                complicationData = new ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT)
+                        .setShortText(ComplicationText.plainText(randomNumberText))
+                        .build();
+                break;
+            case ComplicationData.TYPE_LONG_TEXT:
+                complicationData = new ComplicationData.Builder(ComplicationData.TYPE_LONG_TEXT)
+                        .setLongText(
+                                ComplicationText.plainText("Random Number: " + randomNumberText))
+                        .build();
+                break;
+            default:
+                if (Log.isLoggable(TAG, Log.WARN)) {
+                    Log.w(TAG, "Unexpected complication type " + dataType);
+                }
+        }
+
+        if (complicationData != null) {
+            complicationManager.updateComplicationData(complicationId, complicationData);
+        }
+    }
+
+    /*
+     * Called when the complication has been deactivated. If you are updating the complication
+     * manager outside of this class with updates, you will want to update your class to stop.
+     */
+    @Override
+    public void onComplicationDeactivated(int complicationId) {
+        Log.d(TAG, "onComplicationDeactivated(): " + complicationId);
+        super.onComplicationDeactivated(complicationId);
+    }
+}
\ No newline at end of file
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_complication_simple.png b/wearable/wear/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_complication_simple.png
new file mode 100644
index 0000000..48d25ef
--- /dev/null
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_complication_simple.png
Binary files differ
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/drawable-xhdpi/complications_left_dial.png b/wearable/wear/WatchFace/Wearable/src/main/res/drawable-xhdpi/complications_left_dial.png
new file mode 100644
index 0000000..93bb31c
--- /dev/null
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/drawable-xhdpi/complications_left_dial.png
Binary files differ
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/drawable-xhdpi/complications_right_dial.png b/wearable/wear/WatchFace/Wearable/src/main/res/drawable-xhdpi/complications_right_dial.png
new file mode 100644
index 0000000..5db3c98
--- /dev/null
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/drawable-xhdpi/complications_right_dial.png
Binary files differ
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_complication_simple_config.xml b/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_complication_simple_config.xml
new file mode 100644
index 0000000..01f5cac
--- /dev/null
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_complication_simple_config.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:background="@color/dark_grey"
+    android:paddingTop="4dp">
+
+    <TextView
+        android:id="@+id/header"
+        android:layout_width="match_parent"
+        android:gravity="center"
+        android:text="@string/complication_simple_config_name"
+        android:textSize="20sp"
+        android:layout_height="wrap_content"/>
+
+    <android.support.wearable.view.WearableListView
+        android:id="@+id/wearable_list"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent">
+    </android.support.wearable.view.WearableListView>
+</LinearLayout>
\ No newline at end of file
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_complication_simple_list_item.xml b/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_complication_simple_list_item.xml
new file mode 100644
index 0000000..e995271
--- /dev/null
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_complication_simple_list_item.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="horizontal"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:layout_gravity="center">
+    <ImageView
+        android:id="@+id/icon"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"/>
+
+    <TextView
+        android:id="@+id/name"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:gravity="center"
+        android:textColor="@color/white"
+        android:textSize="18sp"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/values/arrays.xml b/wearable/wear/WatchFace/Wearable/src/main/res/values/arrays.xml
new file mode 100644
index 0000000..a2e37ac
--- /dev/null
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/values/arrays.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+    <string-array name="complication_simple_names">
+        <item>Left dial</item>
+        <item>Right dial</item>
+    </string-array>
+    <array name="complication_simple_icons">
+        <item>@drawable/complications_left_dial</item>
+        <item>@drawable/complications_right_dial</item>
+    </array>
+</resources>
\ No newline at end of file
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/values/strings.xml b/wearable/wear/WatchFace/Wearable/src/main/res/values/strings.xml
index 4090995..e4b2717 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/res/values/strings.xml
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/values/strings.xml
@@ -18,6 +18,7 @@
     <string name="opengl_name">Sample OpenGL</string>
     <string name="interactive_name">Sample Interactive</string>
     <string name="analog_name">Sample Analog</string>
+    <string name="complication_simple">Sample Complication Simple</string>
     <string name="sweep_name">Sample Sweep</string>
     <string name="card_bounds_name">Sample Card Bounds</string>
     <string name="digital_name">Sample Digital</string>
@@ -42,6 +43,9 @@
     <string name="title_activity_calendar_watch_face_permission">Calendar Permission Activity</string>
     <string name="calendar_permission_text">WatchFace requires Calendar access.</string>
 
+    <string name="complication_simple_config_name">Configuration</string>
+    <string name="complications_provider_random_number">Random Number</string>
+
     <!-- TODO: this should be shared (needs covering all the samples with Gradle build model) -->
     <string name="color_black">Black</string>
     <string name="color_blue">Blue</string>