Home | History | Annotate | Download | only in legacyblocking
      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.incallui.legacyblocking;
     18 
     19 import android.content.Context;
     20 import android.database.ContentObserver;
     21 import android.os.Handler;
     22 import android.provider.CallLog;
     23 import android.support.annotation.NonNull;
     24 import com.android.dialer.common.LogUtil;
     25 import com.android.dialer.common.concurrent.AsyncTaskExecutor;
     26 import com.android.dialer.common.concurrent.AsyncTaskExecutors;
     27 import com.android.dialer.util.PermissionsUtil;
     28 import java.util.Objects;
     29 
     30 /**
     31  * Observes the {@link CallLog} to delete the CallLog entry for a blocked call after it is added.
     32  * Automatically de-registers itself {@link #TIMEOUT_MS} ms after registration or if the entry is
     33  * found and deleted.
     34  */
     35 public class BlockedNumberContentObserver extends ContentObserver
     36     implements DeleteBlockedCallTask.Listener {
     37 
     38   /**
     39    * The time after which a {@link BlockedNumberContentObserver} will be automatically unregistered.
     40    */
     41   public static final int TIMEOUT_MS = 5000;
     42 
     43   @NonNull private final Context context;
     44   @NonNull private final Handler handler;
     45   private final String number;
     46   private final long timeAddedMillis;
     47   private final Runnable timeoutRunnable =
     48       new Runnable() {
     49         @Override
     50         public void run() {
     51           unregister();
     52         }
     53       };
     54 
     55   private final AsyncTaskExecutor asyncTaskExecutor = AsyncTaskExecutors.createThreadPoolExecutor();
     56 
     57   /**
     58    * Creates the BlockedNumberContentObserver to delete the new {@link CallLog} entry from the given
     59    * blocked number.
     60    *
     61    * @param number The blocked number.
     62    * @param timeAddedMillis The time at which the call from the blocked number was placed.
     63    */
     64   public BlockedNumberContentObserver(
     65       @NonNull Context context, @NonNull Handler handler, String number, long timeAddedMillis) {
     66     super(handler);
     67     this.context = Objects.requireNonNull(context, "context").getApplicationContext();
     68     this.handler = Objects.requireNonNull(handler);
     69     this.number = number;
     70     this.timeAddedMillis = timeAddedMillis;
     71   }
     72 
     73   @Override
     74   public void onChange(boolean selfChange) {
     75     LogUtil.i(
     76         "BlockedNumberContentObserver.onChange",
     77         "attempting to remove call log entry from blocked number");
     78     asyncTaskExecutor.submit(
     79         DeleteBlockedCallTask.IDENTIFIER,
     80         new DeleteBlockedCallTask(context, this, number, timeAddedMillis));
     81   }
     82 
     83   @Override
     84   public void onDeleteBlockedCallTaskComplete(boolean didFindEntry) {
     85     if (didFindEntry) {
     86       unregister();
     87     }
     88   }
     89 
     90   /**
     91    * Registers this {@link ContentObserver} to listen for changes to the {@link CallLog}. If the
     92    * CallLog entry is not found before {@link #TIMEOUT_MS}, this ContentObserver automatically
     93    * un-registers itself.
     94    */
     95   public void register() {
     96     LogUtil.i("BlockedNumberContentObserver.register", null);
     97     if (PermissionsUtil.hasCallLogReadPermissions(context)
     98         && PermissionsUtil.hasCallLogWritePermissions(context)) {
     99       context.getContentResolver().registerContentObserver(CallLog.CONTENT_URI, true, this);
    100       handler.postDelayed(timeoutRunnable, TIMEOUT_MS);
    101     } else {
    102       LogUtil.w("BlockedNumberContentObserver.register", "no call log read/write permissions.");
    103     }
    104   }
    105 
    106   private void unregister() {
    107     LogUtil.i("BlockedNumberContentObserver.unregister", null);
    108     handler.removeCallbacks(timeoutRunnable);
    109     context.getContentResolver().unregisterContentObserver(this);
    110   }
    111 }
    112