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