1 /* 2 * Copyright (C) 2018 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.dialer.main.impl.bottomnav; 18 19 import android.Manifest; 20 import android.content.Context; 21 import android.database.ContentObserver; 22 import android.database.Cursor; 23 import android.provider.CallLog.Calls; 24 import android.support.annotation.RequiresPermission; 25 import com.android.dialer.common.concurrent.DialerExecutorComponent; 26 import com.android.dialer.common.concurrent.UiListener; 27 import com.android.dialer.main.impl.bottomnav.BottomNavBar.TabIndex; 28 import com.google.common.util.concurrent.ListenableFuture; 29 30 /** 31 * Observes the call log and updates the badge count to show the number of unread missed calls. 32 * 33 * <p>Used only when the new call log fragment is enabled. 34 */ 35 public final class MissedCallCountObserver extends ContentObserver { 36 private final Context appContext; 37 private final BottomNavBar bottomNavBar; 38 private final UiListener<Integer> uiListener; 39 MissedCallCountObserver( Context appContext, BottomNavBar bottomNavBar, UiListener<Integer> uiListener)40 public MissedCallCountObserver( 41 Context appContext, BottomNavBar bottomNavBar, UiListener<Integer> uiListener) { 42 super(null); 43 this.appContext = appContext; 44 this.bottomNavBar = bottomNavBar; 45 this.uiListener = uiListener; 46 } 47 48 @RequiresPermission(Manifest.permission.READ_CALL_LOG) 49 @Override onChange(boolean selfChange)50 public void onChange(boolean selfChange) { 51 ListenableFuture<Integer> countFuture = 52 DialerExecutorComponent.get(appContext) 53 .backgroundExecutor() 54 .submit( 55 () -> { 56 try (Cursor cursor = 57 appContext 58 .getContentResolver() 59 .query( 60 Calls.CONTENT_URI, 61 new String[] {Calls._ID}, 62 "(" 63 + Calls.IS_READ 64 + " = ? OR " 65 + Calls.IS_READ 66 + " IS NULL) AND " 67 + Calls.TYPE 68 + " = ?", 69 new String[] {"0", Integer.toString(Calls.MISSED_TYPE)}, 70 /* sortOrder= */ null)) { 71 return cursor == null ? 0 : cursor.getCount(); 72 } 73 }); 74 uiListener.listen( 75 appContext, 76 countFuture, 77 count -> bottomNavBar.setNotificationCount(TabIndex.CALL_LOG, count == null ? 0 : count), 78 throwable -> { 79 throw new RuntimeException(throwable); 80 }); 81 } 82 } 83