Merge "Adding appropriate logic to check if speaker is supported on the wear device and if not, show a message to user." into mnc-docs
diff --git a/security/AsymmetricFingerprintDialog/Application/src/main/java/com/example/android/asymmetricfingerprintdialog/MainActivity.java b/security/AsymmetricFingerprintDialog/Application/src/main/java/com/example/android/asymmetricfingerprintdialog/MainActivity.java
index 5086a17..26832f2 100644
--- a/security/AsymmetricFingerprintDialog/Application/src/main/java/com/example/android/asymmetricfingerprintdialog/MainActivity.java
+++ b/security/AsymmetricFingerprintDialog/Application/src/main/java/com/example/android/asymmetricfingerprintdialog/MainActivity.java
@@ -16,12 +16,10 @@
 
 package com.example.android.asymmetricfingerprintdialog;
 
-import android.Manifest;
 import android.app.Activity;
 import android.app.KeyguardManager;
 import android.content.Intent;
 import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
 import android.hardware.fingerprint.FingerprintManager;
 import android.os.Bundle;
 import android.security.keystore.KeyGenParameterSpec;
@@ -59,8 +57,6 @@
     /** Alias for our key in the Android Key Store */
     public static final String KEY_NAME = "my_key";
 
-    private static final int FINGERPRINT_PERMISSION_REQUEST_CODE = 0;
-
     @Inject KeyguardManager mKeyguardManager;
     @Inject FingerprintManager mFingerprintManager;
     @Inject FingerprintAuthenticationDialogFragment mFragment;
@@ -74,71 +70,63 @@
         super.onCreate(savedInstanceState);
         ((InjectedApplication) getApplication()).inject(this);
 
-        requestPermissions(new String[]{Manifest.permission.USE_FINGERPRINT},
-                FINGERPRINT_PERMISSION_REQUEST_CODE);
-    }
-
-    @Override
-    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] state) {
-        if (requestCode == FINGERPRINT_PERMISSION_REQUEST_CODE
-                && state[0] == PackageManager.PERMISSION_GRANTED) {
-            setContentView(R.layout.activity_main);
-            Button purchaseButton = (Button) findViewById(R.id.purchase_button);
-            if (!mKeyguardManager.isKeyguardSecure()) {
-                // Show a message that the user hasn't set up a fingerprint or lock screen.
-                Toast.makeText(this,
-                        "Secure lock screen hasn't set up.\n"
-                                + "Go to 'Settings -> Security -> Fingerprint' to set up a fingerprint",
-                        Toast.LENGTH_LONG).show();
-                purchaseButton.setEnabled(false);
-                return;
-            }
-            if (!mFingerprintManager.hasEnrolledFingerprints()) {
-                purchaseButton.setEnabled(false);
-                // This happens when no fingerprints are registered.
-                Toast.makeText(this,
-                        "Go to 'Settings -> Security -> Fingerprint' and register at least one fingerprint",
-                        Toast.LENGTH_LONG).show();
-                return;
-            }
-            createKeyPair();
-            purchaseButton.setEnabled(true);
-            purchaseButton.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    findViewById(R.id.confirmation_message).setVisibility(View.GONE);
-                    findViewById(R.id.encrypted_message).setVisibility(View.GONE);
-
-                    // Set up the crypto object for later. The object will be authenticated by use
-                    // of the fingerprint.
-                    if (initSignature()) {
-
-                        // Show the fingerprint dialog. The user has the option to use the fingerprint with
-                        // crypto, or you can fall back to using a server-side verified password.
-                        mFragment.setCryptoObject(new FingerprintManager.CryptoObject(mSignature));
-                        boolean useFingerprintPreference = mSharedPreferences
-                                .getBoolean(getString(R.string.use_fingerprint_to_authenticate_key),
-                                        true);
-                        if (useFingerprintPreference) {
-                            mFragment.setStage(
-                                    FingerprintAuthenticationDialogFragment.Stage.FINGERPRINT);
-                        } else {
-                            mFragment.setStage(
-                                    FingerprintAuthenticationDialogFragment.Stage.PASSWORD);
-                        }
-                        mFragment.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
-                    } else {
-                        // This happens if the lock screen has been disabled or or a fingerprint got
-                        // enrolled. Thus show the dialog to authenticate with their password first
-                        // and ask the user if they want to authenticate with fingerprints in the
-                        // future
-                        mFragment.setStage(
-                                FingerprintAuthenticationDialogFragment.Stage.NEW_FINGERPRINT_ENROLLED);
-                        mFragment.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
-                    }
-                }
-            });
+        setContentView(R.layout.activity_main);
+        Button purchaseButton = (Button) findViewById(R.id.purchase_button);
+        if (!mKeyguardManager.isKeyguardSecure()) {
+            // Show a message that the user hasn't set up a fingerprint or lock screen.
+            Toast.makeText(this,
+                    "Secure lock screen hasn't set up.\n"
+                            + "Go to 'Settings -> Security -> Fingerprint' to set up a fingerprint",
+                    Toast.LENGTH_LONG).show();
+            purchaseButton.setEnabled(false);
+            return;
         }
