/*
 * Copyright (C) 2021 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.systemui.car.volume;

import static android.car.media.CarAudioManager.AUDIO_FEATURE_VOLUME_GROUP_MUTING;
import static android.car.media.CarAudioManager.PRIMARY_AUDIO_ZONE;

import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorSet;
import android.annotation.DrawableRes;
import android.annotation.Nullable;
import android.app.Dialog;
import android.app.KeyguardManager;
import android.car.Car;
import android.car.media.CarAudioManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.os.Build;
import android.os.Debug;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.UserHandle;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
import android.util.Xml;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.android.systemui.R;
import com.android.systemui.car.CarServiceProvider;
import com.android.systemui.plugins.VolumeDialog;
import com.android.systemui.volume.Events;
import com.android.systemui.volume.SystemUIInterpolators;
import com.android.systemui.volume.VolumeDialogImpl;

import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Car version of the volume dialog.
 *
 * Methods ending in "H" must be called on the (ui) handler.
 */
public class CarVolumeDialogImpl implements VolumeDialog {

    private static final String TAG = "CarVolumeDialog";
    private static final boolean DEBUG = Build.IS_USERDEBUG || Build.IS_ENG;

    private static final String XML_TAG_VOLUME_ITEMS = "carVolumeItems";
    private static final String XML_TAG_VOLUME_ITEM = "item";
    private static final int LISTVIEW_ANIMATION_DURATION_IN_MILLIS = 250;
    private static final int DISMISS_DELAY_IN_MILLIS = 50;
    private static final int ARROW_FADE_IN_START_DELAY_IN_MILLIS = 100;

    private final Context mContext;
    private final H mHandler = new H();
    // All the volume items.
    private final SparseArray<VolumeItem> mVolumeItems = new SparseArray<>();
    // Available volume items in car audio manager.
    private final List<VolumeItem> mAvailableVolumeItems = new ArrayList<>();
    // Volume items in the RecyclerView.
    private final List<CarVolumeItem> mCarVolumeLineItems = new ArrayList<>();
    private final KeyguardManager mKeyguard;
    private final int mNormalTimeout;
    private final int mHoveringTimeout;
    private final int mExpNormalTimeout;
    private final int mExpHoveringTimeout;
    private final CarServiceProvider mCarServiceProvider;

    private Window mWindow;
    private CustomDialog mDialog;
    private RecyclerView mListView;
    private CarVolumeItemAdapter mVolumeItemsAdapter;
    private CarAudioManager mCarAudioManager;
    private boolean mHovering;
    private int mCurrentlyDisplayingGroupId;
    private int mPreviouslyDisplayingGroupId;
    private boolean mShowing;
    private boolean mDismissing;
    private boolean mExpanded;
    private View mExpandIcon;

