From 2cd1b6c77bd4a80d5f9eb8fd741e11ba443b9ecf Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Mon, 11 Mar 2024 17:55:20 +0200 Subject: [PATCH 01/17] Add fullscreen button to media controller --- app/res/drawable-hdpi/ic_media_fullscreen.png | Bin 0 -> 860 bytes app/res/drawable-ldpi/ic_media_fullscreen.png | Bin 0 -> 114 bytes app/res/drawable-mdpi/ic_media_fullscreen.png | Bin 0 -> 661 bytes .../drawable-xhdpi/ic_media_fullscreen.png | Bin 0 -> 1208 bytes .../drawable-xxhdpi/ic_media_fullscreen.png | Bin 0 -> 512 bytes .../views/media/CommCareMediaController.java | 28 ++++++++++++++++++ 6 files changed, 28 insertions(+) create mode 100644 app/res/drawable-hdpi/ic_media_fullscreen.png create mode 100644 app/res/drawable-ldpi/ic_media_fullscreen.png create mode 100644 app/res/drawable-mdpi/ic_media_fullscreen.png create mode 100644 app/res/drawable-xhdpi/ic_media_fullscreen.png create mode 100644 app/res/drawable-xxhdpi/ic_media_fullscreen.png diff --git a/app/res/drawable-hdpi/ic_media_fullscreen.png b/app/res/drawable-hdpi/ic_media_fullscreen.png new file mode 100644 index 0000000000000000000000000000000000000000..80d4d994783007efdd22cd2b978895512bd52da2 GIT binary patch literal 860 zcmV-i1Ec(jP)|9s+u#D^i6JMY09< z&f06@K%626f-*&<@DS8MNe>k*KTVWC{%qg)FWA8eX*PESyK)qJXTEP|c6Merk@#-^ zO@pBSi0w&lG$ffEBboS+j3@XsI0OvKBqvD56ZpfwAgydEo6$};V2MO5z_%s3F)F8Q zK^hSzz|X;NIF|IoP?t&vMM(z+%fop)zstZR9Y;zLSsjiMVJ_Z9j`z}VOeKR=G=q7) zqMfLJie*)1kp1v4{>#d&j3Xy%Sk_=vLW;B_5lf(KNxH#0%|Wl7X=xM)YI zOeyyM81g60*EJO$vV3%n*p?=za^&}k)Bw*7L zI2xvHKi*{uj8YBONg})k__j_pMl*%SJ5SQLU|Ispa+Ppa54U*{Ksh37Lkff^YswKo zUVOOqtu?LbEg1MN3f%N?<5CoT3J<>M!ry$j$9V=*5orB)+ipF%rdzgaNtj{;-gJz0 zT-ka;3*M(#9zQ2x=Gnx|`=dI^z@n8}G-H`OMTC3(UFfno<35NJk0RcJV0DgQ4R)1^C}B!rh=OQw z$u5aevI1F53fr&+y|e(20CL((WiP8N(m{tr>f}rRCp)H zeEq7PaVOyJqFF35=P>2I(YU9IStPp|r0W?J9R4Mff6<@Gv4!Wsi|f&m_u-fC@tyYt mWHwhQo|i!G*Vym&&)Q$8^Cp+Z+4+M20000kdg00009c5p#w0000W z0000W0EhaVod5s=M@d9MR7l6omCa7-KorNPH0c|NhS%T?cmcG8txFXW>xQP&FFK{u z7D7v<>C!}>LEix6A*>tSi*6)p3e4??CV<>kN$%}gb?D$s)h-p{EI%HuD)Bf*5@j zq7~X89`qd7^%Cn30^c60joVbjEu}W>Vc_=%nb&cV*RHhVRVx4vh;_&PdRctTXVE($ z)39eNLck<|fKh~=Jq-zo-siK$$JdMFigj)sa1J2rdh;0}%LO5C&t4ZQxcnmlm!aZy z-<~t?eCB$PJ^ux$Wq?IQNH{s=4GAA$fC{L90X{IKQ$Czz-V{*V3P_SC%OpxTzL0gv zEZM*YW=WSWHdGbn^N{qW)lu1fC82 zY3OxN`0zeU^>M6OsEL}I^*H{Pc7MWq-Dw#3{3bvKO4T0rY^WGJOs}*^r>pv+bc$mDd224mw4(p$fQ+i@L-mikEj+Ez>wMj#}p360j8Ybd!}THdCbx2^BsVcEgc_RqdQ2vXViA&&Vt00000NkvXXu0mjf9rQAa literal 0 HcmV?d00001 diff --git a/app/res/drawable-xhdpi/ic_media_fullscreen.png b/app/res/drawable-xhdpi/ic_media_fullscreen.png new file mode 100644 index 0000000000000000000000000000000000000000..62d9a465c6c34812f1935ce889906e8265111e44 GIT binary patch literal 1208 zcmV;p1V{UcP)1g-`6e+lq)ZCPgaWb|n z*{idX1=to11vLdTVfY11GE7p2q)FOjAY~q9GURb(+1zheSe7h5cw{2a#Crw0h8y&NOlt7HL^WcxNNI0xfGdqzMzsN44M= z8T61+p+}IyjKP>#uUY+g0h>Yc4E9b92QWvCO1W-1-(9DN{&OAYWPhii83w8HA#?$x zNi~duw!h&S}8r> zYr9d-R#N~#EX*d(3&3@R#;$G%aSnE~iplW+EV>nmfm@h0OrBK^c3Tl%*SQ>kfC%U0 zU^k~!4dPU$JHdqVllKl*c-6=Of^!mra8&?pi2CwATNK8_&ihc8i~taHpDckeTm16g zUC-TVZix5|K$LHvH9ckyB-Lh7j)kX z9qaXu^+ENY-!*^8{JjK#Uo!EYWQ!kOcZK%x!T{^V?+>rD#e*jzDcxTe1h8Ihxgzg# zB~D62u<$~KaYi=HgKW+!ENs08R4H@Hl|)@=x$D()0U!xL(>B(cKVR%+k@wxe3JO1Z z$#hhAPI(YVnb(hAMnQ^ztr}V7#a{F0#+s%H0Hb@sEY&Jydv$*YMVCXkb(UH|FSJfi z-#*JJa-Ewzr@VdU&GtMdQ8lo>Qrh3KSJ4Ya;~xM&95K5m7w*g822E-FsY!Shl+l9b9g)UAS|M@8-}R(7Tv~7ILM&n z+ovr%ubMj5=`N^l>Unj`{`SdR4Fzcu5+DcC3`kuZbs*`q)&+ET75&X?Ie|1gIuzD# z*#)gC-20fOL66C*!p1FIc;VPhLSEh8eDjoHSENu0qf+6M|Y!r0Sr912m)r8xFx6ni_4|3DJ^k!)-ZrQ>icAA=W@ zF?cl_gO}4Wc|DKqf+EfHvtHVS)*Z=?j*P{ZU$fHM(zJ2>< zz4fFWP#I@QkY6x^s9#aN_W$$mZ_7t6VPIhF_H=O!sbG9F)zR;;fq*OHi+xVE3>|U| zp|%XU`%ti3qrVP&4( zJJa;-cFcZGZm-w2>@aSe(QIm-07BUBy^_rYd+u7T)lf>EG?}#J?~4Q5`3TP@VA`NAFC=4k3}2 ztkso8bH%(?6*7mqp5~j(x=SzUJQA%U-6g za}uUpo}^ozt@&%xlZde9zt)@9utwjRni_35Ej9RI*QUSWTcQ`gVW^T{S@`1L#%=oR zzF+;3yT6YU7$pL2Kg)aDY+_swhjGczpJ#42VgCx}2E)e+#UWNbvfraL0wM#t0(J+y ydD-v1D0@Zsy471w?>f&YFJqTkV=}eqJVRwojHl6FgBD<1F?hQAxvX Date: Mon, 11 Mar 2024 17:57:36 +0200 Subject: [PATCH 02/17] Lint --- app/src/org/commcare/views/media/CommCareMediaController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/org/commcare/views/media/CommCareMediaController.java b/app/src/org/commcare/views/media/CommCareMediaController.java index 2cd9b28a02..b78af1e4e0 100644 --- a/app/src/org/commcare/views/media/CommCareMediaController.java +++ b/app/src/org/commcare/views/media/CommCareMediaController.java @@ -13,7 +13,8 @@ import org.commcare.utils.AndroidUtil; /** - * Custom MediaController which provides a workaround to the issue where hide and show aren't working while adding it in the view hierarchy. + * Custom MediaController which provides a workaround to the issue where hide and show aren't + * working while adding it in the view hierarchy. * Note: Use only when you're manually adding MediaController in the view hierarchy. * Used here {@link MediaLayout} * @author $|-|!˅@M From b68126ea7f617d9ddac52700a6c589d433390c51 Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Mon, 11 Mar 2024 17:59:03 +0200 Subject: [PATCH 03/17] Style fullscreen button --- app/res/values/styles.xml | 6 ++++++ .../org/commcare/views/media/CommCareMediaController.java | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/res/values/styles.xml b/app/res/values/styles.xml index 580aa8d292..f0984c9aca 100644 --- a/app/res/values/styles.xml +++ b/app/res/values/styles.xml @@ -293,4 +293,10 @@ @color/cc_core_text @color/cc_attention_negative_color 120dp + + diff --git a/app/src/org/commcare/views/media/CommCareMediaController.java b/app/src/org/commcare/views/media/CommCareMediaController.java index b78af1e4e0..8058fa2d29 100644 --- a/app/src/org/commcare/views/media/CommCareMediaController.java +++ b/app/src/org/commcare/views/media/CommCareMediaController.java @@ -71,7 +71,7 @@ public void setAnchorView(View view) { private void addFullscreenButton(CommCareVideoView videoView) { if (fullscreenBtn == null) { - fullscreenBtn = new ImageButton(getContext(), null); + fullscreenBtn = new ImageButton(getContext(), null, R.style.MediaButton); fullscreenBtn.setId(AndroidUtil.generateViewId()); fullscreenBtn.setImageResource(R.drawable.ic_media_fullscreen); } From 5ac61775ad81b063833ef865591b416b1b6d89ce Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Tue, 12 Mar 2024 16:45:29 +0200 Subject: [PATCH 04/17] Return video path --- .../org/commcare/views/media/CommCareVideoView.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/src/org/commcare/views/media/CommCareVideoView.java b/app/src/org/commcare/views/media/CommCareVideoView.java index 433e1e2e2b..3ec97f0421 100644 --- a/app/src/org/commcare/views/media/CommCareVideoView.java +++ b/app/src/org/commcare/views/media/CommCareVideoView.java @@ -1,6 +1,7 @@ package org.commcare.views.media; import android.content.Context; +import android.net.Uri; import android.util.AttributeSet; import android.widget.VideoView; @@ -18,6 +19,8 @@ public class CommCareVideoView extends VideoView { private long duration; private long startTime; + private String videoPath; + public CommCareVideoView(Context context) { super(context); } @@ -54,6 +57,16 @@ protected void onDetachedFromWindow() { } } + @Override + public void setVideoPath(String videoPath){ + super.setVideoPath(videoPath); + this.videoPath = videoPath; + } + + public String getVideoPath() { + return videoPath; + } + public interface VideoDetachedListener { void onVideoDetached(long duration); } From 3aade5422cc9bf53d21dc00f124183a85cd5ddc4 Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Tue, 12 Mar 2024 18:33:21 +0200 Subject: [PATCH 05/17] Add activity to view inline videos in fullscreen mode --- app/AndroidManifest.xml | 4 ++ .../layout/activity_fullscreen_video_view.xml | 14 ++++++ app/res/values/styles.xml | 6 +++ .../activities/FullscreenVideoViewActivity.kt | 43 +++++++++++++++++++ .../components/FormEntryConstants.java | 1 + .../views/media/CommCareMediaController.java | 15 +++++++ 6 files changed, 83 insertions(+) create mode 100644 app/res/layout/activity_fullscreen_video_view.xml create mode 100644 app/src/org/commcare/activities/FullscreenVideoViewActivity.kt diff --git a/app/AndroidManifest.xml b/app/AndroidManifest.xml index 936afbaf0b..670a4b4d4c 100644 --- a/app/AndroidManifest.xml +++ b/app/AndroidManifest.xml @@ -196,6 +196,10 @@ android:name="org.commcare.activities.SessionAwarePreferenceActivity" android:theme="@style/PreferenceTheme"> + + diff --git a/app/res/layout/activity_fullscreen_video_view.xml b/app/res/layout/activity_fullscreen_video_view.xml new file mode 100644 index 0000000000..d40bccf689 --- /dev/null +++ b/app/res/layout/activity_fullscreen_video_view.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/app/res/values/styles.xml b/app/res/values/styles.xml index f0984c9aca..5e94cc35b8 100644 --- a/app/res/values/styles.xml +++ b/app/res/values/styles.xml @@ -299,4 +299,10 @@ 71dip 52dip + + diff --git a/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt b/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt new file mode 100644 index 0000000000..315d84c66f --- /dev/null +++ b/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt @@ -0,0 +1,43 @@ +package org.commcare.activities + +import android.os.Bundle +import android.widget.MediaController +import androidx.appcompat.app.AppCompatActivity +import org.commcare.dalvik.databinding.ActivityFullscreenVideoViewBinding + +/** + * Activity to view inline videos in fullscreen mode, it returns the last time position to the + * calling activity + * + * @author avazirna + */ +class FullscreenVideoViewActivity: AppCompatActivity() { + + private lateinit var viewBinding: ActivityFullscreenVideoViewBinding + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + viewBinding = ActivityFullscreenVideoViewBinding.inflate(layoutInflater) + setContentView(viewBinding.root) + + // Get video URI from intent, finish if no URI is available + intent.data?.let { viewBinding.fullscreenVideoView.setVideoURI(intent.data) } ?: { finish() } + + viewBinding.fullscreenVideoView.setMediaController(MediaController(this)) + viewBinding.fullscreenVideoView.setOnPreparedListener { + viewBinding.fullscreenVideoView.start() + } + } + + override fun onPause() { + super.onPause() + if (viewBinding.fullscreenVideoView != null) { + viewBinding.fullscreenVideoView.pause() + } + } + + override fun onDestroy() { + super.onDestroy() + viewBinding.fullscreenVideoView.stopPlayback() + } +} diff --git a/app/src/org/commcare/activities/components/FormEntryConstants.java b/app/src/org/commcare/activities/components/FormEntryConstants.java index b6ca94b840..2cf0818a96 100644 --- a/app/src/org/commcare/activities/components/FormEntryConstants.java +++ b/app/src/org/commcare/activities/components/FormEntryConstants.java @@ -20,6 +20,7 @@ public class FormEntryConstants { public static final int INTENT_COMPOUND_CALLOUT = 13; public static final int INTENT_LOCATION_PERMISSION = 14; public static final int INTENT_LOCATION_EXCEPTION = 15; + public static final int VIEW_VIDEO_FULLSCREEN = 16; public static final String NAV_STATE_NEXT = "next"; public static final String NAV_STATE_DONE = "done"; diff --git a/app/src/org/commcare/views/media/CommCareMediaController.java b/app/src/org/commcare/views/media/CommCareMediaController.java index 8058fa2d29..67c80a5e37 100644 --- a/app/src/org/commcare/views/media/CommCareMediaController.java +++ b/app/src/org/commcare/views/media/CommCareMediaController.java @@ -1,6 +1,7 @@ package org.commcare.views.media; import android.content.Context; +import android.content.Intent; import android.util.AttributeSet; import android.view.Gravity; import android.view.View; @@ -9,8 +10,15 @@ import android.widget.ImageButton; import android.widget.MediaController; +import androidx.appcompat.app.AppCompatActivity; + +import org.commcare.activities.FullscreenVideoViewActivity; +import org.commcare.activities.components.FormEntryConstants; import org.commcare.dalvik.R; import org.commcare.utils.AndroidUtil; +import org.commcare.utils.FileUtil; + +import java.io.File; /** * Custom MediaController which provides a workaround to the issue where hide and show aren't @@ -74,6 +82,13 @@ private void addFullscreenButton(CommCareVideoView videoView) { fullscreenBtn = new ImageButton(getContext(), null, R.style.MediaButton); fullscreenBtn.setId(AndroidUtil.generateViewId()); fullscreenBtn.setImageResource(R.drawable.ic_media_fullscreen); + fullscreenBtn.setOnClickListener(view1 -> { + Intent intent = new Intent(getContext(), FullscreenVideoViewActivity.class); + intent.setData(FileUtil.getUriForExternalFile(getContext(), + new File(videoView.getVideoPath()))); + ((AppCompatActivity) getContext()).startActivityForResult(intent, + FormEntryConstants.VIEW_VIDEO_FULLSCREEN); + }); } FrameLayout.LayoutParams frameParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.END); From b10af35e2386cae6414fd337e5ba5e614a944461 Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Tue, 12 Mar 2024 18:57:07 +0200 Subject: [PATCH 06/17] Maintain time position when switching to fullscreen mode --- .../activities/FullscreenVideoViewActivity.kt | 23 +++++++++++++++++++ .../views/media/CommCareMediaController.java | 5 ++++ 2 files changed, 28 insertions(+) diff --git a/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt b/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt index 315d84c66f..d932ea671f 100644 --- a/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt +++ b/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt @@ -1,9 +1,11 @@ package org.commcare.activities +import android.content.Intent import android.os.Bundle import android.widget.MediaController import androidx.appcompat.app.AppCompatActivity import org.commcare.dalvik.databinding.ActivityFullscreenVideoViewBinding +import org.commcare.views.media.CommCareMediaController /** * Activity to view inline videos in fullscreen mode, it returns the last time position to the @@ -14,6 +16,7 @@ import org.commcare.dalvik.databinding.ActivityFullscreenVideoViewBinding class FullscreenVideoViewActivity: AppCompatActivity() { private lateinit var viewBinding: ActivityFullscreenVideoViewBinding + private var lastPosition = -1 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -23,8 +26,13 @@ class FullscreenVideoViewActivity: AppCompatActivity() { // Get video URI from intent, finish if no URI is available intent.data?.let { viewBinding.fullscreenVideoView.setVideoURI(intent.data) } ?: { finish() } + lastPosition = restoreLastPosition(savedInstanceState) + viewBinding.fullscreenVideoView.setMediaController(MediaController(this)) viewBinding.fullscreenVideoView.setOnPreparedListener { + if (lastPosition != -1) { + viewBinding.fullscreenVideoView.seekTo(lastPosition) + } viewBinding.fullscreenVideoView.start() } } @@ -40,4 +48,19 @@ class FullscreenVideoViewActivity: AppCompatActivity() { super.onDestroy() viewBinding.fullscreenVideoView.stopPlayback() } + + // priority is given to lastPosition saved state + private fun restoreLastPosition(savedInstanceState: Bundle?): Int { + val intentExtras = intent.extras + if (savedInstanceState != null && savedInstanceState.containsKey( + CommCareMediaController.INLINE_VIDEO_TIME_POSITION + )) { + return savedInstanceState.getInt(CommCareMediaController.INLINE_VIDEO_TIME_POSITION) + } else if (intentExtras !=null && intentExtras.containsKey( + CommCareMediaController.INLINE_VIDEO_TIME_POSITION + )) { + return intentExtras.getInt(CommCareMediaController.INLINE_VIDEO_TIME_POSITION) + } + return -1 + } } diff --git a/app/src/org/commcare/views/media/CommCareMediaController.java b/app/src/org/commcare/views/media/CommCareMediaController.java index 67c80a5e37..2cbd1ecd8a 100644 --- a/app/src/org/commcare/views/media/CommCareMediaController.java +++ b/app/src/org/commcare/views/media/CommCareMediaController.java @@ -29,6 +29,8 @@ */ public class CommCareMediaController extends MediaController { + public static final String INLINE_VIDEO_TIME_POSITION = "inline-video-time-position"; + // A mock to superclass' isShowing property. // {@link https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/widget/MediaController.java#96} private boolean _isShowing = false; @@ -86,6 +88,9 @@ private void addFullscreenButton(CommCareVideoView videoView) { Intent intent = new Intent(getContext(), FullscreenVideoViewActivity.class); intent.setData(FileUtil.getUriForExternalFile(getContext(), new File(videoView.getVideoPath()))); + if (videoView.isPlaying()) { + intent.putExtra(INLINE_VIDEO_TIME_POSITION, videoView.getCurrentPosition()); + } ((AppCompatActivity) getContext()).startActivityForResult(intent, FormEntryConstants.VIEW_VIDEO_FULLSCREEN); }); From 9f4f5a763da50ca6e656c34925759c8002e898d7 Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Tue, 12 Mar 2024 19:01:59 +0200 Subject: [PATCH 07/17] Save time position during activity recreation --- .../commcare/activities/FullscreenVideoViewActivity.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt b/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt index d932ea671f..c76aa7ad10 100644 --- a/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt +++ b/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt @@ -37,10 +37,18 @@ class FullscreenVideoViewActivity: AppCompatActivity() { } } + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + if (lastPosition != -1) { + outState.putInt(CommCareMediaController.INLINE_VIDEO_TIME_POSITION, lastPosition) + } + } + override fun onPause() { super.onPause() if (viewBinding.fullscreenVideoView != null) { viewBinding.fullscreenVideoView.pause() + lastPosition = viewBinding.fullscreenVideoView.currentPosition } } From cd82dc9f01a9fc850a6227450e7cfa6f3f292d1e Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Tue, 12 Mar 2024 19:03:01 +0200 Subject: [PATCH 08/17] Return time position to calling activity --- app/src/org/commcare/activities/FormEntryActivity.java | 8 ++++++++ .../commcare/activities/FullscreenVideoViewActivity.kt | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/app/src/org/commcare/activities/FormEntryActivity.java b/app/src/org/commcare/activities/FormEntryActivity.java index efa0f8dcf5..99ad9be81f 100644 --- a/app/src/org/commcare/activities/FormEntryActivity.java +++ b/app/src/org/commcare/activities/FormEntryActivity.java @@ -77,6 +77,7 @@ import org.commcare.views.dialogs.CommCareAlertDialog; import org.commcare.views.dialogs.CustomProgressDialog; import org.commcare.views.dialogs.StandardAlertDialog; +import org.commcare.views.media.CommCareMediaController; import org.commcare.views.widgets.BarcodeWidget; import org.commcare.views.widgets.ImageWidget; import org.commcare.views.widgets.IntentWidget; @@ -368,6 +369,13 @@ public void onActivityResultSessionSafe(int requestCode, int resultCode, Intent PollSensorController.INSTANCE.requestLocationUpdates(); } break; + case FormEntryConstants.VIEW_VIDEO_FULLSCREEN: + if (intent.getExtras().containsKey( + CommCareMediaController.INLINE_VIDEO_TIME_POSITION)) { + positionOfVideoProgress = intent.getIntExtra( + CommCareMediaController.INLINE_VIDEO_TIME_POSITION, 0); + } + break; } } resetPendingCalloutIndex(); diff --git a/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt b/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt index c76aa7ad10..72004eeb7c 100644 --- a/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt +++ b/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt @@ -52,6 +52,13 @@ class FullscreenVideoViewActivity: AppCompatActivity() { } } + override fun onBackPressed() { + val i = Intent() + i.putExtra(CommCareMediaController.INLINE_VIDEO_TIME_POSITION, viewBinding.fullscreenVideoView.currentPosition) + setResult(RESULT_OK, i) + super.onBackPressed() + } + override fun onDestroy() { super.onDestroy() viewBinding.fullscreenVideoView.stopPlayback() From d67ca3779e1b590f4db069d968016822e880936d Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Fri, 15 Mar 2024 17:35:30 +0200 Subject: [PATCH 09/17] Refactor --- .../commcare/activities/FullscreenVideoViewActivity.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt b/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt index 72004eeb7c..ea642132ba 100644 --- a/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt +++ b/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt @@ -53,10 +53,14 @@ class FullscreenVideoViewActivity: AppCompatActivity() { } override fun onBackPressed() { + setResultIntent() + super.onBackPressed() + } + + private fun setResultIntent(){ val i = Intent() i.putExtra(CommCareMediaController.INLINE_VIDEO_TIME_POSITION, viewBinding.fullscreenVideoView.currentPosition) - setResult(RESULT_OK, i) - super.onBackPressed() + this.setResult(RESULT_OK, i) } override fun onDestroy() { From d5f4d2bef48f5299047a3682a87cd9e245e87597 Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Fri, 15 Mar 2024 17:39:51 +0200 Subject: [PATCH 10/17] Add fullscreen mode flag to media controller --- .../commcare/views/media/CommCareMediaController.java | 10 +++++++--- app/src/org/commcare/views/media/MediaLayout.java | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/src/org/commcare/views/media/CommCareMediaController.java b/app/src/org/commcare/views/media/CommCareMediaController.java index 2cbd1ecd8a..a0fb18ae4e 100644 --- a/app/src/org/commcare/views/media/CommCareMediaController.java +++ b/app/src/org/commcare/views/media/CommCareMediaController.java @@ -35,17 +35,21 @@ public class CommCareMediaController extends MediaController { // {@link https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/widget/MediaController.java#96} private boolean _isShowing = false; private ImageButton fullscreenBtn; + private boolean fullscreenMode; - public CommCareMediaController(Context context, AttributeSet attrs) { + public CommCareMediaController(Context context, AttributeSet attrs, boolean fullscreenMode) { super(context, attrs); + this.fullscreenMode = fullscreenMode; } - public CommCareMediaController(Context context, boolean useFastForward) { + public CommCareMediaController(Context context, boolean useFastForward, boolean fullscreenMode) { super(context, useFastForward); + this.fullscreenMode = fullscreenMode; } - public CommCareMediaController(Context context) { + public CommCareMediaController(Context context, boolean fullscreenMode) { super(context); + this.fullscreenMode = fullscreenMode; } @Override diff --git a/app/src/org/commcare/views/media/MediaLayout.java b/app/src/org/commcare/views/media/MediaLayout.java index 4617cfd4ba..d25f4b3e47 100644 --- a/app/src/org/commcare/views/media/MediaLayout.java +++ b/app/src/org/commcare/views/media/MediaLayout.java @@ -307,7 +307,7 @@ private void setupInlineVideoView(String inlineVideoURI) { setupInlineVideoView(inlineVideoURI); }); } else { - final CommCareMediaController ctrl = new CommCareMediaController(this.getContext()); + final CommCareMediaController ctrl = new CommCareMediaController(this.getContext(), false); ctrl.setId(AndroidUtil.generateViewId()); videoView.setOnPreparedListener(mediaPlayer -> { //Since MediaController will create a default set of controls and put them in a window floating above your application(From AndroidDocs) From b5d5dfb495c244fa60327c7d5fa8210b18af02f7 Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Fri, 15 Mar 2024 18:01:03 +0200 Subject: [PATCH 11/17] Switch to CommCare media controller --- .../commcare/activities/FullscreenVideoViewActivity.kt | 3 +-- .../org/commcare/views/media/CommCareMediaController.java | 8 +++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt b/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt index ea642132ba..687919674e 100644 --- a/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt +++ b/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt @@ -2,7 +2,6 @@ package org.commcare.activities import android.content.Intent import android.os.Bundle -import android.widget.MediaController import androidx.appcompat.app.AppCompatActivity import org.commcare.dalvik.databinding.ActivityFullscreenVideoViewBinding import org.commcare.views.media.CommCareMediaController @@ -28,7 +27,7 @@ class FullscreenVideoViewActivity: AppCompatActivity() { lastPosition = restoreLastPosition(savedInstanceState) - viewBinding.fullscreenVideoView.setMediaController(MediaController(this)) + viewBinding.fullscreenVideoView.setMediaController(CommCareMediaController(this, true)) viewBinding.fullscreenVideoView.setOnPreparedListener { if (lastPosition != -1) { viewBinding.fullscreenVideoView.seekTo(lastPosition) diff --git a/app/src/org/commcare/views/media/CommCareMediaController.java b/app/src/org/commcare/views/media/CommCareMediaController.java index a0fb18ae4e..f623b1b162 100644 --- a/app/src/org/commcare/views/media/CommCareMediaController.java +++ b/app/src/org/commcare/views/media/CommCareMediaController.java @@ -77,7 +77,13 @@ public void hide() { public void setAnchorView(View view) { super.setAnchorView(view); - CommCareVideoView videoView = view.findViewById(R.id.inline_video_view); + CommCareVideoView videoView; + if (fullscreenMode) { + videoView = view.findViewById(R.id.fullscreen_video_view); + } else { + videoView = view.findViewById(R.id.inline_video_view); + } + if (videoView != null) { addFullscreenButton(videoView); } From 0df8eeda34d9df379853a53b4b5495e45ae86401 Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Mon, 18 Mar 2024 10:28:46 +0200 Subject: [PATCH 12/17] Add exit fullscreen mode button --- .../drawable-hdpi/ic_media_exit_fullscreen.png | Bin 0 -> 2150 bytes .../drawable-ldpi/ic_media_exit_fullscreen.png | Bin 0 -> 193 bytes .../drawable-mdpi/ic_media_exit_fullscreen.png | Bin 0 -> 1477 bytes .../drawable-xhdpi/ic_media_exit_fullscreen.png | Bin 0 -> 3320 bytes .../drawable-xxhdpi/ic_media_exit_fullscreen.png | Bin 0 -> 1379 bytes .../views/media/CommCareMediaController.java | 6 +++++- 6 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 app/res/drawable-hdpi/ic_media_exit_fullscreen.png create mode 100644 app/res/drawable-ldpi/ic_media_exit_fullscreen.png create mode 100644 app/res/drawable-mdpi/ic_media_exit_fullscreen.png create mode 100644 app/res/drawable-xhdpi/ic_media_exit_fullscreen.png create mode 100644 app/res/drawable-xxhdpi/ic_media_exit_fullscreen.png diff --git a/app/res/drawable-hdpi/ic_media_exit_fullscreen.png b/app/res/drawable-hdpi/ic_media_exit_fullscreen.png new file mode 100644 index 0000000000000000000000000000000000000000..5300f949d70878f7dc8c21d1df7803fba3ff6f2b GIT binary patch literal 2150 zcmV-s2$}bZP)C;wLlXaM1D2G#2SJH8>JdUn%0OdEz;Q3#*J}->BhJ-F`BqAZW>t_7A7@u z0aSvxXc`wa)fA{38WE#_3X+C8P~>NX`C(qaZ{}U|7??M2&_vVBNha^Td(S=JIrpA> z?zv}#NK%rLl%%&wic#n3)2A)?h43p^6r~PLIrvSfs(KS`gR)<|2E8tZ)r8=W@c9h{ zrc6&yd!0^aHh?O3@7_I&zH##1x^+txk;%|ch|#;UMhx=?aKNckr>d=1>laH)OABaP zs;jGWkB*N16AFcbXm{`0wQK&&nKKfA!&JOG^78V;;Nal0S!--;v>rTo&EQ^+jX2TrLMNTo`+W?j#af zfjxWn9O9C4R*oDwvX6rC9m>tkEhsK7PV4FE83echKsjc~3%*aFSS5|cGZQXQ4jDsm zgG`M34o0OdE-tDLhocPdxwW;moPc_~`>Fh~W5?>t%F1406c!e`?%lgL%t?m4^;o&S z)%3K8*pxFjH#ZOEwn*inl)`6eY3U9E5||1=k^OeNy<~QF_W9<`oAWX=GgY+PAfuQ+ zzO#*ewzg9LC>Ag>Eis9z+y0t|DEE{rmaHWWy~x|I+F=3*5T6l_C( zF2^YmS`o9^rtu5%atz1HiHKG{D#BUTVn9f51R{Y$XGE`5p1RQms02wqS0gt^MVXXM z3}Ts4KCS^Ga$<%~o;;ZWKi-066^I}UJ9qBf$XG3Tw5KY}ld2y}S(HiH#2^+iHRYAp zF(6Dh5kJGsxRIyK)zs7!A{>5?w)cd#{CZ`=+F?Jg(0F-U_+7doWl<(&6N6a96ecL1 z0qXJN$LW*B3kwU=Znyh``uh4tM3S^XAh3W4;fJsKy$SDg z>FMcCGn*JGw*o^v=xT{~kj0Hch&*;&5nTvvK17AQrlzKEk(jMx2-H?WuZRWhi;Oli zGczF=nZC~#XX5H zUcAUl%VR1%Ffj0UcXxLO;=b7vIGJf>GhBoLBCRQ^O+lu6mdAQmyT{im+k z0Db8LpS;5cUc7j*c;du~uXOpmMN6kmCv(!XI96!)3Cg5wVi1d%G8-0aF+i_8OCM1e z@EW=N(g>N;8D-Ua9;v+0+>kQ$g#u!lF(PhZOJBEH+I~jf>=I-+UAOtWgGj*Ltc*I*jUvLVrozUt?0Wd8CB-?;Y9TA-MiO~GRWsK zln>uw!EWa%J2Eoz9EZ%7!4DJwo^5n@-e}DftTqOf;X+iu~VpKa+ z-qOG`asU4PXK=qPxb$x#krfcJ3tP*SXWkE>8#stYkZQdD@Zm!bQvv2Pknxy5zO#*e zk%zn-!?F63 zjUK~nVaxFFkx_`7i7U%mC1-_#nbSm-KIkgp@;a7%siUJ~S#^%(^@@rLEBgH+QY=vP zVLBd0!UjbB`Ov`4go9=trH^#Z3fel+_ouG(5nY{74BmxiY@!(E4Tv)0o&Ad`Nl8jl clHM-;2i`XR*l!@V%m4rY07*qoM6N<$g0}hpW&i*H literal 0 HcmV?d00001 diff --git a/app/res/drawable-ldpi/ic_media_exit_fullscreen.png b/app/res/drawable-ldpi/ic_media_exit_fullscreen.png new file mode 100644 index 0000000000000000000000000000000000000000..7197f3b5d30d1babb9eca4df2b8f85a1e2382590 GIT binary patch literal 193 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 { Intent intent = new Intent(getContext(), FullscreenVideoViewActivity.class); intent.setData(FileUtil.getUriForExternalFile(getContext(), From 5ff7cfadf6c29b0454e99b4030d7d64166bf76c2 Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Mon, 18 Mar 2024 10:41:39 +0200 Subject: [PATCH 13/17] Add exit fullscreen event --- .../commcare/views/media/CommCareMediaController.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/src/org/commcare/views/media/CommCareMediaController.java b/app/src/org/commcare/views/media/CommCareMediaController.java index 88243fd107..635e1d2fcb 100644 --- a/app/src/org/commcare/views/media/CommCareMediaController.java +++ b/app/src/org/commcare/views/media/CommCareMediaController.java @@ -1,5 +1,6 @@ package org.commcare.views.media; +import android.app.Activity; import android.content.Context; import android.content.Intent; import android.util.AttributeSet; @@ -99,6 +100,13 @@ private void addFullscreenButton(CommCareVideoView videoView) { fullscreenBtn.setImageResource(R.drawable.ic_media_fullscreen); } fullscreenBtn.setOnClickListener(view1 -> { + // if in fullscreen mode, we exit + if (fullscreenMode) { + Intent i = new Intent(); + i.putExtra(CommCareMediaController.INLINE_VIDEO_TIME_POSITION, videoView.getCurrentPosition()); + ((AppCompatActivity)getContext()).setResult(Activity.RESULT_OK, i); + ((AppCompatActivity)getContext()).finish(); + } else { Intent intent = new Intent(getContext(), FullscreenVideoViewActivity.class); intent.setData(FileUtil.getUriForExternalFile(getContext(), new File(videoView.getVideoPath()))); @@ -107,7 +115,8 @@ private void addFullscreenButton(CommCareVideoView videoView) { } ((AppCompatActivity) getContext()).startActivityForResult(intent, FormEntryConstants.VIEW_VIDEO_FULLSCREEN); - }); + } + }); } FrameLayout.LayoutParams frameParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.END); From 7ba0f747eb9a2a7ce5b179e21b99859040a79a6c Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Mon, 18 Mar 2024 11:47:56 +0200 Subject: [PATCH 14/17] Lint --- .../activities/FormEntryActivity.java | 93 ++++++++++++------- .../activities/FullscreenVideoViewActivity.kt | 20 ++-- .../org/commcare/views/media/MediaLayout.java | 29 +++--- 3 files changed, 91 insertions(+), 51 deletions(-) diff --git a/app/src/org/commcare/activities/FormEntryActivity.java b/app/src/org/commcare/activities/FormEntryActivity.java index 99ad9be81f..f127f1b6a2 100644 --- a/app/src/org/commcare/activities/FormEntryActivity.java +++ b/app/src/org/commcare/activities/FormEntryActivity.java @@ -177,17 +177,20 @@ public class FormEntryActivity extends SaveSessionCommCareActivity formDefStorage = CommCareApplication.instance().getAppStorage(FormDefRecord.class); + SqlStorage formDefStorage = CommCareApplication.instance() + .getAppStorage(FormDefRecord.class); if (intent.hasExtra(KEY_FORM_RECORD_ID)) { Pair instanceAndStatus = instanceState.getFormDefIdForRecord( formDefStorage, @@ -996,11 +1014,13 @@ private void loadForm() { return; } } catch (FormQueryException e) { - new UserfacingErrorHandling<>().createErrorDialog(this, e.getMessage(), FormEntryConstants.EXIT); + new UserfacingErrorHandling<>().createErrorDialog(this, e.getMessage(), + FormEntryConstants.EXIT); return; } - mFormLoaderTask = new FormLoaderTask(symetricKey, instanceIsReadOnly, formEntryRestoreSession.isRecording(), FormEntryInstanceState.mFormRecordPath, this) { + mFormLoaderTask = new FormLoaderTask(symetricKey, instanceIsReadOnly, + formEntryRestoreSession.isRecording(), FormEntryInstanceState.mFormRecordPath, this) { @Override protected void deliverResult(FormEntryActivity receiver, FECWrapper wrapperResult) { receiver.handleFormLoadCompletion(wrapperResult.getController()); @@ -1016,15 +1036,20 @@ protected void deliverError(FormEntryActivity receiver, Exception e) { receiver.dismissProgressDialogForTask(taskId); if (e != null) { - new UserfacingErrorHandling<>().createErrorDialog(receiver, e.getMessage(), FormEntryConstants.EXIT); + new UserfacingErrorHandling<>().createErrorDialog(receiver, + e.getMessage(), FormEntryConstants.EXIT); } else { - new UserfacingErrorHandling<>().createErrorDialog(receiver, StringUtils.getStringRobust(receiver, R.string.parse_error), FormEntryConstants.EXIT); + new UserfacingErrorHandling<>().createErrorDialog(receiver, + StringUtils.getStringRobust(receiver, R.string.parse_error), + FormEntryConstants.EXIT); } if (intent.hasExtra(KEY_FORM_RECORD_ID)) { // log the form record id for which form load has failed - FormRecord formRecord = FormRecord.getFormRecord(formRecordStorage, intent.getIntExtra(KEY_FORM_RECORD_ID, -1)); - Logger.log(LogTypes.TYPE_FORM_ENTRY, "Form load failed for form with id " + formRecord.getInstanceID()); + FormRecord formRecord = FormRecord.getFormRecord(formRecordStorage, + intent.getIntExtra(KEY_FORM_RECORD_ID, -1)); + Logger.log(LogTypes.TYPE_FORM_ENTRY, + "Form load failed for form with id " + formRecord.getInstanceID()); } } }; @@ -1070,13 +1095,15 @@ private void handleFormLoadCompletion(AndroidFormController fc) { uiController.refreshView(); FormNavigationUI.updateNavigationCues(this, mFormController, uiController.questionsView); if (isRestartAfterSessionExpiration) { - Toast.makeText(this, Localization.get("form.entry.restart.after.expiration"), Toast.LENGTH_LONG).show(); + Toast.makeText(this, + Localization.get("form.entry.restart.after.expiration"), Toast.LENGTH_LONG).show(); } } private void handleXpathErrorBroadcast() { new UserfacingErrorHandling<>().createErrorDialog(FormEntryActivity.this, - "There is a bug in one of your form's XPath Expressions \n" + badLocationXpath, FormEntryConstants.EXIT); + "There is a bug in one of your form's XPath Expressions \n" + badLocationXpath, + FormEntryConstants.EXIT); } /** @@ -1204,7 +1231,8 @@ public void savingComplete(SaveToDiskTask.SaveStatus saveStatus, String errorMes case SAVED_AND_EXIT: hasSaved = true; if (!CommCareApplication.instance().isConsumerApp()) { - Toast.makeText(this, Localization.get("form.entry.complete.save.success"), Toast.LENGTH_SHORT).show(); + Toast.makeText(this, + Localization.get("form.entry.complete.save.success"), Toast.LENGTH_SHORT).show(); } finishReturnInstance(); return; @@ -1217,7 +1245,8 @@ public void savingComplete(SaveToDiskTask.SaveStatus saveStatus, String errorMes case SAVE_ERROR: if (!CommCareApplication.instance().isConsumerApp()) { new UserfacingErrorHandling<>().createErrorDialog(this, errorMessage, - Localization.get("notification.formentry.save_error.title"), FormEntryConstants.EXIT); + Localization.get("notification.formentry.save_error.title"), + FormEntryConstants.EXIT); } quarantineRecordOnError(errorMessage); return; @@ -1465,7 +1494,8 @@ private void setTitleToLoading() { if (mHeaderString != null) { setTitle(mHeaderString); } else { - setTitle(StringUtils.getStringRobust(this, R.string.application_name) + " > " + StringUtils.getStringRobust(this, R.string.loading_form)); + setTitle(StringUtils.getStringRobust(this, R.string.application_name) + " > " + + StringUtils.getStringRobust(this, R.string.loading_form)); } } @@ -1474,7 +1504,8 @@ protected String getHeaderString() { //Localization? return mHeaderString; } else { - return StringUtils.getStringRobust(this, R.string.application_name) + " > " + FormEntryActivity.mFormController.getFormTitle(); + return StringUtils.getStringRobust(this, R.string.application_name) + " > " + + FormEntryActivity.mFormController.getFormTitle(); } } @@ -1492,7 +1523,7 @@ public void requestNeededPermissions(int requestCode) { @Override public void onRequestPermissionsResult(int requestCode, - String permissions[], int[] grantResults) { + String[] permissions, int[] grantResults) { switch (requestCode) { case ImageWidget.REQUEST_CAMERA_PERMISSION: { diff --git a/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt b/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt index 687919674e..4025eaa383 100644 --- a/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt +++ b/app/src/org/commcare/activities/FullscreenVideoViewActivity.kt @@ -12,7 +12,7 @@ import org.commcare.views.media.CommCareMediaController * * @author avazirna */ -class FullscreenVideoViewActivity: AppCompatActivity() { +class FullscreenVideoViewActivity : AppCompatActivity() { private lateinit var viewBinding: ActivityFullscreenVideoViewBinding private var lastPosition = -1 @@ -23,6 +23,7 @@ class FullscreenVideoViewActivity: AppCompatActivity() { setContentView(viewBinding.root) // Get video URI from intent, finish if no URI is available + // TODO: we should inform the user when we finish because there is no data intent.data?.let { viewBinding.fullscreenVideoView.setVideoURI(intent.data) } ?: { finish() } lastPosition = restoreLastPosition(savedInstanceState) @@ -56,9 +57,12 @@ class FullscreenVideoViewActivity: AppCompatActivity() { super.onBackPressed() } - private fun setResultIntent(){ + private fun setResultIntent() { val i = Intent() - i.putExtra(CommCareMediaController.INLINE_VIDEO_TIME_POSITION, viewBinding.fullscreenVideoView.currentPosition) + i.putExtra( + CommCareMediaController.INLINE_VIDEO_TIME_POSITION, + viewBinding.fullscreenVideoView.currentPosition + ) this.setResult(RESULT_OK, i) } @@ -70,13 +74,11 @@ class FullscreenVideoViewActivity: AppCompatActivity() { // priority is given to lastPosition saved state private fun restoreLastPosition(savedInstanceState: Bundle?): Int { val intentExtras = intent.extras - if (savedInstanceState != null && savedInstanceState.containsKey( - CommCareMediaController.INLINE_VIDEO_TIME_POSITION - )) { + if (savedInstanceState != null && + savedInstanceState.containsKey(CommCareMediaController.INLINE_VIDEO_TIME_POSITION)) { return savedInstanceState.getInt(CommCareMediaController.INLINE_VIDEO_TIME_POSITION) - } else if (intentExtras !=null && intentExtras.containsKey( - CommCareMediaController.INLINE_VIDEO_TIME_POSITION - )) { + } else if (intentExtras !=null && + intentExtras.containsKey(CommCareMediaController.INLINE_VIDEO_TIME_POSITION)) { return intentExtras.getInt(CommCareMediaController.INLINE_VIDEO_TIME_POSITION) } return -1 diff --git a/app/src/org/commcare/views/media/MediaLayout.java b/app/src/org/commcare/views/media/MediaLayout.java index d25f4b3e47..c304e31008 100644 --- a/app/src/org/commcare/views/media/MediaLayout.java +++ b/app/src/org/commcare/views/media/MediaLayout.java @@ -46,8 +46,8 @@ import java.io.File; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import kotlinx.coroutines.Dispatchers; @@ -108,7 +108,8 @@ public static MediaLayout buildComprehensiveLayout(Context context, final String ttsText, int questionIndex) { MediaLayout mediaLayout = new MediaLayout(context); - mediaLayout.setAVT(text, audioURI, imageURI, videoURI, bigImageURI, qrCodeContent, inlineVideoURI, false, questionIndex); + mediaLayout.setAVT(text, audioURI, imageURI, videoURI, bigImageURI, qrCodeContent, inlineVideoURI, false, + questionIndex); // Show TTS view only when audioURI is not present if (ttsText != null && audioURI == null) { mediaLayout.showTtsButton(ttsText); @@ -184,7 +185,8 @@ private void setupStandardAudio(String audioURI, int questionIndex) { private void setupVideoButton(String videoURI) { if (videoURI != null) { boolean mediaPresent = FileUtil.referenceFileExists(videoURI); - videoButton.setImageResource(mediaPresent ? android.R.drawable.ic_media_play : R.drawable.update_download_icon); + videoButton.setImageResource( + mediaPresent ? android.R.drawable.ic_media_play : R.drawable.update_download_icon); if (!mediaPresent) { AndroidUtil.showToast(getContext(), R.string.video_download_prompt); } @@ -207,7 +209,8 @@ private void setupVideoButton(String videoURI) { i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); try { getContext().startActivity(i); - FormEntryActivity.mFormController.getFormAnalyticsHelper().recordVideoPlaybackStart(videoFile); + FormEntryActivity.mFormController.getFormAnalyticsHelper() + .recordVideoPlaybackStart(videoFile); } catch (ActivityNotFoundException e) { Toast.makeText(getContext(), getContext().getString(R.string.activity_not_found, "view video"), @@ -224,7 +227,8 @@ private void downloadMissingVideo(ImageButton videoButton, String videoURI) { MissingMediaDownloadHelper.requestMediaDownload(videoURI, Dispatchers.getDefault(), result -> { if (result instanceof MissingMediaDownloadResult.Success) { boolean mediaPresent = FileUtil.referenceFileExists(videoURI); - videoButton.setImageResource(mediaPresent ? android.R.drawable.ic_media_play : R.drawable.update_download_icon); + videoButton.setImageResource( + mediaPresent ? android.R.drawable.ic_media_play : R.drawable.update_download_icon); AndroidUtil.showToast(getContext(), R.string.media_download_completed); videoButton.setVisibility(VISIBLE); } else if (result instanceof MissingMediaDownloadResult.InProgress) { @@ -310,9 +314,9 @@ private void setupInlineVideoView(String inlineVideoURI) { final CommCareMediaController ctrl = new CommCareMediaController(this.getContext(), false); ctrl.setId(AndroidUtil.generateViewId()); videoView.setOnPreparedListener(mediaPlayer -> { - //Since MediaController will create a default set of controls and put them in a window floating above your application(From AndroidDocs) - //It would never follow the parent view's animation or scroll. - //So, adding the MediaController to the view hierarchy here. + // Since MediaController will create a default set of controls and put them in a window + // floating above your application(From AndroidDocs). It would never follow the parent view's + // animation or scroll. So, adding the MediaController to the view hierarchy here. FrameLayout frameLayout = (FrameLayout)ctrl.getParent(); ((ViewGroup)frameLayout.getParent()).removeView(frameLayout); LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); @@ -336,7 +340,8 @@ private void setupInlineVideoView(String inlineVideoURI) { if (duration == 0) { return; } - FirebaseAnalyticsUtil.reportInlineVideoPlayEvent(videoFilename, FileUtil.getDuration(videoFile), duration); + FirebaseAnalyticsUtil.reportInlineVideoPlayEvent(videoFilename, + FileUtil.getDuration(videoFile), duration); }); videoView.setOnClickListener(v -> ViewUtil.hideVirtualKeyboard((AppCompatActivity)getContext())); @@ -367,7 +372,8 @@ private void makeVideoViewVisible() { videoView.setLayoutParams(params); } - private void showMissingMediaView(String mediaUri, String errorMessage, boolean allowDownload, @Nullable Runnable completion) { + private void showMissingMediaView(String mediaUri, String errorMessage, boolean allowDownload, + @Nullable Runnable completion) { missingMediaView.setVisibility(VISIBLE); missingMediaStatus.setText(errorMessage); missingMediaStatus.setVisibility(VISIBLE); @@ -378,7 +384,8 @@ private void showMissingMediaView(String mediaUri, String errorMessage, boolean progressBar.setVisibility(VISIBLE); downloadIcon.setVisibility(INVISIBLE); downloadIcon.setEnabled(false); - missingMediaStatus.setText(StringUtils.getStringRobust(getContext(), R.string.media_download_in_progress)); + missingMediaStatus.setText( + StringUtils.getStringRobust(getContext(), R.string.media_download_in_progress)); MissingMediaDownloadHelper.requestMediaDownload(mediaUri, Dispatchers.getDefault(), result -> { if (result instanceof MissingMediaDownloadResult.Success) { From dd9f9e9bb7f17714bc8b2b80251275f930eb7eca Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Mon, 18 Mar 2024 19:26:50 +0200 Subject: [PATCH 15/17] Refactor --- .../org/commcare/views/media/CommCareMediaController.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/app/src/org/commcare/views/media/CommCareMediaController.java b/app/src/org/commcare/views/media/CommCareMediaController.java index 635e1d2fcb..0d45594879 100644 --- a/app/src/org/commcare/views/media/CommCareMediaController.java +++ b/app/src/org/commcare/views/media/CommCareMediaController.java @@ -78,12 +78,8 @@ public void hide() { public void setAnchorView(View view) { super.setAnchorView(view); - CommCareVideoView videoView; - if (fullscreenMode) { - videoView = view.findViewById(R.id.fullscreen_video_view); - } else { - videoView = view.findViewById(R.id.inline_video_view); - } + int videoViewId = fullscreenMode ? R.id.fullscreen_video_view : R.id.inline_video_view; + CommCareVideoView videoView = view.findViewById(videoViewId); if (videoView != null) { addFullscreenButton(videoView); From fa76bbcc02dcd6bee0de19923d51cb5653169851 Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Wed, 3 Apr 2024 14:42:20 +0200 Subject: [PATCH 16/17] Refactor --- app/res/values/styles.xml | 2 +- app/src/org/commcare/views/media/CommCareMediaController.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/res/values/styles.xml b/app/res/values/styles.xml index 5e94cc35b8..b0d745bb15 100644 --- a/app/res/values/styles.xml +++ b/app/res/values/styles.xml @@ -294,7 +294,7 @@ @color/cc_attention_negative_color 120dp -