Pārlūkot izejas kodu

remove audio support in media fragment

Signed-off-by: parneet-guraya <gurayaparneet@gmail.com>
parneet-guraya 9 mēneši atpakaļ
vecāks
revīzija
01a9042913

+ 10 - 8
app/src/main/AndroidManifest.xml

@@ -127,14 +127,7 @@
         android:usesCleartextTraffic="true"
         tools:ignore="UnusedAttribute"
         tools:replace="android:allowBackup">
-        <service
-            android:name="com.nextcloud.client.media.BackgroundPlayerService"
-            android:foregroundServiceType="mediaPlayback"
-            android:exported="true">
-            <intent-filter>
-                <action android:name="androidx.media3.session.MediaSessionService"/>
-            </intent-filter>
-        </service>
+
         <meta-data android:name="android.content.APP_RESTRICTIONS"
             android:resource="@xml/app_config" />
 
@@ -357,6 +350,15 @@
             android:exported="false"
             android:theme="@style/Theme.ownCloud.Media" />
 
+        <service
+            android:name="com.nextcloud.client.media.BackgroundPlayerService"
+            android:foregroundServiceType="mediaPlayback"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="androidx.media3.session.MediaSessionService"/>
+            </intent-filter>
+        </service>
+
         <service
             android:name=".authentication.AccountAuthenticatorService"
             android:exported="false">

+ 0 - 2
app/src/main/java/com/nextcloud/client/di/AppComponent.java

@@ -18,7 +18,6 @@ import com.nextcloud.client.jobs.JobsModule;
 import com.nextcloud.client.jobs.download.FileDownloadHelper;
 import com.nextcloud.client.jobs.upload.FileUploadHelper;
 import com.nextcloud.client.media.BackgroundPlayerService;
-import com.nextcloud.client.media.CustomExoPlayer;
 import com.nextcloud.client.network.NetworkModule;
 import com.nextcloud.client.onboarding.OnboardingModule;
 import com.nextcloud.client.preferences.PreferencesModule;
@@ -56,7 +55,6 @@ public interface AppComponent {
     void inject(MainApp app);
 
     void inject(MediaControlView mediaControlView);
-    void inject(CustomExoPlayer customExoPlayer);
     void inject(BackgroundPlayerService backgroundPlayerService);
 
     void inject(ThemeableSwitchPreference switchPreference);

+ 0 - 2
app/src/main/java/com/nextcloud/client/di/ComponentsModule.java

@@ -18,8 +18,6 @@ import com.nextcloud.client.jobs.upload.FileUploadHelper;
 import com.nextcloud.client.logger.ui.LogsActivity;
 import com.nextcloud.client.logger.ui.LogsViewModel;
 import com.nextcloud.client.media.BackgroundPlayerService;
-import com.nextcloud.client.media.CustomExoPlayer;
-import com.nextcloud.client.media.NextcloudExoPlayer;
 import com.nextcloud.client.media.PlayerService;
 import com.nextcloud.client.migrations.Migrations;
 import com.nextcloud.client.onboarding.FirstRunActivity;

+ 1 - 3
app/src/main/java/com/nextcloud/client/media/BackgroundPlayerService.kt

@@ -1,7 +1,7 @@
 /*
  * Nextcloud - Android Client
  *
- * SPDX-FileCopyrightText: 2024 Your Name <your@email.com>
+ * SPDX-FileCopyrightText: 2024 Parneet Singh <gurayaparneet@gmail.com>
  * SPDX-License-Identifier: AGPL-3.0-or-later
  */
 
@@ -46,7 +46,6 @@ class BackgroundPlayerService : MediaSessionService(), Injectable {
             }
             nextcloudClient?.let {
                 exoPlayer = createNextcloudExoplayer(this@BackgroundPlayerService, nextcloudClient)
-                println(exoPlayer)
                 mediaSession =
                     MediaSession.Builder(applicationContext, exoPlayer).setCallback(object : MediaSession.Callback {
                         override fun onDisconnected(session: MediaSession, controller: MediaSession.ControllerInfo) {
@@ -54,7 +53,6 @@ class BackgroundPlayerService : MediaSessionService(), Injectable {
                         }
                     }).build()
             }
-            println("created client $nextcloudClient")
         }
     }
 

