/** * ************************************************************************** * AdvOptionsDialog.java * **************************************************************************** * Copyright © 2015 VLC authors and VideoLAN * Author: Geoffrey Métais * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. * *************************************************************************** */ package org.videolan.vlc.gui.dialogs; import android.app.Activity; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v4.app.DialogFragment; import android.text.format.DateFormat; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import org.videolan.libvlc.MediaPlayer; import org.videolan.vlc.PlaybackService; import org.videolan.vlc.R; import org.videolan.vlc.VLCApplication; import org.videolan.vlc.gui.PlaybackServiceFragment; import org.videolan.vlc.gui.SecondaryActivity; import org.videolan.vlc.gui.video.VideoPlayerActivity; import org.videolan.vlc.interfaces.IDelayController; import org.videolan.vlc.util.Strings; import org.videolan.vlc.util.Util; import org.videolan.vlc.util.WeakHandler; import java.util.Calendar; import static org.videolan.vlc.gui.dialogs.PickTimeFragment.ACTION_JUMP_TO_TIME; import static org.videolan.vlc.gui.dialogs.PickTimeFragment.ACTION_SLEEP_TIMER; public class AdvOptionsDialog extends DialogFragment implements View.OnClickListener, PlaybackService.Client.Callback { public final static String TAG = "VLC/AdvOptionsDialog"; public static final String MODE_KEY = "mode"; public static final int MODE_VIDEO = 0; public static final int MODE_AUDIO = 1; public static final int SPEED_TEXT = 0; public static final int SLEEP_TEXT = 1; public static final int TOGGLE_CANCEL = 2; public static final int DIALOG_LISTENER = 3; public static final int RESET_RETRY = 4; public static final int ACTION_AUDIO_DELAY = 2 ; public static final int ACTION_SPU_DELAY = 3 ; private Activity mActivity; private int mTheme; private int mMode = -1; private ImageView mPlayAsAudio; private TextView mEqualizer; private ImageView mPlaybackSpeedIcon; private TextView mPlaybackSpeedValue; private ImageView mSleepIcon; private TextView mSleepValue; private TextView mJumpTitle; private TextView mAudioDelay; private TextView mSpuDelay; private TextView mChaptersTitle; private int mTextColor; private PlaybackService mService; private IDelayController mDelayController; public AdvOptionsDialog() {} @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (VLCApplication.sPlayerSleepTime != null && VLCApplication.sPlayerSleepTime.before(Calendar.getInstance())) VLCApplication.sPlayerSleepTime = null; if (getArguments() != null && getArguments().containsKey(MODE_KEY)) mMode = getArguments().getInt(MODE_KEY); else mMode = MODE_VIDEO; mTheme = (mMode == MODE_VIDEO || Util.isBlackThemeEnabled()) ? R.style.Theme_VLC_Black : R.style.Theme_VLC; setStyle(DialogFragment.STYLE_NO_FRAME, mTheme); } @Override public void onAttach(Activity activity) { super.onAttach(activity); if (mMode == MODE_VIDEO) { mDelayController = (IDelayController) activity; } mActivity = activity; } @Override public void onDetach() { super.onDetach(); mDelayController = null; mActivity = null; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_advanced_options, container, false); getDialog().setCancelable(true); getDialog().setCanceledOnTouchOutside(true); mPlaybackSpeedValue = (TextView) root.findViewById(R.id.playback_speed_value); mPlaybackSpeedValue.setOnFocusChangeListener(mFocusListener); mPlaybackSpeedIcon = (ImageView) root.findViewById(R.id.playback_speed_icon); mPlaybackSpeedIcon.setOnClickListener(this); mSleepValue = (TextView) root.findViewById(R.id.sleep_value); mSleepIcon = (ImageView) root.findViewById(R.id.sleep_icon); mSleepIcon.setOnClickListener(this); mSleepValue.setOnFocusChangeListener(mFocusListener); mJumpTitle = (TextView) root.findViewById(R.id.jump_title); mJumpTitle.setOnClickListener(this); if (mMode == MODE_VIDEO) { mPlayAsAudio = (ImageView) root.findViewById(R.id.play_as_audio_icon); mPlayAsAudio.setOnClickListener(this); mChaptersTitle = (TextView) root.findViewById(R.id.jump_chapter_title); mChaptersTitle.setOnFocusChangeListener(mFocusListener); mChaptersTitle.setOnClickListener(this); mAudioDelay = (TextView) root.findViewById(R.id.audio_delay); mAudioDelay.setOnFocusChangeListener(mFocusListener); mAudioDelay.setOnClickListener(this); mSpuDelay = (TextView) root.findViewById(R.id.spu_delay); mSpuDelay.setOnFocusChangeListener(mFocusListener); mSpuDelay.setOnClickListener(this); } else { root.findViewById(R.id.audio_delay).setVisibility(View.GONE); root.findViewById(R.id.spu_delay).setVisibility(View.GONE); root.findViewById(R.id.jump_chapter_title).setVisibility(View.GONE); root.findViewById(R.id.play_as_audio_icon).setVisibility(View.GONE); } if (mMode == MODE_AUDIO){ mEqualizer = (TextView) root.findViewById(R.id.opt_equalizer); mEqualizer.setOnClickListener(this); } else root.findViewById(R.id.opt_equalizer).setVisibility(View.GONE); mHandler.sendEmptyMessage(TOGGLE_CANCEL); mTextColor = mSleepValue.getCurrentTextColor(); if (getDialog() != null) { int dialogWidth = getResources().getDimensionPixelSize(mMode == MODE_VIDEO ? R.dimen.adv_options_video_width: R.dimen.adv_options_music_width); int dialogHeight = ViewGroup.LayoutParams.WRAP_CONTENT; getDialog().getWindow().setLayout(dialogWidth, dialogHeight); getDialog().getWindow().setBackgroundDrawableResource(Util.getResourceFromAttribute(getActivity(), R.attr.rounded_bg)); } return root; } private void showTimePickerFragment(int action) { DialogFragment newFragment = null; switch (action){ case PickTimeFragment.ACTION_JUMP_TO_TIME: newFragment = JumpToTimeDialog.newInstance(mTheme); break; case PickTimeFragment.ACTION_SLEEP_TIMER: newFragment = SleepTimerDialog.newInstance(mTheme); break; default: return; } if (newFragment != null) newFragment.show(getActivity().getSupportFragmentManager(), "time"); dismiss(); } private void showPlayBackSpeedDialog() { DialogFragment newFragment = null; newFragment = PlaybackSpeedDialog.newInstance(mTheme); if (newFragment != null) newFragment.show(getActivity().getSupportFragmentManager(), "playback_speed"); dismiss(); } private void showSelectChapterDialog() { DialogFragment newFragment = null; newFragment = SelectChapterDialog.newInstance(mTheme); if (newFragment != null) newFragment.show(getActivity().getSupportFragmentManager(), "select_chapter"); dismiss(); } private void showAudioSpuDelayControls(int action) { if (mDelayController == null && getActivity() instanceof IDelayController) mDelayController = (IDelayController) getActivity(); switch (action){ case ACTION_AUDIO_DELAY: if (mDelayController != null) mDelayController.showAudioDelaySetting(); break; case ACTION_SPU_DELAY: if (mDelayController != null) mDelayController.showSubsDelaySetting(); break; default: return; } dismiss(); } View.OnFocusChangeListener mFocusListener = new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (v instanceof TextView) ((TextView) v).setTextColor(v.hasFocus() ? getResources().getColor(R.color.orange300) : mTextColor); } }; public static void setSleep(Calendar time) { AlarmManager alarmMgr = (AlarmManager) VLCApplication.getAppContext().getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(VLCApplication.SLEEP_INTENT); PendingIntent sleepPendingIntent = PendingIntent.getBroadcast(VLCApplication.getAppContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); if (time != null) { alarmMgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), sleepPendingIntent); } else { alarmMgr.cancel(sleepPendingIntent); } VLCApplication.sPlayerSleepTime = time; } private final Handler mHandler = new AdvOptionsDialogHandler(this); private static class AdvOptionsDialogHandler extends WeakHandler<AdvOptionsDialog> { public boolean retry = true; public AdvOptionsDialogHandler(AdvOptionsDialog owner) { super(owner); } @Override public void handleMessage(Message msg) { String text = null; AdvOptionsDialog owner = getOwner(); if (owner == null || owner.isDetached()) return; switch (msg.what) { case SPEED_TEXT: text = (String) msg.obj; owner.mPlaybackSpeedValue.setText(text); owner.mPlaybackSpeedIcon.setImageResource(VLCApplication.sPlayerSleepTime == null ? Util.getResourceFromAttribute(owner.getActivity(), R.attr.ic_speed_normal_style) : R.drawable.ic_speed_on); break; case TOGGLE_CANCEL: owner.mSleepIcon.setImageResource(VLCApplication.sPlayerSleepTime == null ? Util.getResourceFromAttribute(owner.getActivity(), R.attr.ic_sleep_normal_style): R.drawable.ic_sleep_on); case SLEEP_TEXT: if (VLCApplication.sPlayerSleepTime != null) text = DateFormat.getTimeFormat(owner.mSleepValue.getContext()).format(VLCApplication.sPlayerSleepTime.getTime()); owner.mSleepValue.setText(text); break; case DIALOG_LISTENER: DialogFragment newFragment = (DialogFragment) msg.obj; if (newFragment.getShowsDialog()) { newFragment.getDialog().setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { obtainMessage(TOGGLE_CANCEL).sendToTarget(); } }); } else if (retry) { retry = false; sendMessageDelayed(msg, 300); } break; case RESET_RETRY: retry = true; break; } } } @Override public void onClick(View v) { switch (v.getId()){ case R.id.sleep_icon: if (VLCApplication.sPlayerSleepTime == null) showTimePickerFragment(ACTION_SLEEP_TIMER); else { setSleep(null); mHandler.sendEmptyMessage(TOGGLE_CANCEL); } break; case R.id.playback_speed_icon: showPlayBackSpeedDialog(); break; case R.id.jump_chapter_title: showSelectChapterDialog(); break; case R.id.audio_delay: showAudioSpuDelayControls(ACTION_AUDIO_DELAY); break; case R.id.spu_delay: showAudioSpuDelayControls(ACTION_SPU_DELAY); break; case R.id.jump_title: showTimePickerFragment(ACTION_JUMP_TO_TIME); break; case R.id.play_as_audio_icon: ((VideoPlayerActivity)getActivity()).switchToAudioMode(true); break; case R.id.opt_equalizer: Intent i = new Intent(getActivity(), SecondaryActivity.class); i.putExtra("fragment", SecondaryActivity.EQUALIZER); startActivity(i); dismiss(); break; } } private DialogInterface.OnDismissListener onDismissListener; public void setOnDismissListener(DialogInterface.OnDismissListener onDismissListener) { this.onDismissListener = onDismissListener; } @Override public void onDismiss(DialogInterface dialog) { super.onDismiss(dialog); if (onDismissListener != null) { onDismissListener.onDismiss(dialog); } } @Override public void onStart() { super.onStart(); PlaybackServiceFragment.registerPlaybackService(this, this); } @Override public void onStop() { super.onStop(); PlaybackServiceFragment.unregisterPlaybackService(this, this); } @Override public void onConnected(PlaybackService service) { mService = service; // Init Playback Speed if (mService.getRate() == 1.0f) { mPlaybackSpeedValue.setText(null); mPlaybackSpeedIcon.setImageResource( Util.getResourceFromAttribute(this.getActivity(), R.attr.ic_speed_normal_style)); } else { mPlaybackSpeedValue.setText(Strings.formatRateString(mService.getRate())); mPlaybackSpeedIcon.setImageResource(R.drawable.ic_speed_on); } if (mMode == MODE_VIDEO) { // Init Chapter final MediaPlayer.Chapter[] chapters = mService.getChapters(-1); final int chaptersCount = chapters != null ? chapters.length : 0; if (chaptersCount > 1) { mChaptersTitle.setText(chapters[mService.getChapterIdx()].name); } else mChaptersTitle.setVisibility(View.GONE); //Init Audio Delay long audiodelay = mService.getAudioDelay() / 1000l; if (audiodelay == 0l) { mAudioDelay.setText(null); mAudioDelay.setCompoundDrawablesWithIntrinsicBounds(0, Util.getResourceFromAttribute(mActivity, R.attr.ic_audiodelay), 0, 0); } else { mAudioDelay.setText(Long.toString(audiodelay) + " ms"); mAudioDelay.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_audiodelay_on, 0, 0); } //Init Subtitle Delay long spudelay = mService.getSpuDelay() / 1000l; if (spudelay == 0l) { mSpuDelay.setText(null); mSpuDelay.setCompoundDrawablesWithIntrinsicBounds(0, Util.getResourceFromAttribute(mActivity, R.attr.ic_subtitledelay), 0, 0); } else { mSpuDelay.setText(Long.toString(spudelay) + " ms"); mSpuDelay.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_subtitledelay_on, 0, 0); } } } @Override public void onDisconnected() { mService = null; } }