package com.ruangguru.livestudents.ui.onlinevideo; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.res.Configuration; import android.os.Build; import android.os.Bundle; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.webkit.ConsoleMessage; import android.webkit.JavascriptInterface; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Button; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import android.widget.ViewFlipper; import com.birbit.android.jobqueue.Params; import com.ruangguru.livestudents.R; import com.ruangguru.livestudents.RGStudentsApplication; import com.ruangguru.livestudents.events.onlinevideo.IGetUaIpFailed; import com.ruangguru.livestudents.events.onlinevideo.IGetUaIpSuccess; import com.ruangguru.livestudents.events.onlinevideo.videodetail.IGetVideoDetailFailed; import com.ruangguru.livestudents.events.onlinevideo.videodetail.IGetVideoDetailSuccess; import com.ruangguru.livestudents.events.onlinevideo.sendlikevideo.ISendLikeVideoFailed; import com.ruangguru.livestudents.events.onlinevideo.sendlikevideo.ISendLikeVideoSuccess; import com.ruangguru.livestudents.events.onlinevideo.watched.ISendWatchedVideoFailed; import com.ruangguru.livestudents.events.onlinevideo.watched.ISendWatchedVideoSuccess; import com.ruangguru.livestudents.models.http.Pagination; import com.ruangguru.livestudents.models.http.onlinevideo.VideoDetail; import com.ruangguru.livestudents.models.http.onlinevideo.VideoItem; import com.ruangguru.livestudents.services.APIClient; import com.ruangguru.livestudents.services.UserService; import com.ruangguru.livestudents.services.jobs.onlinevideo.GetUserAgentIpJob; import com.ruangguru.livestudents.services.jobs.onlinevideo.GetVideoDetailJob; import com.ruangguru.livestudents.services.jobs.onlinevideo.SendLikeVideoJob; import com.ruangguru.livestudents.services.jobs.onlinevideo.SendWatchedVideoJob; import com.ruangguru.livestudents.ui.BaseActivity; import com.ruangguru.livestudents.ui.onlinevideo.fragments.VideoPlayListFragment; import com.ruangguru.livestudents.ui.widget.webview.VideoEnabledWebChromeClient; import com.ruangguru.livestudents.ui.widget.webview.VideoEnabledWebView; import com.ruangguru.livestudents.utils.DeviceUtil; import com.ruangguru.livestudents.utils.ExtrasKeys; import com.ruangguru.livestudents.utils.PrefUtil; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import java.util.ArrayList; import java.util.HashMap; public class VideoPlayerActivity extends BaseActivity implements View.OnClickListener { private static final String TAG = VideoPlayerActivity.class.getSimpleName(); private static final String JOB_SEND_LIKE_TAG = "job_send_like_tag"; private static final String JOB_SEND_WATCHED_TAG = "job_send_watched_tag"; private TextView descriptionTextView, titleTextView, topicTextView; private ImageView caretImageView; private ArrayList allVideos; private Button summaryButton; private Toolbar mToolbar; private ImageButton btnLike; private ImageButton btnLiked; private ImageButton btnShare; private ViewFlipper flipperBtnLike; private boolean isJobAdded = false; private VideoItem chosenVideo; private VideoDetail videoDetail; private final int NOT_LIKED = 0; private final int LIKED = 1; private String fileId, description, topicName; private int chosenIndex; private VideoEnabledWebView webView; private VideoEnabledWebChromeClient webChromeClient; private View nonVideoLayout; // Your own view, read class comments private ViewGroup videoLayout; // Your own view, read class comments private View loadingView; private View scrollView; private ProgressBar mProgressBarVideo; private boolean isVideoFullyLoaded; private boolean isVideoWatched; public static final String END_OF_VIDEO_LOG_MESSAGE = "VIDEOEND"; private Bundle mData; private int mPage, totalVideo; private Pagination mPagination; private String mUserAgent; private String mIp; private String getVideoUrl(String fileId) { return APIClient.getExternalUrl(this) + "video/player?file_id=" + fileId; } private String getVideoUrl(String fileId, String userAgent, String ip) { String url = APIClient.getExternalUrl(this) + "video/player?file_id=" + fileId + "&ip=" +ip +"&ua=" + userAgent; return url; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_online_video_player); mData = getIntent().getExtras(); allVideos = mData.getParcelableArrayList(ExtrasKeys.KEY_RELATED_VIDEOS); chosenIndex = mData.getInt(ExtrasKeys.KEY_CHOSEN_INDEX); mPagination = mData.getParcelable(ExtrasKeys.KEY_PAGINATION); topicName = mData.getString(ExtrasKeys.KEY_TOPIC_NAME, ""); mPage = mPagination.getCurrentPage(); totalVideo = mPagination.getTotal(); chosenVideo = allVideos.get(chosenIndex); fileId = chosenVideo.getFileId(); initUi(savedInstanceState); setExpWebView(); manageUserAgentIp(); } private void initUi(Bundle savedInstanceState) { mToolbar = (Toolbar) findViewById(R.id.toolbar_player); if (mToolbar != null) { setSupportActionBar(mToolbar); showBackArrow(); } mProgressBarVideo = (ProgressBar) findViewById(R.id.progress_video); if (mProgressBarVideo != null) { mProgressBarVideo.setVisibility(View.VISIBLE); } titleTextView = (TextView) findViewById(R.id.tv_video_title); if (titleTextView != null) { titleTextView.setText(chosenVideo.getTitleDisplayName()); } descriptionTextView = (TextView) findViewById(R.id.tv_video_description); if (descriptionTextView != null) { descriptionTextView.setVisibility(View.GONE); } caretImageView = (ImageView) findViewById(R.id.iv_caret_sign); if (caretImageView != null) { caretImageView.setOnClickListener(this); caretImageView.setVisibility(View.GONE); } summaryButton = (Button) findViewById(R.id.btn_show_summary); if (summaryButton != null) { summaryButton.setOnClickListener(this); } topicTextView = (TextView) findViewById(R.id.tv_player_topic); int chosenIndexShown = chosenIndex + 1; String topicTitle = topicName + " " + "(" + chosenIndexShown + "/" + totalVideo + " " + "video" + ")"; if (topicTextView != null) { topicTextView.setText(topicTitle); } btnLike = (ImageButton) findViewById(R.id.btn_video_like); btnLiked = (ImageButton) findViewById(R.id.btn_video_liked); btnShare = (ImageButton) findViewById(R.id.btn_video_share); flipperBtnLike = (ViewFlipper) findViewById(R.id.vf_video_like); if (flipperBtnLike != null) { if (chosenVideo.isLiked()) { flipperBtnLike.setDisplayedChild(LIKED); } } if (btnLike != null) btnLike.setOnClickListener(this); if (btnLiked != null) btnLiked.setOnClickListener(this); if (btnShare != null) btnShare.setOnClickListener(this); if (savedInstanceState != null) { mData.putParcelableArrayList(ExtrasKeys.KEY_RELATED_VIDEOS, savedInstanceState.getParcelableArrayList(ExtrasKeys.KEY_LIST_VIDEO)); } else { mData.putParcelableArrayList(ExtrasKeys.KEY_RELATED_VIDEOS, allVideos); } if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { VideoPlayListFragment newFragment = VideoPlayListFragment.newInstance(mData, VideoPlayListFragment.MODE_PLAYER); getSupportFragmentManager().beginTransaction().add(R.id.related_videos_container, newFragment).commit(); } nonVideoLayout = findViewById(R.id.nonVideoLayout); videoLayout = (ViewGroup) findViewById(R.id.videoLayout); loadingView = getLayoutInflater().inflate(R.layout.view_loading_video, null); scrollView = findViewById(R.id.video_info_scroll); } @Override protected void onResume() { super.onResume(); if (webView != null) webView.onResume(); EventBus.getDefault().register(this); if (!isJobAdded) { GetVideoDetailJob job = new GetVideoDetailJob(new Params(1).requireNetwork().addTags(this.toString()), chosenVideo.getFileId()); jobManager.addJobInBackground(job); isJobAdded = true; } } private void loadVideoUrl(String url) { final HashMap params = new HashMap() { { put("Authorization", "Bearer " + UserService.getCurrentUser().getAccessToken()); } }; webView.loadUrl(url, params); } private void manageUserAgentIp(){ RGStudentsApplication app = RGStudentsApplication.getInstance(); if (app.getUserAgent() == null || app.getIp() == null) { GetUserAgentIpJob getUaIpjob = new GetUserAgentIpJob(new Params(1).requireNetwork().addTags("getUaIpjob")); jobManager.addJobInBackground(getUaIpjob); } else { mUserAgent = app.getUserAgent(); mIp = app.getIp(); loadVideoUrl(getVideoUrl(fileId, mUserAgent, mIp)); } } @Override protected void onPause() { super.onPause(); if (webView != null) webView.onPause(); EventBus.getDefault().unregister(this); } @Override protected void onDestroy() { super.onDestroy(); if (webView != null) { webView.destroy(); } } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { scrollView.setVisibility(View.GONE); ViewGroup.LayoutParams params = webView.getLayoutParams(); params.height = ViewGroup.LayoutParams.MATCH_PARENT; params.width = ViewGroup.LayoutParams.MATCH_PARENT; webView.setLayoutParams(params); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { scrollView.setVisibility(View.VISIBLE); ViewGroup.LayoutParams params = webView.getLayoutParams(); params.height = (int) getResources().getDimension(R.dimen.video_webview_height); params.width = ViewGroup.LayoutParams.MATCH_PARENT; webView.setLayoutParams(params); } } @Override protected void onSaveInstanceState(Bundle savedInstanceState) { savedInstanceState.putInt(ExtrasKeys.KEY_CHOSEN_INDEX, chosenIndex); savedInstanceState.putString(ExtrasKeys.KEY_FILE_ID, fileId); savedInstanceState.putParcelableArrayList(ExtrasKeys.KEY_LIST_VIDEO, allVideos); savedInstanceState.putString(ExtrasKeys.KEY_VIDEO_DESCRIPTION, description); super.onSaveInstanceState(savedInstanceState); } @Override public void onBackPressed() { // Notify the VideoEnabledWebChromeClient, and handle it ourselves if it doesn't handle it if (!webChromeClient.onBackPressed()) { if (webView.canGoBack()) { webView.goBack(); } else { // Standard back button implementation (for example this could close the app) super.onBackPressed(); } } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_show_summary: showSummary(); break; case R.id.iv_caret_sign: toggleDescription(v); break; case R.id.btn_video_like: likeVideo(); break; case R.id.btn_video_liked: unlikeVideo(); break; case R.id.btn_video_share: share(); break; } } private void showSummary() { if (videoDetail.getSummaryData() != null) { Bundle data = new Bundle(); data.putParcelableArrayList(SummaryActivity.SUMMARY_LIST, (ArrayList) videoDetail.getSummaryData()); data.putString(SummaryActivity.VIDEO_TITLE, videoDetail.getVideoItem().getTitle()); data.putString(SummaryActivity.VIDEO_ID, videoDetail.getVideoItem().getId()); Intent intent = new Intent(this, SummaryActivity.class); intent.putExtras(data); startActivity(intent); } } private void share() { String message = getString(R.string.msg_share_video); Intent shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.setType("text/plain"); shareIntent.putExtra(Intent.EXTRA_TEXT, message); startActivity(Intent.createChooser(shareIntent, getString(R.string.title_share_intent))); } private void watchedVideo() { if (videoDetail != null) { jobManager.addJobInBackground(new SendWatchedVideoJob( new Params(2).addTags(JOB_SEND_WATCHED_TAG), videoDetail.getVideoItem().getFileId(), "Y")); } } private void likeVideo() { jobManager.addJobInBackground(new SendLikeVideoJob( new Params(2).addTags(JOB_SEND_LIKE_TAG), videoDetail.getVideoItem().getFileId(), "Y")); } private void unlikeVideo() { jobManager.addJobInBackground(new SendLikeVideoJob( new Params(2).addTags(JOB_SEND_LIKE_TAG), videoDetail.getVideoItem().getFileId(), "N")); } @Subscribe public void onEvent(IGetUaIpSuccess event){ RGStudentsApplication app = RGStudentsApplication.getInstance(); app.setIp(event.getIp()); app.setUserAgent(DeviceUtil.getUdid(this)); Log.d("iy", "udid : " +DeviceUtil.getUdid(this)); mIp = event.getIp(); mUserAgent = DeviceUtil.getUdid(this); loadVideoUrl(getVideoUrl(fileId, mUserAgent, mIp)); } @Subscribe public void onEvent(IGetUaIpFailed event){ loadVideoUrl(getVideoUrl(fileId)); setExpWebView(); // initialize video anyway without UserAgent and Ip } @Subscribe public void onEvent(IGetVideoDetailSuccess event) { videoDetail = event.getVideoDetail(); runOnUiThread(new Runnable() { @Override public void run() { if (videoDetail.getDescription() != null && !videoDetail.getDescription().equals("")) { caretImageView.setVisibility(View.VISIBLE); description = videoDetail.getDescription(); descriptionTextView.setText(description); descriptionTextView.setVisibility(View.VISIBLE); if (videoDetail.getVideoItem().isLiked()) { flipperBtnLike.setDisplayedChild(LIKED); } } if (videoDetail.getSummaryData() != null && videoDetail.getSummaryData().size() > 0) { summaryButton.setVisibility(View.VISIBLE); } } }); } @Subscribe public void onEvent(IGetVideoDetailFailed event) { hideProgressDialog(); if (event != null) { showToast(this, event.getErrorMessage()); Log.e(TAG, event.getLogErrorMessage()); } } @Subscribe public void onEvent(ISendLikeVideoSuccess event) { if (event != null) { if (event.getLikeStatus().equals("Y")) { showToast(this, getString(R.string.msg_like_video_sucess)); flipperBtnLike.setDisplayedChild(LIKED); } else { showToast(this, getString(R.string.msg_unlike_video_success)); flipperBtnLike.setDisplayedChild(NOT_LIKED); } } } @Subscribe public void onEvent(ISendWatchedVideoSuccess event) { if (event != null) { if (event.getWatchedStatus().equals("Y")) { Log.d(TAG, "watched success"); isVideoWatched = true; // showToast(this, getString(R.string.msg_like_video_sucess)); } } } @Subscribe public void onEvent(ISendWatchedVideoFailed event) { if (event != null) { Log.d(TAG, event.getErrorMessage()); } } @Subscribe public void onEvent(ISendLikeVideoFailed event) { if (event != null) { showToast(this, event.getErrorMessage()); Log.e(TAG, event.getLogErrorMessage()); } } public void toggleDescription(View v) { if (descriptionTextView.isShown()) { animSlideUp(descriptionTextView); descriptionTextView.setVisibility(View.GONE); caretImageView.setImageResource(R.drawable.ic_caret_down); } else { descriptionTextView.setVisibility(View.VISIBLE); caretImageView.setImageResource(R.drawable.ic_caret_up); animSlideDown(descriptionTextView); } } public void animSlideDown(View v) { Animation a = AnimationUtils.loadAnimation(this, R.anim.slide_down); if (a != null) { a.reset(); if (v != null) { v.clearAnimation(); v.startAnimation(a); } } } public void animSlideUp(View v) { Animation a = AnimationUtils.loadAnimation(this, R.anim.slide_up); if (a != null) { a.reset(); if (v != null) { v.clearAnimation(); v.startAnimation(a); } } } public class WebAppInterface { Context mContext; /** * Instantiate the interface and set the context */ WebAppInterface(Context c) { mContext = c; } /** * Show a toast from the web page */ @JavascriptInterface public void showToast(String toast) { Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show(); } @JavascriptInterface public void toggleFullscreen(boolean state) { Toast.makeText(mContext, state ? "FULLSCREEN TRUE" : "FULLSCREEN FALSE", Toast.LENGTH_SHORT).show(); } } private void setExpWebView() { webView = (VideoEnabledWebView) findViewById(R.id.wv_video); WebSettings settings = webView.getSettings(); settings.setJavaScriptEnabled(true); settings.setPluginState(WebSettings.PluginState.ON); settings.setSupportMultipleWindows(true); settings.setJavaScriptCanOpenWindowsAutomatically(true); settings.setLoadsImagesAutomatically(true); settings.setDomStorageEnabled(true); settings.setLoadWithOverviewMode(true); settings.setAllowUniversalAccessFromFileURLs(true); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { settings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE); } webChromeClient = new VideoEnabledWebChromeClient(nonVideoLayout, videoLayout, loadingView, webView) // See all available constructors... { public boolean onConsoleMessage(ConsoleMessage cm) { ConsoleMessage.MessageLevel ml = cm.messageLevel(); if (cm.message().equals(END_OF_VIDEO_LOG_MESSAGE) && PrefUtil.hasWatchedFirstVideoUntilEnd(VideoPlayerActivity.this)) { showCustomDialog(getLayoutInflater().inflate(R.layout.dialog_video_finish, null), null, null, getString(R.string.action_see_summary), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { showSummary(); } }); PrefUtil.setHasWatchedVideoUntilEnd(VideoPlayerActivity.this); } Log.d(TAG, cm.message() + " " + " -- From line " + cm.lineNumber() + "Message Level name: " + ml.name()); return true; } // Subscribe to standard events, such as onProgressChanged()... @Override public void onProgressChanged(WebView view, int progress) { // if progress == 100, hide progress bar if (progress == 100) { if (mProgressBarVideo != null) { mProgressBarVideo.setVisibility(View.GONE); } showFullscreenGuideToast(); isVideoFullyLoaded = true; } } }; webChromeClient.setOnToggledFullscreen(new VideoEnabledWebChromeClient.ToggledFullscreenCallback() { @Override public void toggledFullscreen(boolean fullscreen) { // Your code to handle the full-screen change, for example showing and hiding the title bar. Example: if (fullscreen) { WindowManager.LayoutParams attrs = getWindow().getAttributes(); attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN; attrs.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; getWindow().setAttributes(attrs); if (android.os.Build.VERSION.SDK_INT >= 14) { //noinspection all getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE); } } else { WindowManager.LayoutParams attrs = getWindow().getAttributes(); attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN; attrs.flags &= ~WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; getWindow().setAttributes(attrs); if (android.os.Build.VERSION.SDK_INT >= 14) { //noinspection all getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); } } } }); webView.setWebChromeClient(webChromeClient); // Call private class InsideWebViewClient webView.setWebViewClient(new InsideWebViewClient()); webView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN){ if (isVideoFullyLoaded && !isVideoWatched) watchedVideo(); } return false; } }); } private class InsideWebViewClient extends WebViewClient { final HashMap params = new HashMap() { { put("Authorization", "Bearer " + UserService.getCurrentUser().getAccessToken()); } }; @Override // Force links to be opened inside WebView and not in Default Browser // Thanks http://stackoverflow.com/a/33681975/1815624 public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url, params); return true; } } private void showFullscreenGuideToast() { Toast toastMessage = Toast.makeText(VideoPlayerActivity.this, getString(R.string.rotate_device), Toast.LENGTH_SHORT); toastMessage.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, (int) getResources().getDimension(R.dimen.video_webview_height) / 2); toastMessage.show(); } }