140f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska/* 240f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * Copyright (C) 2017 The Android Open Source Project 340f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * 440f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * Licensed under the Apache License, Version 2.0 (the "License"); 540f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * you may not use this file except in compliance with the License. 640f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * You may obtain a copy of the License at 740f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * 840f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * http://www.apache.org/licenses/LICENSE-2.0 940f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * 1040f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * Unless required by applicable law or agreed to in writing, software 1140f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * distributed under the License is distributed on an "AS IS" BASIS, 1240f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1340f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * See the License for the specific language governing permissions and 1440f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * limitations under the License. 1540f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska */ 1640f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurskapackage android.support.wear.utils; 1740f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska 1840f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurskaimport android.annotation.TargetApi; 1940f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurskaimport android.content.Context; 2040f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurskaimport android.content.pm.ApplicationInfo; 2140f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurskaimport android.content.pm.PackageManager; 2240f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurskaimport android.os.Build; 2340f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska 2440f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska/** 2540f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * Constants for android wear apps which are related to manifest meta-data. 2640f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska */ 2740f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska@TargetApi(Build.VERSION_CODES.N) 2840f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurskapublic class MetadataConstants { 29a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska 30a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska // Constants for standalone apps. // 31a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska 3240f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska /** 3340f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * The name of the meta-data element in the Wear app manifest for specifying whether this app 3440f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * does not require a companion phone app. The value should be set to "true" or "false". 3540f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * <p> 3640f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * <p>Wear apps that do not require a phone side companion app to function can declare this in 3740f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * their AndroidManifest.xml file by setting the standalone meta-data element to true as shown 3840f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * in the following example. If this value is true, all users can discover this app regardless 3940f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * of what phone they have. If this value is false (or not set), only users with compatible 4040f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * Android phones can discover this app. 4140f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * <p> 4240f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * <pre class="prettyprint">{@code 4340f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * <meta-data 4440f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * android:name="com.google.android.wearable.standalone" 4540f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * android:value="true" /> 4640f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * }</pre> 4740f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska */ 4840f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska public static final String STANDALONE_METADATA_NAME = "com.google.android.wearable.standalone"; 4940f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska 50a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska // Constants for customizing bridging of notifications from the phone to the wearable. // 517c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska 527c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska /** 537c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * We support specifying whether notifications should be bridged from the phone to the wearable 547c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * in the Wear app manifest file. Simply add a meta-data element to the Wear app manifest with 557c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * the name "com.google.android.wearable.notificationBridgeMode" and either the value 567c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * NO_BRIDGING or the value BRIDGING. If you choose not to update your Wear app manifest, then 577c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * notifications will be bridged by default from the phone to the wearable. 587c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * 597c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * <p>NO_BRIDGING means that phone notifications will not be bridged to the wearable if the 607c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * wearable app is installed. 617c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * 627c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * <p>BRIDGING means that phone notifications will be bridged to the wearable, unless they are 637c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * posted with 647c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * {@link android.app.Notification.Builder#setLocalOnly(boolean) setLocalOnly(true)}. 657c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * 667c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * <p>Example AndroidManifest.xml meta-data element for NO_BRIDGING: 677c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * 687c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * <pre class="prettyprint">{@code 697c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * <meta-data 707c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * android:name="com.google.android.wearable.notificationBridgeMode" 717c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * android:value="NO_BRIDGING" /> 727c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * }</pre> 737c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * 747c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * <p>Example AndroidManifest.xml meta-data element for BRIDGING: 757c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * 767c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * <pre class="prettyprint">{@code 777c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * <meta-data 787c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * android:name="com.google.android.wearable.notificationBridgeMode" 797c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * android:value="BRIDGING" /> 807c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * }</pre> 817c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska */ 827c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska public static final String NOTIFICATION_BRIDGE_MODE_METADATA_NAME = 837c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska "com.google.android.wearable.notificationBridgeMode"; 847c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska 857c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska /** 867c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * The value of the notification bridge mode meta-data element in the case where the Wear app 877c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * wants notifications to be bridged from the phone to the wearable. 887c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska */ 897c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska public static final String NOTIFICATION_BRIDGE_MODE_BRIDGING = "BRIDGING"; 907c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska 917c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska /** 927c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * The value of the notification bridge mode meta-data element in the case where the Wear app 937c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * does not want notifications to be bridged from the phone to the wearable. 947c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska */ 957c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska public static final String NOTIFICATION_BRIDGE_MODE_NO_BRIDGING = "NO_BRIDGING"; 967c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska 97a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska // Constants for watch face preview. // 98a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska 99a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska /** 100a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * The name of the meta-data element in the watch face service manifest declaration used 101a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * to assign a non-circular preview image to the watch face. The value should be set to 102a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * a drawable reference. 103a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * 104a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * <pre class="prettyprint"> 105a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * <meta-data 106a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * android:name="com.google.android.wearable.watchface.preview" 107a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * android:resource="@drawable/preview_face" /> 108a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * </pre> 109a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska */ 110a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska public static final String WATCH_FACE_PREVIEW_METADATA_NAME = 111a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska "com.google.android.wearable.watchface.preview"; 112a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska 113a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska /** 114a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * The name of the meta-data element in the watch face service manifest declaration used 115a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * to assign a circular preview image to the watch face. The value should be set to 116a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * a drawable reference. 117a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * 118a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * <pre class="prettyprint"> 119a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * <meta-data 120a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * android:name="com.google.android.wearable.watchface.preview_circular" 121a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * android:resource="@drawable/preview_face_circular" /> 122a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * </pre> 123a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska */ 124a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska public static final String WATCH_FACE_PREVIEW_CIRCULAR_METADATA_NAME = 125a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska "com.google.android.wearable.watchface.preview_circular"; 126a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska 127a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska // HELPER METHODS // 128a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska 12940f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska /** 13040f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * Determines whether a given context comes from a standalone app. This can be used as a proxy 13140f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * to check if any given app is compatible with iOS Companion devices. 13240f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * 13340f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska * @param context to be evaluated. 1347c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * @return Whether a given context comes from a standalone app. 13540f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska */ 13640f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska public static boolean isStandalone(Context context) { 13740f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska try { 13840f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo( 13940f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska context.getPackageName(), PackageManager.GET_META_DATA); 14040f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska if (appInfo.metaData != null) { 14140f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska return appInfo.metaData.getBoolean(STANDALONE_METADATA_NAME); 14240f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska } 14340f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska } catch (PackageManager.NameNotFoundException e) { 14440f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska // Do nothing 14540f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska } 14640f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska 14740f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska return false; 14840f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska } 14940f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska 1507c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska /** 1517c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * Determines whether a given context has notification bridging enabled. 1527c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * 1537c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * @param context to be evaluated. 1547c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska * @return Whether a given context has notification bridging enabled. 1557c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska */ 1567c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska public static boolean isNotificationBridgingEnabled(Context context) { 1577c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska try { 1587c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo( 1597c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska context.getPackageName(), PackageManager.GET_META_DATA); 1607c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska if (appInfo.metaData != null) { 1617c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska return NOTIFICATION_BRIDGE_MODE_BRIDGING.equals( 1627c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska appInfo.metaData.getString(NOTIFICATION_BRIDGE_MODE_METADATA_NAME)); 1637c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska } 1647c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska } catch (PackageManager.NameNotFoundException e) { 1657c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska // Do nothing 1667c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska } 1677c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska 1687c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska return true; 16940f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska } 1707c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska 171a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska /** 172a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * 173a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * @param context to be evaluated. 174a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * @param circular Whether to return the circular or regular preview. 175a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * 176a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * @return an integer id representing the resource id of the requested drawable, or 0 if 177a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska * no drawable was found. 178a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska */ 179a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska public static int getPreviewDrawableResourceId(Context context, boolean circular) { 180a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska try { 181a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo( 182a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska context.getPackageName(), PackageManager.GET_META_DATA); 183a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska if (appInfo.metaData != null) { 184a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska return circular 185a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska ? appInfo.metaData.getInt(WATCH_FACE_PREVIEW_CIRCULAR_METADATA_NAME, 0) 186a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska : appInfo.metaData.getInt(WATCH_FACE_PREVIEW_METADATA_NAME, 0); 187a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska } 188a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska } catch (PackageManager.NameNotFoundException e) { 189a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska // Do nothing 190a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska } 191a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska 192a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska return 0; 193a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska } 194a16e54f81e9327a6fa681f2f1a313f862845d879Aga Madurska 1957c90066cf055a00a328a24ae3356a003ad7b7f53Aga Madurska private MetadataConstants() {} 19640f89de052f31b1ef61c59af720e3a2c8f2e825aAga Madurska} 197