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