1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package android.support.wear.utils; 17 18import android.annotation.TargetApi; 19import android.content.Context; 20import android.content.pm.ApplicationInfo; 21import android.content.pm.PackageManager; 22import android.os.Build; 23 24/** 25 * Constants for android wear apps which are related to manifest meta-data. 26 */ 27@TargetApi(Build.VERSION_CODES.N) 28public class MetadataConstants { 29 30 // Constants for standalone apps. // 31 32 /** 33 * The name of the meta-data element in the Wear app manifest for specifying whether this app 34 * does not require a companion phone app. The value should be set to "true" or "false". 35 * <p> 36 * <p>Wear apps that do not require a phone side companion app to function can declare this in 37 * their AndroidManifest.xml file by setting the standalone meta-data element to true as shown 38 * in the following example. If this value is true, all users can discover this app regardless 39 * of what phone they have. If this value is false (or not set), only users with compatible 40 * Android phones can discover this app. 41 * <p> 42 * <pre class="prettyprint">{@code 43 * <meta-data 44 * android:name="com.google.android.wearable.standalone" 45 * android:value="true" /> 46 * }</pre> 47 */ 48 public static final String STANDALONE_METADATA_NAME = "com.google.android.wearable.standalone"; 49 50 // Constants for customizing bridging of notifications from the phone to the wearable. // 51 52 /** 53 * We support specifying whether notifications should be bridged from the phone to the wearable 54 * in the Wear app manifest file. Simply add a meta-data element to the Wear app manifest with 55 * the name "com.google.android.wearable.notificationBridgeMode" and either the value 56 * NO_BRIDGING or the value BRIDGING. If you choose not to update your Wear app manifest, then 57 * notifications will be bridged by default from the phone to the wearable. 58 * 59 * <p>NO_BRIDGING means that phone notifications will not be bridged to the wearable if the 60 * wearable app is installed. 61 * 62 * <p>BRIDGING means that phone notifications will be bridged to the wearable, unless they are 63 * posted with 64 * {@link android.app.Notification.Builder#setLocalOnly(boolean) setLocalOnly(true)}. 65 * 66 * <p>Example AndroidManifest.xml meta-data element for NO_BRIDGING: 67 * 68 * <pre class="prettyprint">{@code 69 * <meta-data 70 * android:name="com.google.android.wearable.notificationBridgeMode" 71 * android:value="NO_BRIDGING" /> 72 * }</pre> 73 * 74 * <p>Example AndroidManifest.xml meta-data element for BRIDGING: 75 * 76 * <pre class="prettyprint">{@code 77 * <meta-data 78 * android:name="com.google.android.wearable.notificationBridgeMode" 79 * android:value="BRIDGING" /> 80 * }</pre> 81 */ 82 public static final String NOTIFICATION_BRIDGE_MODE_METADATA_NAME = 83 "com.google.android.wearable.notificationBridgeMode"; 84 85 /** 86 * The value of the notification bridge mode meta-data element in the case where the Wear app 87 * wants notifications to be bridged from the phone to the wearable. 88 */ 89 public static final String NOTIFICATION_BRIDGE_MODE_BRIDGING = "BRIDGING"; 90 91 /** 92 * The value of the notification bridge mode meta-data element in the case where the Wear app 93 * does not want notifications to be bridged from the phone to the wearable. 94 */ 95 public static final String NOTIFICATION_BRIDGE_MODE_NO_BRIDGING = "NO_BRIDGING"; 96 97 // Constants for watch face preview. // 98 99 /** 100 * The name of the meta-data element in the watch face service manifest declaration used 101 * to assign a non-circular preview image to the watch face. The value should be set to 102 * a drawable reference. 103 * 104 * <pre class="prettyprint"> 105 * <meta-data 106 * android:name="com.google.android.wearable.watchface.preview" 107 * android:resource="@drawable/preview_face" /> 108 * </pre> 109 */ 110 public static final String WATCH_FACE_PREVIEW_METADATA_NAME = 111 "com.google.android.wearable.watchface.preview"; 112 113 /** 114 * The name of the meta-data element in the watch face service manifest declaration used 115 * to assign a circular preview image to the watch face. The value should be set to 116 * a drawable reference. 117 * 118 * <pre class="prettyprint"> 119 * <meta-data 120 * android:name="com.google.android.wearable.watchface.preview_circular" 121 * android:resource="@drawable/preview_face_circular" /> 122 * </pre> 123 */ 124 public static final String WATCH_FACE_PREVIEW_CIRCULAR_METADATA_NAME = 125 "com.google.android.wearable.watchface.preview_circular"; 126 127 // HELPER METHODS // 128 129 /** 130 * Determines whether a given context comes from a standalone app. This can be used as a proxy 131 * to check if any given app is compatible with iOS Companion devices. 132 * 133 * @param context to be evaluated. 134 * @return Whether a given context comes from a standalone app. 135 */ 136 public static boolean isStandalone(Context context) { 137 try { 138 ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo( 139 context.getPackageName(), PackageManager.GET_META_DATA); 140 if (appInfo.metaData != null) { 141 return appInfo.metaData.getBoolean(STANDALONE_METADATA_NAME); 142 } 143 } catch (PackageManager.NameNotFoundException e) { 144 // Do nothing 145 } 146 147 return false; 148 } 149 150 /** 151 * Determines whether a given context has notification bridging enabled. 152 * 153 * @param context to be evaluated. 154 * @return Whether a given context has notification bridging enabled. 155 */ 156 public static boolean isNotificationBridgingEnabled(Context context) { 157 try { 158 ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo( 159 context.getPackageName(), PackageManager.GET_META_DATA); 160 if (appInfo.metaData != null) { 161 return NOTIFICATION_BRIDGE_MODE_BRIDGING.equals( 162 appInfo.metaData.getString(NOTIFICATION_BRIDGE_MODE_METADATA_NAME)); 163 } 164 } catch (PackageManager.NameNotFoundException e) { 165 // Do nothing 166 } 167 168 return true; 169 } 170 171 /** 172 * 173 * @param context to be evaluated. 174 * @param circular Whether to return the circular or regular preview. 175 * 176 * @return an integer id representing the resource id of the requested drawable, or 0 if 177 * no drawable was found. 178 */ 179 public static int getPreviewDrawableResourceId(Context context, boolean circular) { 180 try { 181 ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo( 182 context.getPackageName(), PackageManager.GET_META_DATA); 183 if (appInfo.metaData != null) { 184 return circular 185 ? appInfo.metaData.getInt(WATCH_FACE_PREVIEW_CIRCULAR_METADATA_NAME, 0) 186 : appInfo.metaData.getInt(WATCH_FACE_PREVIEW_METADATA_NAME, 0); 187 } 188 } catch (PackageManager.NameNotFoundException e) { 189 // Do nothing 190 } 191 192 return 0; 193 } 194 195 private MetadataConstants() {} 196} 197