/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.car.dialer;

import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.telecom.Call;
import android.telecom.CallAudioState;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;

import com.android.car.apps.common.FabDrawable;
import com.android.car.dialer.telecom.TelecomUtils;
import com.android.car.dialer.telecom.UiCall;
import com.android.car.dialer.telecom.UiCallManager;
import com.android.car.dialer.ui.CircleBitmapDrawable;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * A fragment that displays information about an on-going call with options to hang up.
 */
@Deprecated
public class OngoingCallFragment extends Fragment implements CallListener {
    private static final String TAG = "OngoingCall";
    private static final SparseArray<Character> mDialpadButtonMap = new SparseArray<>();

    static {
        mDialpadButtonMap.put(R.id.one, '1');
        mDialpadButtonMap.put(R.id.two, '2');
        mDialpadButtonMap.put(R.id.three, '3');
        mDialpadButtonMap.put(R.id.four, '4');
        mDialpadButtonMap.put(R.id.five, '5');
        mDialpadButtonMap.put(R.id.six, '6');
        mDialpadButtonMap.put(R.id.seven, '7');
        mDialpadButtonMap.put(R.id.eight, '8');
        mDialpadButtonMap.put(R.id.nine, '9');
        mDialpadButtonMap.put(R.id.zero, '0');
        mDialpadButtonMap.put(R.id.star, '*');
        mDialpadButtonMap.put(R.id.pound, '#');
    }

    private final Handler mHandler = new Handler();

    private UiCall mLastRemovedCall;
    private UiCallManager mUiCallManager;
    private View mRingingCallControls;
    private View mActiveCallControls;
    private ImageButton mEndCallButton;
    private ImageButton mUnholdCallButton;
    private ImageButton mMuteButton;
    private ImageButton mToggleDialpadButton;
    private ImageButton mSwapButton;
    private ImageButton mMergeButton;
    private ImageButton mAnswerCallButton;
    private ImageButton mRejectCallButton;
    private TextView mNameTextView;
    private TextView mSecondaryNameTextView;
    private TextView mStateTextView;
    private TextView mSecondaryStateTextView;
    private ImageView mLargeContactPhotoView;
    private ImageView mSmallContactPhotoView;
    private View mDialpadContainer;
    private View mSecondaryCallContainer;
    private View mSecondaryCallControls;
    private String mLoadedNumber;
    private CharSequence mCallInfoLabel;
    private UiBluetoothMonitor mUiBluetoothMonitor;

    static OngoingCallFragment newInstance(UiCallManager callManager,
            UiBluetoothMonitor btMonitor) {
        OngoingCallFragment fragment = new OngoingCallFragment();
        fragment.mUiCallManager = callManager;
        fragment.mUiBluetoothMonitor = btMonitor;
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mHandler.removeCallbacks(mUpdateDurationRunnable);
        mHandler.removeCallbacks(mStopDtmfToneRunnable);
        mLoadedNumber = null;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.ongoing_call, container, false);
        initializeViews(view);
        initializeClickListeners();

        List<View> dialpadViews = Arrays.asList(
                mDialpadContainer.findViewById(R.id.one),
                mDialpadContainer.findViewById(R.id.two),
                mDialpadContainer.findViewById(R.id.three),
                mDialpadContainer.findViewById(R.id.four),
                mDialpadContainer.findViewById(R.id.five),
                mDialpadContainer.findViewById(R.id.six),
                mDialpadContainer.findViewById(R.id.seven),
                mDialpadContainer.findViewById(R.id.eight),
                mDialpadContainer.findViewById(R.id.nine),
                mDialpadContainer.findViewById(R.id.zero),
                mDialpadContainer.findViewById(R.id.pound),
                mDialpadContainer.findViewById(R.id.star));

