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 */ 16 package androidx.wear.utils; 17 18 import android.content.Context; 19 import android.content.pm.ApplicationInfo; 20 import android.content.pm.PackageManager; 21 22 /** 23 * Constants for android wear apps which are related to manifest meta-data. 24 */ 25 public 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 @SuppressWarnings("deprecation") isStandalone(Context context)134 public static boolean isStandalone(Context context) { 135 try { 136 ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo( 137 context.getPackageName(), PackageManager.GET_META_DATA); 138 if (appInfo.metaData != null) { 139 return appInfo.metaData.getBoolean(STANDALONE_METADATA_NAME); 140 } 141 } catch (PackageManager.NameNotFoundException e) { 142 // Do nothing 143 } 144 145 return false; 146 } 147 148 /** 149 * Determines whether a given context has notification bridging enabled. 150 * 151 * @param context to be evaluated. 152 * @return Whether a given context has notification bridging enabled. 153 */ 154 @SuppressWarnings("deprecation") isNotificationBridgingEnabled(Context context)155 public static boolean isNotificationBridgingEnabled(Context context) { 156 try { 157 ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo( 158 context.getPackageName(), PackageManager.GET_META_DATA); 159 if (appInfo.metaData != null) { 160 return NOTIFICATION_BRIDGE_MODE_BRIDGING.equals( 161 appInfo.metaData.getString(NOTIFICATION_BRIDGE_MODE_METADATA_NAME)); 162 } 163 } catch (PackageManager.NameNotFoundException e) { 164 // Do nothing 165 } 166 167 return true; 168 } 169 170 /** 171 * 172 * @param context to be evaluated. 173 * @param circular Whether to return the circular or regular preview. 174 * 175 * @return an integer id representing the resource id of the requested drawable, or 0 if 176 * no drawable was found. 177 */ 178 @SuppressWarnings("deprecation") getPreviewDrawableResourceId(Context context, boolean circular)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 MetadataConstants()195 private MetadataConstants() {} 196 } 197