1/*
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 */
16
17package com.android.server.telecom.callfiltering;
18
19import android.content.Context;
20import android.net.Uri;
21import android.os.AsyncTask;
22import android.os.Bundle;
23import android.provider.BlockedNumberContract;
24import android.telecom.Log;
25import android.telecom.Logging.Session;
26import android.telecom.TelecomManager;
27
28import com.android.internal.telephony.CallerInfo;
29import com.android.server.telecom.Call;
30import com.android.server.telecom.CallerInfoLookupHelper;
31import com.android.server.telecom.LogUtils;
32import com.android.server.telecom.settings.BlockedNumbersUtil;
33
34/**
35 * An {@link AsyncTask} that checks if a call needs to be blocked.
36 * <p> An {@link AsyncTask} is used to perform the block check to avoid blocking the main thread.
37 * The block check itself is performed in the {@link AsyncTask#doInBackground(Object[])}.
38 */
39public class AsyncBlockCheckFilter extends AsyncTask<String, Void, Boolean>
40        implements IncomingCallFilter.CallFilter {
41    private final Context mContext;
42    private final BlockCheckerAdapter mBlockCheckerAdapter;
43    private Call mIncomingCall;
44    private Session mBackgroundTaskSubsession;
45    private Session mPostExecuteSubsession;
46    private CallFilterResultCallback mCallback;
47    private CallerInfoLookupHelper mCallerInfoLookupHelper;
48
49    public AsyncBlockCheckFilter(Context context, BlockCheckerAdapter blockCheckerAdapter,
50            CallerInfoLookupHelper callerInfoLookupHelper) {
51        mContext = context;
52        mBlockCheckerAdapter = blockCheckerAdapter;
53        mCallerInfoLookupHelper = callerInfoLookupHelper;
54    }
55
56    @Override
57    public void startFilterLookup(Call call, CallFilterResultCallback callback) {
58        mCallback = callback;
59        mIncomingCall = call;
60        String number = call.getHandle() == null ?
61                null : call.getHandle().getSchemeSpecificPart();
62        if (BlockedNumbersUtil.isEnhancedCallBlockingEnabledByPlatform(mContext)) {
63            int presentation = mIncomingCall.getHandlePresentation();
64            if (presentation == TelecomManager.PRESENTATION_ALLOWED) {
65                mCallerInfoLookupHelper.startLookup(call.getHandle(),
66                        new CallerInfoLookupHelper.OnQueryCompleteListener() {
67                            @Override
68                            public void onCallerInfoQueryComplete(Uri handle, CallerInfo info) {
69                                boolean contactExists = info == null ? false : info.contactExists;
70                                execute(number, String.valueOf(presentation),
71                                        String.valueOf(contactExists));
72                            }
73
74                            @Override
75                            public void onContactPhotoQueryComplete(Uri handle, CallerInfo info) {
76                                // ignore
77                            }
78                        });
79            } else {
80                this.execute(number, String.valueOf(presentation));
81            }
82        } else {
83            this.execute(number);
84        }
85    }
86
87    @Override
88    protected void onPreExecute() {
89        mBackgroundTaskSubsession = Log.createSubsession();
90        mPostExecuteSubsession = Log.createSubsession();
91    }
92
93    @Override
94    protected Boolean doInBackground(String... params) {
95        try {
96            Log.continueSession(mBackgroundTaskSubsession, "ABCF.dIB");
97            Log.addEvent(mIncomingCall, LogUtils.Events.BLOCK_CHECK_INITIATED);
98            Bundle extras = new Bundle();
99            if (params.length > 1) {
100                extras.putInt(BlockedNumberContract.EXTRA_CALL_PRESENTATION,
101                        Integer.valueOf(params[1]));
102            }
103            if (params.length > 2) {
104                extras.putBoolean(BlockedNumberContract.EXTRA_CONTACT_EXIST,
105                        Boolean.valueOf(params[2]));
106            }
107            return mBlockCheckerAdapter.isBlocked(mContext, params[0], extras);
108        } finally {
109            Log.endSession();
110        }
111    }
112
113    @Override
114    protected void onPostExecute(Boolean isBlocked) {
115        Log.continueSession(mPostExecuteSubsession, "ABCF.oPE");
116        try {
117            CallFilteringResult result;
118            if (isBlocked) {
119                result = new CallFilteringResult(
120                        false, // shouldAllowCall
121                        true, //shouldReject
122                        false, //shouldAddToCallLog
123                        false // shouldShowNotification
124                );
125            } else {
126                result = new CallFilteringResult(
127                        true, // shouldAllowCall
128                        false, // shouldReject
129                        true, // shouldAddToCallLog
130                        true // shouldShowNotification
131                );
132            }
133            Log.addEvent(mIncomingCall, LogUtils.Events.BLOCK_CHECK_FINISHED, result);
134            mCallback.onCallFilteringComplete(mIncomingCall, result);
135        } finally {
136            Log.endSession();
137        }
138    }
139}
140