    private final CarAudioManager.CarVolumeCallback mVolumeChangeCallback =
            new CarAudioManager.CarVolumeCallback() {
                @Override
                public void onGroupVolumeChanged(int zoneId, int groupId, int flags) {
                    updateVolumeAndMute(zoneId, groupId, flags);
                }

                @Override
                public void onMasterMuteChanged(int zoneId, int flags) {
                    // ignored
                }

                @Override
                public void onGroupMuteChanged(int zoneId, int groupId, int flags) {
                    updateVolumeAndMute(zoneId, groupId, flags);
                }

                private void updateVolumeAndMute(int zoneId, int groupId, int flags) {
                    // TODO: Include zoneId into consideration.
                    VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
                    boolean muted = isGroupMuted(mCarAudioManager, groupId);
                    int value = getSeekbarValue(mCarAudioManager, groupId);

                    boolean isShowing = mCarVolumeLineItems.stream().anyMatch(
                            item -> item.getGroupId() == groupId);

                    if ((value != volumeItem.mProgress || muted != volumeItem.mIsMuted)
                            && isShowing) {
                        volumeItem.mCarVolumeItem.setProgress(value);
                        volumeItem.mProgress = value;
                        volumeItem.mCarVolumeItem.setIsMuted(muted);
                        volumeItem.mIsMuted = muted;
                    }
                    if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
                        mPreviouslyDisplayingGroupId = mCurrentlyDisplayingGroupId;
                        mCurrentlyDisplayingGroupId = groupId;
                        mHandler.obtainMessage(H.SHOW,
                                Events.SHOW_REASON_VOLUME_CHANGED).sendToTarget();
                    }
                }
            };

    private final CarServiceProvider.CarServiceOnConnectedListener mCarServiceOnConnectedListener =
            car -> {
                mExpanded = false;
                mCarAudioManager = (CarAudioManager) car.getCarManager(Car.AUDIO_SERVICE);
                int volumeGroupCount = mCarAudioManager.getVolumeGroupCount();
                // Populates volume slider items from volume groups to UI.
                for (int groupId = 0; groupId < volumeGroupCount; groupId++) {
                    VolumeItem volumeItem = getVolumeItemForUsages(
                            mCarAudioManager.getUsagesForVolumeGroupId(groupId));
                    mAvailableVolumeItems.add(volumeItem);
                    // The first one is the default item.
                    if (groupId == 0) {
                        clearAllAndSetupDefaultCarVolumeLineItem(0);
                    }
                }

                // If list is already initiated, update its content.
                if (mVolumeItemsAdapter != null) {
                    mVolumeItemsAdapter.notifyDataSetChanged();
                }
                mCarAudioManager.registerCarVolumeCallback(mVolumeChangeCallback);
            };

    private final BroadcastReceiver mHomeButtonPressedBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (!intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
                return;
            }

            dismissH(Events.DISMISS_REASON_VOLUME_CONTROLLER);
        }
    };

    public CarVolumeDialogImpl(Context context, CarServiceProvider carServiceProvider) {
        mContext = context;
        mCarServiceProvider = carServiceProvider;
        mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
        mNormalTimeout = mContext.getResources().getInteger(
                R.integer.car_volume_dialog_display_normal_timeout);
        mHoveringTimeout = mContext.getResources().getInteger(
                R.integer.car_volume_dialog_display_hovering_timeout);
        mExpNormalTimeout = mContext.getResources().getInteger(
                R.integer.car_volume_dialog_display_expanded_normal_timeout);
        mExpHoveringTimeout = mContext.getResources().getInteger(
                R.integer.car_volume_dialog_display_expanded_hovering_timeout);
    }

    private static int getSeekbarValue(CarAudioManager carAudioManager, int volumeGroupId) {
        return carAudioManager.getGroupVolume(volumeGroupId);
    }

    private static boolean isGroupMuted(CarAudioManager carAudioManager, int volumeGroupId) {
        if (!carAudioManager.isAudioFeatureEnabled(AUDIO_FEATURE_VOLUME_GROUP_MUTING)) {
            return false;
        }
        return carAudioManager.isVolumeGroupMuted(PRIMARY_AUDIO_ZONE, volumeGroupId);
    }

    private static int getMaxSeekbarValue(CarAudioManager carAudioManager, int volumeGroupId) {
        return carAudioManager.getGroupMaxVolume(volumeGroupId);
    }

    /**
     * Build the volume window and connect to the CarService which registers with car audio
     * manager.
     */
    @Override
    public void init(int windowType, Callback callback) {
        initDialog();
        mCarServiceProvider.addListener(mCarServiceOnConnectedListener);

        mContext.registerReceiverAsUser(mHomeButtonPressedBroadcastReceiver, UserHandle.CURRENT,
                new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), /* broadcastPermission= */
                null, /* scheduler= */ null);
    }

    @Override
    public void destroy() {
        mHandler.removeCallbacksAndMessages(/* token= */ null);

        mContext.unregisterReceiver(mHomeButtonPressedBroadcastReceiver);

        cleanupAudioManager();
    }

    /**
     * Reveals volume dialog.
     */
    public void show(int reason) {
        mHandler.obtainMessage(H.SHOW, reason).sendToTarget();
    }

    /**
     * Hides volume dialog.
     */
    public void dismiss(int reason) {
        mHandler.obtainMessage(H.DISMISS, reason).sendToTarget();
    }

    private void initDialog() {
        loadAudioUsageItems();
        mCarVolumeLineItems.clear();
        mDialog = new CustomDialog(mContext);

        mHovering = false;
        mShowing = false;
        mDismissing = false;
        mExpanded = false;
        mWindow = mDialog.getWindow();
        mWindow.requestFeature(Window.FEATURE_NO_TITLE);
        mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND
                | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
        mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
        mWindow.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
        mWindow.setWindowAnimations(com.android.internal.R.style.Animation_Toast);
        final WindowManager.LayoutParams lp = mWindow.getAttributes();
        lp.format = PixelFormat.TRANSLUCENT;
        lp.setTitle(VolumeDialogImpl.class.getSimpleName());
        lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
        lp.windowAnimations = -1;
        mWindow.setAttributes(lp);

        mDialog.setContentView(R.layout.car_volume_dialog);
        mWindow.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);

        mDialog.setCanceledOnTouchOutside(true);
        mDialog.setOnShowListener(dialog -> {
            mListView.setTranslationY(-mListView.getHeight());
            mListView.setAlpha(0);
            mListView.animate()
                    .alpha(1)
                    .translationY(0)
                    .setDuration(LISTVIEW_ANIMATION_DURATION_IN_MILLIS)
                    .setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator())
                    .start();
        });
        mListView = mWindow.findViewById(R.id.volume_list);
        mListView.setOnHoverListener((v, event) -> {
            int action = event.getActionMasked();
            mHovering = (action == MotionEvent.ACTION_HOVER_ENTER)
                    || (action == MotionEvent.ACTION_HOVER_MOVE);
            rescheduleTimeoutH();
            return true;
        });

        mVolumeItemsAdapter = new CarVolumeItemAdapter(mContext, mCarVolumeLineItems);
        mListView.setAdapter(mVolumeItemsAdapter);
        mListView.setLayoutManager(new LinearLayoutManager(mContext));
    }


    private void showH(int reason) {
        if (DEBUG) {
            Log.d(TAG, "showH r=" + Events.DISMISS_REASONS[reason]);
        }

        mHandler.removeMessages(H.SHOW);
        mHandler.removeMessages(H.DISMISS);

        rescheduleTimeoutH();

        // Refresh the data set before showing.
        mVolumeItemsAdapter.notifyDataSetChanged();

        if (mShowing) {
            if (mPreviouslyDisplayingGroupId == mCurrentlyDisplayingGroupId || mExpanded) {
                return;
            }

            clearAllAndSetupDefaultCarVolumeLineItem(mCurrentlyDisplayingGroupId);
            return;
        }

        mShowing = true;
        clearAllAndSetupDefaultCarVolumeLineItem(mCurrentlyDisplayingGroupId);
        mDialog.show();
        Events.writeEvent(Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
    }

    private void clearAllAndSetupDefaultCarVolumeLineItem(int groupId) {
        mCarVolumeLineItems.clear();
        VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
        volumeItem.mDefaultItem = true;
        addCarVolumeListItem(volumeItem, /* volumeGroupId = */ groupId,
                R.drawable.car_ic_keyboard_arrow_down, new ExpandIconListener());
    }

    protected void rescheduleTimeoutH() {
        mHandler.removeMessages(H.DISMISS);
        final int timeout = computeTimeoutH();
        mHandler.sendMessageDelayed(mHandler
                .obtainMessage(H.DISMISS, Events.DISMISS_REASON_TIMEOUT), timeout);

        if (DEBUG) {
            Log.d(TAG, "rescheduleTimeout " + timeout + " " + Debug.getCaller());
        }
    }

    private int computeTimeoutH() {
        if (mExpanded) {
            return mHovering ? mExpHoveringTimeout : mExpNormalTimeout;
        } else {
            return mHovering ? mHoveringTimeout : mNormalTimeout;
        }
    }

    private void dismissH(int reason) {
        if (DEBUG) {
            Log.d(TAG, "dismissH r=" + Events.DISMISS_REASONS[reason]);
        }

        mHandler.removeMessages(H.DISMISS);
        mHandler.removeMessages(H.SHOW);
        if (!mShowing || mDismissing) {
            return;
        }

        mDismissing = true;
        mListView.animate()
                .alpha(0)
                .translationY(-mListView.getHeight())
                .setDuration(LISTVIEW_ANIMATION_DURATION_IN_MILLIS)
                .setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator())
                .withEndAction(() -> mHandler.postDelayed(() -> {
                    if (DEBUG) {
                        Log.d(TAG, "mDialog.dismiss()");
                    }
                    mDialog.dismiss();
                    mShowing = false;
                    mDismissing = false;
                    // if mExpandIcon is null that means user never clicked on the expanded arrow
                    // which implies that the dialog is still not expanded. In that case we do
                    // not want to reset the state
                    if (mExpandIcon != null && mExpanded) {
                        toggleDialogExpansion(/* isClicked = */ false);
                    }
                }, DISMISS_DELAY_IN_MILLIS))
                .start();

        Events.writeEvent(Events.EVENT_DISMISS_DIALOG, reason);
    }

    private void loadAudioUsageItems() {
        if (DEBUG) {
            Log.i(TAG, "loadAudioUsageItems start");
        }

        try (XmlResourceParser parser = mContext.getResources().getXml(R.xml.car_volume_items)) {
            AttributeSet attrs = Xml.asAttributeSet(parser);
            int type;
            // Traverse to the first start tag
            while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT
                    && type != XmlResourceParser.START_TAG) {
                // Do Nothing (moving parser to start element)
            }

            if (!XML_TAG_VOLUME_ITEMS.equals(parser.getName())) {
                throw new RuntimeException("Meta-data does not start with carVolumeItems tag");
            }
            int outerDepth = parser.getDepth();
            int rank = 0;
            while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT
                    && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) {
                if (type == XmlResourceParser.END_TAG) {
                    continue;
                }
                if (XML_TAG_VOLUME_ITEM.equals(parser.getName())) {
                    TypedArray item = mContext.getResources().obtainAttributes(
                            attrs, R.styleable.carVolumeItems_item);
                    int usage = item.getInt(R.styleable.carVolumeItems_item_usage,
                            /* defValue= */ -1);
                    if (usage >= 0) {
                        VolumeItem volumeItem = new VolumeItem();
                        volumeItem.mRank = rank;
                        volumeItem.mIcon = item.getResourceId(
                                R.styleable.carVolumeItems_item_icon, /* defValue= */ 0);
                        volumeItem.mMuteIcon = item.getResourceId(
                                R.styleable.carVolumeItems_item_mute_icon, /* defValue= */ 0);
                        mVolumeItems.put(usage, volumeItem);
                        rank++;
                    }
                    item.recycle();
                }
            }
        } catch (XmlPullParserException | IOException e) {
            Log.e(TAG, "Error parsing volume groups configuration", e);
        }

        if (DEBUG) {
            Log.i(TAG,
                    "loadAudioUsageItems finished. Number of volume items: " + mVolumeItems.size());
        }
    }

    private VolumeItem getVolumeItemForUsages(int[] usages) {
        int rank = Integer.MAX_VALUE;
        VolumeItem result = null;
        for (int usage : usages) {
            VolumeItem volumeItem = mVolumeItems.get(usage);
            if (DEBUG) {
                Log.i(TAG, "getVolumeItemForUsage: " + usage + ": " + volumeItem);
            }
            if (volumeItem.mRank < rank) {
                rank = volumeItem.mRank;
                result = volumeItem;
            }
        }
        return result;
    }

    private CarVolumeItem createCarVolumeListItem(VolumeItem volumeItem, int volumeGroupId,
            Drawable supplementalIcon, int seekbarProgressValue,
            boolean isMuted, @Nullable View.OnClickListener supplementalIconOnClickListener) {
        CarVolumeItem carVolumeItem = new CarVolumeItem();
        carVolumeItem.setMax(getMaxSeekbarValue(mCarAudioManager, volumeGroupId));
        carVolumeItem.setProgress(seekbarProgressValue);
        carVolumeItem.setIsMuted(isMuted);
        carVolumeItem.setOnSeekBarChangeListener(
                new CarVolumeDialogImpl.VolumeSeekBarChangeListener(volumeGroupId,
                        mCarAudioManager));
        carVolumeItem.setGroupId(volumeGroupId);

        int color = mContext.getColor(R.color.car_volume_dialog_tint);
        Drawable primaryIcon = mContext.getDrawable(volumeItem.mIcon);
        primaryIcon.mutate().setTint(color);
        carVolumeItem.setPrimaryIcon(primaryIcon);

        Drawable primaryMuteIcon = mContext.getDrawable(volumeItem.mMuteIcon);
        primaryMuteIcon.mutate().setTint(color);
        carVolumeItem.setPrimaryMuteIcon(primaryMuteIcon);

        if (supplementalIcon != null) {
            supplementalIcon.mutate().setTint(color);
            carVolumeItem.setSupplementalIcon(supplementalIcon,
                    /* showSupplementalIconDivider= */ true);
            carVolumeItem.setSupplementalIconListener(supplementalIconOnClickListener);
        } else {
            carVolumeItem.setSupplementalIcon(/* drawable= */ null,
                    /* showSupplementalIconDivider= */ false);
        }

        volumeItem.mCarVolumeItem = carVolumeItem;
        volumeItem.mProgress = seekbarProgressValue;

        return carVolumeItem;
    }

    private CarVolumeItem addCarVolumeListItem(VolumeItem volumeItem, int volumeGroupId,
            int supplementalIconId,
            @Nullable View.OnClickListener supplementalIconOnClickListener) {
        int seekbarProgressValue = getSeekbarValue(mCarAudioManager, volumeGroupId);
        boolean isMuted = isGroupMuted(mCarAudioManager, volumeGroupId);
        Drawable supplementalIcon = supplementalIconId == 0 ? null : mContext.getDrawable(
                supplementalIconId);
        CarVolumeItem carVolumeItem = createCarVolumeListItem(volumeItem, volumeGroupId,
                supplementalIcon, seekbarProgressValue, isMuted, supplementalIconOnClickListener);
        mCarVolumeLineItems.add(carVolumeItem);
        return carVolumeItem;
    }

    private void cleanupAudioManager() {
        mCarAudioManager.unregisterCarVolumeCallback(mVolumeChangeCallback);
        mCarVolumeLineItems.clear();
        mCarAudioManager = null;
    }

    /**
     * Wrapper class which contains information of each volume group.
     */
    private static class VolumeItem {
        private int mRank;
        private boolean mDefaultItem = false;
        @DrawableRes
        private int mIcon;
        @DrawableRes
        private int mMuteIcon;
        private CarVolumeItem mCarVolumeItem;
        private int mProgress;
        private boolean mIsMuted;
    }

    private final class H extends Handler {

        private static final int SHOW = 1;
        private static final int DISMISS = 2;

        private H() {
            super(Looper.getMainLooper());
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case SHOW:
                    showH(msg.arg1);
                    break;
                case DISMISS:
                    dismissH(msg.arg1);
                    break;
                default:
            }
        }
    }

    private final class CustomDialog extends Dialog implements DialogInterface {

        private CustomDialog(Context context) {
            super(context, com.android.systemui.R.style.Theme_SystemUI);
        }

        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            rescheduleTimeoutH();
            return super.dispatchTouchEvent(ev);
        }

        @Override
        protected void onStart() {
            super.setCanceledOnTouchOutside(true);
            super.onStart();
        }

        @Override
        protected void onStop() {
            super.onStop();
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (isShowing()) {
                if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
                    mHandler.obtainMessage(
                            H.DISMISS, Events.DISMISS_REASON_TOUCH_OUTSIDE).sendToTarget();
                    return true;
                }
            }
            return false;
        }
    }

    private final class ExpandIconListener implements View.OnClickListener {
        @Override
        public void onClick(final View v) {
            mExpandIcon = v;
            toggleDialogExpansion(true);
            rescheduleTimeoutH();
        }
    }

    private void toggleDialogExpansion(boolean isClicked) {
        mExpanded = !mExpanded;
        Animator inAnimator;
        if (mExpanded) {
            for (int groupId = 0; groupId < mAvailableVolumeItems.size(); ++groupId) {
                if (groupId != mCurrentlyDisplayingGroupId) {
                    VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
                    addCarVolumeListItem(volumeItem, groupId, /* supplementalIconId= */ 0,
                            /* supplementalIconOnClickListener= */ null);
                }
            }
            inAnimator = AnimatorInflater.loadAnimator(
                    mContext, R.anim.car_arrow_fade_in_rotate_up);

        } else {
            clearAllAndSetupDefaultCarVolumeLineItem(mCurrentlyDisplayingGroupId);
            inAnimator = AnimatorInflater.loadAnimator(
                    mContext, R.anim.car_arrow_fade_in_rotate_down);
        }

        Animator outAnimator = AnimatorInflater.loadAnimator(
                mContext, R.anim.car_arrow_fade_out);
        inAnimator.setStartDelay(ARROW_FADE_IN_START_DELAY_IN_MILLIS);
        AnimatorSet animators = new AnimatorSet();
        animators.playTogether(outAnimator, inAnimator);
        if (!isClicked) {
            // Do not animate when the state is called to reset the dialogs view and not clicked
            // by user.
            animators.setDuration(0);
        }
        animators.setTarget(mExpandIcon);
        animators.start();
        mVolumeItemsAdapter.notifyDataSetChanged();
    }

    private final class VolumeSeekBarChangeListener implements OnSeekBarChangeListener {

        private final int mVolumeGroupId;
        private final CarAudioManager mCarAudioManager;

        private VolumeSeekBarChangeListener(int volumeGroupId, CarAudioManager carAudioManager) {
            mVolumeGroupId = volumeGroupId;
            mCarAudioManager = carAudioManager;
        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            if (!fromUser) {
                // For instance, if this event is originated from AudioService,
                // we can ignore it as it has already been handled and doesn't need to be
                // sent back down again.
                return;
            }
            if (mCarAudioManager == null) {
                Log.w(TAG, "Ignoring volume change event because the car isn't connected");
                return;
            }
            mAvailableVolumeItems.get(mVolumeGroupId).mProgress = progress;
            mAvailableVolumeItems.get(
                    mVolumeGroupId).mCarVolumeItem.setProgress(progress);
            mCarAudioManager.setGroupVolume(mVolumeGroupId, progress, 0);
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
        }
    }
}
