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