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 17package android.car.cluster.demorenderer; 18 19import android.annotation.Nullable; 20import android.car.cluster.demorenderer.PhoneBook.Contact; 21import android.car.cluster.demorenderer.PhoneBook.ContactLoadedListener; 22import android.car.cluster.demorenderer.PhoneBook.ContactPhotoLoadedListener; 23import android.content.Context; 24import android.graphics.Bitmap; 25import android.telephony.TelephonyManager; 26import android.util.Log; 27 28import java.lang.ref.WeakReference; 29 30/** 31 * Monitors call state. 32 */ 33public class CallStateMonitor implements ContactLoadedListener, ContactPhotoLoadedListener { 34 private final static String TAG = CallStateMonitor.class.getSimpleName(); 35 36 private final PhoneBook mPhoneBook; 37 private final TelephonyManager mTelephonyManager; 38 private final PhoneStateListener mListener; 39 private final CallStateListener mCallStateListener; 40 41 CallStateMonitor(Context context, PhoneStateListener listener) { 42 Log.d(TAG, "ctor, context: " + context + ", phoneRenderer: " + listener + 43 ", contentResolver: " + context.getContentResolver() + 44 ", applicationContext: " + context.getApplicationContext()); 45 46 mListener = listener; 47 mTelephonyManager = context.getSystemService(TelephonyManager.class); 48 mPhoneBook = new PhoneBook(context, mTelephonyManager); 49 mCallStateListener = new CallStateListener(this); 50 mTelephonyManager.listen(mCallStateListener, 51 android.telephony.PhoneStateListener.LISTEN_CALL_STATE); 52 53 updateRendererPhoneStatusIfAvailable(); 54 } 55 56 public void release() { 57 mTelephonyManager.listen(mCallStateListener, 58 android.telephony.PhoneStateListener.LISTEN_NONE); 59 } 60 61 private void updateRendererPhoneStatusIfAvailable() { 62 onCallStateChanged(mTelephonyManager.getCallState(), null); 63 } 64 65 private void onCallStateChanged(int state, final String number) { 66 Log.d(TAG, "onCallStateChanged, state:" + state + ", phoneNumber: " + number); 67 68 // Update call state immediately on instrument cluster. 69 mListener.onCallStateChanged(state, PhoneBook.getFormattedNumber(number)); 70 71 // Now fetching details asynchronously. 72 mPhoneBook.getContactDetailsAsync(number, this); 73 } 74 75 @Override 76 public void onContactLoaded(String number, @Nullable Contact contact) { 77 if (contact != null) { 78 mListener.onContactDetailsUpdated(contact.getName(), contact.getType(), 79 mPhoneBook.isVoicemail(number)); 80 81 mPhoneBook.getContactPictureAsync(contact.getId(), this); 82 } 83 } 84 85 @Override 86 public void onPhotoLoaded(int contactId, @Nullable Bitmap photo) { 87 mListener.onContactPhotoUpdated(photo); 88 } 89 90 public interface PhoneStateListener { 91 void onCallStateChanged(int state, @Nullable String number); 92 void onContactDetailsUpdated( 93 @Nullable CharSequence name, 94 @Nullable CharSequence typeLabel, 95 boolean isVoiceMail); 96 void onContactPhotoUpdated(Bitmap picture); 97 } 98 99 private static class CallStateListener extends android.telephony.PhoneStateListener { 100 private final WeakReference<CallStateMonitor> mServiceRef; 101 102 CallStateListener(CallStateMonitor service) { 103 mServiceRef = new WeakReference<>(service); 104 } 105 106 @Override 107 public void onCallStateChanged(int state, String incomingNumber) { 108 CallStateMonitor service = mServiceRef.get(); 109 if (service != null) { 110 service.onCallStateChanged(state, incomingNumber); 111 } 112 } 113 } 114} 115