1ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/* 2ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Copyright (C) 2016 The Android Open Source Project 3ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 4ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Licensed under the Apache License, Version 2.0 (the "License"); 5ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * you may not use this file except in compliance with the License. 6ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * You may obtain a copy of the License at 7ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 8ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * http://www.apache.org/licenses/LICENSE-2.0 9ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 10ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Unless required by applicable law or agreed to in writing, software 11ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * distributed under the License is distributed on an "AS IS" BASIS, 12ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * See the License for the specific language governing permissions and 14ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * limitations under the License. 15ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 16ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 17ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpackage com.android.incallui.legacyblocking; 18ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 19ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.Context; 20ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.database.ContentObserver; 21ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.os.Handler; 22ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.CallLog; 23ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.support.annotation.NonNull; 24ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.common.LogUtil; 259779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanianimport com.android.dialer.common.concurrent.AsyncTaskExecutor; 269779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanianimport com.android.dialer.common.concurrent.AsyncTaskExecutors; 27c857f90590e7d7fcffa89511982eb33afd34805fEric Erfanianimport com.android.dialer.util.PermissionsUtil; 28ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.Objects; 29ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 30ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/** 31ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Observes the {@link CallLog} to delete the CallLog entry for a blocked call after it is added. 32ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Automatically de-registers itself {@link #TIMEOUT_MS} ms after registration or if the entry is 33ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * found and deleted. 34ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 35ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpublic class BlockedNumberContentObserver extends ContentObserver 36ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian implements DeleteBlockedCallTask.Listener { 37ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 38ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 39ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * The time after which a {@link BlockedNumberContentObserver} will be automatically unregistered. 40ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 41ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public static final int TIMEOUT_MS = 5000; 42ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 43ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian @NonNull private final Context context; 44ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian @NonNull private final Handler handler; 45ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private final String number; 46ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private final long timeAddedMillis; 47ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private final Runnable timeoutRunnable = 48ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian new Runnable() { 49ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian @Override 50ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public void run() { 51ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian unregister(); 52ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 53ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian }; 54ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 55ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private final AsyncTaskExecutor asyncTaskExecutor = AsyncTaskExecutors.createThreadPoolExecutor(); 56ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 57ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 58ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Creates the BlockedNumberContentObserver to delete the new {@link CallLog} entry from the given 59ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * blocked number. 60ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 61ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * @param number The blocked number. 62ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * @param timeAddedMillis The time at which the call from the blocked number was placed. 63ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 64ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public BlockedNumberContentObserver( 65ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian @NonNull Context context, @NonNull Handler handler, String number, long timeAddedMillis) { 66ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian super(handler); 67ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian this.context = Objects.requireNonNull(context, "context").getApplicationContext(); 68ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian this.handler = Objects.requireNonNull(handler); 69ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian this.number = number; 70ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian this.timeAddedMillis = timeAddedMillis; 71ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 72ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 73ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian @Override 74ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public void onChange(boolean selfChange) { 75ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian LogUtil.i( 76ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian "BlockedNumberContentObserver.onChange", 77ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian "attempting to remove call log entry from blocked number"); 78ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian asyncTaskExecutor.submit( 79ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian DeleteBlockedCallTask.IDENTIFIER, 80ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian new DeleteBlockedCallTask(context, this, number, timeAddedMillis)); 81ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 82ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 83ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian @Override 84ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public void onDeleteBlockedCallTaskComplete(boolean didFindEntry) { 85ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (didFindEntry) { 86ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian unregister(); 87ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 88ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 89ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 90ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 91ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Registers this {@link ContentObserver} to listen for changes to the {@link CallLog}. If the 92ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * CallLog entry is not found before {@link #TIMEOUT_MS}, this ContentObserver automatically 93ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * un-registers itself. 94ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 95ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public void register() { 96ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian LogUtil.i("BlockedNumberContentObserver.register", null); 97c857f90590e7d7fcffa89511982eb33afd34805fEric Erfanian if (PermissionsUtil.hasCallLogReadPermissions(context) 98c857f90590e7d7fcffa89511982eb33afd34805fEric Erfanian && PermissionsUtil.hasCallLogWritePermissions(context)) { 99c857f90590e7d7fcffa89511982eb33afd34805fEric Erfanian context.getContentResolver().registerContentObserver(CallLog.CONTENT_URI, true, this); 100c857f90590e7d7fcffa89511982eb33afd34805fEric Erfanian handler.postDelayed(timeoutRunnable, TIMEOUT_MS); 101c857f90590e7d7fcffa89511982eb33afd34805fEric Erfanian } else { 102c857f90590e7d7fcffa89511982eb33afd34805fEric Erfanian LogUtil.w("BlockedNumberContentObserver.register", "no call log read/write permissions."); 103c857f90590e7d7fcffa89511982eb33afd34805fEric Erfanian } 104ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 105ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 106ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private void unregister() { 107ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian LogUtil.i("BlockedNumberContentObserver.unregister", null); 108ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian handler.removeCallbacks(timeoutRunnable); 109ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian context.getContentResolver().unregisterContentObserver(this); 110ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 111ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian} 112