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