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.activecall;
18 
19 import android.os.Bundle;
20 import android.os.SystemClock;
21 import android.telecom.Call;
22 import android.view.LayoutInflater;
23 import android.view.View;
24 import android.view.ViewGroup;
25 import android.widget.Chronometer;
26 import android.widget.TextView;
27 
28 import androidx.annotation.NonNull;
29 import androidx.annotation.Nullable;
30 import androidx.annotation.VisibleForTesting;
31 import androidx.core.util.Pair;
32 import androidx.fragment.app.Fragment;
33 import androidx.lifecycle.MutableLiveData;
34 import androidx.lifecycle.ViewModelProviders;
35 
36 import com.android.car.dialer.R;
37 import com.android.car.telephony.common.TelecomUtils;
38 import com.android.car.ui.recyclerview.CarUiRecyclerView;
39 
40 /**
41  * A fragment that displays information about an on-going call with options to hang up.
42  */
43 public class OngoingConfCallFragment extends Fragment {
44     private static final String TAG = "CD.OngoingConfCallFrag";
45 
46     private Fragment mDialpadFragment;
47     private Fragment mOnholdCallFragment;
48     private View mConferenceCallProfilesView;
49     private MutableLiveData<Boolean> mDialpadState;
50     private CarUiRecyclerView mRecyclerView;
51     private Chronometer mConferenceTimeTextView;
52     private TextView mConferenceTitle;
53 
54     private ConferenceProfileAdapter mConfProfileAdapter;
55 
56     private String mConferenceTitleString;
57     private String mConfStrTitleFormat;
58 
59     @Override
onCreate(@ullable Bundle savedInstanceState)60     public void onCreate(@Nullable Bundle savedInstanceState) {
61         super.onCreate(savedInstanceState);
62         mConferenceTitleString = getString(R.string.ongoing_conf_title);
63         mConfStrTitleFormat = getString(R.string.ongoing_conf_title_format);
64     }
65 
66     @Override
onCreateView(@onNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)67     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
68             @Nullable Bundle savedInstanceState) {
69         View fragmentView = inflater.inflate(R.layout.ongoing_conf_call_fragment,
70                 container, false);
71 
72         mOnholdCallFragment = getChildFragmentManager().findFragmentById(R.id.onhold_user_profile);
73         mDialpadFragment = getChildFragmentManager().findFragmentById(R.id.incall_dialpad_fragment);
74         mConferenceCallProfilesView = fragmentView.findViewById(R.id.conference_profiles);
75         mRecyclerView = mConferenceCallProfilesView.findViewById(R.id.recycler_view);
76         mConferenceTimeTextView = mConferenceCallProfilesView.findViewById(R.id.call_duration);
77         mConferenceTitle = mConferenceCallProfilesView.findViewById(R.id.conference_title);
78 
79         if (mConfProfileAdapter == null) {
80             mConfProfileAdapter = new ConferenceProfileAdapter(getContext());
81         }
82         mRecyclerView.setAdapter(mConfProfileAdapter);
83 
84         InCallViewModel inCallViewModel = ViewModelProviders.of(getActivity()).get(
85                 InCallViewModel.class);
86 
87         inCallViewModel.getCallStateAndConnectTime().observe(this,
88                 this::updateCallDescription);
89 
90         inCallViewModel.getConferenceCallDetailList().observe(this, list -> {
91             mConfProfileAdapter.setConferenceList(list);
92             updateTitle(list.size());
93         });
94 
95         mDialpadState = inCallViewModel.getDialpadOpenState();
96         mDialpadState.observe(this, isDialpadOpen -> {
97             if (isDialpadOpen) {
98                 onOpenDialpad();
99             } else {
100                 onCloseDialpad();
101             }
102         });
103 
104         inCallViewModel.shouldShowOnholdCall().observe(this,
105                 this::updateOnholdCallFragmentVisibility);
106 
107         return fragmentView;
108     }
109 
110     @VisibleForTesting
onOpenDialpad()111     void onOpenDialpad() {
112         getChildFragmentManager().beginTransaction()
113                 .show(mDialpadFragment)
114                 .commit();
115         mConferenceCallProfilesView.setVisibility(View.GONE);
116     }
117 
118     @VisibleForTesting
onCloseDialpad()119     void onCloseDialpad() {
120         getChildFragmentManager().beginTransaction()
121                 .hide(mDialpadFragment)
122                 .commit();
123         mConferenceCallProfilesView.setVisibility(View.VISIBLE);
124     }
125 
updateTitle(int numParticipants)126     private void updateTitle(int numParticipants) {
127         String title = String.format(mConfStrTitleFormat, mConferenceTitleString, numParticipants);
128         mConferenceTitle.setText(title);
129     }
130 
131     /** Presents the call state and call duration. */
updateCallDescription(@ullable Pair<Integer, Long> callStateAndConnectTime)132     private void updateCallDescription(@Nullable Pair<Integer, Long> callStateAndConnectTime) {
133         if (callStateAndConnectTime == null || callStateAndConnectTime.first == null) {
134             mConferenceTimeTextView.stop();
135             mConferenceTimeTextView.setText("");
136             return;
137         }
138         if (callStateAndConnectTime.first == Call.STATE_ACTIVE) {
139             mConferenceTimeTextView.setBase(callStateAndConnectTime.second
140                     - System.currentTimeMillis() + SystemClock.elapsedRealtime());
141             mConferenceTimeTextView.start();
142         } else {
143             mConferenceTimeTextView.stop();
144             mConferenceTimeTextView.setText(TelecomUtils.callStateToUiString(getContext(),
145                     callStateAndConnectTime.first));
146         }
147     }
148 
updateOnholdCallFragmentVisibility(Boolean showOnholdCall)149     private void updateOnholdCallFragmentVisibility(Boolean showOnholdCall) {
150         if (showOnholdCall) {
151             getChildFragmentManager().beginTransaction().show(mOnholdCallFragment).commit();
152         } else {
153             getChildFragmentManager().beginTransaction().hide(mOnholdCallFragment).commit();
154         }
155     }
156 }
157