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 static android.view.autofill.Helper.sDebug;
19
20import android.annotation.NonNull;
21import android.annotation.TestApi;
22import android.os.Parcelable;
23import android.util.Log;
24import android.util.Pair;
25import android.widget.RemoteViews;
26
27import java.util.ArrayList;
28
29/**
30 * Superclass of all transformation the system understands. As this is not public all
31 * subclasses have to implement {@link Transformation} again.
32 *
33 * @hide
34 */
35@TestApi
36public abstract class InternalTransformation implements Transformation, Parcelable {
37
38    private static final String TAG = "InternalTransformation";
39
40    /**
41     * Applies this transformation to a child view of a {@link android.widget.RemoteViews
42     * presentation template}.
43     *
44     * @param finder object used to find the value of a field in the screen.
45     * @param template the {@link RemoteViews presentation template}.
46     * @param childViewId resource id of the child view inside the template.
47     *
48     * @hide
49     */
50    abstract void apply(@NonNull ValueFinder finder, @NonNull RemoteViews template,
51            int childViewId) throws Exception;
52
53    /**
54     * Applies multiple transformations to the children views of a
55     * {@link android.widget.RemoteViews presentation template}.
56     *
57     * @param finder object used to find the value of a field in the screen.
58     * @param template the {@link RemoteViews presentation template}.
59     * @param transformations map of resource id of the child view inside the template to
60     * transformation.
61     *
62     * @hide
63     */
64    public static boolean batchApply(@NonNull ValueFinder finder, @NonNull RemoteViews template,
65            @NonNull ArrayList<Pair<Integer, InternalTransformation>> transformations) {
66        final int size = transformations.size();
67        if (sDebug) Log.d(TAG, "getPresentation(): applying " + size + " transformations");
68        for (int i = 0; i < size; i++) {
69            final Pair<Integer, InternalTransformation> pair = transformations.get(i);
70            final int id = pair.first;
71            final InternalTransformation transformation = pair.second;
72            if (sDebug) Log.d(TAG, "#" + i + ": " + transformation);
73
74            try {
75                transformation.apply(finder, template, id);
76            } catch (Exception e) {
77                // Do not log full exception to avoid PII leaking
78                Log.e(TAG, "Could not apply transformation " + transformation + ": "
79                        + e.getClass());
80                return false;
81            }
82        }
83        return true;
84    }
85}
86