1 /* 2 * Copyright (C) 2022 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 17 package android.app.wearable; 18 19 import android.Manifest; 20 import android.annotation.CallbackExecutor; 21 import android.annotation.IntDef; 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.annotation.RequiresPermission; 25 import android.annotation.SystemApi; 26 import android.annotation.SystemService; 27 import android.app.ambientcontext.AmbientContextEvent; 28 import android.content.Context; 29 import android.os.Binder; 30 import android.os.ParcelFileDescriptor; 31 import android.os.PersistableBundle; 32 import android.os.RemoteCallback; 33 import android.os.RemoteException; 34 import android.os.SharedMemory; 35 import android.service.wearable.WearableSensingService; 36 import android.system.OsConstants; 37 38 import java.util.concurrent.Executor; 39 import java.util.function.Consumer; 40 41 /** 42 * Allows granted apps to manage the WearableSensingService. 43 * Applications are responsible for managing the connection to Wearables. Applications can choose 44 * to provide a data stream to the WearableSensingService to use for 45 * computing {@link AmbientContextEvent}s. Applications can also optionally provide their own 46 * defined data to power the detection of {@link AmbientContextEvent}s. 47 * Methods on this class requires the caller to hold and be granted the 48 * {@link Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE}. 49 * 50 * <p>The use of "Wearable" here is not the same as the Android Wear platform and should be treated 51 * separately. </p> 52 * 53 * @hide 54 */ 55 56 @SystemApi 57 @SystemService(Context.WEARABLE_SENSING_SERVICE) 58 public class WearableSensingManager { 59 /** 60 * The bundle key for the service status query result, used in 61 * {@code RemoteCallback#sendResult}. 62 * 63 * @hide 64 */ 65 public static final String STATUS_RESPONSE_BUNDLE_KEY = 66 "android.app.wearable.WearableSensingStatusBundleKey"; 67 68 69 /** 70 * An unknown status. 71 */ 72 public static final int STATUS_UNKNOWN = 0; 73 74 /** 75 * The value of the status code that indicates success. 76 */ 77 public static final int STATUS_SUCCESS = 1; 78 79 /** 80 * The value of the status code that indicates one or more of the 81 * requested events are not supported. 82 */ 83 public static final int STATUS_UNSUPPORTED = 2; 84 85 /** 86 * The value of the status code that indicates service not available. 87 */ 88 public static final int STATUS_SERVICE_UNAVAILABLE = 3; 89 90 /** 91 * The value of the status code that there's no connection to the wearable. 92 */ 93 public static final int STATUS_WEARABLE_UNAVAILABLE = 4; 94 95 /** 96 * The value of the status code that the app is not granted access. 97 */ 98 public static final int STATUS_ACCESS_DENIED = 5; 99 100 /** @hide */ 101 @IntDef(prefix = { "STATUS_" }, value = { 102 STATUS_UNKNOWN, 103 STATUS_SUCCESS, 104 STATUS_UNSUPPORTED, 105 STATUS_SERVICE_UNAVAILABLE, 106 STATUS_WEARABLE_UNAVAILABLE, 107 STATUS_ACCESS_DENIED 108 }) public @interface StatusCode {} 109 110 private final Context mContext; 111 private final IWearableSensingManager mService; 112 113 /** 114 * {@hide} 115 */ WearableSensingManager(Context context, IWearableSensingManager service)116 public WearableSensingManager(Context context, IWearableSensingManager service) { 117 mContext = context; 118 mService = service; 119 } 120 121 /** 122 * Provides a data stream to the WearableSensingService that's backed by the 123 * parcelFileDescriptor, and sends the result to the {@link Consumer} right after the call. 124 * This is used by applications that will also provide an implementation of 125 * an isolated WearableSensingService. If the data stream was provided successfully 126 * {@link WearableSensingManager#STATUS_SUCCESS} will be provided. 127 * 128 * @param parcelFileDescriptor The data stream to provide 129 * @param executor Executor on which to run the consumer callback 130 * @param statusConsumer A consumer that handles the status codes, which is returned 131 * right after the call. 132 */ 133 @RequiresPermission(Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) provideDataStream( @onNull ParcelFileDescriptor parcelFileDescriptor, @NonNull @CallbackExecutor Executor executor, @NonNull @StatusCode Consumer<Integer> statusConsumer)134 public void provideDataStream( 135 @NonNull ParcelFileDescriptor parcelFileDescriptor, 136 @NonNull @CallbackExecutor Executor executor, 137 @NonNull @StatusCode Consumer<Integer> statusConsumer) { 138 try { 139 RemoteCallback callback = new RemoteCallback(result -> { 140 int status = result.getInt(STATUS_RESPONSE_BUNDLE_KEY); 141 final long identity = Binder.clearCallingIdentity(); 142 try { 143 executor.execute(() -> statusConsumer.accept(status)); 144 } finally { 145 Binder.restoreCallingIdentity(identity); 146 } 147 }); 148 mService.provideDataStream(parcelFileDescriptor, callback); 149 } catch (RemoteException e) { 150 throw e.rethrowFromSystemServer(); 151 } 152 } 153 154 /** 155 * Sets configuration and provides read-only data in a {@link PersistableBundle} that may be 156 * used by the WearableSensingService, and sends the result to the {@link Consumer} 157 * right after the call. It is dependent on the application to 158 * define the type of data to provide. This is used by applications that will also 159 * provide an implementation of an isolated WearableSensingService. If the data was 160 * provided successfully {@link WearableSensingManager#STATUS_SUCCESS} will be povided. 161 * 162 * @param data Application configuration data to provide to the {@link WearableSensingService}. 163 * PersistableBundle does not allow any remotable objects or other contents 164 * that can be used to communicate with other processes. 165 * @param sharedMemory The unrestricted data blob to 166 * provide to the {@link WearableSensingService}. Use this to provide the 167 * sensing models data or other such data to the trusted process. 168 * The sharedMemory must be read only and protected with 169 * {@link OsConstants.PROT_READ}. 170 * Other operations will be removed by the system. 171 * @param executor Executor on which to run the consumer callback 172 * @param statusConsumer A consumer that handles the status codes, which is returned 173 * right after the call 174 */ 175 @RequiresPermission(Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) provideData( @onNull PersistableBundle data, @Nullable SharedMemory sharedMemory, @NonNull @CallbackExecutor Executor executor, @NonNull @StatusCode Consumer<Integer> statusConsumer)176 public void provideData( 177 @NonNull PersistableBundle data, @Nullable SharedMemory sharedMemory, 178 @NonNull @CallbackExecutor Executor executor, 179 @NonNull @StatusCode Consumer<Integer> statusConsumer) { 180 try { 181 RemoteCallback callback = new RemoteCallback(result -> { 182 int status = result.getInt(STATUS_RESPONSE_BUNDLE_KEY); 183 final long identity = Binder.clearCallingIdentity(); 184 try { 185 executor.execute(() -> statusConsumer.accept(status)); 186 } finally { 187 Binder.restoreCallingIdentity(identity); 188 } 189 }); 190 mService.provideData(data, sharedMemory, callback); 191 } catch (RemoteException e) { 192 throw e.rethrowFromSystemServer(); 193 } 194 } 195 196 } 197