13d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer/* 23d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * Copyright (C) 2015 The Android Open Source Project 33d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * 43d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * Licensed under the Apache License, Version 2.0 (the "License"); 53d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * you may not use this file except in compliance with the License. 63d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * You may obtain a copy of the License at 73d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * 83d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * http://www.apache.org/licenses/LICENSE-2.0 93d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * 103d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * Unless required by applicable law or agreed to in writing, software 113d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * distributed under the License is distributed on an "AS IS" BASIS, 123d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * See the License for the specific language governing permissions and 143d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * limitations under the License. 153d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer */ 163d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerpackage com.android.car.dialer; 173d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 189fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jiaimport static com.android.car.dialer.ui.CallHistoryFragment.CALL_TYPE_KEY; 199fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia 203d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.content.Intent; 213d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.graphics.PorterDuff; 223d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.graphics.drawable.Drawable; 233d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.os.Bundle; 2417d5ac7d0b429687765e940279726623f5f5f823Anthony Chenimport android.support.annotation.Nullable; 2517d5ac7d0b429687765e940279726623f5f5f823Anthony Chenimport android.support.annotation.StringRes; 263d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.support.v4.app.Fragment; 273d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.telecom.Call; 283d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.telephony.PhoneNumberUtils; 293d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport android.util.Log; 306f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan 31bfa1ab18a847f1e3b60c2e3fca35d0d923d7fa61Yuzhouimport androidx.car.drawer.CarDrawerActivity; 32bfa1ab18a847f1e3b60c2e3fca35d0d923d7fa61Yuzhouimport androidx.car.drawer.CarDrawerAdapter; 33bfa1ab18a847f1e3b60c2e3fca35d0d923d7fa61Yuzhouimport androidx.car.drawer.DrawerItemViewHolder; 34bfa1ab18a847f1e3b60c2e3fca35d0d923d7fa61Yuzhou 3502a83b90ad2a990c22b4654fbfa23b84aae0fafcYuzhouimport com.android.car.dialer.telecom.InMemoryPhoneBook; 363d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport com.android.car.dialer.telecom.PhoneLoader; 373d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport com.android.car.dialer.telecom.UiCall; 383d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyerimport com.android.car.dialer.telecom.UiCallManager; 39bfa1ab18a847f1e3b60c2e3fca35d0d923d7fa61Yuzhouimport com.android.car.dialer.ui.CallHistoryFragment; 403fe91522bb3db3b2f8d74a3fed935e35a9bcbb2dYuzhouimport com.android.car.dialer.ui.ContactListFragment; 419fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jiaimport com.android.car.dialer.ui.InCallFragment; 423d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 43bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhouimport java.util.stream.Stream; 44ec71b277c15a3ff003181b0d323c70258043241aAurimas Liutikas 453d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer/** 463d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * Main activity for the Dialer app. Displays different fragments depending on call and 473d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * connectivity status: 483d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * <ul> 493d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * <li>OngoingCallFragment 503d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * <li>NoHfpFragment 513d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * <li>DialerFragment 523d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * <li>StrequentFragment 533d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * </ul> 543d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer */ 550ee4ae4c98ab4a94e1217399d4a71f6f6db87e99Yuzhoupublic class TelecomActivity extends CarDrawerActivity implements CallListener { 5617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen private static final String TAG = "TelecomActivity"; 573d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 58e23918bbc5b7c304ac7f71790340955b5cd32be8Anthony Chen private static final String ACTION_ANSWER_CALL = "com.android.car.dialer.ANSWER_CALL"; 59e23918bbc5b7c304ac7f71790340955b5cd32be8Anthony Chen private static final String ACTION_END_CALL = "com.android.car.dialer.END_CALL"; 6017d5ac7d0b429687765e940279726623f5f5f823Anthony Chen 613d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer private static final String DIALER_BACKSTACK = "DialerBackstack"; 6217d5ac7d0b429687765e940279726623f5f5f823Anthony Chen private static final String CONTENT_FRAGMENT_TAG = "CONTENT_FRAGMENT_TAG"; 6317d5ac7d0b429687765e940279726623f5f5f823Anthony Chen private static final String DIALER_FRAGMENT_TAG = "DIALER_FRAGMENT_TAG"; 643d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 65e23918bbc5b7c304ac7f71790340955b5cd32be8Anthony Chen private final UiBluetoothMonitor.Listener mBluetoothListener = this::updateCurrentFragment; 663d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 673d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer private UiCallManager mUiCallManager; 683d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer private UiBluetoothMonitor mUiBluetoothMonitor; 693d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 7017d5ac7d0b429687765e940279726623f5f5f823Anthony Chen /** 7117d5ac7d0b429687765e940279726623f5f5f823Anthony Chen * Whether or not it is safe to make transactions on the 7217d5ac7d0b429687765e940279726623f5f5f823Anthony Chen * {@link android.support.v4.app.FragmentManager}. This variable prevents a possible exception 7317d5ac7d0b429687765e940279726623f5f5f823Anthony Chen * when calling commit() on the FragmentManager. 7417d5ac7d0b429687765e940279726623f5f5f823Anthony Chen * 7517d5ac7d0b429687765e940279726623f5f5f823Anthony Chen * <p>The default value is {@code true} because it is only after 7617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen * {@link #onSaveInstanceState(Bundle)} that fragment commits are not allowed. 7717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen */ 7817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen private boolean mAllowFragmentCommits = true; 79c3f2621c65a0da3398b6ff0dcd39dcfdf6b6bbb8Rakesh Iyer 803d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer @Override 813d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer protected void onCreate(Bundle savedInstanceState) { 823d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer super.onCreate(savedInstanceState); 837b25f0ec4138d9179b54d10501add89e7c9ff768Anthony Chen setToolbarElevation(0f); 847b25f0ec4138d9179b54d10501add89e7c9ff768Anthony Chen 853d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer if (vdebug()) { 863d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer Log.d(TAG, "onCreate"); 873d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 88f7ed46be024b7cfb448f93d71f235b30f72aa1eeAnthony Chen 89f7ed46be024b7cfb448f93d71f235b30f72aa1eeAnthony Chen setMainContent(R.layout.telecom_activity); 906f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan getWindow().getDecorView().setBackgroundColor(getColor(R.color.phone_theme)); 919fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia updateTitle(); 923d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 930ee4ae4c98ab4a94e1217399d4a71f6f6db87e99Yuzhou mUiCallManager = UiCallManager.init(getApplicationContext()); 94a16cb24e5b5690af55597ad5c8540a7c90ae146aSrinivas Visvanathan mUiBluetoothMonitor = new UiBluetoothMonitor(this); 95c3f2621c65a0da3398b6ff0dcd39dcfdf6b6bbb8Rakesh Iyer 9602a83b90ad2a990c22b4654fbfa23b84aae0fafcYuzhou InMemoryPhoneBook.init(getApplicationContext()); 9702a83b90ad2a990c22b4654fbfa23b84aae0fafcYuzhou 98f7ed46be024b7cfb448f93d71f235b30f72aa1eeAnthony Chen findViewById(R.id.search).setOnClickListener( 99f7ed46be024b7cfb448f93d71f235b30f72aa1eeAnthony Chen v -> startActivity(new Intent(this, ContactSearchActivity.class))); 1009fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia 1019fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia getDrawerController().setRootAdapter(new DialerRootAdapter()); 102c3f2621c65a0da3398b6ff0dcd39dcfdf6b6bbb8Rakesh Iyer } 103c3f2621c65a0da3398b6ff0dcd39dcfdf6b6bbb8Rakesh Iyer 104c3f2621c65a0da3398b6ff0dcd39dcfdf6b6bbb8Rakesh Iyer @Override 1053d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer protected void onDestroy() { 1063d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer super.onDestroy(); 1073d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer if (vdebug()) { 1083d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer Log.d(TAG, "onDestroy"); 1093d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 110a16cb24e5b5690af55597ad5c8540a7c90ae146aSrinivas Visvanathan mUiBluetoothMonitor.tearDown(); 11102a83b90ad2a990c22b4654fbfa23b84aae0fafcYuzhou InMemoryPhoneBook.tearDown(); 1120ee4ae4c98ab4a94e1217399d4a71f6f6db87e99Yuzhou mUiCallManager.tearDown(); 1133d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer mUiCallManager = null; 1143d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 1153d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 1163d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer @Override 11717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen protected void onStop() { 11817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen super.onStop(); 119bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou mUiCallManager.removeListener(this); 1203d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer mUiBluetoothMonitor.removeListener(mBluetoothListener); 1213d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 1223d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 1233d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer @Override 1243d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer public void onSaveInstanceState(Bundle outState) { 12517d5ac7d0b429687765e940279726623f5f5f823Anthony Chen // A transaction can only be committed with this method prior to its containing activity 12617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen // saving its state. 12717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen mAllowFragmentCommits = false; 1283d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer super.onSaveInstanceState(outState); 1293d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 1303d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 1313d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer @Override 1323d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer protected void onNewIntent(Intent i) { 1333d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer super.onNewIntent(i); 1343d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer setIntent(i); 1353d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 1363d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 1373d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer @Override 13817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen protected void onStart() { 1393d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer if (vdebug()) { 14017d5ac7d0b429687765e940279726623f5f5f823Anthony Chen Log.d(TAG, "onStart"); 1413d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 14217d5ac7d0b429687765e940279726623f5f5f823Anthony Chen super.onStart(); 14317d5ac7d0b429687765e940279726623f5f5f823Anthony Chen 14417d5ac7d0b429687765e940279726623f5f5f823Anthony Chen // Fragment commits are not allowed once the Activity's state has been saved. Once 14517d5ac7d0b429687765e940279726623f5f5f823Anthony Chen // onStart() has been called, the FragmentManager should now allow commits. 14617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen mAllowFragmentCommits = true; 147e23918bbc5b7c304ac7f71790340955b5cd32be8Anthony Chen 148e23918bbc5b7c304ac7f71790340955b5cd32be8Anthony Chen // Update the current fragment before handling the intent so that any UI updates in 149e23918bbc5b7c304ac7f71790340955b5cd32be8Anthony Chen // handleIntent() is not overridden by updateCurrentFragment(). 150e23918bbc5b7c304ac7f71790340955b5cd32be8Anthony Chen updateCurrentFragment(); 1513d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer handleIntent(); 152e23918bbc5b7c304ac7f71790340955b5cd32be8Anthony Chen 153bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou mUiCallManager.addListener(this); 1543d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer mUiBluetoothMonitor.addListener(mBluetoothListener); 1553d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 1563d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 1573d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer private void handleIntent() { 1583d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer Intent intent = getIntent(); 1593d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer String action = intent != null ? intent.getAction() : null; 1603d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 1613d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer if (vdebug()) { 1623d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer Log.d(TAG, "handleIntent, intent: " + intent + ", action: " + action); 1633d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 1643d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 1653d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer if (action == null || action.length() == 0) { 1663d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer return; 1673d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 1683d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 169f7ed46be024b7cfb448f93d71f235b30f72aa1eeAnthony Chen String number; 1703d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer UiCall ringingCall; 1713d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer switch (action) { 1723d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer case ACTION_ANSWER_CALL: 1733d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer ringingCall = mUiCallManager.getCallWithState(Call.STATE_RINGING); 1743d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer if (ringingCall == null) { 1753d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer Log.e(TAG, "Unable to answer ringing call. There is none."); 1763d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } else { 1773d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer mUiCallManager.answerCall(ringingCall); 1783d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 1793d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer break; 1803d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 1813d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer case ACTION_END_CALL: 1823d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer ringingCall = mUiCallManager.getCallWithState(Call.STATE_RINGING); 1833d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer if (ringingCall == null) { 1843d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer Log.e(TAG, "Unable to end ringing call. There is none."); 1853d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } else { 1863d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer mUiCallManager.disconnectCall(ringingCall); 1873d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 1883d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer break; 1893d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 1903d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer case Intent.ACTION_DIAL: 191f7ed46be024b7cfb448f93d71f235b30f72aa1eeAnthony Chen number = PhoneNumberUtils.getNumberFromIntent(intent, this); 19217d5ac7d0b429687765e940279726623f5f5f823Anthony Chen if (!(getCurrentFragment() instanceof NoHfpFragment)) { 19317d5ac7d0b429687765e940279726623f5f5f823Anthony Chen showDialer(number); 1943d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 1953d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer break; 1963d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 197f7ed46be024b7cfb448f93d71f235b30f72aa1eeAnthony Chen case Intent.ACTION_CALL: 198f7ed46be024b7cfb448f93d71f235b30f72aa1eeAnthony Chen number = PhoneNumberUtils.getNumberFromIntent(intent, this); 199f7ed46be024b7cfb448f93d71f235b30f72aa1eeAnthony Chen mUiCallManager.safePlaceCall(number, false /* bluetoothRequired */); 200476856e35551612a71a33c0f797d09dc73569f2fRakesh Iyer break; 201476856e35551612a71a33c0f797d09dc73569f2fRakesh Iyer 2023d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer default: 2033d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer // Do nothing. 2043d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 2053d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 2063d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer setIntent(null); 2073d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 2083d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 2093d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer /** 21017d5ac7d0b429687765e940279726623f5f5f823Anthony Chen * Updates the content fragment of this Activity based on the state of the application. 2113d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer */ 2123d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer private void updateCurrentFragment() { 213e23918bbc5b7c304ac7f71790340955b5cd32be8Anthony Chen if (vdebug()) { 21417d5ac7d0b429687765e940279726623f5f5f823Anthony Chen Log.d(TAG, "updateCurrentFragment()"); 2153d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 2163d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 2173d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer boolean callEmpty = mUiCallManager.getCalls().isEmpty(); 2183d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer if (!mUiBluetoothMonitor.isBluetoothEnabled() && callEmpty) { 2193d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer showNoHfpFragment(R.string.bluetooth_disabled); 2203d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } else if (!mUiBluetoothMonitor.isBluetoothPaired() && callEmpty) { 2213d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer showNoHfpFragment(R.string.bluetooth_unpaired); 2223d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } else if (!mUiBluetoothMonitor.isHfpConnected() && callEmpty) { 2233d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer showNoHfpFragment(R.string.no_hfp); 2243d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } else { 2253d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer UiCall ongoingCall = mUiCallManager.getPrimaryCall(); 2263d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 227e23918bbc5b7c304ac7f71790340955b5cd32be8Anthony Chen if (vdebug()) { 228e23918bbc5b7c304ac7f71790340955b5cd32be8Anthony Chen Log.d(TAG, "ongoingCall: " + ongoingCall + ", mCurrentFragment: " 22917d5ac7d0b429687765e940279726623f5f5f823Anthony Chen + getCurrentFragment()); 2303d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 2313d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 232e8901d7dac94f2dcbbecdfbdf484b9d0cff5783eYuzhou if (ongoingCall == null && getCurrentFragment() instanceof InCallFragment) { 233e23918bbc5b7c304ac7f71790340955b5cd32be8Anthony Chen showSpeedDialFragment(); 2343d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } else if (ongoingCall != null) { 2353d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer showOngoingCallFragment(); 2363d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } else { 2373d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer showSpeedDialFragment(); 2383d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 2393d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 2403d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 241e23918bbc5b7c304ac7f71790340955b5cd32be8Anthony Chen if (vdebug()) { 2423d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer Log.d(TAG, "updateCurrentFragment: done"); 2433d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 2443d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 2453d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 246e23918bbc5b7c304ac7f71790340955b5cd32be8Anthony Chen private void showSpeedDialFragment() { 247e23918bbc5b7c304ac7f71790340955b5cd32be8Anthony Chen if (vdebug()) { 2483d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer Log.d(TAG, "showSpeedDialFragment"); 2493d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 2503d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 25117d5ac7d0b429687765e940279726623f5f5f823Anthony Chen if (!mAllowFragmentCommits || getCurrentFragment() instanceof StrequentsFragment) { 2523d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer return; 2533d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 2543d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 255f3a67514e1f4068cf594f2636fca742ef4a2ef07Yuzhou Jia Fragment fragment = StrequentsFragment.newInstance(); 25602a83b90ad2a990c22b4654fbfa23b84aae0fafcYuzhou setContentFragment(fragment); 2573d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 2583d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 2593d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer private void showOngoingCallFragment() { 260e23918bbc5b7c304ac7f71790340955b5cd32be8Anthony Chen if (vdebug()) { 2613d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer Log.d(TAG, "showOngoingCallFragment"); 2623d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 263e8901d7dac94f2dcbbecdfbdf484b9d0cff5783eYuzhou if (!mAllowFragmentCommits || getCurrentFragment() instanceof InCallFragment) { 264d81ee5f73e1ab4689883687a8a8d059d5111e34eLujiang Xue // in case the dialer is still open, (e.g. when dialing the second phone during 265d81ee5f73e1ab4689883687a8a8d059d5111e34eLujiang Xue // a phone call), close it 266d81ee5f73e1ab4689883687a8a8d059d5111e34eLujiang Xue maybeHideDialer(); 267f769ab772c1b5792702ef7861d892a680b346e98Anthony Chen getDrawerController().closeDrawer(); 2683d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer return; 2693d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 270e8901d7dac94f2dcbbecdfbdf484b9d0cff5783eYuzhou Fragment fragment = InCallFragment.newInstance(); 27117d5ac7d0b429687765e940279726623f5f5f823Anthony Chen setContentFragmentWithFadeAnimation(fragment); 272f769ab772c1b5792702ef7861d892a680b346e98Anthony Chen getDrawerController().closeDrawer(); 27317d5ac7d0b429687765e940279726623f5f5f823Anthony Chen } 27417d5ac7d0b429687765e940279726623f5f5f823Anthony Chen 27517d5ac7d0b429687765e940279726623f5f5f823Anthony Chen private void showDialer() { 27617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen if (vdebug()) { 27717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen Log.d(TAG, "showDialer"); 2783d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 2793d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 28017d5ac7d0b429687765e940279726623f5f5f823Anthony Chen showDialer(null /* dialNumber */); 2813d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 2823d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 2833d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer /** 28417d5ac7d0b429687765e940279726623f5f5f823Anthony Chen * Displays the {@link DialerFragment} and initialize it with the given phone number. 2853d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer */ 28617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen private void showDialer(@Nullable String dialNumber) { 2873d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer if (vdebug()) { 28817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen Log.d(TAG, "showDialer with number: " + dialNumber); 2893d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 2903d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 29117d5ac7d0b429687765e940279726623f5f5f823Anthony Chen if (!mAllowFragmentCommits || 29217d5ac7d0b429687765e940279726623f5f5f823Anthony Chen getSupportFragmentManager().findFragmentByTag(DIALER_FRAGMENT_TAG) != null) { 2933d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer return; 2943d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 2953d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 2960ee4ae4c98ab4a94e1217399d4a71f6f6db87e99Yuzhou Fragment fragment = DialerFragment.newInstance(dialNumber); 2973d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer // Add the dialer fragment to the backstack so that it can be popped off to dismiss it. 2983fe91522bb3db3b2f8d74a3fed935e35a9bcbb2dYuzhou setContentFragment(fragment); 2993d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 3003d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 3013d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer /** 3023d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer * Checks if the dialpad fragment is opened and hides it if it is. 3033d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer */ 3043d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer private void maybeHideDialer() { 30517d5ac7d0b429687765e940279726623f5f5f823Anthony Chen // The dialer is the only fragment to be added to the back stack. Dismiss the dialer by 30617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen // removing it from the back stack. 30717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen if (getSupportFragmentManager().getBackStackEntryCount() > 0) { 3083d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer getSupportFragmentManager().popBackStack(); 3093d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 3103d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 3113d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 31217d5ac7d0b429687765e940279726623f5f5f823Anthony Chen private void showNoHfpFragment(@StringRes int stringResId) { 31317d5ac7d0b429687765e940279726623f5f5f823Anthony Chen if (!mAllowFragmentCommits) { 3143d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer return; 3153d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 3163d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 3176f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan String errorMessage = getString(stringResId); 31817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen Fragment currentFragment = getCurrentFragment(); 3193d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 32017d5ac7d0b429687765e940279726623f5f5f823Anthony Chen if (currentFragment instanceof NoHfpFragment) { 32117d5ac7d0b429687765e940279726623f5f5f823Anthony Chen ((NoHfpFragment) currentFragment).setErrorMessage(errorMessage); 32217d5ac7d0b429687765e940279726623f5f5f823Anthony Chen } else { 32317d5ac7d0b429687765e940279726623f5f5f823Anthony Chen setContentFragment(NoHfpFragment.newInstance(errorMessage)); 32417d5ac7d0b429687765e940279726623f5f5f823Anthony Chen } 325476856e35551612a71a33c0f797d09dc73569f2fRakesh Iyer } 326476856e35551612a71a33c0f797d09dc73569f2fRakesh Iyer 3273d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer private void setContentFragmentWithSlideAndDelayAnimation(Fragment fragment) { 328e23918bbc5b7c304ac7f71790340955b5cd32be8Anthony Chen if (vdebug()) { 3293d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer Log.d(TAG, "setContentFragmentWithSlideAndDelayAnimation, fragment: " + fragment); 3303d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 3313d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer setContentFragmentWithAnimations(fragment, 3323d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer R.anim.telecom_slide_in_with_delay, R.anim.telecom_slide_out); 3333d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 3343d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 3353d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer private void setContentFragmentWithFadeAnimation(Fragment fragment) { 336e23918bbc5b7c304ac7f71790340955b5cd32be8Anthony Chen if (vdebug()) { 3373d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer Log.d(TAG, "setContentFragmentWithFadeAnimation, fragment: " + fragment); 3383d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 3393d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer setContentFragmentWithAnimations(fragment, 3403d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer R.anim.telecom_fade_in, R.anim.telecom_fade_out); 3413d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 3423d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 34317d5ac7d0b429687765e940279726623f5f5f823Anthony Chen private void setContentFragmentWithAnimations(Fragment fragment, int enter, int exit) { 34417d5ac7d0b429687765e940279726623f5f5f823Anthony Chen if (vdebug()) { 34517d5ac7d0b429687765e940279726623f5f5f823Anthony Chen Log.d(TAG, "setContentFragmentWithAnimations: " + fragment); 34617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen } 34717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen 34817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen maybeHideDialer(); 3493fe91522bb3db3b2f8d74a3fed935e35a9bcbb2dYuzhou 35017d5ac7d0b429687765e940279726623f5f5f823Anthony Chen getSupportFragmentManager().beginTransaction() 35117d5ac7d0b429687765e940279726623f5f5f823Anthony Chen .setCustomAnimations(enter, exit) 352f7ed46be024b7cfb448f93d71f235b30f72aa1eeAnthony Chen .replace(R.id.content_fragment_container, fragment, CONTENT_FRAGMENT_TAG) 35317d5ac7d0b429687765e940279726623f5f5f823Anthony Chen .commitNow(); 35417d5ac7d0b429687765e940279726623f5f5f823Anthony Chen } 35517d5ac7d0b429687765e940279726623f5f5f823Anthony Chen 35617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen /** 35717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen * Sets the fragment that will be shown as the main content of this Activity. Note that this 35817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen * fragment is not always visible. In particular, the dialer fragment can show up on top of this 35917d5ac7d0b429687765e940279726623f5f5f823Anthony Chen * fragment. 36017d5ac7d0b429687765e940279726623f5f5f823Anthony Chen */ 36117d5ac7d0b429687765e940279726623f5f5f823Anthony Chen private void setContentFragment(Fragment fragment) { 36217d5ac7d0b429687765e940279726623f5f5f823Anthony Chen maybeHideDialer(); 36317d5ac7d0b429687765e940279726623f5f5f823Anthony Chen getSupportFragmentManager().beginTransaction() 364f7ed46be024b7cfb448f93d71f235b30f72aa1eeAnthony Chen .replace(R.id.content_fragment_container, fragment, CONTENT_FRAGMENT_TAG) 36517d5ac7d0b429687765e940279726623f5f5f823Anthony Chen .commitNow(); 3669fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia updateTitle(); 36717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen } 36817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen 36917d5ac7d0b429687765e940279726623f5f5f823Anthony Chen /** 37017d5ac7d0b429687765e940279726623f5f5f823Anthony Chen * Returns the fragment that is currently being displayed as the content view. Note that this 37117d5ac7d0b429687765e940279726623f5f5f823Anthony Chen * is not necessarily the fragment that is visible. For example, the returned fragment 37217d5ac7d0b429687765e940279726623f5f5f823Anthony Chen * could be the content, but the dial fragment is being displayed on top of it. Check for 37317d5ac7d0b429687765e940279726623f5f5f823Anthony Chen * the existence of the dial fragment with the TAG {@link #DIALER_FRAGMENT_TAG}. 37417d5ac7d0b429687765e940279726623f5f5f823Anthony Chen */ 37517d5ac7d0b429687765e940279726623f5f5f823Anthony Chen @Nullable 37617d5ac7d0b429687765e940279726623f5f5f823Anthony Chen private Fragment getCurrentFragment() { 37717d5ac7d0b429687765e940279726623f5f5f823Anthony Chen return getSupportFragmentManager().findFragmentByTag(CONTENT_FRAGMENT_TAG); 37817d5ac7d0b429687765e940279726623f5f5f823Anthony Chen } 37917d5ac7d0b429687765e940279726623f5f5f823Anthony Chen 380bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou private static boolean vdebug() { 381bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou return Log.isLoggable(TAG, Log.DEBUG); 382bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou } 3833d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 384bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou @Override 385bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou public void onAudioStateChanged(boolean isMuted, int route, int supportedRouteMask) { 386bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou fragmentsToPropagateCallback().forEach(fragment -> ((CallListener) fragment) 387bfa1ab18a847f1e3b60c2e3fca35d0d923d7fa61Yuzhou .onAudioStateChanged(isMuted, route, supportedRouteMask)); 388bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou } 389bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou 390bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou @Override 391bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou public void onCallStateChanged(UiCall call, int state) { 392bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou if (vdebug()) { 393bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou Log.d(TAG, "onCallStateChanged"); 3943d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 395bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou updateCurrentFragment(); 3963d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 397bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou fragmentsToPropagateCallback().forEach(fragment -> ((CallListener) fragment) 398bfa1ab18a847f1e3b60c2e3fca35d0d923d7fa61Yuzhou .onCallStateChanged(call, state)); 399bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou } 400bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou 401bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou @Override 402bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou public void onCallUpdated(UiCall call) { 403bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou if (vdebug()) { 404bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou Log.d(TAG, "onCallUpdated"); 4053d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 406bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou updateCurrentFragment(); 4073d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 408bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou fragmentsToPropagateCallback().forEach(fragment -> ((CallListener) fragment) 409bfa1ab18a847f1e3b60c2e3fca35d0d923d7fa61Yuzhou .onCallUpdated(call)); 410bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou } 411bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou 412bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou @Override 413bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou public void onCallAdded(UiCall call) { 414bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou if (vdebug()) { 415bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou Log.d(TAG, "onCallAdded"); 4163d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 417bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou updateCurrentFragment(); 4183d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 419bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou fragmentsToPropagateCallback().forEach(fragment -> ((CallListener) fragment) 420bfa1ab18a847f1e3b60c2e3fca35d0d923d7fa61Yuzhou .onCallAdded(call)); 4213d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 4223d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 4236f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan @Override 424bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou public void onCallRemoved(UiCall call) { 425bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou if (vdebug()) { 426bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou Log.d(TAG, "onCallRemoved"); 427bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou } 428bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou updateCurrentFragment(); 429bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou 430bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou fragmentsToPropagateCallback().forEach(fragment -> ((CallListener) fragment) 431bfa1ab18a847f1e3b60c2e3fca35d0d923d7fa61Yuzhou .onCallRemoved(call)); 432bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou } 433bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou 434bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou private static boolean shouldPropagateCallback(Fragment fragment) { 435bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou return fragment instanceof CallListener && fragment.isAdded(); 436bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou } 437bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou 438bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou private Stream<Fragment> fragmentsToPropagateCallback() { 439bb51ff67f2973488079684ca58924a1c4b712dabJohnny Zhou return getSupportFragmentManager().getFragments().stream() 440bfa1ab18a847f1e3b60c2e3fca35d0d923d7fa61Yuzhou .filter(fragment -> shouldPropagateCallback(fragment)); 4416f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan } 4426f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan 443f5483be6462054b62a700f35d4bbc7a69aa444f1Srinivas Visvanathan private class DialerRootAdapter extends CarDrawerAdapter { 444c636d2d78f004667cd47efe5ecdf3897e75c1fe2Yuzhou private static final int ITEM_FAVORITES = 0; 4456f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan private static final int ITEM_CALLLOG_ALL = 1; 4466f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan private static final int ITEM_CALLLOG_MISSED = 2; 4473fe91522bb3db3b2f8d74a3fed935e35a9bcbb2dYuzhou private static final int ITEM_CONTACT = 3; 4483fe91522bb3db3b2f8d74a3fed935e35a9bcbb2dYuzhou private static final int ITEM_DIAL = 4; 449c636d2d78f004667cd47efe5ecdf3897e75c1fe2Yuzhou 4503fe91522bb3db3b2f8d74a3fed935e35a9bcbb2dYuzhou private static final int ITEM_COUNT = 5; 4513d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 4526f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan DialerRootAdapter() { 45368d51ec195f609b1138402f9b446ec301e9c5f4cSrinivas Visvanathan super(TelecomActivity.this, false /* showDisabledListOnEmpty */); 4543d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 4553d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 4563d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer @Override 4576f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan protected int getActualItemCount() { 458c636d2d78f004667cd47efe5ecdf3897e75c1fe2Yuzhou return ITEM_COUNT; 4596f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan } 4603d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 4616f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan @Override 4626f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan public void populateViewHolder(DrawerItemViewHolder holder, int position) { 4636f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan final int iconColor = getResources().getColor(R.color.car_tint); 4646f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan int textResId, iconResId; 4656f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan switch (position) { 4666f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan case ITEM_DIAL: 4676f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan textResId = R.string.calllog_dial_number; 4686f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan iconResId = R.drawable.ic_drawer_dialpad; 4693d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer break; 4706f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan case ITEM_CALLLOG_ALL: 4716f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan textResId = R.string.calllog_all; 4726f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan iconResId = R.drawable.ic_drawer_history; 4736f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan break; 4746f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan case ITEM_CALLLOG_MISSED: 4756f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan textResId = R.string.calllog_missed; 476c636d2d78f004667cd47efe5ecdf3897e75c1fe2Yuzhou iconResId = R.drawable.ic_call_missed; 477c636d2d78f004667cd47efe5ecdf3897e75c1fe2Yuzhou break; 478c636d2d78f004667cd47efe5ecdf3897e75c1fe2Yuzhou case ITEM_FAVORITES: 479c636d2d78f004667cd47efe5ecdf3897e75c1fe2Yuzhou textResId = R.string.calllog_favorites; 480c636d2d78f004667cd47efe5ecdf3897e75c1fe2Yuzhou iconResId = R.drawable.ic_favorite; 4813d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer break; 4823fe91522bb3db3b2f8d74a3fed935e35a9bcbb2dYuzhou case ITEM_CONTACT: 4833fe91522bb3db3b2f8d74a3fed935e35a9bcbb2dYuzhou textResId = R.string.contact_menu_label; 4843fe91522bb3db3b2f8d74a3fed935e35a9bcbb2dYuzhou iconResId = R.drawable.ic_contact; 4853fe91522bb3db3b2f8d74a3fed935e35a9bcbb2dYuzhou break; 4863d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer default: 4876f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan Log.wtf(TAG, "Unexpected position: " + position); 4886f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan return; 4896f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan } 4906f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan holder.getTitle().setText(textResId); 4916f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan Drawable drawable = getDrawable(iconResId); 4926f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan drawable.setColorFilter(iconColor, PorterDuff.Mode.SRC_IN); 4936f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan holder.getIcon().setImageDrawable(drawable); 4943d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 4953d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 4963d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer @Override 4976f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan public void onItemClick(int position) { 498bfa1ab18a847f1e3b60c2e3fca35d0d923d7fa61Yuzhou getDrawerController().closeDrawer(); 4996f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan switch (position) { 5006f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan case ITEM_DIAL: 5016f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan showDialer(); 5026f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan break; 5036f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan case ITEM_CALLLOG_ALL: 504bfa1ab18a847f1e3b60c2e3fca35d0d923d7fa61Yuzhou showCallHistory(PhoneLoader.CallType.CALL_TYPE_ALL); 5056f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan break; 5066f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan case ITEM_CALLLOG_MISSED: 507bfa1ab18a847f1e3b60c2e3fca35d0d923d7fa61Yuzhou showCallHistory(PhoneLoader.CallType.MISSED_TYPE); 5086f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan break; 509c636d2d78f004667cd47efe5ecdf3897e75c1fe2Yuzhou case ITEM_FAVORITES: 510c636d2d78f004667cd47efe5ecdf3897e75c1fe2Yuzhou showSpeedDialFragment(); 511c636d2d78f004667cd47efe5ecdf3897e75c1fe2Yuzhou break; 5123fe91522bb3db3b2f8d74a3fed935e35a9bcbb2dYuzhou case ITEM_CONTACT: 5133fe91522bb3db3b2f8d74a3fed935e35a9bcbb2dYuzhou showContact(); 5143fe91522bb3db3b2f8d74a3fed935e35a9bcbb2dYuzhou break; 5156f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan default: 5166f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan Log.w(TAG, "Invalid position in ROOT menu! " + position); 5173d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 5189fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia setTitle(getTitleString()); 5193d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 5206f8e1dbe4629b499128dade1e6d83e37147403c4Srinivas Visvanathan } 5213d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer 522bfa1ab18a847f1e3b60c2e3fca35d0d923d7fa61Yuzhou private void showCallHistory(@PhoneLoader.CallType int callType) { 5233fe91522bb3db3b2f8d74a3fed935e35a9bcbb2dYuzhou setContentFragment(CallHistoryFragment.newInstance(callType)); 5243fe91522bb3db3b2f8d74a3fed935e35a9bcbb2dYuzhou } 5253fe91522bb3db3b2f8d74a3fed935e35a9bcbb2dYuzhou 5263fe91522bb3db3b2f8d74a3fed935e35a9bcbb2dYuzhou private void showContact() { 5273fe91522bb3db3b2f8d74a3fed935e35a9bcbb2dYuzhou setContentFragment(ContactListFragment.newInstance()); 5283d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer } 5299fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia 5309fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia private void updateTitle() { 5319fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia setTitle(getTitleString()); 5329fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia } 5339fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia 5349fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia private String getTitleString() { 5359fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia Fragment currentFragment = getCurrentFragment(); 5369fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia 5379fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia int titleResId = R.string.phone_app_name; 5389fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia 5399fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia if (currentFragment instanceof StrequentsFragment) { 540f3a67514e1f4068cf594f2636fca742ef4a2ef07Yuzhou Jia titleResId = R.string.contacts_title; 5419fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia } else if (currentFragment instanceof CallHistoryFragment) { 5429fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia int callType = currentFragment.getArguments().getInt(CALL_TYPE_KEY); 5439fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia if (callType == PhoneLoader.CallType.MISSED_TYPE) { 5449fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia titleResId = R.string.missed_call_title; 5459fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia } else { 5469fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia titleResId = R.string.call_history_title; 5479fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia } 5489fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia } else if (currentFragment instanceof ContactListFragment) { 5499fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia titleResId = R.string.contacts_title; 5509fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia } else if (currentFragment instanceof DialerFragment) { 5519fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia titleResId = R.string.dialpad_title; 5529fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia } else if (currentFragment instanceof InCallFragment 5539fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia || currentFragment instanceof OngoingCallFragment) { 5549fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia titleResId = R.string.in_call_title; 5559fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia } 5569fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia 5579fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia return getString(titleResId); 5589fbc1333f54984d799e91f858e37f72dcfcfca3dYuzhou Jia } 5593d724a4b70dd9a08d9adddc3b403edfd572bcaa6Rakesh Iyer} 560