blob: 0aff9d2263e1909469855787be4f632416c44dac [file] [log] [blame]
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.inlinefillservice;
import android.app.PendingIntent;
import android.app.slice.Slice;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.service.autofill.Dataset;
import android.service.autofill.FillRequest;
import android.service.autofill.InlinePresentation;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.view.autofill.AutofillId;
import android.view.inputmethod.InlineSuggestionsRequest;
import android.widget.inline.InlinePresentationSpec;
import androidx.autofill.inline.v1.InlineSuggestionUi;
import androidx.autofill.inline.v1.InlineSuggestionUi.Content;
import java.util.Optional;
public class InlineRequestHelper {
static Optional<InlineSuggestionsRequest> getInlineSuggestionsRequest(FillRequest request) {
final InlineSuggestionsRequest inlineRequest = request.getInlineSuggestionsRequest();
if (inlineRequest != null && inlineRequest.getMaxSuggestionCount() > 0
&& !inlineRequest.getInlinePresentationSpecs().isEmpty()) {
return Optional.of(inlineRequest);
}
return Optional.empty();
}
static int getMaxSuggestionCount(Optional<InlineSuggestionsRequest> inlineRequest, int max) {
if (inlineRequest.isPresent()) {
return Math.min(max, inlineRequest.get().getMaxSuggestionCount());
}
return max;
}
static InlinePresentation maybeCreateInlineAuthenticationResponse(
Context context, Optional<InlineSuggestionsRequest> inlineRequest) {
if (!inlineRequest.isPresent()) {
return null;
}
final PendingIntent attribution = createAttribution(context,
"Please tap on the chip to authenticate the Autofill response.");
final Slice slice = createSlice("Tap to auth response", null, null, null, attribution);
final InlinePresentationSpec spec = inlineRequest.get().getInlinePresentationSpecs().get(0);
return new InlinePresentation(slice, spec, false);
}
static InlinePresentation createInlineDataset(Context context,
InlineSuggestionsRequest inlineRequest, String value, int index) {
final PendingIntent attribution = createAttribution(context,
"Please tap on the chip to autofill the value:" + value);
final Slice slice = createSlice(value, null, null, null, attribution);
index = Math.min(inlineRequest.getInlinePresentationSpecs().size() - 1, index);
final InlinePresentationSpec spec = inlineRequest.getInlinePresentationSpecs().get(index);
return new InlinePresentation(slice, spec, false);
}
static Dataset createInlineActionDataset(Context context,
ArrayMap<String, AutofillId> fields,
InlineSuggestionsRequest inlineRequest, int drawable) {
PendingIntent pendingIntent =
PendingIntent.getActivity(context, 0, new Intent(context, SettingsActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
Dataset.Builder builder =
new Dataset.Builder()
.setInlinePresentation(createInlineAction(context, inlineRequest, drawable))
.setAuthentication(pendingIntent.getIntentSender());
for (AutofillId fieldId : fields.values()) {
builder.setValue(fieldId, null);
}
return builder.build();
}
private static InlinePresentation createInlineAction(Context context,
InlineSuggestionsRequest inlineRequest, int drawable) {
final PendingIntent attribution = createAttribution(context,
"Please tap on the chip to launch the action.");
final Icon icon = Icon.createWithResource(context, drawable);
final Slice slice = createSlice(null, null, icon, null, attribution);
// Reuse the first spec's height for the inline action size, as there isn't dedicated
// value from the request for this.
final InlinePresentationSpec spec = inlineRequest.getInlinePresentationSpecs().get(0);
return new InlinePresentation(slice, spec, true);
}
private static Slice createSlice(
String title, String subtitle, Icon startIcon, Icon endIcon,
PendingIntent attribution) {
Content.Builder builder = InlineSuggestionUi.newContentBuilder(attribution);
if (!TextUtils.isEmpty(title)) {
builder.setTitle(title);
}
if (!TextUtils.isEmpty(subtitle)) {
builder.setSubtitle(subtitle);
}
if (startIcon != null) {
builder.setStartIcon(startIcon);
}
if (endIcon != null) {
builder.setEndIcon(endIcon);
}
return builder.build().getSlice();
}
private static PendingIntent createAttribution(Context context, String msg) {
Intent intent = new Intent(context, AttributionDialogActivity.class);
intent.putExtra(AttributionDialogActivity.KEY_MSG, msg);
// Should use different request code to avoid the new intent overriding the old one.
PendingIntent pendingIntent = PendingIntent.getActivity(context, msg.hashCode(), intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
return pendingIntent;
}
}