1 /*
2  * Copyright (C) 2019 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.car.dialer.ui;
18 
19 import android.bluetooth.BluetoothDevice;
20 import android.telecom.Call;
21 
22 import androidx.annotation.NonNull;
23 import androidx.annotation.Nullable;
24 import androidx.annotation.VisibleForTesting;
25 import androidx.lifecycle.LiveData;
26 import androidx.lifecycle.MutableLiveData;
27 import androidx.lifecycle.ViewModel;
28 
29 import com.android.car.dialer.log.L;
30 import com.android.car.dialer.telecom.LocalCallHandler;
31 import com.android.car.dialer.ui.common.SingleLiveEvent;
32 
33 import java.util.List;
34 
35 import javax.inject.Inject;
36 import javax.inject.Named;
37 
38 import dagger.hilt.android.lifecycle.HiltViewModel;
39 
40 /**
41  * View model for {@link TelecomActivity}.
42  */
43 @HiltViewModel
44 public class TelecomActivityViewModel extends ViewModel {
45     private static final String TAG = "CD.TelecomActivityViewModel";
46 
47     private final LocalCallHandler mLocalCallHandler;
48     private final LiveData<List<BluetoothDevice>> mHfpDeviceListLiveData;
49     private final LiveData<BluetoothDevice> mCurrentHfpDeviceLiveData;
50     private final LiveData<Boolean> mHasHfpDeviceConnectedLiveData;
51 
52     private RefreshUiEvent mRefreshTabsLiveData;
53 
54     private final ToolbarTitleLiveData mToolbarTitleLiveData;
55     private final MutableLiveData<Integer> mToolbarTitleMode;
56 
57     @Inject
TelecomActivityViewModel( @amedR) LiveData<List<BluetoothDevice>> hfpDeviceListLiveData, @Named(R) LiveData<BluetoothDevice> currentHfpDeviceLiveData, @Named(R) LiveData<Boolean> hasHfpDeviceConnectedLiveData, LocalCallHandler localCallHandler, ToolbarTitleLiveData toolbarTitleLiveData)58     public TelecomActivityViewModel(
59             @Named("Hfp") LiveData<List<BluetoothDevice>> hfpDeviceListLiveData,
60             @Named("Hfp") LiveData<BluetoothDevice> currentHfpDeviceLiveData,
61             @Named("Hfp") LiveData<Boolean> hasHfpDeviceConnectedLiveData,
62             LocalCallHandler localCallHandler,
63             ToolbarTitleLiveData toolbarTitleLiveData) {
64         mLocalCallHandler = localCallHandler;
65         mHfpDeviceListLiveData = hfpDeviceListLiveData;
66         mCurrentHfpDeviceLiveData = currentHfpDeviceLiveData;
67         mHasHfpDeviceConnectedLiveData = hasHfpDeviceConnectedLiveData;
68         mToolbarTitleLiveData = toolbarTitleLiveData;
69 
70         mToolbarTitleMode = mToolbarTitleLiveData.getToolbarTitleModeLiveData();
71         mRefreshTabsLiveData = new RefreshUiEvent(mHfpDeviceListLiveData,
72                 mCurrentHfpDeviceLiveData);
73     }
74 
75     /**
76      * Returns the {@link LiveData} for the toolbar title, which provides the toolbar title
77      * depending on the {@link com.android.car.dialer.R.attr#toolbarTitleMode}.
78      */
getToolbarTitle()79     public LiveData<String> getToolbarTitle() {
80         return mToolbarTitleLiveData;
81     }
82 
83     /**
84      * Returns the {@link MutableLiveData} of the toolbar title mode. The value should be set by the
85      * {@link TelecomActivity}.
86      */
getToolbarTitleMode()87     public MutableLiveData<Integer> getToolbarTitleMode() {
88         return mToolbarTitleMode;
89     }
90 
91     /**
92      * Returns the live data which monitors whether to refresh Dialer.
93      */
getRefreshTabsLiveData()94     public LiveData<Boolean> getRefreshTabsLiveData() {
95         return mRefreshTabsLiveData;
96     }
97 
98     /** Returns a {@link LiveData} which monitors if there are any connected HFP devices. */
hasHfpDeviceConnected()99     public LiveData<Boolean> hasHfpDeviceConnected() {
100         return mHasHfpDeviceConnectedLiveData;
101     }
102 
103     /** Returns the live data which monitors the ongoing call list. */
getOngoingCallListLiveData()104     public LiveData<List<Call>> getOngoingCallListLiveData() {
105         return mLocalCallHandler.getOngoingCallListLiveData();
106     }
107 
108     @Override
onCleared()109     protected void onCleared() {
110         mLocalCallHandler.tearDown();
111     }
112 
113     /**
114      * This is an event live data to determine if the Ui needs to be refreshed.
115      */
116     @VisibleForTesting
117     static class RefreshUiEvent extends SingleLiveEvent<Boolean> {
118         private LiveData<BluetoothDevice> mCurrentHfpDevice;
119         private BluetoothDevice mBluetoothDevice;
120 
121         @VisibleForTesting
RefreshUiEvent( LiveData<List<BluetoothDevice>> hfpDeviceListLiveData, LiveData<BluetoothDevice> currentHfpDevice)122         RefreshUiEvent(
123                 LiveData<List<BluetoothDevice>> hfpDeviceListLiveData,
124                 LiveData<BluetoothDevice> currentHfpDevice) {
125             mCurrentHfpDevice = currentHfpDevice;
126             addSource(hfpDeviceListLiveData, v -> update(v));
127         }
128 
update(List<BluetoothDevice> hfpDeviceList)129         private void update(List<BluetoothDevice> hfpDeviceList) {
130             L.v(TAG, "HfpDeviceList update");
131             if (mBluetoothDevice != null && !listContainsDevice(hfpDeviceList, mBluetoothDevice)) {
132                 setValue(true);
133             }
134             mBluetoothDevice = mCurrentHfpDevice.getValue();
135         }
136 
listContainsDevice(@ullable List<BluetoothDevice> hfpDeviceList, @NonNull BluetoothDevice device)137         private boolean listContainsDevice(@Nullable List<BluetoothDevice> hfpDeviceList,
138                 @NonNull BluetoothDevice device) {
139             if (hfpDeviceList != null && hfpDeviceList.contains(device)) {
140                 return true;
141             }
142 
143             return false;
144         }
145     }
146 }
147