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