AutofillService.java revision 2e30c6f371be6211f1fa2b2257084df24a535795
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.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 37/** 38 * Top-level service of the current autofill service for a given user. 39 * 40 * <p>Apps providing autofill capabilities must extend this service. 41 */ 42public abstract class AutofillService extends Service { 43 private static final String TAG = "AutofillService"; 44 45 /** 46 * The {@link Intent} that must be declared as handled by the service. 47 * To be supported, the service must also require the 48 * {@link android.Manifest.permission#BIND_AUTOFILL_SERVICE} permission so 49 * that other applications can not abuse it. 50 */ 51 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) 52 public static final String SERVICE_INTERFACE = "android.service.autofill.AutofillService"; 53 54 /** 55 * Name under which a AutoFillService component publishes information about itself. 56 * This meta-data should reference an XML resource containing a 57 * <code><{@link 58 * android.R.styleable#AutofillService autofill-service}></code> tag. 59 * This is a a sample XML file configuring an AutoFillService: 60 * <pre> <autofill-service 61 * android:settingsActivity="foo.bar.SettingsActivity" 62 * . . . 63 * /></pre> 64 */ 65 public static final String SERVICE_META_DATA = "android.autofill"; 66 67 // Handler messages. 68 private static final int MSG_CONNECT = 1; 69 private static final int MSG_DISCONNECT = 2; 70 private static final int MSG_ON_FILL_REQUEST = 3; 71 private static final int MSG_ON_SAVE_REQUEST = 4; 72 73 private final IAutoFillService mInterface = new IAutoFillService.Stub() { 74 @Override 75 public void onConnectedStateChanged(boolean connected) { 76 if (connected) { 77 mHandlerCaller.obtainMessage(MSG_CONNECT).sendToTarget(); 78 } else { 79 mHandlerCaller.obtainMessage(MSG_DISCONNECT).sendToTarget(); 80 } 81 } 82 83 @Override 84 public void onFillRequest(FillRequest request, IFillCallback callback) { 85 ICancellationSignal transport = CancellationSignal.createTransport(); 86 try { 87 callback.onCancellable(transport); 88 } catch (RemoteException e) { 89 e.rethrowFromSystemServer(); 90 } 91 mHandlerCaller.obtainMessageOOO(MSG_ON_FILL_REQUEST, request, 92 CancellationSignal.fromTransport(transport), callback) 93 .sendToTarget(); 94 } 95 96 @Override 97 public void onSaveRequest(SaveRequest request, ISaveCallback callback) { 98 mHandlerCaller.obtainMessageOO(MSG_ON_SAVE_REQUEST, request, 99 callback).sendToTarget(); 100 } 101 }; 102 103 private final HandlerCaller.Callback mHandlerCallback = (msg) -> { 104 switch (msg.what) { 105 case MSG_CONNECT: { 106 onConnected(); 107 break; 108 } case MSG_ON_FILL_REQUEST: { 109 final SomeArgs args = (SomeArgs) msg.obj; 110 final FillRequest request = (FillRequest) args.arg1; 111 final CancellationSignal cancellation = (CancellationSignal) args.arg2; 112 final IFillCallback callback = (IFillCallback) args.arg3; 113 final FillCallback fillCallback = new FillCallback(callback, request.getId()); 114 args.recycle(); 115 onFillRequest(request, cancellation, fillCallback); 116 break; 117 } case MSG_ON_SAVE_REQUEST: { 118 final SomeArgs args = (SomeArgs) msg.obj; 119 final SaveRequest request = (SaveRequest) args.arg1; 120 final ISaveCallback callback = (ISaveCallback) args.arg2; 121 final SaveCallback saveCallback = new SaveCallback(callback); 122 args.recycle(); 123 onSaveRequest(request, saveCallback); 124 break; 125 } case MSG_DISCONNECT: { 126 onDisconnected(); 127 break; 128 } default: { 129 Log.w(TAG, "MyCallbacks received invalid message type: " + msg); 130 } 131 } 132 }; 133 134 private HandlerCaller mHandlerCaller; 135 136 /** 137 * {@inheritDoc} 138 * 139 * <strong>NOTE: </strong>if overridden, it must call {@code super.onCreate()}. 140 */ 141 @CallSuper 142 @Override 143 public void onCreate() { 144 super.onCreate(); 145 mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(), mHandlerCallback, true); 146 } 147 148 @Override 149 public final IBinder onBind(Intent intent) { 150 if (SERVICE_INTERFACE.equals(intent.getAction())) { 151 return mInterface.asBinder(); 152 } 153 Log.w(TAG, "Tried to bind to wrong intent: " + intent); 154 return null; 155 } 156 157 /** 158 * Called when the Android system connects to service. 159 * 160 * <p>You should generally do initialization here rather than in {@link #onCreate}. 161 */ 162 public void onConnected() { 163 } 164 165 /** 166 * Called by the Android system do decide if an {@link Activity} can be autofilled by the 167 * service. 168 * 169 * <p>Service must call one of the {@link FillCallback} methods (like 170 * {@link FillCallback#onSuccess(FillResponse)} 171 * or {@link FillCallback#onFailure(CharSequence)}) 172 * to notify the result of the request. 173 * 174 * @param request the {@link FillRequest request} to handle. 175 * See {@link FillResponse} for examples of multiple-sections requests. 176 * @param cancellationSignal signal for observing cancellation requests. The system will use 177 * this to notify you that the fill result is no longer needed and you should stop 178 * handling this fill request in order to save resources. 179 * @param callback object used to notify the result of the request. 180 */ 181 public abstract void onFillRequest(@NonNull FillRequest request, 182 @NonNull CancellationSignal cancellationSignal, @NonNull FillCallback callback); 183 184 /** 185 * Called when user requests service to save the fields of an {@link Activity}. 186 * 187 * <p>Service must call one of the {@link SaveCallback} methods (like 188 * {@link SaveCallback#onSuccess()} or {@link SaveCallback#onFailure(CharSequence)}) 189 * to notify the result of the request. 190 * 191 * <p><b>NOTE: </b>to retrieve the actual value of the field, the service should call 192 * {@link android.app.assist.AssistStructure.ViewNode#getAutofillValue()}; if it calls 193 * {@link android.app.assist.AssistStructure.ViewNode#getText()} or other methods, there is no 194 * guarantee such method will return the most recent value of the field. 195 * 196 * @param request the {@link SaveRequest request} to handle. 197 * See {@link FillResponse} for examples of multiple-sections requests. 198 * @param callback object used to notify the result of the request. 199 */ 200 public abstract void onSaveRequest(@NonNull SaveRequest request, 201 @NonNull SaveCallback callback); 202 203 /** 204 * Called when the Android system disconnects from the service. 205 * 206 * <p> At this point this service may no longer be an active {@link AutofillService}. 207 */ 208 public void onDisconnected() { 209 } 210 211 /** @hide */ 212 @Deprecated 213 public final void disableSelf() { 214 getSystemService(AutofillManager.class).disableOwnedAutofillServices(); 215 } 216 217 /** 218 * Gets the events that happened after the last 219 * {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal, FillCallback)} 220 * call. 221 * 222 * <p>This method is typically used to keep track of previous user actions to optimize further 223 * requests. For example, the service might return email addresses in alphabetical order by 224 * default, but change that order based on the address the user picked on previous requests. 225 * 226 * <p>The history is not persisted over reboots, and it's cleared every time the service 227 * replies to a {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} by calling 228 * {@link FillCallback#onSuccess(FillResponse)} or {@link FillCallback#onFailure(CharSequence)} 229 * (if the service doesn't call any of these methods, the history will clear out after some 230 * pre-defined time). Hence, the service should call {@link #getFillEventHistory()} before 231 * finishing the {@link FillCallback}. 232 * 233 * @return The history or {@code null} if there are no events. 234 */ 235 @Nullable public final FillEventHistory getFillEventHistory() { 236 AutofillManager afm = getSystemService(AutofillManager.class); 237 238 if (afm == null) { 239 return null; 240 } else { 241 return afm.getFillEventHistory(); 242 } 243 } 244} 245