+        //noinspection ResourceType
+        if (!mFingerprintManager.hasEnrolledFingerprints()) {
+            purchaseButton.setEnabled(false);
+            // This happens when no fingerprints are registered.
+            Toast.makeText(this,
+                    "Go to 'Settings -> Security -> Fingerprint' and register at least one fingerprint",
+                    Toast.LENGTH_LONG).show();
+            return;
+        }
+        createKeyPair();
+        purchaseButton.setEnabled(true);
+        purchaseButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                findViewById(R.id.confirmation_message).setVisibility(View.GONE);
+                findViewById(R.id.encrypted_message).setVisibility(View.GONE);
+
+                // Set up the crypto object for later. The object will be authenticated by use
+                // of the fingerprint.
+                if (initSignature()) {
+
+                    // Show the fingerprint dialog. The user has the option to use the fingerprint with
+                    // crypto, or you can fall back to using a server-side verified password.
+                    mFragment.setCryptoObject(new FingerprintManager.CryptoObject(mSignature));
+                    boolean useFingerprintPreference = mSharedPreferences
+                            .getBoolean(getString(R.string.use_fingerprint_to_authenticate_key),
+                                    true);
+                    if (useFingerprintPreference) {
+                        mFragment.setStage(
+                                FingerprintAuthenticationDialogFragment.Stage.FINGERPRINT);
+                    } else {
+                        mFragment.setStage(
+                                FingerprintAuthenticationDialogFragment.Stage.PASSWORD);
+                    }
+                    mFragment.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
+                } else {
+                    // This happens if the lock screen has been disabled or or a fingerprint got
+                    // enrolled. Thus show the dialog to authenticate with their password first
+                    // and ask the user if they want to authenticate with fingerprints in the
+                    // future
+                    mFragment.setStage(
+                            FingerprintAuthenticationDialogFragment.Stage.NEW_FINGERPRINT_ENROLLED);
+                    mFragment.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
+                }
+            }
+        });
     }
 
     /**
diff --git a/security/keystore/BasicAndroidKeyStore/Application/src/main/java/com/example/android/basicandroidkeystore/BasicAndroidKeyStoreFragment.java b/security/keystore/BasicAndroidKeyStore/Application/src/main/java/com/example/android/basicandroidkeystore/BasicAndroidKeyStoreFragment.java
index 12873e8..e6244bf 100644
--- a/security/keystore/BasicAndroidKeyStore/Application/src/main/java/com/example/android/basicandroidkeystore/BasicAndroidKeyStoreFragment.java
+++ b/security/keystore/BasicAndroidKeyStore/Application/src/main/java/com/example/android/basicandroidkeystore/BasicAndroidKeyStoreFragment.java
@@ -156,7 +156,7 @@
         // generated.
         Calendar start = new GregorianCalendar();
         Calendar end = new GregorianCalendar();
-        end.add(1, Calendar.YEAR);
+        end.add(Calendar.YEAR, 1);
         //END_INCLUDE(create_valid_dates)
 
 
@@ -316,8 +316,7 @@
         // Verify the data.
         s.initVerify(((KeyStore.PrivateKeyEntry) entry).getCertificate());
         s.update(data);
-        boolean valid = s.verify(signature);
-        return valid;
+        return s.verify(signature);
         // END_INCLUDE(verify_data)
     }
 
diff --git a/wearable/wear/WatchFace/Wearable/src/main/AndroidManifest.xml b/wearable/wear/WatchFace/Wearable/src/main/AndroidManifest.xml
index 9a3f04b..026107e 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/AndroidManifest.xml
+++ b/wearable/wear/WatchFace/Wearable/src/main/AndroidManifest.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!--
+ 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.
@@ -13,12 +14,12 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.example.android.wearable.watchface" >
+    package="com.example.android.wearable.watchface" >
 
-    <uses-sdk android:minSdkVersion="21"
-        android:targetSdkVersion="22" />
+    <uses-sdk
+        android:minSdkVersion="21"
+        android:targetSdkVersion="23" />
 
     <uses-feature android:name="android.hardware.type.watch" />
 
@@ -33,101 +34,109 @@
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
 
     <application
-            android:allowBackup="true"
-            android:icon="@drawable/ic_launcher"
-            android:label="@string/app_name" >
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name" >
+
+        <meta-data
+            android:name="com.google.android.gms.version"
+            android:value="@integer/google_play_services_version" />
+
+        <uses-library android:name="com.google.android.wearable" android:required="false" />
 
         <service
-                android:name=".AnalogWatchFaceService"
-                android:label="@string/analog_name"
-                android:permission="android.permission.BIND_WALLPAPER" >
+            android:name=".AnalogWatchFaceService"
+            android:label="@string/analog_name"
+            android:permission="android.permission.BIND_WALLPAPER" >
             <meta-data
-                    android:name="android.service.wallpaper"
-                    android:resource="@xml/watch_face" />
+                android:name="android.service.wallpaper"
+                android:resource="@xml/watch_face" />
             <meta-data
-                    android:name="com.google.android.wearable.watchface.preview"
-                    android:resource="@drawable/preview_analog" />
+                android:name="com.google.android.wearable.watchface.preview"
+                android:resource="@drawable/preview_analog" />
             <meta-data
-                    android:name="com.google.android.wearable.watchface.preview_circular"
-                    android:resource="@drawable/preview_analog_circular" />
+                android:name="com.google.android.wearable.watchface.preview_circular"
+                android:resource="@drawable/preview_analog_circular" />
             <meta-data
-                    android:name="com.google.android.wearable.watchface.companionConfigurationAction"
-                    android:value="com.example.android.wearable.watchface.CONFIG_ANALOG" />
-            <intent-filter>
-                <action android:name="android.service.wallpaper.WallpaperService" />
-                <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
-            </intent-filter>
-        </service>
-
-        <service
-                android:name=".SweepWatchFaceService"
-                android:label="@string/sweep_name"
-                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_analog" />
-            <meta-data
-                    android:name="com.google.android.wearable.watchface.preview_circular"
-                    android:resource="@drawable/preview_analog_circular" />
-            <intent-filter>
-                <action android:name="android.service.wallpaper.WallpaperService" />
-                <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
-            </intent-filter>
-        </service>
-
-        <service
-                android:name=".OpenGLWatchFaceService"
-                android:label="@string/opengl_name"
-                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_opengl" />
-            <meta-data
-                    android:name="com.google.android.wearable.watchface.preview_circular"
-                    android:resource="@drawable/preview_opengl_circular" />
-            <meta-data
-                    android:name="com.google.android.wearable.watchface.companionConfigurationAction"
-                    android:value="com.example.android.wearable.watchface.CONFIG_OPENGL" />
+                android:name="com.google.android.wearable.watchface.companionConfigurationAction"
+                android:value="com.example.android.wearable.watchface.CONFIG_ANALOG" />
 
             <intent-filter>
                 <action android:name="android.service.wallpaper.WallpaperService" />
+
                 <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
             </intent-filter>
         </service>
-
         <service
-                android:name=".CardBoundsWatchFaceService"
-                android:label="@string/card_bounds_name"
-                android:permission="android.permission.BIND_WALLPAPER" >
+            android:name=".SweepWatchFaceService"
+            android:label="@string/sweep_name"
+            android:permission="android.permission.BIND_WALLPAPER" >
             <meta-data
-                    android:name="android.service.wallpaper"
-                    android:resource="@xml/watch_face" />
+                android:name="android.service.wallpaper"
+                android:resource="@xml/watch_face" />
             <meta-data
-                    android:name="com.google.android.wearable.watchface.preview"
-                    android:resource="@drawable/preview_card_bounds" />
+                android:name="com.google.android.wearable.watchface.preview"
+                android:resource="@drawable/preview_analog" />
             <meta-data
-                    android:name="com.google.android.wearable.watchface.preview_circular"
-                    android:resource="@drawable/preview_card_bounds_circular" />
-            <meta-data
-                    android:name="com.google.android.wearable.watchface.companionConfigurationAction"
-                    android:value="com.example.android.wearable.watchface.CONFIG_CARD_BOUNDS" />
+                android:name="com.google.android.wearable.watchface.preview_circular"
+                android:resource="@drawable/preview_analog_circular" />
+
             <intent-filter>
                 <action android:name="android.service.wallpaper.WallpaperService" />
+
                 <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
             </intent-filter>
         </service>
-
-
         <service
-                android:name=".InteractiveWatchFaceService"
-                android:label="@string/interactive_name"
-                android:permission="android.permission.BIND_WALLPAPER" >
+            android:name=".OpenGLWatchFaceService"
+            android:label="@string/opengl_name"
+            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_opengl" />
+            <meta-data
+                android:name="com.google.android.wearable.watchface.preview_circular"
+                android:resource="@drawable/preview_opengl_circular" />
+            <meta-data
+                android:name="com.google.android.wearable.watchface.companionConfigurationAction"
+                android:value="com.example.android.wearable.watchface.CONFIG_OPENGL" />
+
+            <intent-filter>
+                <action android:name="android.service.wallpaper.WallpaperService" />
+
+                <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
+            </intent-filter>
+        </service>
+        <service
+            android:name=".CardBoundsWatchFaceService"
+            android:label="@string/card_bounds_name"
+            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_card_bounds" />
+            <meta-data
+                android:name="com.google.android.wearable.watchface.preview_circular"
+                android:resource="@drawable/preview_card_bounds_circular" />
+            <meta-data
+                android:name="com.google.android.wearable.watchface.companionConfigurationAction"
+                android:value="com.example.android.wearable.watchface.CONFIG_CARD_BOUNDS" />
+
+            <intent-filter>
+                <action android:name="android.service.wallpaper.WallpaperService" />
+
+                <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
+            </intent-filter>
+        </service>
+        <service
+            android:name=".InteractiveWatchFaceService"
+            android:label="@string/interactive_name"
+            android:permission="android.permission.BIND_WALLPAPER" >
             <meta-data
                 android:name="android.service.wallpaper"
                 android:resource="@xml/watch_face" />
@@ -137,77 +146,82 @@
             <meta-data
                 android:name="com.google.android.wearable.watchface.preview_circular"
                 android:resource="@drawable/preview_interactive_circular" />
+
             <intent-filter>
                 <action android:name="android.service.wallpaper.WallpaperService" />
-                <category
-                    android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
+
+                <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
             </intent-filter>
         </service>
-
         <service
-                android:name=".DigitalWatchFaceService"
-                android:label="@string/digital_name"
-                android:permission="android.permission.BIND_WALLPAPER" >
+            android:name=".DigitalWatchFaceService"
+            android:label="@string/digital_name"
+            android:permission="android.permission.BIND_WALLPAPER" >
             <meta-data
-                    android:name="android.service.wallpaper"
-                    android:resource="@xml/watch_face" />
+                android:name="android.service.wallpaper"
+                android:resource="@xml/watch_face" />
             <meta-data
-                    android:name="com.google.android.wearable.watchface.preview"
-                    android:resource="@drawable/preview_digital" />
+                android:name="com.google.android.wearable.watchface.preview"
+                android:resource="@drawable/preview_digital" />
             <meta-data
-                    android:name="com.google.android.wearable.watchface.preview_circular"
-                    android:resource="@drawable/preview_digital_circular" />
+                android:name="com.google.android.wearable.watchface.preview_circular"
+                android:resource="@drawable/preview_digital_circular" />
             <meta-data
-                    android:name="com.google.android.wearable.watchface.companionConfigurationAction"
-                    android:value="com.example.android.wearable.watchface.CONFIG_DIGITAL" />
+                android:name="com.google.android.wearable.watchface.companionConfigurationAction"
+                android:value="com.example.android.wearable.watchface.CONFIG_DIGITAL" />
             <meta-data
-                    android:name="com.google.android.wearable.watchface.wearableConfigurationAction"
-                    android:value="com.example.android.wearable.watchface.CONFIG_DIGITAL" />
+                android:name="com.google.android.wearable.watchface.wearableConfigurationAction"
+                android:value="com.example.android.wearable.watchface.CONFIG_DIGITAL" />
+
             <intent-filter>
                 <action android:name="android.service.wallpaper.WallpaperService" />
+
                 <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
             </intent-filter>
         </service>
 
-        <!-- All intent-filters for config actions must include the categories
+        <!--
+             All intent-filters for config actions must include the categories
             com.google.android.wearable.watchface.category.WEARABLE_CONFIGURATION
-            and android.intent.category.DEFAULT. -->
+            and android.intent.category.DEFAULT.
+        -->
 
         <activity
-                android:name=".DigitalWatchFaceWearableConfigActivity"
-                android:label="@string/digital_config_name">
+            android:name=".DigitalWatchFaceWearableConfigActivity"
+            android:label="@string/digital_config_name" >
             <intent-filter>
                 <action android:name="com.example.android.wearable.watchface.CONFIG_DIGITAL" />
+
                 <category android:name="com.google.android.wearable.watchface.category.WEARABLE_CONFIGURATION" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
         </activity>
 
         <service
-                android:name=".CalendarWatchFaceService"
-                android:label="@string/calendar_name"
-                android:permission="android.permission.BIND_WALLPAPER" >
+            android:name=".CalendarWatchFaceService"
+            android:label="@string/calendar_name"
+            android:permission="android.permission.BIND_WALLPAPER" >
             <meta-data
-                    android:name="android.service.wallpaper"
-                    android:resource="@xml/watch_face" />
+                android:name="android.service.wallpaper"
+                android:resource="@xml/watch_face" />
             <meta-data
-                    android:name="com.google.android.wearable.watchface.preview"
-                    android:resource="@drawable/preview_calendar" />
+                android:name="com.google.android.wearable.watchface.preview"
+                android:resource="@drawable/preview_calendar" />
             <meta-data
-                    android:name="com.google.android.wearable.watchface.preview_circular"
-                    android:resource="@drawable/preview_calendar_circular" />
+                android:name="com.google.android.wearable.watchface.preview_circular"
+                android:resource="@drawable/preview_calendar_circular" />
+
             <intent-filter>
                 <action android:name="android.service.wallpaper.WallpaperService" />
+
                 <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
             </intent-filter>
         </service>
-
-        <service android:name=".DigitalWatchFaceConfigListenerService">
+        <service android:name=".DigitalWatchFaceConfigListenerService" >
             <intent-filter>
                 <action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
             </intent-filter>
         </service>
-
         <service
             android:name=".FitDistanceWatchFaceService"
             android:label="@string/fit_distance_name"
@@ -221,17 +235,16 @@
             <meta-data
                 android:name="com.google.android.wearable.watchface.preview_circular"
                 android:resource="@drawable/preview_distance_circular" />
-
             <meta-data
                 android:name="com.google.android.wearable.watchface.companionConfigurationAction"
                 android:value="com.example.android.wearable.watchface.CONFIG_FIT_DISTANCE" />
 
             <intent-filter>
                 <action android:name="android.service.wallpaper.WallpaperService" />
+
                 <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
             </intent-filter>
         </service>
-
         <service
             android:name=".FitStepsWatchFaceService"
             android:label="@string/fit_steps_name"
@@ -248,14 +261,15 @@
 
             <intent-filter>
                 <action android:name="android.service.wallpaper.WallpaperService" />
+
                 <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
             </intent-filter>
         </service>
 
-        <meta-data
-                android:name="com.google.android.gms.version"
-                android:value="@integer/google_play_services_version" />
-
+        <activity
+            android:name=".CalendarWatchFacePermissionActivity"
+            android:label="@string/title_activity_calendar_watch_face_permission" >
+        </activity>
     </application>
 
 </manifest>
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/CalendarWatchFacePermissionActivity.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/CalendarWatchFacePermissionActivity.java
new file mode 100644
index 0000000..7effd33
--- /dev/null
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/CalendarWatchFacePermissionActivity.java
@@ -0,0 +1,56 @@
+package com.example.android.wearable.watchface;
+
+import android.Manifest;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v4.app.ActivityCompat;
+import android.support.wearable.activity.WearableActivity;
+import android.util.Log;
+import android.view.View;
+
+/**
+ * Simple Activity for displaying Calendar Permission Rationale to user.
+ */
+public class CalendarWatchFacePermissionActivity extends WearableActivity {
+
+    private static final String TAG = "PermissionActivity";
+
+    /* Id to identify permission request for calendar. */
+    private static final int PERMISSION_REQUEST_READ_CALENDAR = 1;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_calendar_watch_face_permission);
+        setAmbientEnabled();
+    }
+
+    public void onClickEnablePermission(View view) {
+        Log.d(TAG, "onClickEnablePermission()");
+
+        // On 23+ (M+) devices, GPS permission not granted. Request permission.
+        ActivityCompat.requestPermissions(
+                this,
+                new String[]{Manifest.permission.READ_CALENDAR},
+                PERMISSION_REQUEST_READ_CALENDAR);
+
+    }
+
+    /*
+     * Callback received when a permissions request has been completed.
+     */
+    @Override
+    public void onRequestPermissionsResult(
+            int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+
+        Log.d(TAG, "onRequestPermissionsResult()");
+
+        if (requestCode == PERMISSION_REQUEST_READ_CALENDAR) {
+            if ((grantResults.length == 1)
+                    && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
+                finish();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/CalendarWatchFaceService.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/CalendarWatchFaceService.java
index a8ab955..98a251c 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/CalendarWatchFaceService.java
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/CalendarWatchFaceService.java
@@ -16,11 +16,13 @@
 
 package com.example.android.wearable.watchface;
 
+import android.Manifest;
 import android.content.BroadcastReceiver;
 import android.content.ContentUris;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -30,8 +32,10 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.PowerManager;
+import android.support.v4.app.ActivityCompat;
 import android.support.wearable.provider.WearableCalendarContract;
 import android.support.wearable.watchface.CanvasWatchFaceService;
+import android.support.wearable.watchface.WatchFaceService;
 import android.support.wearable.watchface.WatchFaceStyle;
 import android.text.DynamicLayout;
 import android.text.Editable;
@@ -74,31 +78,37 @@
         final TextPaint mTextPaint = new TextPaint();
 
         int mNumMeetings;
+        private boolean mCalendarPermissionApproved;
+        private String mCalendarNotApprovedMessage;
 
         private AsyncTask<Void, Void, Integer> mLoadMeetingsTask;
 
+        private boolean mIsReceiverRegistered;
+
         /** Handler to load the meetings once a minute in interactive mode. */
         final Handler mLoadMeetingsHandler = new Handler() {
             @Override
             public void handleMessage(Message message) {
                 switch (message.what) {
                     case MSG_LOAD_MEETINGS:
+
                         cancelLoadMeetingTask();
-                        mLoadMeetingsTask = new LoadMeetingsTask();
-                        mLoadMeetingsTask.execute();
+
+                        // Loads meetings.
+                        if (mCalendarPermissionApproved) {
+                            mLoadMeetingsTask = new LoadMeetingsTask();
+                            mLoadMeetingsTask.execute();
+                        }
                         break;
                 }
             }
         };
 
-        private boolean mIsReceiverRegistered;
-
         private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
                 if (Intent.ACTION_PROVIDER_CHANGED.equals(intent.getAction())
                         && WearableCalendarContract.CONTENT_URI.equals(intent.getData())) {
-                    cancelLoadMeetingTask();
                     mLoadMeetingsHandler.sendEmptyMessage(MSG_LOAD_MEETINGS);
                 }
             }
@@ -106,29 +116,59 @@
 
         @Override
         public void onCreate(SurfaceHolder holder) {
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "onCreate");
-            }
             super.onCreate(holder);
+            Log.d(TAG, "onCreate");
+
+            mCalendarNotApprovedMessage =
+                    getResources().getString(R.string.calendar_permission_not_approved);
+
+            /* Accepts tap events to allow permission changes by user. */
             setWatchFaceStyle(new WatchFaceStyle.Builder(CalendarWatchFaceService.this)
                     .setCardPeekMode(WatchFaceStyle.PEEK_MODE_VARIABLE)
                     .setBackgroundVisibility(WatchFaceStyle.BACKGROUND_VISIBILITY_INTERRUPTIVE)
                     .setShowSystemUiTime(false)
+                    .setAcceptsTapEvents(true)
                     .build());
 
             mTextPaint.setColor(FOREGROUND_COLOR);
             mTextPaint.setTextSize(TEXT_SIZE);
 
-            mLoadMeetingsHandler.sendEmptyMessage(MSG_LOAD_MEETINGS);
+            // Enables app to handle 23+ (M+) style permissions.
+            mCalendarPermissionApproved =
+                    ActivityCompat.checkSelfPermission(
+                            getApplicationContext(),
+                            Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_GRANTED;
+
+            if (mCalendarPermissionApproved) {
+                mLoadMeetingsHandler.sendEmptyMessage(MSG_LOAD_MEETINGS);
+            }
         }
 
         @Override
         public void onDestroy() {
             mLoadMeetingsHandler.removeMessages(MSG_LOAD_MEETINGS);
-            cancelLoadMeetingTask();
             super.onDestroy();
         }
 
+        /*
+         * Captures tap event (and tap type) and increments correct tap type total.
+         */
+        @Override
+        public void onTapCommand(int tapType, int x, int y, long eventTime) {
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "Tap Command: " + tapType);
+            }
+
+            // Ignore lint error (fixed in wearable support library 1.4)
+            if (tapType == WatchFaceService.TAP_TYPE_TAP && !mCalendarPermissionApproved) {
+                Intent permissionIntent = new Intent(
+                        getApplicationContext(),
+                        CalendarWatchFacePermissionActivity.class);
+                permissionIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                startActivity(permissionIntent);
+            }
+        }
+
         @Override
         public void onDraw(Canvas canvas, Rect bounds) {
             // Create or update mLayout if necessary.
@@ -141,8 +181,13 @@
 
             // Update the contents of mEditable.
             mEditable.clear();
-            mEditable.append(Html.fromHtml(getResources().getQuantityString(
-                    R.plurals.calendar_meetings, mNumMeetings, mNumMeetings)));
+
+            if (mCalendarPermissionApproved) {
+                mEditable.append(Html.fromHtml(getResources().getQuantityString(
+                        R.plurals.calendar_meetings, mNumMeetings, mNumMeetings)));
+            } else {
+                mEditable.append(Html.fromHtml(mCalendarNotApprovedMessage));
+            }
 
             // Draw the text on a solid background.
             canvas.drawColor(BACKGROUND_COLOR);
@@ -151,15 +196,24 @@
 
         @Override
         public void onVisibilityChanged(boolean visible) {
+            Log.d(TAG, "onVisibilityChanged()");
             super.onVisibilityChanged(visible);
             if (visible) {
-                IntentFilter filter = new IntentFilter(Intent.ACTION_PROVIDER_CHANGED);
-                filter.addDataScheme("content");
-                filter.addDataAuthority(WearableCalendarContract.AUTHORITY, null);
-                registerReceiver(mBroadcastReceiver, filter);
-                mIsReceiverRegistered = true;
 
-                mLoadMeetingsHandler.sendEmptyMessage(MSG_LOAD_MEETINGS);
+                // Enables app to handle 23+ (M+) style permissions.
+                mCalendarPermissionApproved = ActivityCompat.checkSelfPermission(
+                        getApplicationContext(),
+                        Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_GRANTED;
+
+                if (mCalendarPermissionApproved) {
+                    IntentFilter filter = new IntentFilter(Intent.ACTION_PROVIDER_CHANGED);
+                    filter.addDataScheme("content");
+                    filter.addDataAuthority(WearableCalendarContract.AUTHORITY, null);
+                    registerReceiver(mBroadcastReceiver, filter);
+                    mIsReceiverRegistered = true;
+
+                    mLoadMeetingsHandler.sendEmptyMessage(MSG_LOAD_MEETINGS);
+                }
             } else {
                 if (mIsReceiverRegistered) {
                     unregisterReceiver(mBroadcastReceiver);
@@ -204,9 +258,9 @@
                 final Cursor cursor = getContentResolver().query(builder.build(),
                         null, null, null, null);
                 int numMeetings = cursor.getCount();
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "Num meetings: " + numMeetings);
-                }
+
+                Log.d(TAG, "Num meetings: " + numMeetings);
+
                 return numMeetings;
             }
 
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/drawable-hdpi/ic_lock_open_white_24dp.png b/wearable/wear/WatchFace/Wearable/src/main/res/drawable-hdpi/ic_lock_open_white_24dp.png
new file mode 100644
index 0000000..6bae68f
--- /dev/null
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/drawable-hdpi/ic_lock_open_white_24dp.png
Binary files differ
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/drawable-mdpi/ic_lock_open_white_24dp.png b/wearable/wear/WatchFace/Wearable/src/main/res/drawable-mdpi/ic_lock_open_white_24dp.png
new file mode 100644
index 0000000..3f47b54
--- /dev/null
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/drawable-mdpi/ic_lock_open_white_24dp.png
Binary files differ
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/drawable-xhdpi/ic_lock_open_white_24dp.png b/wearable/wear/WatchFace/Wearable/src/main/res/drawable-xhdpi/ic_lock_open_white_24dp.png
new file mode 100644
index 0000000..cbe9e1c
--- /dev/null
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/drawable-xhdpi/ic_lock_open_white_24dp.png
Binary files differ
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/drawable-xxhdpi/ic_lock_open_white_24dp.png b/wearable/wear/WatchFace/Wearable/src/main/res/drawable-xxhdpi/ic_lock_open_white_24dp.png
new file mode 100644
index 0000000..1d1b0f4
--- /dev/null
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/drawable-xxhdpi/ic_lock_open_white_24dp.png
Binary files differ
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_calendar_watch_face_permission.xml b/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_calendar_watch_face_permission.xml
new file mode 100644
index 0000000..bf0e3f6
--- /dev/null
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_calendar_watch_face_permission.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.wearable.view.BoxInsetLayout
+    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:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/container"
+    android:background="@color/white"
+    android:paddingTop="32dp"
+    android:paddingLeft="36dp"
+    android:paddingRight="22dp"
+    tools:context="com.example.android.wearable.watchface.CalendarWatchFacePermissionActivity"
+    tools:deviceIds="wear">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:onClick="onClickEnablePermission"
+        android:orientation="vertical"
+        app:layout_box="all">
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textSize="16sp"
+            android:paddingBottom="18dp"
+            android:textColor="#000000"
+            android:text="@string/calendar_permission_text"/>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+            <android.support.wearable.view.CircledImageView
+                android:id="@+id/circle"
+                android:layout_width="40dp"
+                android:layout_height="40dp"
+                app:circle_radius="20dp"
+                app:circle_color="#0086D4"
+                android:src="@drawable/ic_lock_open_white_24dp"/>
+
+            <android.support.v4.widget.Space
+                android:layout_width="8dp"
+                android:layout_height="8dp"/>
+
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:textSize="16sp"
+                android:textColor="#0086D4"
+                android:text="Enable Permission"/>
+
+
+        </LinearLayout>
+
+    </LinearLayout>
+</android.support.wearable.view.BoxInsetLayout>
\ 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 ed2f0a3..4090995 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/res/values/strings.xml
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/values/strings.xml
@@ -34,10 +34,13 @@
     <string name="fit_distance">%1$,.2f meters</string>
 
     <string name="calendar_name">Sample Calendar</string>
+    <string name="calendar_permission_not_approved">&lt;br&gt;&lt;br&gt;&lt;br&gt;WatchFace requires Calendar permission. Click on this WatchFace or visit Settings &gt; Permissions to approve.</string>
     <plurals name="calendar_meetings">
         <item quantity="one">&lt;br&gt;&lt;br&gt;&lt;br&gt;You have &lt;b&gt;%1$d&lt;/b&gt; meeting in the next 24 hours.</item>
         <item quantity="other">&lt;br&gt;&lt;br&gt;&lt;br&gt;You have &lt;b&gt;%1$d&lt;/b&gt; meetings in the next 24 hours.</item>
     </plurals>
+    <string name="title_activity_calendar_watch_face_permission">Calendar Permission Activity</string>
+    <string name="calendar_permission_text">WatchFace requires Calendar access.</string>
 
     <!-- TODO: this should be shared (needs covering all the samples with Gradle build model) -->
     <string name="color_black">Black</string>
diff --git a/wearable/wear/WatchFace/template-params.xml b/wearable/wear/WatchFace/template-params.xml
index 3c8b72b..15df71a 100644
--- a/wearable/wear/WatchFace/template-params.xml
+++ b/wearable/wear/WatchFace/template-params.xml
@@ -24,12 +24,12 @@
 
     <minSdk>18</minSdk>
     <targetSdkVersion>23</targetSdkVersion>
-    <targetSdkVersionWear>22</targetSdkVersionWear>
+    <targetSdkVersionWear>23</targetSdkVersionWear>
 
     <dependency_wearable>com.android.support:palette-v7:23.1.0</dependency_wearable>
     <dependency>com.google.android.support:wearable:1.3.0</dependency>
-    <dependency>com.google.android.gms:play-services-fitness:8.1.0</dependency>
-    <dependency_wearable>com.google.android.gms:play-services-fitness:8.1.0</dependency_wearable>
+    <dependency>com.google.android.gms:play-services-fitness:8.3.0</dependency>
+    <dependency_wearable>com.google.android.gms:play-services-fitness:8.3.0</dependency_wearable>
 
     <wearable>
         <has_handheld_app>true</has_handheld_app>