        // In touch screen, we need to adjust the InCall card for the narrow screen to show the
        // full dial pad.
        for (View dialpadView : dialpadViews) {
            dialpadView.setOnTouchListener(mDialpadTouchListener);
            dialpadView.setOnKeyListener(mDialpadKeyListener);
        }

        updateCalls();

        return view;
    }

    private void initializeViews(View parent) {
        mRingingCallControls = parent.findViewById(R.id.ringing_call_controls);
        mActiveCallControls = parent.findViewById(R.id.active_call_controls);
        mEndCallButton = parent.findViewById(R.id.end_call);
        mUnholdCallButton = parent.findViewById(R.id.unhold_call);
        mMuteButton = parent.findViewById(R.id.mute);
        mToggleDialpadButton = parent.findViewById(R.id.toggle_dialpad);
        mDialpadContainer = parent.findViewById(R.id.dialpad_container);
        mNameTextView = parent.findViewById(R.id.name);
        mSecondaryNameTextView = parent.findViewById(R.id.name_secondary);
        mStateTextView = parent.findViewById(R.id.info);
        mSecondaryStateTextView = parent.findViewById(R.id.info_secondary);
        mLargeContactPhotoView = parent.findViewById(R.id.large_contact_photo);
        mSmallContactPhotoView = parent.findViewById(R.id.small_contact_photo);
        mSecondaryCallContainer = parent.findViewById(R.id.secondary_call_container);
        mSecondaryCallControls = parent.findViewById(R.id.secondary_call_controls);
        mSwapButton = parent.findViewById(R.id.swap);
        mMergeButton = parent.findViewById(R.id.merge);
        mAnswerCallButton = parent.findViewById(R.id.answer_call_button);
        mRejectCallButton = parent.findViewById(R.id.reject_call_button);

        Context context = getContext();
        FabDrawable drawable = new FabDrawable(context);
        drawable.setFabAndStrokeColor(context.getColor(R.color.phone_call));
        mAnswerCallButton.setBackground(drawable);

        drawable = new FabDrawable(context);
        drawable.setFabAndStrokeColor(context.getColor(R.color.phone_end_call));
        mEndCallButton.setBackground(drawable);

        drawable = new FabDrawable(context);
        drawable.setFabAndStrokeColor(context.getColor(R.color.phone_call));
        mUnholdCallButton.setBackground(drawable);
    }

    private void initializeClickListeners() {
        mAnswerCallButton.setOnClickListener((unusedView) -> {
            UiCall call = mUiCallManager.getCallWithState(Call.STATE_RINGING);
            if (call == null) {
                Log.w(TAG, "There is no incoming call to answer.");
                return;
            }
            mUiCallManager.answerCall(call);
        });

        mRejectCallButton.setOnClickListener((unusedView) -> {
            UiCall call = mUiCallManager.getCallWithState(Call.STATE_RINGING);
            if (call == null) {
                Log.w(TAG, "There is no incoming call to reject.");
                return;
            }
            mUiCallManager.rejectCall(call, false, null);
        });

        mEndCallButton.setOnClickListener((unusedView) -> {
            UiCall call = mUiCallManager.getPrimaryCall();
            if (call == null) {
                Log.w(TAG, "There is no active call to end.");
                return;
            }
            mUiCallManager.disconnectCall(call);
        });

        mUnholdCallButton.setOnClickListener((unusedView) -> {
            UiCall call = mUiCallManager.getPrimaryCall();
            if (call == null) {
                Log.w(TAG, "There is no active call to unhold.");
                return;
            }
            mUiCallManager.unholdCall(call);
        });

        mMuteButton.setOnClickListener(
                (unusedView) -> mUiCallManager.setMuted(!mUiCallManager.getMuted()));

        mSwapButton.setOnClickListener((unusedView) -> {
            UiCall call = mUiCallManager.getPrimaryCall();
            if (call == null) {
                Log.w(TAG, "There is no active call to hold.");
                return;
            }
            if (call.getState() == Call.STATE_HOLDING) {
                mUiCallManager.unholdCall(call);
            } else {
                mUiCallManager.holdCall(call);
            }
        });

        mMergeButton.setOnClickListener((unusedView) -> {
            UiCall call = mUiCallManager.getPrimaryCall();
            UiCall secondaryCall = mUiCallManager.getSecondaryCall();
            if (call == null || secondaryCall == null) {
                Log.w(TAG, "There aren't two call to merge.");
                return;
            }

            mUiCallManager.conference(call, secondaryCall);
        });

        mToggleDialpadButton.setOnClickListener((unusedView) -> {
            if (mToggleDialpadButton.isActivated()) {
                closeDialpad();
            } else {
                openDialpad(true /*animate*/);
            }
        });
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
    }

    @Override
    public void onStart() {
        super.onStart();
        trySpeakerAudioRouteIfNecessary();
    }

    private void updateCalls() {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "updateCalls(); Primary call: " + mUiCallManager.getPrimaryCall()
                    + "; Secondary call:" + mUiCallManager.getSecondaryCall());
        }

        mHandler.removeCallbacks(mUpdateDurationRunnable);

        UiCall primaryCall = mUiCallManager.getPrimaryCall();
        CharSequence disconnectCauseLabel = mLastRemovedCall == null
                ? null : mLastRemovedCall.getDisconnectCause();
        if (primaryCall == null && !TextUtils.isEmpty(disconnectCauseLabel)) {
            closeDialpad();
            setStateText(disconnectCauseLabel);
            return;
        }

        if (primaryCall == null || primaryCall.getState() == Call.STATE_DISCONNECTED) {
            closeDialpad();
            setStateText(getString(R.string.call_state_call_ended));
            mRingingCallControls.setVisibility(View.GONE);
            mActiveCallControls.setVisibility(View.GONE);
            return;
        }

        if (primaryCall.getState() == Call.STATE_RINGING) {
            mRingingCallControls.setVisibility(View.VISIBLE);
            mActiveCallControls.setVisibility(View.GONE);
        } else {
            mRingingCallControls.setVisibility(View.GONE);
            mActiveCallControls.setVisibility(View.VISIBLE);
        }

        loadContactPhotoForPrimaryNumber(primaryCall.getNumber());

        String displayName = TelecomUtils.getDisplayName(getContext(), primaryCall);
        mNameTextView.setText(displayName);
        mNameTextView.setVisibility(TextUtils.isEmpty(displayName) ? View.GONE : View.VISIBLE);

        Context context = getContext();
        switch (primaryCall.getState()) {
            case Call.STATE_NEW:
                // Since the content resolver call is only cached when a contact is found,
                // this should only be called once on a new call to avoid jank.
                // TODO: consider moving TelecomUtils.getTypeFromNumber into a CursorLoader
                mCallInfoLabel = TelecomUtils.getTypeFromNumber(context, primaryCall.getNumber());
            case Call.STATE_CONNECTING:
            case Call.STATE_DIALING:
            case Call.STATE_SELECT_PHONE_ACCOUNT:
            case Call.STATE_HOLDING:
            case Call.STATE_DISCONNECTED:
                mHandler.removeCallbacks(mUpdateDurationRunnable);
                String callInfoText = TelecomUtils.getCallInfoText(context,
                        primaryCall, mCallInfoLabel);
                setStateText(callInfoText);
                break;
            case Call.STATE_ACTIVE:
                if (mUiBluetoothMonitor.isHfpConnected()) {
                    mHandler.post(mUpdateDurationRunnable);
                }
                break;
            case Call.STATE_RINGING:
                Log.w(TAG, "There should not be a ringing call in the ongoing call fragment.");
                break;
            default:
                Log.w(TAG, "Unhandled call state: " + primaryCall.getState());
        }

        // If it is a voicemail call, open the dialpad (with no animation).
        if (Objects.equals(primaryCall.getNumber(), TelecomUtils.getVoicemailNumber(context))) {
            openDialpad(false /*animate*/);
            mToggleDialpadButton.setVisibility(View.GONE);
        } else {
            mToggleDialpadButton.setVisibility(View.VISIBLE);
        }

        // Handle the holding case.
        if (primaryCall.getState() == Call.STATE_HOLDING) {
            mEndCallButton.setVisibility(View.GONE);
            mUnholdCallButton.setVisibility(View.VISIBLE);
            mMuteButton.setVisibility(View.INVISIBLE);
            mToggleDialpadButton.setVisibility(View.INVISIBLE);
        } else {
            mEndCallButton.setVisibility(View.VISIBLE);
            mUnholdCallButton.setVisibility(View.GONE);
            mMuteButton.setVisibility(View.VISIBLE);
            mToggleDialpadButton.setVisibility(View.VISIBLE);
        }

        updateSecondaryCall(primaryCall, mUiCallManager.getSecondaryCall());
    }

    private void updateSecondaryCall(UiCall primaryCall, UiCall secondaryCall) {
        if (primaryCall == null || secondaryCall == null) {
            mSecondaryCallContainer.setVisibility(View.GONE);
            mSecondaryCallControls.setVisibility(View.GONE);
            return;
        }

        mSecondaryCallContainer.setVisibility(View.VISIBLE);

        if (primaryCall.getState() == Call.STATE_ACTIVE
                && secondaryCall.getState() == Call.STATE_HOLDING) {
            mSecondaryCallControls.setVisibility(View.VISIBLE);
        } else {
            mSecondaryCallControls.setVisibility(View.GONE);
        }

        Context context = getContext();
        mSecondaryNameTextView.setText(TelecomUtils.getDisplayName(context, secondaryCall));
        mSecondaryStateTextView.setText(
                TelecomUtils.callStateToUiString(context, secondaryCall.getState()));

        loadContactPhotoForSecondaryNumber(secondaryCall.getNumber());
    }

    /**
     * Loads the contact photo associated with the given number and sets it in the views that
     * correspond with a primary number.
     */
    private void loadContactPhotoForPrimaryNumber(String primaryNumber) {
        // Don't reload the image if the number is the same.
        if (Objects.equals(primaryNumber, mLoadedNumber)) {
            return;
        }

        final ContentResolver cr = getContext().getContentResolver();
        BitmapWorkerTask.BitmapRunnable runnable = new BitmapWorkerTask.BitmapRunnable() {
            @Override
            public void run() {
                if (mBitmap != null) {
                    Resources r = getResources();
                    mSmallContactPhotoView.setImageDrawable(new CircleBitmapDrawable(r, mBitmap));
                    mLargeContactPhotoView.setImageBitmap(mBitmap);
                    mLargeContactPhotoView.clearColorFilter();
                } else {
                    mSmallContactPhotoView.setImageResource(R.drawable.logo_avatar);
                    mLargeContactPhotoView.setImageResource(R.drawable.ic_avatar_bg);
                }
            }
        };
        mLoadedNumber = primaryNumber;
        BitmapWorkerTask.loadBitmap(cr, mLargeContactPhotoView, primaryNumber, runnable);
    }

    /**
     * Loads the contact photo associated with the given number and sets it in the views that
     * correspond to a secondary number.
     */
    private void loadContactPhotoForSecondaryNumber(String secondaryNumber) {
        BitmapWorkerTask.BitmapRunnable runnable = new BitmapWorkerTask.BitmapRunnable() {
            @Override
            public void run() {
                if (mBitmap != null) {
                    mLargeContactPhotoView.setImageBitmap(mBitmap);
                } else {
                    mLargeContactPhotoView.setImageResource(R.drawable.logo_avatar);
                }
            }
        };

        Context context = getContext();
        BitmapWorkerTask.loadBitmap(context.getContentResolver(), mLargeContactPhotoView,
                secondaryNumber, runnable);

        int scrimColor = context.getColor(R.color.phone_secondary_call_scrim);
        mLargeContactPhotoView.setColorFilter(scrimColor);
    }

    private void setStateText(CharSequence stateText) {
        mStateTextView.setText(stateText);
        mStateTextView.setVisibility(TextUtils.isEmpty(stateText) ? View.GONE : View.VISIBLE);
    }

    /**
     * If the phone is using bluetooth, then do nothing. If the phone is not using bluetooth:
     * <p>
     * <ol>
     *     <li>If the phone supports bluetooth, use it.
     *     <li>If the phone doesn't support bluetooth and support speaker, use speaker
     *     <li>Otherwise, do nothing. Hopefully no phones won't have bt or speaker.
     * </ol>
     */
    private void trySpeakerAudioRouteIfNecessary() {
        if (mUiCallManager == null) {
            return;
        }

        int supportedAudioRouteMask = mUiCallManager.getSupportedAudioRouteMask();
        boolean supportsBluetooth = (supportedAudioRouteMask & CallAudioState.ROUTE_BLUETOOTH) != 0;
        boolean supportsSpeaker = (supportedAudioRouteMask & CallAudioState.ROUTE_SPEAKER) != 0;
        boolean isUsingBluetooth =
                mUiCallManager.getAudioRoute() == CallAudioState.ROUTE_BLUETOOTH;

        if (supportsBluetooth && !isUsingBluetooth) {
            mUiCallManager.setAudioRoute(CallAudioState.ROUTE_BLUETOOTH);
        } else if (!supportsBluetooth && supportsSpeaker) {
            mUiCallManager.setAudioRoute(CallAudioState.ROUTE_SPEAKER);
        }
    }

    private void openDialpad(boolean animate) {
        if (mToggleDialpadButton.isActivated()) {
            return;
        }
        mToggleDialpadButton.setActivated(true);
        // This array of of size 2 because getLocationOnScreen returns (x,y) coordinates.
        int[] location = new int[2];
        mToggleDialpadButton.getLocationOnScreen(location);

        // The dialpad should be aligned with the right edge of mToggleDialpadButton.
        int startingMargin = location[1] + mToggleDialpadButton.getWidth();

        ViewGroup.MarginLayoutParams layoutParams =
                (ViewGroup.MarginLayoutParams) mDialpadContainer.getLayoutParams();

        if (layoutParams.getMarginStart() != startingMargin) {
            layoutParams.setMarginStart(startingMargin);
            mDialpadContainer.setLayoutParams(layoutParams);
        }

        Animation anim = new DialpadAnimation(getContext(), false /* reverse */, animate);
        mDialpadContainer.startAnimation(anim);
    }

    private void closeDialpad() {
        if (!mToggleDialpadButton.isActivated()) {
            return;
        }
        mToggleDialpadButton.setActivated(false);
        Animation anim = new DialpadAnimation(getContext(), true /* reverse */);
        mDialpadContainer.startAnimation(anim);
    }

    private final View.OnTouchListener mDialpadTouchListener = new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Character digit = mDialpadButtonMap.get(v.getId());
            if (digit == null) {
                Log.w(TAG, "Unknown dialpad button pressed.");
                return false;
            }
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                v.setPressed(true);
                mUiCallManager.playDtmfTone(mUiCallManager.getPrimaryCall(), digit);
                return true;
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                v.setPressed(false);
                v.performClick();
                mUiCallManager.stopDtmfTone(mUiCallManager.getPrimaryCall());
                return true;
            }

            return false;
        }
    };

    private final View.OnKeyListener mDialpadKeyListener = new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            Character digit = mDialpadButtonMap.get(v.getId());
            if (digit == null) {
                Log.w(TAG, "Unknown dialpad button pressed.");
                return false;
            }

            if (event.getKeyCode() != KeyEvent.KEYCODE_DPAD_CENTER) {
                return false;
            }

            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                v.setPressed(true);
                mUiCallManager.playDtmfTone(mUiCallManager.getPrimaryCall(), digit);
                return true;
            } else if (event.getAction() == KeyEvent.ACTION_UP) {
                v.setPressed(false);
                mUiCallManager.stopDtmfTone(mUiCallManager.getPrimaryCall());
                return true;
            }

            return false;
        }
    };

    private final Runnable mUpdateDurationRunnable = new Runnable() {
        @Override
        public void run() {
            UiCall primaryCall = mUiCallManager.getPrimaryCall();
            if (primaryCall.getState() != Call.STATE_ACTIVE) {
                return;
            }
            String callInfoText = TelecomUtils.getCallInfoText(getContext(),
                    primaryCall, mCallInfoLabel);
            setStateText(callInfoText);
            mHandler.postDelayed(this /* runnable */, DateUtils.SECOND_IN_MILLIS);

        }
    };

    private final Runnable mStopDtmfToneRunnable =
            () -> mUiCallManager.stopDtmfTone(mUiCallManager.getPrimaryCall());

    @Override
    public void onAudioStateChanged(boolean isMuted, int route, int supportedRouteMask) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, String.format(
                "onAudioStateChanged(); isMuted: %b, audioRoute: %d, supportedAudioRouteMask: %d",
                isMuted, route, supportedRouteMask));
        }
        mMuteButton.setActivated(isMuted);
        trySpeakerAudioRouteIfNecessary();
    }

    @Override
    public void onCallStateChanged(UiCall call, int state) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, String.format("onCallStateChanged(); call: %s, state: %s", call, state));
        }
        updateCalls();
    }

    @Override
    public void onCallUpdated(UiCall call) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "onCallUpdated(); call: " + call);
        }
        updateCalls();
    }

    @Override
    public void onCallAdded(UiCall call) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "onCallAdded(); call: " + call);
        }
        updateCalls();
        trySpeakerAudioRouteIfNecessary();
    }

    @Override
    public void onCallRemoved(UiCall call) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "onCallRemoved(); call: " + call);
        }
        mLastRemovedCall = call;
        updateCalls();
    }

    private final class DialpadAnimation extends Animation {
        private static final int DURATION = 300;
        private static final float MAX_SCRIM_ALPHA = 0.6f;

        private final int mStartingTranslation;
        private final int mScrimColor;
        private final boolean mReverse;

        DialpadAnimation(Context context, boolean reverse) {
            this(context, reverse, true);
        }

        DialpadAnimation(Context context, boolean reverse, boolean animate) {
            setDuration(animate ? DURATION : 0);
            setInterpolator(new AccelerateDecelerateInterpolator());
            mStartingTranslation = context.getResources().getDimensionPixelOffset(
                    R.dimen.in_call_card_dialpad_translation_x);
            mScrimColor = context.getColor(R.color.phone_theme);
            mReverse = reverse;
        }

        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            if (mReverse) {
                interpolatedTime = 1f - interpolatedTime;
            }
            int translationX = (int) (mStartingTranslation * (1f - interpolatedTime));
            mDialpadContainer.setTranslationX(translationX);
            mDialpadContainer.setAlpha(interpolatedTime);
            if (interpolatedTime == 0f) {
                mDialpadContainer.setVisibility(View.GONE);
            } else {
                mDialpadContainer.setVisibility(View.VISIBLE);
            }
            float alpha = 255f * interpolatedTime * MAX_SCRIM_ALPHA;
            mLargeContactPhotoView.setColorFilter(Color.argb((int) alpha, Color.red(mScrimColor),
                    Color.green(mScrimColor), Color.blue(mScrimColor)));

            mSecondaryNameTextView.setAlpha(1f - interpolatedTime);
            mSecondaryStateTextView.setAlpha(1f - interpolatedTime);
        }
    }
}
