Loading src/com/android/server/telecom/CallsManager.java +4 −4 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ import com.android.server.telecom.callfiltering.AsyncBlockCheckFilter; import com.android.server.telecom.callfiltering.BlockCheckerAdapter; import com.android.server.telecom.callfiltering.CallFilterResultCallback; import com.android.server.telecom.callfiltering.CallFilteringResult; import com.android.server.telecom.callfiltering.CallScreeningServiceFilter; import com.android.server.telecom.callfiltering.CallScreeningServiceController; import com.android.server.telecom.callfiltering.DirectToVoicemailCallFilter; import com.android.server.telecom.callfiltering.IncomingCallFilter; import com.android.server.telecom.components.ErrorDialogActivity; Loading Loading @@ -568,9 +568,9 @@ public class CallsManager extends Call.ListenerBase filters.add(new DirectToVoicemailCallFilter(mCallerInfoLookupHelper)); filters.add(new AsyncBlockCheckFilter(mContext, new BlockCheckerAdapter(), mCallerInfoLookupHelper, null)); filters.add(new CallScreeningServiceFilter(mContext, this, mPhoneAccountRegistrar, mDefaultDialerCache, new ParcelableCallUtils.Converter(), mLock, new TelecomServiceImpl.SettingsSecureAdapterImpl())); filters.add(new CallScreeningServiceController(mContext, this, mPhoneAccountRegistrar, new ParcelableCallUtils.Converter(), mLock, new TelecomServiceImpl.SettingsSecureAdapterImpl(), mCallerInfoLookupHelper)); new IncomingCallFilter(mContext, this, incomingCall, mLock, mTimeoutsAdapter, filters).performFiltering(); } Loading src/com/android/server/telecom/LogUtils.java +2 −0 Original line number Diff line number Diff line Loading @@ -108,6 +108,8 @@ public class LogUtils { public static final String BIND_SCREENING = "BIND_SCREENING"; public static final String SCREENING_BOUND = "SCREENING_BOUND"; public static final String SCREENING_SENT = "SCREENING_SENT"; public static final String CONTROLLER_SCREENING_COMPLETED = "CONTROLLER_SCREENING_COMPLETED"; public static final String SCREENING_COMPLETED = "SCREENING_COMPLETED"; public static final String BLOCK_CHECK_INITIATED = "BLOCK_CHECK_INITIATED"; public static final String BLOCK_CHECK_FINISHED = "BLOCK_CHECK_FINISHED"; Loading src/com/android/server/telecom/callfiltering/CallScreeningServiceController.java 0 → 100644 +264 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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.android.server.telecom.callfiltering; import android.content.ComponentName; import android.content.Context; import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.PersistableBundle; import android.os.UserHandle; import android.provider.CallLog; import android.provider.Settings; import android.telecom.Log; import android.telecom.Logging.Runnable; import android.telecom.TelecomManager; import android.telephony.CarrierConfigManager; import android.text.TextUtils; import com.android.internal.telephony.CallerInfo; import com.android.server.telecom.Call; import com.android.server.telecom.CallerInfoLookupHelper; import com.android.server.telecom.CallsManager; import com.android.server.telecom.LogUtils; import com.android.server.telecom.ParcelableCallUtils; import com.android.server.telecom.PhoneAccountRegistrar; import com.android.server.telecom.TelecomServiceImpl; import com.android.server.telecom.TelecomSystem; /** * This class supports binding to the various {@link android.telecom.CallScreeningService}: * carrier, default dialer and user chosen. Carrier's CallScreeningService implementation will be * bound first, and then default dialer's and user chosen's. If Carrier's CallScreeningService * blocks a call, no further CallScreeningService after it will be bound. */ public class CallScreeningServiceController implements IncomingCallFilter.CallFilter, CallScreeningServiceFilter.CallScreeningFilterResultCallback { private final Context mContext; private final CallsManager mCallsManager; private final PhoneAccountRegistrar mPhoneAccountRegistrar; private final ParcelableCallUtils.Converter mParcelableCallUtilsConverter; private final TelecomSystem.SyncRoot mTelecomLock; private final TelecomServiceImpl.SettingsSecureAdapter mSettingsSecureAdapter; private final CallerInfoLookupHelper mCallerInfoLookupHelper; private final int CARRIER_CALL_FILTERING_TIMED_OUT = 2000; // 2 seconds private final int CALL_FILTERING_TIMED_OUT = 4500; // 4.5 seconds private final Handler mHandler = new Handler(Looper.getMainLooper()); private Call mCall; private CallFilterResultCallback mCallback; private CallFilteringResult mResult = new CallFilteringResult( true, // shouldAllowCall false, // shouldReject true, // shouldAddToCallLog true // shouldShowNotification ); private boolean mIsFinished; private boolean mIsCarrierFinished; private boolean mIsDefaultDialerFinished; private boolean mIsUserChosenFinished; public CallScreeningServiceController( Context context, CallsManager callsManager, PhoneAccountRegistrar phoneAccountRegistrar, ParcelableCallUtils.Converter parcelableCallUtilsConverter, TelecomSystem.SyncRoot lock, TelecomServiceImpl.SettingsSecureAdapter settingsSecureAdapter, CallerInfoLookupHelper callerInfoLookupHelper) { mContext = context; mCallsManager = callsManager; mPhoneAccountRegistrar = phoneAccountRegistrar; mParcelableCallUtilsConverter = parcelableCallUtilsConverter; mTelecomLock = lock; mSettingsSecureAdapter = settingsSecureAdapter; mCallerInfoLookupHelper = callerInfoLookupHelper; } @Override public void startFilterLookup(Call call, CallFilterResultCallback callBack) { mCall = call; mCallback = callBack; mIsFinished = false; mIsCarrierFinished = false; mIsDefaultDialerFinished = false; mIsUserChosenFinished = false; bindCarrierService(); // Call screening filtering timed out mHandler.postDelayed(new Runnable("ICF.pFTO", mTelecomLock) { @Override public void loggedRun() { if (!mIsFinished) { Log.i(CallScreeningServiceController.this, "Call screening has timed out."); finishCallScreening(); } } }.prepare(), CALL_FILTERING_TIMED_OUT); } @Override public void onCallScreeningFilterComplete(Call call, CallFilteringResult result, String packageName) { synchronized (mTelecomLock) { mResult = result.combine(mResult); if (!TextUtils.isEmpty(packageName) && packageName.equals(getCarrierPackageName())) { mIsCarrierFinished = true; if (result.mCallBlockReason == CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE) { finishCallScreening(); } else { checkContactExistsAndBindService(); } } else if (!TextUtils.isEmpty(packageName) && packageName.equals(getDefaultDialerPackageName())) { mIsDefaultDialerFinished = true; if (result.mCallBlockReason == CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE || mIsUserChosenFinished) { finishCallScreening(); } } else if (!TextUtils.isEmpty(packageName) && packageName.equals(getUserChosenPackageName())) { mIsUserChosenFinished = true; if (mIsDefaultDialerFinished) { finishCallScreening(); } } } } private void bindCarrierService() { String carrierPackageName = getCarrierPackageName(); if (TextUtils.isEmpty(carrierPackageName)) { mIsCarrierFinished = true; bindDefaultDialerAndUserChosenService(); } else { createCallScreeningServiceFilter().startCallScreeningFilter(mCall, this, carrierPackageName); } // Carrier filtering timed out mHandler.postDelayed(new Runnable("ICF.pFTO", mTelecomLock) { @Override public void loggedRun() { if (!mIsCarrierFinished) { mIsCarrierFinished = true; checkContactExistsAndBindService(); } } }.prepare(), CARRIER_CALL_FILTERING_TIMED_OUT); } private void bindDefaultDialerAndUserChosenService() { if (mIsCarrierFinished) { String dialerPackageName = getDefaultDialerPackageName(); if (TextUtils.isEmpty(dialerPackageName)) { mIsDefaultDialerFinished = true; } else { createCallScreeningServiceFilter().startCallScreeningFilter(mCall, CallScreeningServiceController.this, dialerPackageName); } String userChosenPackageName = getUserChosenPackageName(); if (TextUtils.isEmpty(userChosenPackageName)) { mIsUserChosenFinished = true; } else { createCallScreeningServiceFilter().startCallScreeningFilter(mCall, CallScreeningServiceController.this, userChosenPackageName); } if (mIsDefaultDialerFinished && mIsUserChosenFinished) { finishCallScreening(); } } } private CallScreeningServiceFilter createCallScreeningServiceFilter() { return new CallScreeningServiceFilter( mContext, mCallsManager, mPhoneAccountRegistrar, mParcelableCallUtilsConverter, mTelecomLock, mSettingsSecureAdapter); } private void checkContactExistsAndBindService() { mCallerInfoLookupHelper.startLookup(mCall.getHandle(), new CallerInfoLookupHelper.OnQueryCompleteListener() { @Override public void onCallerInfoQueryComplete(Uri handle, CallerInfo info) { boolean contactExists = info != null && info.contactExists; Log.i(CallScreeningServiceController.this, "Contact exists: " + contactExists); if (!contactExists) { bindDefaultDialerAndUserChosenService(); } else { finishCallScreening(); } } @Override public void onContactPhotoQueryComplete(Uri handle, CallerInfo info) { // ignore } }); } private void finishCallScreening() { Log.addEvent(mCall, LogUtils.Events.CONTROLLER_SCREENING_COMPLETED, mResult); mCallback.onCallFilteringComplete(mCall, mResult); mIsFinished = true; } private String getCarrierPackageName() { ComponentName componentName = null; CarrierConfigManager configManager = (CarrierConfigManager) mContext.getSystemService (Context.CARRIER_CONFIG_SERVICE); PersistableBundle configBundle = configManager.getConfig(); if (configBundle != null) { componentName = ComponentName.unflattenFromString(configBundle.getString (CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING)); } return componentName != null ? componentName.getPackageName() : null; } private String getDefaultDialerPackageName() { return TelecomManager.from(mContext).getDefaultDialerPackage(); } private String getUserChosenPackageName() { ComponentName componentName = null; String defaultCallScreeningApplication = mSettingsSecureAdapter.getStringForUser(mContext .getContentResolver(), Settings.Secure.CALL_SCREENING_DEFAULT_COMPONENT, UserHandle.USER_CURRENT); if (!TextUtils.isEmpty(defaultCallScreeningApplication)) { componentName = ComponentName.unflattenFromString(defaultCallScreeningApplication); } return componentName != null ? componentName.getPackageName() : null; } } src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java +38 −36 Original line number Diff line number Diff line Loading @@ -39,11 +39,9 @@ import com.android.internal.telecom.ICallScreeningAdapter; import com.android.internal.telecom.ICallScreeningService; import com.android.server.telecom.Call; import com.android.server.telecom.CallsManager; import com.android.server.telecom.DefaultDialerCache; import com.android.server.telecom.LogUtils; import com.android.server.telecom.ParcelableCallUtils; import com.android.server.telecom.PhoneAccountRegistrar; import com.android.server.telecom.TelecomServiceImpl; import com.android.server.telecom.TelecomServiceImpl.SettingsSecureAdapter; import com.android.server.telecom.TelecomSystem; Loading @@ -53,7 +51,13 @@ import java.util.List; * Binds to {@link ICallScreeningService} to allow call blocking. A single instance of this class * handles a single call. */ public class CallScreeningServiceFilter implements IncomingCallFilter.CallFilter { public class CallScreeningServiceFilter { public interface CallScreeningFilterResultCallback { void onCallScreeningFilterComplete(Call call, CallFilteringResult result, String packageName); } private class CallScreeningServiceConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName componentName, IBinder service) { Loading Loading @@ -150,17 +154,17 @@ public class CallScreeningServiceFilter implements IncomingCallFilter.CallFilter private final Context mContext; private final PhoneAccountRegistrar mPhoneAccountRegistrar; private final CallsManager mCallsManager; private final DefaultDialerCache mDefaultDialerCache; private final ParcelableCallUtils.Converter mParcelableCallUtilsConverter; private final TelecomSystem.SyncRoot mTelecomLock; private final SettingsSecureAdapter mSettingsSecureAdapter; private Call mCall; private CallFilterResultCallback mCallback; private CallScreeningFilterResultCallback mCallback; private ICallScreeningService mService; private ServiceConnection mConnection; private String mPackageName; private boolean mHasFinished = false; private CallFilteringResult mResult = new CallFilteringResult( true, // shouldAllowCall false, //shouldReject Loading @@ -172,28 +176,28 @@ public class CallScreeningServiceFilter implements IncomingCallFilter.CallFilter Context context, CallsManager callsManager, PhoneAccountRegistrar phoneAccountRegistrar, DefaultDialerCache defaultDialerCache, ParcelableCallUtils.Converter parcelableCallUtilsConverter, TelecomSystem.SyncRoot lock, SettingsSecureAdapter settingsSecureAdapter) { mContext = context; mPhoneAccountRegistrar = phoneAccountRegistrar; mCallsManager = callsManager; mDefaultDialerCache = defaultDialerCache; mParcelableCallUtilsConverter = parcelableCallUtilsConverter; mTelecomLock = lock; mSettingsSecureAdapter = settingsSecureAdapter; } @Override public void startFilterLookup(Call call, CallFilterResultCallback callback) { public void startCallScreeningFilter(Call call, CallScreeningFilterResultCallback callback, String packageName) { if (mHasFinished) { Log.w(this, "Attempting to reuse CallScreeningServiceFilter. Ignoring."); return; } Log.addEvent(call, LogUtils.Events.SCREENING_SENT); Log.addEvent(call, LogUtils.Events.SCREENING_SENT, packageName); mCall = call; mCallback = callback; mPackageName = packageName; if (!bindService()) { Log.i(this, "Could not bind to call screening service"); finishCallScreening(); Loading @@ -203,7 +207,7 @@ public class CallScreeningServiceFilter implements IncomingCallFilter.CallFilter private void finishCallScreening() { if (!mHasFinished) { Log.addEvent(mCall, LogUtils.Events.SCREENING_COMPLETED, mResult); mCallback.onCallFilteringComplete(mCall, mResult); mCallback.onCallScreeningFilterComplete(mCall, mResult, mPackageName); if (mConnection != null) { // We still need to call unbind even if the service disconnected. Loading @@ -216,25 +220,23 @@ public class CallScreeningServiceFilter implements IncomingCallFilter.CallFilter } private boolean bindService() { String dialerPackage = mDefaultDialerCache .getDefaultDialerApplication(UserHandle.USER_CURRENT); if (TextUtils.isEmpty(dialerPackage)) { Log.i(this, "Default dialer is empty. Not performing call screening."); if (TextUtils.isEmpty(mPackageName)) { Log.i(this, "PackageName is empty. Not performing call screening."); return false; } Intent intent = new Intent(CallScreeningService.SERVICE_INTERFACE) .setPackage(dialerPackage); .setPackage(mPackageName); List<ResolveInfo> entries = mContext.getPackageManager().queryIntentServicesAsUser( intent, 0, mCallsManager.getCurrentUserHandle().getIdentifier()); if (entries.isEmpty()) { Log.i(this, "There are no call screening services installed on this device."); Log.i(this, mPackageName + "is no call screening services installed on this device."); return false; } ResolveInfo entry = entries.get(0); if (entry.serviceInfo == null) { Log.w(this, "The call screening service has invalid service info"); Log.w(this, mPackageName + " call screening service has invalid service info"); return false; } Loading tests/src/com/android/server/telecom/tests/CallScreeningServiceControllerTest.java 0 → 100644 +351 −0 File added.Preview size limit exceeded, changes collapsed. Show changes Loading
src/com/android/server/telecom/CallsManager.java +4 −4 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ import com.android.server.telecom.callfiltering.AsyncBlockCheckFilter; import com.android.server.telecom.callfiltering.BlockCheckerAdapter; import com.android.server.telecom.callfiltering.CallFilterResultCallback; import com.android.server.telecom.callfiltering.CallFilteringResult; import com.android.server.telecom.callfiltering.CallScreeningServiceFilter; import com.android.server.telecom.callfiltering.CallScreeningServiceController; import com.android.server.telecom.callfiltering.DirectToVoicemailCallFilter; import com.android.server.telecom.callfiltering.IncomingCallFilter; import com.android.server.telecom.components.ErrorDialogActivity; Loading Loading @@ -568,9 +568,9 @@ public class CallsManager extends Call.ListenerBase filters.add(new DirectToVoicemailCallFilter(mCallerInfoLookupHelper)); filters.add(new AsyncBlockCheckFilter(mContext, new BlockCheckerAdapter(), mCallerInfoLookupHelper, null)); filters.add(new CallScreeningServiceFilter(mContext, this, mPhoneAccountRegistrar, mDefaultDialerCache, new ParcelableCallUtils.Converter(), mLock, new TelecomServiceImpl.SettingsSecureAdapterImpl())); filters.add(new CallScreeningServiceController(mContext, this, mPhoneAccountRegistrar, new ParcelableCallUtils.Converter(), mLock, new TelecomServiceImpl.SettingsSecureAdapterImpl(), mCallerInfoLookupHelper)); new IncomingCallFilter(mContext, this, incomingCall, mLock, mTimeoutsAdapter, filters).performFiltering(); } Loading
src/com/android/server/telecom/LogUtils.java +2 −0 Original line number Diff line number Diff line Loading @@ -108,6 +108,8 @@ public class LogUtils { public static final String BIND_SCREENING = "BIND_SCREENING"; public static final String SCREENING_BOUND = "SCREENING_BOUND"; public static final String SCREENING_SENT = "SCREENING_SENT"; public static final String CONTROLLER_SCREENING_COMPLETED = "CONTROLLER_SCREENING_COMPLETED"; public static final String SCREENING_COMPLETED = "SCREENING_COMPLETED"; public static final String BLOCK_CHECK_INITIATED = "BLOCK_CHECK_INITIATED"; public static final String BLOCK_CHECK_FINISHED = "BLOCK_CHECK_FINISHED"; Loading
src/com/android/server/telecom/callfiltering/CallScreeningServiceController.java 0 → 100644 +264 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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.android.server.telecom.callfiltering; import android.content.ComponentName; import android.content.Context; import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.PersistableBundle; import android.os.UserHandle; import android.provider.CallLog; import android.provider.Settings; import android.telecom.Log; import android.telecom.Logging.Runnable; import android.telecom.TelecomManager; import android.telephony.CarrierConfigManager; import android.text.TextUtils; import com.android.internal.telephony.CallerInfo; import com.android.server.telecom.Call; import com.android.server.telecom.CallerInfoLookupHelper; import com.android.server.telecom.CallsManager; import com.android.server.telecom.LogUtils; import com.android.server.telecom.ParcelableCallUtils; import com.android.server.telecom.PhoneAccountRegistrar; import com.android.server.telecom.TelecomServiceImpl; import com.android.server.telecom.TelecomSystem; /** * This class supports binding to the various {@link android.telecom.CallScreeningService}: * carrier, default dialer and user chosen. Carrier's CallScreeningService implementation will be * bound first, and then default dialer's and user chosen's. If Carrier's CallScreeningService * blocks a call, no further CallScreeningService after it will be bound. */ public class CallScreeningServiceController implements IncomingCallFilter.CallFilter, CallScreeningServiceFilter.CallScreeningFilterResultCallback { private final Context mContext; private final CallsManager mCallsManager; private final PhoneAccountRegistrar mPhoneAccountRegistrar; private final ParcelableCallUtils.Converter mParcelableCallUtilsConverter; private final TelecomSystem.SyncRoot mTelecomLock; private final TelecomServiceImpl.SettingsSecureAdapter mSettingsSecureAdapter; private final CallerInfoLookupHelper mCallerInfoLookupHelper; private final int CARRIER_CALL_FILTERING_TIMED_OUT = 2000; // 2 seconds private final int CALL_FILTERING_TIMED_OUT = 4500; // 4.5 seconds private final Handler mHandler = new Handler(Looper.getMainLooper()); private Call mCall; private CallFilterResultCallback mCallback; private CallFilteringResult mResult = new CallFilteringResult( true, // shouldAllowCall false, // shouldReject true, // shouldAddToCallLog true // shouldShowNotification ); private boolean mIsFinished; private boolean mIsCarrierFinished; private boolean mIsDefaultDialerFinished; private boolean mIsUserChosenFinished; public CallScreeningServiceController( Context context, CallsManager callsManager, PhoneAccountRegistrar phoneAccountRegistrar, ParcelableCallUtils.Converter parcelableCallUtilsConverter, TelecomSystem.SyncRoot lock, TelecomServiceImpl.SettingsSecureAdapter settingsSecureAdapter, CallerInfoLookupHelper callerInfoLookupHelper) { mContext = context; mCallsManager = callsManager; mPhoneAccountRegistrar = phoneAccountRegistrar; mParcelableCallUtilsConverter = parcelableCallUtilsConverter; mTelecomLock = lock; mSettingsSecureAdapter = settingsSecureAdapter; mCallerInfoLookupHelper = callerInfoLookupHelper; } @Override public void startFilterLookup(Call call, CallFilterResultCallback callBack) { mCall = call; mCallback = callBack; mIsFinished = false; mIsCarrierFinished = false; mIsDefaultDialerFinished = false; mIsUserChosenFinished = false; bindCarrierService(); // Call screening filtering timed out mHandler.postDelayed(new Runnable("ICF.pFTO", mTelecomLock) { @Override public void loggedRun() { if (!mIsFinished) { Log.i(CallScreeningServiceController.this, "Call screening has timed out."); finishCallScreening(); } } }.prepare(), CALL_FILTERING_TIMED_OUT); } @Override public void onCallScreeningFilterComplete(Call call, CallFilteringResult result, String packageName) { synchronized (mTelecomLock) { mResult = result.combine(mResult); if (!TextUtils.isEmpty(packageName) && packageName.equals(getCarrierPackageName())) { mIsCarrierFinished = true; if (result.mCallBlockReason == CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE) { finishCallScreening(); } else { checkContactExistsAndBindService(); } } else if (!TextUtils.isEmpty(packageName) && packageName.equals(getDefaultDialerPackageName())) { mIsDefaultDialerFinished = true; if (result.mCallBlockReason == CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE || mIsUserChosenFinished) { finishCallScreening(); } } else if (!TextUtils.isEmpty(packageName) && packageName.equals(getUserChosenPackageName())) { mIsUserChosenFinished = true; if (mIsDefaultDialerFinished) { finishCallScreening(); } } } } private void bindCarrierService() { String carrierPackageName = getCarrierPackageName(); if (TextUtils.isEmpty(carrierPackageName)) { mIsCarrierFinished = true; bindDefaultDialerAndUserChosenService(); } else { createCallScreeningServiceFilter().startCallScreeningFilter(mCall, this, carrierPackageName); } // Carrier filtering timed out mHandler.postDelayed(new Runnable("ICF.pFTO", mTelecomLock) { @Override public void loggedRun() { if (!mIsCarrierFinished) { mIsCarrierFinished = true; checkContactExistsAndBindService(); } } }.prepare(), CARRIER_CALL_FILTERING_TIMED_OUT); } private void bindDefaultDialerAndUserChosenService() { if (mIsCarrierFinished) { String dialerPackageName = getDefaultDialerPackageName(); if (TextUtils.isEmpty(dialerPackageName)) { mIsDefaultDialerFinished = true; } else { createCallScreeningServiceFilter().startCallScreeningFilter(mCall, CallScreeningServiceController.this, dialerPackageName); } String userChosenPackageName = getUserChosenPackageName(); if (TextUtils.isEmpty(userChosenPackageName)) { mIsUserChosenFinished = true; } else { createCallScreeningServiceFilter().startCallScreeningFilter(mCall, CallScreeningServiceController.this, userChosenPackageName); } if (mIsDefaultDialerFinished && mIsUserChosenFinished) { finishCallScreening(); } } } private CallScreeningServiceFilter createCallScreeningServiceFilter() { return new CallScreeningServiceFilter( mContext, mCallsManager, mPhoneAccountRegistrar, mParcelableCallUtilsConverter, mTelecomLock, mSettingsSecureAdapter); } private void checkContactExistsAndBindService() { mCallerInfoLookupHelper.startLookup(mCall.getHandle(), new CallerInfoLookupHelper.OnQueryCompleteListener() { @Override public void onCallerInfoQueryComplete(Uri handle, CallerInfo info) { boolean contactExists = info != null && info.contactExists; Log.i(CallScreeningServiceController.this, "Contact exists: " + contactExists); if (!contactExists) { bindDefaultDialerAndUserChosenService(); } else { finishCallScreening(); } } @Override public void onContactPhotoQueryComplete(Uri handle, CallerInfo info) { // ignore } }); } private void finishCallScreening() { Log.addEvent(mCall, LogUtils.Events.CONTROLLER_SCREENING_COMPLETED, mResult); mCallback.onCallFilteringComplete(mCall, mResult); mIsFinished = true; } private String getCarrierPackageName() { ComponentName componentName = null; CarrierConfigManager configManager = (CarrierConfigManager) mContext.getSystemService (Context.CARRIER_CONFIG_SERVICE); PersistableBundle configBundle = configManager.getConfig(); if (configBundle != null) { componentName = ComponentName.unflattenFromString(configBundle.getString (CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING)); } return componentName != null ? componentName.getPackageName() : null; } private String getDefaultDialerPackageName() { return TelecomManager.from(mContext).getDefaultDialerPackage(); } private String getUserChosenPackageName() { ComponentName componentName = null; String defaultCallScreeningApplication = mSettingsSecureAdapter.getStringForUser(mContext .getContentResolver(), Settings.Secure.CALL_SCREENING_DEFAULT_COMPONENT, UserHandle.USER_CURRENT); if (!TextUtils.isEmpty(defaultCallScreeningApplication)) { componentName = ComponentName.unflattenFromString(defaultCallScreeningApplication); } return componentName != null ? componentName.getPackageName() : null; } }
src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java +38 −36 Original line number Diff line number Diff line Loading @@ -39,11 +39,9 @@ import com.android.internal.telecom.ICallScreeningAdapter; import com.android.internal.telecom.ICallScreeningService; import com.android.server.telecom.Call; import com.android.server.telecom.CallsManager; import com.android.server.telecom.DefaultDialerCache; import com.android.server.telecom.LogUtils; import com.android.server.telecom.ParcelableCallUtils; import com.android.server.telecom.PhoneAccountRegistrar; import com.android.server.telecom.TelecomServiceImpl; import com.android.server.telecom.TelecomServiceImpl.SettingsSecureAdapter; import com.android.server.telecom.TelecomSystem; Loading @@ -53,7 +51,13 @@ import java.util.List; * Binds to {@link ICallScreeningService} to allow call blocking. A single instance of this class * handles a single call. */ public class CallScreeningServiceFilter implements IncomingCallFilter.CallFilter { public class CallScreeningServiceFilter { public interface CallScreeningFilterResultCallback { void onCallScreeningFilterComplete(Call call, CallFilteringResult result, String packageName); } private class CallScreeningServiceConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName componentName, IBinder service) { Loading Loading @@ -150,17 +154,17 @@ public class CallScreeningServiceFilter implements IncomingCallFilter.CallFilter private final Context mContext; private final PhoneAccountRegistrar mPhoneAccountRegistrar; private final CallsManager mCallsManager; private final DefaultDialerCache mDefaultDialerCache; private final ParcelableCallUtils.Converter mParcelableCallUtilsConverter; private final TelecomSystem.SyncRoot mTelecomLock; private final SettingsSecureAdapter mSettingsSecureAdapter; private Call mCall; private CallFilterResultCallback mCallback; private CallScreeningFilterResultCallback mCallback; private ICallScreeningService mService; private ServiceConnection mConnection; private String mPackageName; private boolean mHasFinished = false; private CallFilteringResult mResult = new CallFilteringResult( true, // shouldAllowCall false, //shouldReject Loading @@ -172,28 +176,28 @@ public class CallScreeningServiceFilter implements IncomingCallFilter.CallFilter Context context, CallsManager callsManager, PhoneAccountRegistrar phoneAccountRegistrar, DefaultDialerCache defaultDialerCache, ParcelableCallUtils.Converter parcelableCallUtilsConverter, TelecomSystem.SyncRoot lock, SettingsSecureAdapter settingsSecureAdapter) { mContext = context; mPhoneAccountRegistrar = phoneAccountRegistrar; mCallsManager = callsManager; mDefaultDialerCache = defaultDialerCache; mParcelableCallUtilsConverter = parcelableCallUtilsConverter; mTelecomLock = lock; mSettingsSecureAdapter = settingsSecureAdapter; } @Override public void startFilterLookup(Call call, CallFilterResultCallback callback) { public void startCallScreeningFilter(Call call, CallScreeningFilterResultCallback callback, String packageName) { if (mHasFinished) { Log.w(this, "Attempting to reuse CallScreeningServiceFilter. Ignoring."); return; } Log.addEvent(call, LogUtils.Events.SCREENING_SENT); Log.addEvent(call, LogUtils.Events.SCREENING_SENT, packageName); mCall = call; mCallback = callback; mPackageName = packageName; if (!bindService()) { Log.i(this, "Could not bind to call screening service"); finishCallScreening(); Loading @@ -203,7 +207,7 @@ public class CallScreeningServiceFilter implements IncomingCallFilter.CallFilter private void finishCallScreening() { if (!mHasFinished) { Log.addEvent(mCall, LogUtils.Events.SCREENING_COMPLETED, mResult); mCallback.onCallFilteringComplete(mCall, mResult); mCallback.onCallScreeningFilterComplete(mCall, mResult, mPackageName); if (mConnection != null) { // We still need to call unbind even if the service disconnected. Loading @@ -216,25 +220,23 @@ public class CallScreeningServiceFilter implements IncomingCallFilter.CallFilter } private boolean bindService() { String dialerPackage = mDefaultDialerCache .getDefaultDialerApplication(UserHandle.USER_CURRENT); if (TextUtils.isEmpty(dialerPackage)) { Log.i(this, "Default dialer is empty. Not performing call screening."); if (TextUtils.isEmpty(mPackageName)) { Log.i(this, "PackageName is empty. Not performing call screening."); return false; } Intent intent = new Intent(CallScreeningService.SERVICE_INTERFACE) .setPackage(dialerPackage); .setPackage(mPackageName); List<ResolveInfo> entries = mContext.getPackageManager().queryIntentServicesAsUser( intent, 0, mCallsManager.getCurrentUserHandle().getIdentifier()); if (entries.isEmpty()) { Log.i(this, "There are no call screening services installed on this device."); Log.i(this, mPackageName + "is no call screening services installed on this device."); return false; } ResolveInfo entry = entries.get(0); if (entry.serviceInfo == null) { Log.w(this, "The call screening service has invalid service info"); Log.w(this, mPackageName + " call screening service has invalid service info"); return false; } Loading
tests/src/com/android/server/telecom/tests/CallScreeningServiceControllerTest.java 0 → 100644 +351 −0 File added.Preview size limit exceeded, changes collapsed. Show changes