blob: 83b2065f44fe8ef6b10997d8ffabcf61bbc48df4 [file] [log] [blame]
Felipe Leme5381aa42016-10-13 09:02:32 -07001/*
2 * Copyright (C) 2016 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
Felipe Leme29a5b0d2016-10-25 14:57:11 -070018import android.annotation.IntDef;
Felipe Leme5381aa42016-10-13 09:02:32 -070019import android.annotation.SdkConstant;
Felipe Leme29a5b0d2016-10-25 14:57:11 -070020import android.app.Activity;
Felipe Leme5381aa42016-10-13 09:02:32 -070021import android.app.Service;
22import android.app.assist.AssistStructure;
23import android.content.Intent;
24import android.os.Bundle;
Felipe Leme29a5b0d2016-10-25 14:57:11 -070025import android.os.CancellationSignal;
Felipe Leme5381aa42016-10-13 09:02:32 -070026import android.os.IBinder;
27import android.os.Looper;
28import android.os.Message;
Felipe Leme29a5b0d2016-10-25 14:57:11 -070029import android.os.RemoteException;
30import android.service.voice.VoiceInteractionSession;
Felipe Leme5381aa42016-10-13 09:02:32 -070031import android.util.Log;
32
33import com.android.internal.os.HandlerCaller;
Felipe Leme29a5b0d2016-10-25 14:57:11 -070034import com.android.internal.os.IResultReceiver;
Felipe Leme5381aa42016-10-13 09:02:32 -070035import com.android.internal.os.SomeArgs;
36
Felipe Leme29a5b0d2016-10-25 14:57:11 -070037import java.lang.annotation.Retention;
38import java.lang.annotation.RetentionPolicy;
39
Felipe Leme5381aa42016-10-13 09:02:32 -070040/**
41 * Top-level service of the current auto-fill service for a given user.
Felipe Leme29a5b0d2016-10-25 14:57:11 -070042 *
43 * <p>Apps providing auto-fill capabilities must extend this service.
Felipe Leme5381aa42016-10-13 09:02:32 -070044 */
Felipe Leme5381aa42016-10-13 09:02:32 -070045public abstract class AutoFillService extends Service {
46
Felipe Leme29a5b0d2016-10-25 14:57:11 -070047 static final String TAG = "AutoFillService";
48 static final boolean DEBUG = true; // TODO: set to false once stable
Felipe Leme5381aa42016-10-13 09:02:32 -070049
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 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
57 public static final String SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
58
59 private static final int MSG_READY = 1;
Felipe Leme29a5b0d2016-10-25 14:57:11 -070060 private static final int MSG_AUTO_FILL = 2;
61 private static final int MSG_SHUTDOWN = 3;
Felipe Leme5381aa42016-10-13 09:02:32 -070062
Felipe Leme29a5b0d2016-10-25 14:57:11 -070063 private final IResultReceiver mAssistReceiver = new IResultReceiver.Stub() {
64 @Override
65 public void send(int resultCode, Bundle resultData) throws RemoteException {
66 final AssistStructure structure = resultData
67 .getParcelable(VoiceInteractionSession.KEY_STRUCTURE);
68
69 final IBinder binder = resultData
70 .getBinder(VoiceInteractionSession.KEY_AUTO_FILL_CALLBACK);
71
72 mHandlerCaller
73 .obtainMessageOO(MSG_AUTO_FILL, structure, binder).sendToTarget();
74 }
75
76 };
Felipe Leme5381aa42016-10-13 09:02:32 -070077
78 private final IAutoFillService mInterface = new IAutoFillService.Stub() {
79 @Override
80 public void ready() {
81 mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_READY));
82 }
83
84 @Override
Felipe Leme29a5b0d2016-10-25 14:57:11 -070085 public IResultReceiver getAssistReceiver() {
86 return mAssistReceiver;
Felipe Leme5381aa42016-10-13 09:02:32 -070087 }
88
89 @Override
90 public void shutdown() {
91 mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_SHUTDOWN));
92 }
93 };
94
95 private final HandlerCaller.Callback mHandlerCallback = new HandlerCaller.Callback() {
96
97 @Override
98 public void executeMessage(Message msg) {
99 switch (msg.what) {
100 case MSG_READY: {
101 onReady();
102 break;
Felipe Leme29a5b0d2016-10-25 14:57:11 -0700103 } case MSG_AUTO_FILL: {
Felipe Leme5381aa42016-10-13 09:02:32 -0700104 final SomeArgs args = (SomeArgs) msg.obj;
Felipe Leme29a5b0d2016-10-25 14:57:11 -0700105 final AssistStructure structure = (AssistStructure) args.arg1;
106 final IBinder binder = (IBinder) args.arg2;
107 autoFillActivity(structure, binder);
Felipe Leme5381aa42016-10-13 09:02:32 -0700108 break;
109 } case MSG_SHUTDOWN: {
110 onShutdown();
111 break;
112 } default: {
113 Log.w(TAG, "MyCallbacks received invalid message type: " + msg);
114 }
115 }
116 }
117 };
118
119 private HandlerCaller mHandlerCaller;
120
121 @Override
122 public void onCreate() {
123 super.onCreate();
124
125 mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(), mHandlerCallback, true);
126 }
127
128 @Override
129 public final IBinder onBind(Intent intent) {
130 if (SERVICE_INTERFACE.equals(intent.getAction())) {
131 return mInterface.asBinder();
132 }
Felipe Leme29a5b0d2016-10-25 14:57:11 -0700133 Log.w(TAG, "Tried to bind to wrong intent: " + intent);
Felipe Leme5381aa42016-10-13 09:02:32 -0700134 return null;
135 }
136
137 /**
138 * Called during service initialization to tell you when the system is ready
139 * to receive interaction from it.
140 *
141 * <p>You should generally do initialization here rather than in {@link #onCreate}.
Felipe Leme5381aa42016-10-13 09:02:32 -0700142 */
Felipe Leme29a5b0d2016-10-25 14:57:11 -0700143 // TODO: rename to onConnect() / update javadoc
Felipe Leme5381aa42016-10-13 09:02:32 -0700144 public void onReady() {
145 if (DEBUG) Log.d(TAG, "onReady()");
146 }
147
148 /**
Felipe Leme29a5b0d2016-10-25 14:57:11 -0700149 * Handles an auto-fill request.
Felipe Leme5381aa42016-10-13 09:02:32 -0700150 *
Felipe Leme29a5b0d2016-10-25 14:57:11 -0700151 * @param structure {@link Activity}'s view structure .
152 * @param cancellationSignal signal for observing cancel requests.
153 * @param callback object used to fulllfill the request.
Felipe Leme5381aa42016-10-13 09:02:32 -0700154 */
Felipe Leme29a5b0d2016-10-25 14:57:11 -0700155 public abstract void onFillRequest(AssistStructure structure,
156 CancellationSignal cancellationSignal, FillCallback callback);
Felipe Leme5381aa42016-10-13 09:02:32 -0700157
Felipe Leme29a5b0d2016-10-25 14:57:11 -0700158 private void autoFillActivity(AssistStructure structure, IBinder binder) {
159 final FillCallback callback = new FillCallback(binder);
160 // TODO: hook up the cancelationSignal
161 onFillRequest(structure, new CancellationSignal(), callback);
Felipe Leme5381aa42016-10-13 09:02:32 -0700162 }
163
164 /**
165 * Called during service de-initialization to tell you when the system is shutting the
166 * service down.
167 *
168 * <p> At this point this service may no longer be an active {@link AutoFillService}.
169 */
Felipe Leme29a5b0d2016-10-25 14:57:11 -0700170 // TODO: rename to onDisconnected() / update javadoc
Felipe Leme5381aa42016-10-13 09:02:32 -0700171 public void onShutdown() {
172 if (DEBUG) Log.d(TAG, "onShutdown()");
173 }
Felipe Leme29a5b0d2016-10-25 14:57:11 -0700174
Felipe Leme5381aa42016-10-13 09:02:32 -0700175}