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 17 package com.android.server.telecom.callfiltering; 18 19 import android.provider.CallLog; 20 import android.provider.CallLog.Calls; 21 import android.text.TextUtils; 22 23 public class CallFilteringResult { 24 public boolean shouldAllowCall; 25 public boolean shouldReject; 26 public boolean shouldSilence; 27 public boolean shouldAddToCallLog; 28 public boolean shouldShowNotification; 29 public int mCallBlockReason = CallLog.Calls.BLOCK_REASON_NOT_BLOCKED; 30 public CharSequence mCallScreeningAppName = null; 31 public String mCallScreeningComponentName = null; 32 CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean shouldAddToCallLog, boolean shouldShowNotification)33 public CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean 34 shouldAddToCallLog, boolean shouldShowNotification) { 35 this.shouldAllowCall = shouldAllowCall; 36 this.shouldReject = shouldReject; 37 this.shouldSilence = false; 38 this.shouldAddToCallLog = shouldAddToCallLog; 39 this.shouldShowNotification = shouldShowNotification; 40 } 41 CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean shouldAddToCallLog, boolean shouldShowNotification, int callBlockReason, CharSequence callScreeningAppName, String callScreeningComponentName)42 public CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean 43 shouldAddToCallLog, boolean shouldShowNotification, int callBlockReason, 44 CharSequence callScreeningAppName, String callScreeningComponentName) { 45 this.shouldAllowCall = shouldAllowCall; 46 this.shouldReject = shouldReject; 47 this.shouldSilence = false; 48 this.shouldAddToCallLog = shouldAddToCallLog; 49 this.shouldShowNotification = shouldShowNotification; 50 this.mCallBlockReason = callBlockReason; 51 this.mCallScreeningAppName = callScreeningAppName; 52 this.mCallScreeningComponentName = callScreeningComponentName; 53 } 54 CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean shouldSilence, boolean shouldAddToCallLog, boolean shouldShowNotification)55 public CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean 56 shouldSilence, boolean shouldAddToCallLog, boolean shouldShowNotification) { 57 this.shouldAllowCall = shouldAllowCall; 58 this.shouldReject = shouldReject; 59 this.shouldSilence = shouldSilence; 60 this.shouldAddToCallLog = shouldAddToCallLog; 61 this.shouldShowNotification = shouldShowNotification; 62 } 63 CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean shouldSilence, boolean shouldAddToCallLog, boolean shouldShowNotification, int callBlockReason, CharSequence callScreeningAppName, String callScreeningComponentName)64 public CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean 65 shouldSilence, boolean shouldAddToCallLog, boolean shouldShowNotification, int 66 callBlockReason, CharSequence callScreeningAppName, String callScreeningComponentName) { 67 this.shouldAllowCall = shouldAllowCall; 68 this.shouldReject = shouldReject; 69 this.shouldSilence = shouldSilence; 70 this.shouldAddToCallLog = shouldAddToCallLog; 71 this.shouldShowNotification = shouldShowNotification; 72 this.mCallBlockReason = callBlockReason; 73 this.mCallScreeningAppName = callScreeningAppName; 74 this.mCallScreeningComponentName = callScreeningComponentName; 75 } 76 77 /** 78 * Combine this CallFilteringResult with another, returning a CallFilteringResult with the more 79 * restrictive properties of the two. Where there are multiple call filtering components which 80 * block a call, the first filter from {@link AsyncBlockCheckFilter}, 81 * {@link DirectToVoicemailCallFilter}, {@link CallScreeningServiceFilter} which blocked a call 82 * shall be used to populate the call block reason, component name, etc. 83 */ combine(CallFilteringResult other)84 public CallFilteringResult combine(CallFilteringResult other) { 85 if (other == null) { 86 return this; 87 } 88 89 if (isBlockedByProvider(mCallBlockReason)) { 90 return getCombinedCallFilteringResult(other, mCallBlockReason, 91 null /*callScreeningAppName*/, null /*callScreeningComponentName*/); 92 } else if (isBlockedByProvider(other.mCallBlockReason)) { 93 return getCombinedCallFilteringResult(other, other.mCallBlockReason, 94 null /*callScreeningAppName*/, null /*callScreeningComponentName*/); 95 } 96 97 if (mCallBlockReason == Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL 98 || other.mCallBlockReason == Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL) { 99 return getCombinedCallFilteringResult(other, Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL, 100 null /*callScreeningAppName*/, null /*callScreeningComponentName*/); 101 } 102 103 if (shouldReject && mCallBlockReason == CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE) { 104 return getCombinedCallFilteringResult(other, Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, 105 mCallScreeningAppName, mCallScreeningComponentName); 106 } else if (other.shouldReject && other.mCallBlockReason == CallLog.Calls 107 .BLOCK_REASON_CALL_SCREENING_SERVICE) { 108 return getCombinedCallFilteringResult(other, Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, 109 other.mCallScreeningAppName, other.mCallScreeningComponentName); 110 } 111 112 return new CallFilteringResult( 113 shouldAllowCall && other.shouldAllowCall, 114 shouldReject || other.shouldReject, 115 shouldSilence || other.shouldSilence, 116 shouldAddToCallLog && other.shouldAddToCallLog, 117 shouldShowNotification && other.shouldShowNotification); 118 } 119 isBlockedByProvider(int blockReason)120 private boolean isBlockedByProvider(int blockReason) { 121 if (blockReason == Calls.BLOCK_REASON_BLOCKED_NUMBER 122 || blockReason == Calls.BLOCK_REASON_UNKNOWN_NUMBER 123 || blockReason == Calls.BLOCK_REASON_RESTRICTED_NUMBER 124 || blockReason == Calls.BLOCK_REASON_PAY_PHONE 125 || blockReason == Calls.BLOCK_REASON_NOT_IN_CONTACTS) { 126 return true; 127 } 128 129 return false; 130 } 131 getCombinedCallFilteringResult(CallFilteringResult other, int callBlockReason, CharSequence callScreeningAppName, String callScreeningComponentName)132 private CallFilteringResult getCombinedCallFilteringResult(CallFilteringResult other, 133 int callBlockReason, CharSequence callScreeningAppName, String callScreeningComponentName) { 134 return new CallFilteringResult( 135 shouldAllowCall && other.shouldAllowCall, 136 shouldReject || other.shouldReject, 137 shouldSilence|| other.shouldSilence, 138 shouldAddToCallLog && other.shouldAddToCallLog, 139 shouldShowNotification && other.shouldShowNotification, 140 callBlockReason, 141 callScreeningAppName, 142 callScreeningComponentName); 143 } 144 145 146 @Override equals(Object o)147 public boolean equals(Object o) { 148 if (this == o) return true; 149 if (o == null || getClass() != o.getClass()) return false; 150 151 CallFilteringResult that = (CallFilteringResult) o; 152 153 if (shouldAllowCall != that.shouldAllowCall) return false; 154 if (shouldReject != that.shouldReject) return false; 155 if (shouldSilence != that.shouldSilence) return false; 156 if (shouldAddToCallLog != that.shouldAddToCallLog) return false; 157 if (shouldShowNotification != that.shouldShowNotification) return false; 158 if (mCallBlockReason != that.mCallBlockReason) return false; 159 160 if ((TextUtils.isEmpty(mCallScreeningAppName) && 161 TextUtils.isEmpty(that.mCallScreeningAppName)) && 162 (TextUtils.isEmpty(mCallScreeningComponentName) && 163 TextUtils.isEmpty(that.mCallScreeningComponentName))) { 164 return true; 165 } else if (!TextUtils.isEmpty(mCallScreeningAppName) && 166 !TextUtils.isEmpty(that.mCallScreeningAppName) && 167 mCallScreeningAppName.equals(that.mCallScreeningAppName) && 168 !TextUtils.isEmpty(mCallScreeningComponentName) && 169 !TextUtils.isEmpty(that.mCallScreeningComponentName) && 170 mCallScreeningComponentName.equals(that.mCallScreeningComponentName)) { 171 return true; 172 } 173 174 return false; 175 } 176 177 @Override hashCode()178 public int hashCode() { 179 int result = (shouldAllowCall ? 1 : 0); 180 result = 31 * result + (shouldReject ? 1 : 0); 181 result = 31 * result + (shouldSilence ? 1 : 0); 182 result = 31 * result + (shouldAddToCallLog ? 1 : 0); 183 result = 31 * result + (shouldShowNotification ? 1 : 0); 184 return result; 185 } 186 187 @Override toString()188 public String toString() { 189 StringBuilder sb = new StringBuilder(); 190 sb.append("["); 191 if (shouldAllowCall) { 192 sb.append("Allow"); 193 } else if (shouldReject) { 194 sb.append("Reject"); 195 } else if (shouldSilence) { 196 sb.append("Silence"); 197 } else { 198 sb.append("Ignore"); 199 } 200 201 if (shouldAddToCallLog) { 202 sb.append(", logged"); 203 } 204 205 if (shouldShowNotification) { 206 sb.append(", notified"); 207 } 208 209 if (mCallBlockReason != 0) { 210 sb.append(", mCallBlockReason = "); 211 sb.append(mCallBlockReason); 212 } 213 214 if (!TextUtils.isEmpty(mCallScreeningAppName)) { 215 sb.append(", mCallScreeningAppName = "); 216 sb.append(mCallScreeningAppName); 217 } 218 219 if (!TextUtils.isEmpty(mCallScreeningComponentName)) { 220 sb.append(", mCallScreeningComponentName = "); 221 sb.append(mCallScreeningComponentName); 222 } 223 sb.append("]"); 224 225 return sb.toString(); 226 } 227 } 228