AutofillService.java revision e5f9c30688f0277505fb6b50ea385e5df6271ed8
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.service.autofill; 17 18import android.annotation.NonNull; 19import android.annotation.Nullable; 20import android.os.RemoteException; 21import com.android.internal.os.HandlerCaller; 22import android.annotation.SdkConstant; 23import android.app.Activity; 24import android.app.Service; 25import android.app.assist.AssistStructure; 26import android.content.Intent; 27import android.os.Bundle; 28import android.os.CancellationSignal; 29import android.os.IBinder; 30import android.os.ICancellationSignal; 31import android.os.Looper; 32import android.util.Log; 33import android.view.autofill.AutofillManager; 34 35import com.android.internal.os.SomeArgs; 36 37import java.util.List; 38 39//TODO(b/33197203): improve javadoc (of both class and methods); in particular, make sure the 40//life-cycle (and how state could be maintained on server-side) is well documented. 41 42/** 43 * Top-level service of the current autofill service for a given user. 44 * 45 * <p>Apps providing autofill capabilities must extend this service. 46 */ 47public abstract class AutofillService extends Service { 48 private static final String TAG = "AutofillService"; 49 50 /** 51 * The {@link Intent} that must be declared as handled by the service. 52 * To be supported, the service must also require the 53 * {@link android.Manifest.permission#BIND_AUTO_FILL} permission so 54 * that other applications can not abuse it. 55 * 56 * @hide 57 * @deprecated TODO(b/35956626): remove once clients use AutofillService 58 */ 59 @Deprecated 60 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) 61 public static final String OLD_SERVICE_INTERFACE = "android.service.autofill.AutoFillService"; 62 63 /** 64 * The {@link Intent} that must be declared as handled by the service. 65 * To be supported, the service must also require the 66 * {@link android.Manifest.permission#BIND_AUTOFILL} permission so 67 * that other applications can not abuse it. 68 */ 69 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) 70 public static final String SERVICE_INTERFACE = "android.service.autofill.AutofillService"; 71 72 /** 73 * Name under which a AutoFillService component publishes information about itself. 74 * This meta-data should reference an XML resource containing a 75 * <code><{@link 76 * android.R.styleable#AutofillService autofill-service}></code> tag. 77 * This is a a sample XML file configuring an AutoFillService: 78 * <pre> <autofill-service 79 * android:settingsActivity="foo.bar.SettingsActivity" 80 * . . . 81 * /></pre> 82 */ 83 public static final String SERVICE_META_DATA = "android.autofill"; 84 85 // Internal extras 86 /** @hide */ 87 public static final String EXTRA_SESSION_ID = "android.service.autofill.extra.SESSION_ID"; 88 89 // Handler messages. 90 private static final int MSG_CONNECT = 1; 91 private static final int MSG_DISCONNECT = 2; 92 private static final int MSG_ON_FILL_REQUEST = 3; 93 private static final int MSG_ON_SAVE_REQUEST = 4; 94 95 private static final int UNUSED_ARG = -1; 96 97 private final IAutoFillService mInterface = new IAutoFillService.Stub() { 98 @Override 99 public void onConnectedStateChanged(boolean connected) { 100 if (connected) { 101 mHandlerCaller.obtainMessage(MSG_CONNECT).sendToTarget(); 102 } else { 103 mHandlerCaller.obtainMessage(MSG_DISCONNECT).sendToTarget(); 104 } 105 } 106 107 @Override 108 public void onFillRequest(FillRequest request, IFillCallback callback) { 109 ICancellationSignal transport = CancellationSignal.createTransport(); 110 try { 111 callback.onCancellable(transport); 112 } catch (RemoteException e) { 113 e.rethrowFromSystemServer(); 114 } 115 mHandlerCaller.obtainMessageOOO(MSG_ON_FILL_REQUEST, request, 116 CancellationSignal.fromTransport(transport), callback) 117 .sendToTarget(); 118 } 119 120 @Override 121 public void onSaveRequest(SaveRequest request, ISaveCallback callback) { 122 mHandlerCaller.obtainMessageOO(MSG_ON_SAVE_REQUEST, request, 123 callback).sendToTarget(); 124 } 125 }; 126 127 private final HandlerCaller.Callback mHandlerCallback = (msg) -> { 128 switch (msg.what) { 129 case MSG_CONNECT: { 130 onConnected(); 131 break; 132 } case MSG_ON_FILL_REQUEST: { 133 final SomeArgs args = (SomeArgs) msg.obj; 134 final FillRequest request = (FillRequest) args.arg1; 135 final CancellationSignal cancellation = (CancellationSignal) args.arg2; 136 final IFillCallback callback = (IFillCallback) args.arg3; 137 final FillCallback fillCallback = new FillCallback(callback, request.getId()); 138 args.recycle(); 139 onFillRequest(request, cancellation, fillCallback); 140 break; 141 } case MSG_ON_SAVE_REQUEST: { 142 final SomeArgs args = (SomeArgs) msg.obj; 143 final SaveRequest request = (SaveRequest) args.arg1; 144 final ISaveCallback callback = (ISaveCallback) args.arg2; 145 final SaveCallback saveCallback = new SaveCallback(callback); 146 args.recycle(); 147 onSaveRequest(request, saveCallback); 148 break; 149 } case MSG_DISCONNECT: { 150 onDisconnected(); 151 break; 152 } default: { 153 Log.w(TAG, "MyCallbacks received invalid message type: " + msg); 154 } 155 } 156 }; 157 158 private HandlerCaller mHandlerCaller; 159 160 /** 161 * {@inheritDoc} 162 * 163 * <strong>NOTE: </strong>if overridden, it must call {@code super.onCreate()}. 164 */ 165 @Override 166 public void onCreate() { 167 super.onCreate(); 168 mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(), mHandlerCallback, true); 169 } 170 171 @Override 172 public final IBinder onBind(Intent intent) { 173 if (SERVICE_INTERFACE.equals(intent.getAction()) 174 || OLD_SERVICE_INTERFACE.equals(intent.getAction())) { 175 return mInterface.asBinder(); 176 } 177 Log.w(TAG, "Tried to bind to wrong intent: " + intent); 178 return null; 179 } 180 181 /** 182 * Called when the Android system connects to service. 183 * 184 * <p>You should generally do initialization here rather than in {@link #onCreate}. 185 */ 186 public void onConnected() { 187 } 188 189 /** 190 * Called by the Android system do decide if an {@link Activity} can be autofilled by the 191 * service. 192 * 193 * <p>Service must call one of the {@link FillCallback} methods (like 194 * {@link FillCallback#onSuccess(FillResponse)} 195 * or {@link FillCallback#onFailure(CharSequence)}) 196 * to notify the result of the request. 197 * 198 * @param request the {@link FillRequest request} to handle. 199 * See {@link FillResponse} for examples of multiple-sections requests. 200 * @param cancellationSignal signal for observing cancellation requests. The system will use 201 * this to notify you that the fill result is no longer needed and you should stop 202 * handling this fill request in order to save resources. 203 * @param callback object used to notify the result of the request. 204 */ 205 public void onFillRequest(@NonNull FillRequest request, 206 @NonNull CancellationSignal cancellationSignal, @NonNull FillCallback callback) { 207 onFillRequest(request.getStructure(), request.getClientState(), request.getFlags(), 208 cancellationSignal, callback); 209 } 210 211 /** 212 * Called by the Android system do decide if an {@link Activity} can be autofilled by the 213 * service. 214 * 215 * <p>Service must call one of the {@link FillCallback} methods (like 216 * {@link FillCallback#onSuccess(FillResponse)} 217 * or {@link FillCallback#onFailure(CharSequence)}) 218 * to notify the result of the request. 219 * 220 * @param structure {@link Activity}'s view structure. 221 * @param data bundle containing data passed by the service in a last call to 222 * {@link FillResponse.Builder#setExtras(Bundle)}, if any. This bundle allows your 223 * service to keep state between fill and save requests as well as when filling different 224 * sections of the UI as the system will try to aggressively unbind from the service to 225 * conserve resources. 226 * See {@link FillResponse} for examples of multiple-sections requests. 227 * @param flags either {@code 0} or {@link AutofillManager#FLAG_MANUAL_REQUEST}. 228 * @param cancellationSignal signal for observing cancellation requests. The system will use 229 * this to notify you that the fill result is no longer needed and you should stop 230 * handling this fill request in order to save resources. 231 * @param callback object used to notify the result of the request. 232 */ 233 @Deprecated 234 public abstract void onFillRequest(@NonNull AssistStructure structure, @Nullable Bundle data, 235 int flags, @NonNull CancellationSignal cancellationSignal, 236 @NonNull FillCallback callback); 237 238 /** 239 * Called when user requests service to save the fields of an {@link Activity}. 240 * 241 * <p>Service must call one of the {@link SaveCallback} methods (like 242 * {@link SaveCallback#onSuccess()} or {@link SaveCallback#onFailure(CharSequence)}) 243 * to notify the result of the request. 244 * 245 * @param request the {@link SaveRequest request} to handle. 246 * See {@link FillResponse} for examples of multiple-sections requests. 247 * @param callback object used to notify the result of the request. 248 */ 249 public void onSaveRequest(@NonNull SaveRequest request, @NonNull SaveCallback callback) { 250 final List<FillContext> contexts = request.getFillContexts(); 251 onSaveRequest(contexts.get(contexts.size() - 1).getStructure(), 252 request.getClientState(), callback); 253 } 254 255 /** 256 * Called when user requests service to save the fields of an {@link Activity}. 257 * 258 * <p>Service must call one of the {@link SaveCallback} methods (like 259 * {@link SaveCallback#onSuccess()} or {@link SaveCallback#onFailure(CharSequence)}) 260 * to notify the result of the request. 261 * 262 * @param structure {@link Activity}'s view structure. 263 * @param data bundle containing data passed by the service in a last call to 264 * {@link FillResponse.Builder#setExtras(Bundle)}, if any. This bundle allows your 265 * service to keep state between fill and save requests as well as when filling different 266 * sections of the UI as the system will try to aggressively unbind from the service to 267 * conserve resources. 268 * See {@link FillResponse} for examples of multiple-sections requests. 269 * @param callback object used to notify the result of the request. 270 */ 271 @Deprecated 272 public abstract void onSaveRequest(@NonNull AssistStructure structure, @Nullable Bundle data, 273 @NonNull SaveCallback callback); 274 275 /** 276 * Called when the Android system disconnects from the service. 277 * 278 * <p> At this point this service may no longer be an active {@link AutofillService}. 279 */ 280 public void onDisconnected() { 281 } 282 283 @Deprecated 284 public final void disableSelf() { 285 // TODO(b/33197203): Remove when GCore has migrated off this API 286 getSystemService(AutofillManager.class).disableOwnedAutofillServices(); 287 } 288} 289