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 */
16
17package com.android.server.am;
18
19import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
20import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
21
22import android.app.IAssistDataReceiver;
23import android.graphics.Bitmap;
24import android.os.Binder;
25import android.os.Bundle;
26import android.os.RemoteException;
27import android.util.Log;
28
29import com.android.server.am.AssistDataRequester.AssistDataRequesterCallbacks;
30
31/**
32 * Proxies assist data to the given receiver, skipping all callbacks if the receiver dies.
33 */
34class AssistDataReceiverProxy implements AssistDataRequesterCallbacks,
35        Binder.DeathRecipient {
36
37    private static final String TAG = TAG_WITH_CLASS_NAME ? "AssistDataReceiverProxy" : TAG_AM;
38
39    private String mCallerPackage;
40    private IAssistDataReceiver mReceiver;
41
42    public AssistDataReceiverProxy(IAssistDataReceiver receiver, String callerPackage) {
43        mReceiver = receiver;
44        mCallerPackage = callerPackage;
45        linkToDeath();
46    }
47
48    @Override
49    public boolean canHandleReceivedAssistDataLocked() {
50        // We are forwarding, so we can always receive this data
51        return true;
52    }
53
54    @Override
55    public void onAssistDataReceivedLocked(Bundle data, int activityIndex, int activityCount) {
56        if (mReceiver != null) {
57            try {
58                mReceiver.onHandleAssistData(data);
59            } catch (RemoteException e) {
60                Log.w(TAG, "Failed to proxy assist data to receiver in package="
61                        + mCallerPackage, e);
62            }
63        }
64    }
65
66    @Override
67    public void onAssistScreenshotReceivedLocked(Bitmap screenshot) {
68        if (mReceiver != null) {
69            try {
70                mReceiver.onHandleAssistScreenshot(screenshot);
71            } catch (RemoteException e) {
72                Log.w(TAG, "Failed to proxy assist screenshot to receiver in package="
73                        + mCallerPackage, e);
74            }
75        }
76    }
77
78    @Override
79    public void onAssistRequestCompleted() {
80        unlinkToDeath();
81    }
82
83    @Override
84    public void binderDied() {
85        unlinkToDeath();
86    }
87
88    private void linkToDeath() {
89        try {
90            mReceiver.asBinder().linkToDeath(this, 0);
91        } catch (RemoteException e) {
92            Log.w(TAG, "Could not link to client death", e);
93        }
94    }
95
96    private void unlinkToDeath() {
97        if (mReceiver != null) {
98            mReceiver.asBinder().unlinkToDeath(this, 0);
99        }
100        mReceiver = null;
101    }
102}