+ 0 - 22
app/src/main/java/com/nextcloud/client/media/CustomExoPlayer.kt

@@ -1,22 +0,0 @@
-/*
- * Nextcloud - Android Client
- *
- * SPDX-FileCopyrightText: 2024 Your Name <your@email.com>
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-
-package com.nextcloud.client.media
-
-import android.accounts.AccountManager
-import android.content.Context
-import androidx.media3.exoplayer.ExoPlayer
-import com.nextcloud.client.account.UserAccountManager
-import com.nextcloud.client.account.UserAccountManagerImpl
-import com.nextcloud.client.di.Injectable
-import com.nextcloud.client.network.ClientFactory
-import com.owncloud.android.MainApp
-import javax.inject.Inject
-
-class CustomExoPlayer  {
-
-}

+ 0 - 4
app/src/main/java/com/nextcloud/client/media/NextcloudExoPlayer.kt

@@ -15,11 +15,8 @@ import androidx.media3.datasource.DefaultDataSource
 import androidx.media3.datasource.okhttp.OkHttpDataSource
 import androidx.media3.exoplayer.ExoPlayer
 import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
-import com.nextcloud.client.account.UserAccountManager
-import com.nextcloud.client.network.ClientFactory
 import com.nextcloud.common.NextcloudClient
 import com.owncloud.android.MainApp
-import javax.inject.Inject
 
 object NextcloudExoPlayer {
     private const val FIVE_SECONDS_IN_MILLIS = 5000L
@@ -48,5 +45,4 @@ object NextcloudExoPlayer {
             .setSeekForwardIncrementMs(FIVE_SECONDS_IN_MILLIS)
             .build()
     }
-
 }

+ 2 - 9
app/src/main/java/com/owncloud/android/media/MediaControlView.kt

@@ -104,7 +104,6 @@ class MediaControlView(context: Context, attrs: AttributeSet?) :
      */
     private fun disableUnsupportedButtons() {
         try {
-            //TODO: should we check for nullability && see if we need try catch block
             if (playerControl!!.isCommandAvailable(Player.COMMAND_PLAY_PAUSE).not()) {
                 binding.playBtn.isEnabled = false
             }
@@ -275,7 +274,6 @@ class MediaControlView(context: Context, attrs: AttributeSet?) :
 
     @Suppress("MagicNumber")
     override fun onClick(v: View) {
-        var pos: Long
 
         playerControl?.let { playerControl ->
             val playing = playerControl.playWhenReady
@@ -287,9 +285,7 @@ class MediaControlView(context: Context, attrs: AttributeSet?) :
                 }
 
                 R.id.rewindBtn -> {
-                    pos = playerControl.currentPosition
-                    pos -= 5000
-                    playerControl.seekTo(pos)
+                    playerControl.seekBack()
                     if (!playing) {
                         playerControl.pause() // necessary in some 2.3.x devices
                     }
@@ -297,10 +293,7 @@ class MediaControlView(context: Context, attrs: AttributeSet?) :
                 }
 
                 R.id.forwardBtn -> {
-                    pos = playerControl.currentPosition
-                    pos += 15000
-                    playerControl.seekTo(pos)
-
+                    playerControl.seekForward()
                     if (!playing) {
                         playerControl.pause() // necessary in some 2.3.x devices
                     }

+ 0 - 1
app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java

@@ -1832,7 +1832,6 @@ public class FileDisplayActivity extends FileActivity
                     ((PreviewMediaFragment) fileFragment).updateFile(renamedFile);
                     if (PreviewMediaFragment.canBePreviewed(renamedFile)) {
                         long position = ((PreviewMediaFragment) fileFragment).getPosition();
-                        System.out.println("Start Fragment Media Preview");
                         startMediaPreview(renamedFile, position, true, true, true, false);
                     } else {
                         getFileOperationsHelper().openFile(renamedFile);

+ 9 - 17
app/src/main/java/com/owncloud/android/ui/preview/PreviewMediaActivity.kt

@@ -59,7 +59,6 @@ import com.nextcloud.client.jobs.download.FileDownloadHelper
 import com.nextcloud.client.media.BackgroundPlayerService
 import com.nextcloud.client.media.ExoplayerListener
 import com.nextcloud.client.media.NextcloudExoPlayer.createNextcloudExoplayer
-import com.nextcloud.client.media.PlayerServiceConnection
 import com.nextcloud.client.network.ClientFactory
 import com.nextcloud.client.network.ClientFactory.CreationException
 import com.nextcloud.common.NextcloudClient
@@ -115,8 +114,6 @@ class PreviewMediaActivity :
     private var user: User? = null
     private var savedPlaybackPosition: Long = 0
     private var autoplay = true
-    private val prepared = false
-    private var mediaPlayerServiceConnection: PlayerServiceConnection? = null
     private var streamUri: Uri? = null
 
     @Inject
@@ -150,7 +147,6 @@ class PreviewMediaActivity :
         WindowCompat.setDecorFitsSystemWindows(window, false)
         applyWindowInsets()
         initArguments(savedInstanceState)
-        mediaPlayerServiceConnection = PlayerServiceConnection(this)
         showMediaTypeViews()
         configureSystemBars()
         emptyListView = binding.emptyView.emptyListView
@@ -286,17 +282,19 @@ class PreviewMediaActivity :
 
     private fun saveMediaInstanceState(bundle: Bundle) {
         bundle.run {
-            if (MimeTypeUtil.isVideo(file) && audioMediaController != null) {
+            if (MimeTypeUtil.isVideo(file)) {
+                videoPlayer?.let {
+                    savedPlaybackPosition = it.currentPosition
+                    autoplay = it.playWhenReady
+                }
+            } else {
                 audioMediaController?.let {
                     savedPlaybackPosition = it.currentPosition
-                    autoplay = it.isPlaying
+                    autoplay = it.playWhenReady
                 }
-                putLong(EXTRA_PLAY_POSITION, savedPlaybackPosition)
-                putBoolean(EXTRA_PLAYING, autoplay)
-            } else if (mediaPlayerServiceConnection != null && mediaPlayerServiceConnection!!.isConnected) {
-                putInt(EXTRA_PLAY_POSITION, mediaPlayerServiceConnection!!.currentPosition)
-                putBoolean(EXTRA_PLAYING, mediaPlayerServiceConnection!!.isPlaying)
             }
+            putLong(EXTRA_PLAY_POSITION, savedPlaybackPosition)
+            putBoolean(EXTRA_PLAYING, autoplay)
         }
     }
 
@@ -306,7 +304,6 @@ class PreviewMediaActivity :
         Log_OC.v(TAG, "onStart")
 
         if (MimeTypeUtil.isVideo(file)) {
-            //TODO: should we somehow release any previous audio sessions?
             initializeVideoPlayer()
         }
     }
@@ -467,9 +464,6 @@ class PreviewMediaActivity :
         }
     }
 
-    private fun stopAudio() {
-        mediaPlayerServiceConnection?.stop()
-    }
 
     override fun onCreateOptionsMenu(menu: Menu?): Boolean {
         menuInflater.inflate(R.menu.custom_menu_placeholder, menu)
@@ -783,8 +777,6 @@ class PreviewMediaActivity :
     }
 
     private fun stopPreview(stopAudio: Boolean) {
-        //TODO: stop removes the media item attached but not release the player
-        // do we want to keep this behaviour or release the player too just like in onStop?
         if (MimeTypeUtil.isAudio(file) && stopAudio) {
             audioMediaController?.pause()
         } else if (MimeTypeUtil.isVideo(file)) {

+ 17 - 136
app/src/main/java/com/owncloud/android/ui/preview/PreviewMediaFragment.kt

@@ -17,8 +17,6 @@ import android.content.Context
 import android.content.Intent
 import android.content.res.Configuration
 import android.content.res.Resources
-import android.graphics.BitmapFactory
-import android.media.MediaMetadataRetriever
 import android.net.Uri
 import android.os.AsyncTask
 import android.os.Bundle
@@ -34,8 +32,6 @@ import android.view.View.OnTouchListener
 import android.view.ViewGroup
 import androidx.annotation.OptIn
 import androidx.annotation.StringRes
-import androidx.appcompat.content.res.AppCompatResources
-import androidx.core.graphics.drawable.DrawableCompat
 import androidx.core.view.MenuHost
 import androidx.core.view.MenuProvider
 import androidx.drawerlayout.widget.DrawerLayout
@@ -50,7 +46,6 @@ import com.nextcloud.client.jobs.BackgroundJobManager
 import com.nextcloud.client.jobs.download.FileDownloadHelper.Companion.instance
 import com.nextcloud.client.media.ExoplayerListener
 import com.nextcloud.client.media.NextcloudExoPlayer.createNextcloudExoplayer
-import com.nextcloud.client.media.PlayerServiceConnection
 import com.nextcloud.client.network.ClientFactory
 import com.nextcloud.client.network.ClientFactory.CreationException
 import com.nextcloud.common.NextcloudClient
@@ -61,7 +56,6 @@ import com.owncloud.android.MainApp
 import com.owncloud.android.R
 import com.owncloud.android.databinding.FragmentPreviewMediaBinding
 import com.owncloud.android.datamodel.OCFile
-import com.owncloud.android.datamodel.ThumbnailsCacheManager
 import com.owncloud.android.files.StreamMediaFileOperation
 import com.owncloud.android.lib.common.OwnCloudClient
 import com.owncloud.android.lib.common.utils.Log_OC
@@ -105,7 +99,6 @@ class PreviewMediaFragment : FileFragment(), OnTouchListener, Injectable {
     private var autoplay = true
     private var isLivePhoto = false
     private val prepared = false
-    private var mediaPlayerServiceConnection: PlayerServiceConnection? = null
 
     private var videoUri: Uri? = null
 
@@ -129,8 +122,6 @@ class PreviewMediaFragment : FileFragment(), OnTouchListener, Injectable {
         arguments?.let {
             initArguments(it)
         }
-
-        mediaPlayerServiceConnection = PlayerServiceConnection(requireContext())
     }
 
     override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
@@ -150,10 +141,6 @@ class PreviewMediaFragment : FileFragment(), OnTouchListener, Injectable {
 
         checkArgumentsAfterViewCreation(savedInstanceState)
 
-        if (file != null) {
-            prepareExoPlayerView()
-        }
-
         toggleDrawerLockMode(containerActivity, DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
         addMenuHost()
     }
@@ -198,62 +185,6 @@ class PreviewMediaFragment : FileFragment(), OnTouchListener, Injectable {
         binding.progress.visibility = View.GONE
     }
 
-    /**
-     * tries to read the cover art from the audio file and sets it as cover art.
-     *
-     * @param file audio file with potential cover art
-     */
-
-    @Suppress("TooGenericExceptionCaught")
-    private fun extractAndSetCoverArt(file: OCFile) {
-        if (!MimeTypeUtil.isAudio(file)) return
-
-        if (file.storagePath == null) {
-            setThumbnailForAudio(file)
-        } else {
-            try {
-                val mmr = MediaMetadataRetriever().apply {
-                    setDataSource(file.storagePath)
-                }
-
-                val data = mmr.embeddedPicture
-                if (data != null) {
-                    val bitmap = BitmapFactory.decodeByteArray(data, 0, data.size)
-                    binding.imagePreview.setImageBitmap(bitmap) // associated cover art in bitmap
-                } else {
-                    setThumbnailForAudio(file)
-                }
-            } catch (t: Throwable) {
-                setGenericThumbnail()
-            }
-        }
-    }
-
-    private fun setThumbnailForAudio(file: OCFile) {
-        val thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
-            ThumbnailsCacheManager.PREFIX_THUMBNAIL + file.remoteId
-        )
-
-        if (thumbnail != null) {
-            binding.imagePreview.setImageBitmap(thumbnail)
-        } else {
-            setGenericThumbnail()
-        }
-    }
-
-    /**
-     * Set generic icon (logo) as placeholder for thumbnail in preview.
-     */
-    private fun setGenericThumbnail() {
-        AppCompatResources.getDrawable(requireContext(), R.drawable.logo)?.let { logo ->
-            if (!resources.getBoolean(R.bool.is_branded_client)) {
-                // only colour logo of non-branded client
-                DrawableCompat.setTint(logo, resources.getColor(R.color.primary, requireContext().theme))
-            }
-            binding.imagePreview.setImageDrawable(logo)
-        }
-    }
-
     override fun onSaveInstanceState(outState: Bundle) {
         super.onSaveInstanceState(outState)
         file.logFileSize(TAG)
@@ -263,15 +194,11 @@ class PreviewMediaFragment : FileFragment(), OnTouchListener, Injectable {
             putParcelable(EXTRA_FILE, file)
             putParcelable(EXTRA_USER, user)
 
-            if (MimeTypeUtil.isVideo(file) && exoPlayer != null) {
-                savedPlaybackPosition = exoPlayer?.currentPosition ?: 0L
-                autoplay = exoPlayer?.isPlaying ?: false
-                putLong(EXTRA_PLAY_POSITION, savedPlaybackPosition)
-                putBoolean(EXTRA_PLAYING, autoplay)
-            } else if (mediaPlayerServiceConnection != null && mediaPlayerServiceConnection?.isConnected == true) {
-                putInt(EXTRA_PLAY_POSITION, mediaPlayerServiceConnection?.currentPosition ?: 0)
-                putBoolean(EXTRA_PLAYING, mediaPlayerServiceConnection?.isPlaying ?: false)
-            }
+            savedPlaybackPosition = exoPlayer?.currentPosition ?: 0L
+            autoplay = exoPlayer?.isPlaying ?: false
+            putLong(EXTRA_PLAY_POSITION, savedPlaybackPosition)
+            putBoolean(EXTRA_PLAYING, autoplay)
+
         }
     }
 
@@ -285,22 +212,11 @@ class PreviewMediaFragment : FileFragment(), OnTouchListener, Injectable {
             Log_OC.d(TAG, "File is null or fragment not attached to a context.")
             return
         }
-
-        mediaPlayerServiceConnection?.bind()
-
-        if (MimeTypeUtil.isAudio(file)) {
-            prepareForAudio()
-        } else if (MimeTypeUtil.isVideo(file)) {
-            prepareForVideo(context ?: MainApp.getAppContext())
-        }
+        prepareForVideo(context ?: MainApp.getAppContext())
     }
 
     @Suppress("DEPRECATION", "TooGenericExceptionCaught")
     private fun prepareForVideo(context: Context) {
-        if (mediaPlayerServiceConnection?.isConnected == true) {
-            // always stop player
-            stopAudio()
-        }
         if (exoPlayer != null) {
             playVideo()
         } else {
@@ -329,12 +245,13 @@ class PreviewMediaFragment : FileFragment(), OnTouchListener, Injectable {
         }
     }
 
-    private fun prepareForAudio() {
-        binding.mediaController.setMediaPlayer(null)
-        binding.mediaController.visibility = View.VISIBLE
-        mediaPlayerServiceConnection?.start(user!!, file, autoplay, savedPlaybackPosition)
-        binding.emptyView.emptyListView.visibility = View.GONE
-        binding.progress.visibility = View.GONE
+    private fun releaseVideoPlayer() {
+        exoPlayer?.let {
+            savedPlaybackPosition = it.currentPosition
+            autoplay = it.playWhenReady
+            it.release()
+        }
+        exoPlayer = null
     }
 
     private fun goBackToLivePhoto() {
@@ -346,17 +263,6 @@ class PreviewMediaFragment : FileFragment(), OnTouchListener, Injectable {
         requireActivity().supportFragmentManager.popBackStack()
     }
 
-    private fun prepareExoPlayerView() {
-        if (MimeTypeUtil.isVideo(file)) {
-            binding.exoplayerView.visibility = View.VISIBLE
-            binding.imagePreview.visibility = View.GONE
-        } else {
-            binding.exoplayerView.visibility = View.GONE
-            binding.imagePreview.visibility = View.VISIBLE
-            extractAndSetCoverArt(file)
-        }
-    }
-
     private fun showActionBar() {
         val currentActivity: Activity = requireActivity()
         if (currentActivity is PreviewImageActivity) {
@@ -374,10 +280,6 @@ class PreviewMediaFragment : FileFragment(), OnTouchListener, Injectable {
         }
     }
 
-    private fun stopAudio() {
-        mediaPlayerServiceConnection?.stop()
-    }
-
     private fun addMenuHost() {
         val menuHost: MenuHost = requireActivity()
 
@@ -490,12 +392,12 @@ class PreviewMediaFragment : FileFragment(), OnTouchListener, Injectable {
     }
 
     private fun seeDetails() {
-        stopPreview(false)
+        releaseVideoPlayer()
         containerActivity.showDetails(file)
     }
 
     private fun sendShareFile() {
-        stopPreview(false)
+        releaseVideoPlayer()
         containerActivity.fileOperationsHelper.sendShareFile(file)
     }
 
@@ -583,19 +485,7 @@ class PreviewMediaFragment : FileFragment(), OnTouchListener, Injectable {
     }
 
     override fun onStop() {
-        Log_OC.v(TAG, "onStop")
-        val file = file
-
-        if (MimeTypeUtil.isAudio(file) && mediaPlayerServiceConnection?.isPlaying == false) {
-            stopAudio()
-        } else if (MimeTypeUtil.isVideo(file) && exoPlayer != null && exoPlayer?.isPlaying == true) {
-            savedPlaybackPosition = exoPlayer?.currentPosition ?: 0L
-            exoPlayer?.pause()
-        }
-
-        mediaPlayerServiceConnection?.unbind()
-        toggleDrawerLockMode(containerActivity, DrawerLayout.LOCK_MODE_UNLOCKED)
-
+        releaseVideoPlayer()
         super.onStop()
     }
 
@@ -641,17 +531,8 @@ class PreviewMediaFragment : FileFragment(), OnTouchListener, Injectable {
      * Opens the previewed file with an external application.
      */
     private fun openFile() {
-        stopPreview(true)
-        containerActivity.fileOperationsHelper.openFile(file)
-    }
 
-    private fun stopPreview(stopAudio: Boolean) {
-        if (stopAudio && mediaPlayerServiceConnection != null) {
-            mediaPlayerServiceConnection?.stop()
-        } else if (exoPlayer != null) {
-            savedPlaybackPosition = exoPlayer?.currentPosition ?: 0L
-            exoPlayer?.stop()
-        }
+        containerActivity.fileOperationsHelper.openFile(file)
     }
 
     val position: Long

+ 1 - 3
app/src/main/res/layout/activity_preview_media.xml

@@ -65,9 +65,7 @@
 
     <FrameLayout
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:visibility="gone"
-        >
+        android:layout_height="match_parent">
 
         <include
             android:id="@+id/empty_view"

+ 0 - 17
app/src/main/res/layout/fragment_preview_media.xml

@@ -18,15 +18,6 @@
     android:gravity="center"
     tools:context=".ui.preview.PreviewMediaFragment">
 
-    <ImageView
-        android:id="@+id/image_preview"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:layout_margin="@dimen/standard_margin"
-        android:contentDescription="@string/preview_image_description"
-        android:src="@drawable/logo" />
-
     <androidx.media3.ui.PlayerView
         android:id="@+id/exoplayer_view"
         android:layout_width="match_parent"
@@ -34,14 +25,6 @@
         android:layout_gravity="center"
         app:show_buffering="always" />
 
-    <com.owncloud.android.media.MediaControlView
-        android:id="@+id/media_controller"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_alignParentBottom="true"
-        android:layout_margin="@dimen/standard_margin"
-        android:visibility="gone" />
-
     <FrameLayout
         android:id="@+id/progress"
         android:layout_width="match_parent"