Skip to content

Commit

Permalink
Merge pull request #11936 from nextcloud/migrate-to-media3
Browse files Browse the repository at this point in the history
Migrate to media3 and Immersive mode for video playback
  • Loading branch information
alperozturk96 authored Dec 29, 2023
2 parents 4bd0943 + 9a746c2 commit 76369d4
Show file tree
Hide file tree
Showing 20 changed files with 1,047 additions and 246 deletions.
5 changes: 3 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,9 @@ dependencies {

implementation 'org.conscrypt:conscrypt-android:2.5.2'

implementation "com.google.android.exoplayer:exoplayer:$exoplayerVersion"
implementation "com.google.android.exoplayer:extension-okhttp:$exoplayerVersion"
implementation "androidx.media3:media3-ui:1.2.0"
implementation "androidx.media3:media3-exoplayer:1.2.0"
implementation "androidx.media3:media3-datasource-okhttp:1.2.0"

implementation 'me.zhanghai.android.fastscroll:library:1.2.0'

Expand Down
5 changes: 5 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,11 @@
android:name=".ui.preview.PreviewImageActivity"
android:exported="false"
android:theme="@style/Theme.ownCloud.Overlay" />
<activity
android:name=".ui.preview.PreviewMediaActivity"
android:exported="false"
android:configChanges="orientation|screenLayout|screenSize|keyboardHidden"
android:theme="@style/Theme.ownCloud.Media" />
<service
android:name=".authentication.AccountAuthenticatorService"
android:exported="false">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
import com.owncloud.android.ui.preview.PreviewBitmapActivity;
import com.owncloud.android.ui.preview.PreviewImageActivity;
import com.owncloud.android.ui.preview.PreviewImageFragment;
import com.owncloud.android.ui.preview.PreviewMediaActivity;
import com.owncloud.android.ui.preview.PreviewMediaFragment;
import com.owncloud.android.ui.preview.PreviewTextFileFragment;
import com.owncloud.android.ui.preview.PreviewTextFragment;
Expand Down Expand Up @@ -206,6 +207,9 @@ abstract class ComponentsModule {
@ContributesAndroidInjector
abstract PreviewImageActivity previewImageActivity();

@ContributesAndroidInjector
abstract PreviewMediaActivity previewMediaActivity();

@ContributesAndroidInjector
abstract ReceiveExternalFilesActivity receiveExternalFilesActivity();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ package com.nextcloud.client.media

import android.content.Context
import android.media.MediaPlayer
import com.google.android.exoplayer2.PlaybackException
import androidx.media3.common.PlaybackException
import com.owncloud.android.R

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ package com.nextcloud.client.media
import android.content.Context
import android.content.DialogInterface
import android.view.View
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.PlaybackException
import com.google.android.exoplayer2.Player
import androidx.media3.common.PlaybackException
import androidx.media3.common.Player
import androidx.media3.exoplayer.ExoPlayer
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.owncloud.android.R
import com.owncloud.android.lib.common.utils.Log_OC
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@
package com.nextcloud.client.media

import android.content.Context
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSource
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory
import com.google.android.exoplayer2.upstream.DefaultDataSource
import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi
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.common.NextcloudClient
import com.owncloud.android.MainApp

Expand All @@ -37,6 +39,7 @@ object NextcloudExoPlayer {
* IP versions and certificates.
*
*/
@OptIn(UnstableApi::class)
@JvmStatic
fun createNextcloudExoplayer(context: Context, nextcloudClient: NextcloudClient): ExoPlayer {
val okHttpDataSourceFactory = OkHttpDataSource.Factory(nextcloudClient.client)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
import com.owncloud.android.ui.helpers.UriUploader;
import com.owncloud.android.ui.preview.PreviewImageActivity;
import com.owncloud.android.ui.preview.PreviewImageFragment;
import com.owncloud.android.ui.preview.PreviewMediaActivity;
import com.owncloud.android.ui.preview.PreviewMediaFragment;
import com.owncloud.android.ui.preview.PreviewTextFileFragment;
import com.owncloud.android.ui.preview.PreviewTextFragment;
Expand Down Expand Up @@ -168,7 +169,10 @@
/**
* Displays, what files the user has available in his ownCloud. This is the main view.
*/
public class FileDisplayActivity extends FileActivity implements FileFragment.ContainerActivity, OnEnforceableRefreshListener, SortingOrderDialogFragment.OnSortingOrderListener, SendShareDialog.SendShareDialogDownloader, Injectable {
public class FileDisplayActivity extends FileActivity
implements FileFragment.ContainerActivity,
OnEnforceableRefreshListener, SortingOrderDialogFragment.OnSortingOrderListener,
SendShareDialog.SendShareDialogDownloader, Injectable {

public static final String RESTART = "RESTART";
public static final String ALL_FILES = "ALL_FILES";
Expand Down Expand Up @@ -693,8 +697,8 @@ protected void refreshDetailsFragmentIfVisible(String downloadEvent, String down
// update the file from database, for the local storage path
mWaitingToPreview = getStorageManager().getFileById(mWaitingToPreview.getFileId());

if (PreviewMediaFragment.canBePreviewed(mWaitingToPreview)) {
startMediaPreview(mWaitingToPreview, 0, true, true, true);
if (PreviewMediaActivity.Companion.canBePreviewed(mWaitingToPreview)) {
startMediaPreview(mWaitingToPreview, 0, true, true, true, true);
detailsFragmentChanged = true;
} else if (MimeTypeUtil.isVCard(mWaitingToPreview.getMimeType())) {
startContactListFragment(mWaitingToPreview);
Expand Down Expand Up @@ -1391,7 +1395,7 @@ public void onReceive(Context context, Intent intent) {
if (uploadWasFine) {
OCFile ocFile = getFile();
if (PreviewImageFragment.canBePreviewed(ocFile)) {
startImagePreview(getFile(),true);
startImagePreview(getFile(), true);
} else if (PreviewTextFileFragment.canBePreviewed(ocFile)) {
startTextPreview(ocFile, true);
}
Expand Down Expand Up @@ -1643,10 +1647,7 @@ private void refreshShowDetails() {
OCFile file = ((FileFragment) details).getFile();
if (file != null) {
file = getStorageManager().getFileByPath(file.getRemotePath());
if (details instanceof PreviewMediaFragment) {
// Refresh OCFile of the fragment
((PreviewMediaFragment) details).updateFile(file);
} else if (details instanceof PreviewTextFragment) {
if (details instanceof PreviewTextFragment) {
// Refresh OCFile of the fragment
((PreviewTextFileFragment) details).updateFile(file);
} else {
Expand Down Expand Up @@ -1676,12 +1677,7 @@ private void onRemoveFileOperationFinish(RemoveFileOperation operation, RemoteOp

// check if file is still available, if so do nothing
boolean fileAvailable = getStorageManager().fileExists(removedFile.getFileId());

if (leftFragment instanceof FileFragment && !fileAvailable && removedFile.equals(((FileFragment) leftFragment).getFile())) {
if (leftFragment instanceof PreviewMediaFragment previewMediaFragment) {
previewMediaFragment.stopPreview(true);
onBackPressed();
}
setFile(getStorageManager().getFileById(removedFile.getParentId()));
resetTitleBarAndScrolling();
}
Expand Down Expand Up @@ -1796,7 +1792,7 @@ private void onRenameFileOperationFinish(RenameFileOperation operation, RemoteOp
((PreviewMediaFragment) fileFragment).updateFile(renamedFile);
if (PreviewMediaFragment.canBePreviewed(renamedFile)) {
long position = ((PreviewMediaFragment) fileFragment).getPosition();
startMediaPreview(renamedFile, position, true, true, true);
startMediaPreview(renamedFile, position, true, true, true, false);
} else {
getFileOperationsHelper().openFile(renamedFile);
}
Expand Down Expand Up @@ -2041,15 +2037,19 @@ public void startImagePreview(OCFile file, VirtualFolderType type, boolean showP
* @param startPlaybackPosition Media position where the playback will be started, in milliseconds.
* @param autoplay When 'true', the playback will start without user interactions.
*/
public void startMediaPreview(OCFile file, long startPlaybackPosition, boolean autoplay, boolean showPreview, boolean streamMedia) {
public void startMediaPreview(OCFile file, long startPlaybackPosition, boolean autoplay, boolean showPreview, boolean streamMedia, boolean showInActivity) {
Optional<User> user = getUser();
if (!user.isPresent()) {
return; // not reachable under normal conditions
}
if (showPreview && file.isDown() && !file.isDownloading() || streamMedia) {
configureToolbarForPreview(file);
Fragment mediaFragment = PreviewMediaFragment.newInstance(file, user.get(), startPlaybackPosition, autoplay, false);
setLeftFragment(mediaFragment, false);
if (showInActivity) {
startMediaActivity(file, startPlaybackPosition, autoplay, user);
} else {
configureToolbarForPreview(file);
Fragment mediaFragment = PreviewMediaFragment.newInstance(file, user.get(), startPlaybackPosition, autoplay, false);
setLeftFragment(mediaFragment, false);
}
} else {
Intent previewIntent = new Intent();
previewIntent.putExtra(EXTRA_FILE, file);
Expand All @@ -2060,6 +2060,15 @@ public void startMediaPreview(OCFile file, long startPlaybackPosition, boolean a
}
}

private void startMediaActivity(OCFile file, long startPlaybackPosition, boolean autoplay, Optional<User> user) {
Intent previewMediaIntent = new Intent(this, PreviewMediaActivity.class);
previewMediaIntent.putExtra(PreviewMediaActivity.EXTRA_FILE, file);
previewMediaIntent.putExtra(PreviewMediaActivity.EXTRA_USER, user.get());
previewMediaIntent.putExtra(PreviewMediaActivity.EXTRA_START_POSITION, startPlaybackPosition);
previewMediaIntent.putExtra(PreviewMediaActivity.EXTRA_AUTOPLAY, autoplay);
startActivity(previewMediaIntent);
}

public void configureToolbarForPreview(OCFile file) {
lockScrolling();
super.updateActionBarTitleAndHomeButton(file);
Expand Down Expand Up @@ -2242,7 +2251,7 @@ public void onMessageEvent(SyncEventFinished event) {
if (event.getIntent().getBooleanExtra(TEXT_PREVIEW, false)) {
startTextPreview((OCFile) bundle.get(EXTRA_FILE), true);
} else if (bundle.containsKey(PreviewMediaFragment.EXTRA_START_POSITION)) {
startMediaPreview((OCFile) bundle.get(EXTRA_FILE), (long) bundle.get(PreviewMediaFragment.EXTRA_START_POSITION), (boolean) bundle.get(PreviewMediaFragment.EXTRA_AUTOPLAY), true, true);
startMediaPreview((OCFile) bundle.get(EXTRA_FILE), (long) bundle.get(PreviewMediaFragment.EXTRA_START_POSITION), (boolean) bundle.get(PreviewMediaFragment.EXTRA_AUTOPLAY), true, true, true);
} else if (bundle.containsKey(PreviewImageActivity.EXTRA_VIRTUAL_TYPE)) {
startImagePreview((OCFile) bundle.get(EXTRA_FILE), (VirtualFolderType) bundle.get(PreviewImageActivity.EXTRA_VIRTUAL_TYPE), true);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,13 +155,15 @@ class SetupEncryptionDialogFragment : DialogFragment(), Injectable {
dialog.dismiss()
notifyResult()
}

KEY_EXISTING_USED -> {
decryptPrivateKey(dialog)
}

KEY_GENERATE -> {
generateKey()
}

else -> dialog.dismiss()
}
}
Expand Down Expand Up @@ -376,7 +378,7 @@ class SetupEncryptionDialogFragment : DialogFragment(), Injectable {
binding.encryptionStatus.setText(R.string.end_to_end_encryption_generating_keys)
}

@Suppress("TooGenericExceptionCaught", "TooGenericExceptionThrown", "ReturnCount")
@Suppress("TooGenericExceptionCaught", "TooGenericExceptionThrown", "ReturnCount", "LongMethod")
@Deprecated("Deprecated in Java")
override fun doInBackground(vararg voids: Void?): String {
// - create CSR, push to server, store returned public key in database
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@
import com.owncloud.android.ui.helpers.FileOperationsHelper;
import com.owncloud.android.ui.interfaces.OCFileListFragmentInterface;
import com.owncloud.android.ui.preview.PreviewImageFragment;
import com.owncloud.android.ui.preview.PreviewMediaFragment;
import com.owncloud.android.ui.preview.PreviewMediaActivity;
import com.owncloud.android.ui.preview.PreviewTextFileFragment;
import com.owncloud.android.utils.DisplayUtils;
import com.owncloud.android.utils.EncryptionUtils;
Expand All @@ -139,13 +139,15 @@
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
import androidx.annotation.StringRes;
import androidx.appcompat.app.ActionBar;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.content.ContextCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.media3.common.util.UnstableApi;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
Expand Down Expand Up @@ -977,6 +979,7 @@ public boolean onLongItemClicked(OCFile file) {
}

@Override
@OptIn(markerClass = UnstableApi.class)
public void onItemClicked(OCFile file) {
((FileActivity) mContainerActivity).checkInternetConnection();

Expand Down Expand Up @@ -1068,10 +1071,10 @@ public void onItemClicked(OCFile file) {
setFabVisible(false);
((FileDisplayActivity) mContainerActivity).startTextPreview(file, false);
} else if (file.isDown()) {
if (PreviewMediaFragment.canBePreviewed(file)) {
if (PreviewMediaActivity.Companion.canBePreviewed(file)) {
// media preview
setFabVisible(false);
((FileDisplayActivity) mContainerActivity).startMediaPreview(file, 0, true, true, false);
((FileDisplayActivity) mContainerActivity).startMediaPreview(file, 0, true, true, false, true);
} else {
mContainerActivity.getFileOperationsHelper().openFile(file);
}
Expand All @@ -1081,10 +1084,10 @@ public void onItemClicked(OCFile file) {
OCCapability capability = mContainerActivity.getStorageManager()
.getCapability(account.getAccountName());

if (PreviewMediaFragment.canBePreviewed(file) && !file.isEncrypted()) {
if (PreviewMediaActivity.Companion.canBePreviewed(file) && !file.isEncrypted()) {
// stream media preview on >= NC14
setFabVisible(false);
((FileDisplayActivity) mContainerActivity).startMediaPreview(file, 0, true, true, true);
((FileDisplayActivity) mContainerActivity).startMediaPreview(file, 0, true, true, true, true);
} else if (editorUtils.isEditorAvailable(accountManager.getUser(),
file.getMimeType()) &&
!file.isEncrypted()) {
Expand Down Expand Up @@ -1822,8 +1825,7 @@ public void onMessageEvent(FileLockEvent event) {
}

/**
* Theme default action bar according to provided parameters.
* Replaces back arrow with hamburger menu icon.
* Theme default action bar according to provided parameters. Replaces back arrow with hamburger menu icon.
*
* @param title string res id of title to be shown in action bar
*/
Expand All @@ -1834,7 +1836,7 @@ protected void setTitle(@StringRes final int title) {
/**
* Theme default action bar according to provided parameters.
*
* @param title title to be shown in action bar
* @param title title to be shown in action bar
* @param showBackAsMenu iff true replace back arrow with hamburger menu icon
*/
protected void setTitle(final String title, Boolean showBackAsMenu) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/
package com.owncloud.android.ui.preview;

import android.content.Intent;
import android.util.SparseArray;
import android.view.ViewGroup;

Expand All @@ -38,9 +39,11 @@
import javax.annotation.Nullable;

import androidx.annotation.NonNull;
import androidx.annotation.OptIn;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.media3.common.util.UnstableApi;

/**
* Adapter class that provides Fragment instances
Expand All @@ -59,10 +62,10 @@ public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
/**
* Constructor
*
* @param fragmentManager {@link FragmentManager} instance that will handle
* the {@link Fragment}s provided by the adapter.
* @param parentFolder Folder where images will be searched for.
* @param storageManager Bridge to database.
* @param fragmentManager {@link FragmentManager} instance that will handle the {@link Fragment}s provided by the
* adapter.
* @param parentFolder Folder where images will be searched for.
* @param storageManager Bridge to database.
*/
public PreviewImagePagerAdapter(FragmentManager fragmentManager,
OCFile selectedFile,
Expand Down Expand Up @@ -96,8 +99,8 @@ public PreviewImagePagerAdapter(FragmentManager fragmentManager,
/**
* Constructor
*
* @param fragmentManager {@link FragmentManager} instance that will handle
* the {@link Fragment}s provided by the adapter.
* @param fragmentManager {@link FragmentManager} instance that will handle the {@link Fragment}s provided by the
* adapter.
* @param type Type of virtual folder, e.g. favorite or photos
* @param storageManager Bridge to database.
*/
Expand All @@ -113,7 +116,7 @@ public PreviewImagePagerAdapter(FragmentManager fragmentManager,
if (type == null) {
throw new IllegalArgumentException("NULL parent folder");
}
if(type == VirtualFolderType.NONE){
if (type == VirtualFolderType.NONE) {
throw new IllegalArgumentException("NONE virtual folder type");
}
if (storageManager == null) {
Expand Down Expand Up @@ -155,6 +158,7 @@ private void addVideoOfLivePhoto(OCFile file) {
}

@NonNull
@OptIn(markerClass = UnstableApi.class)
public Fragment getItem(int i) {
OCFile file = getFileAt(i);
Fragment fragment;
Expand Down Expand Up @@ -242,7 +246,7 @@ public Object instantiateItem(@NonNull ViewGroup container, int position) {
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
mCachedFragments.remove(position);
super.destroyItem(container, position, object);
super.destroyItem(container, position, object);
}


Expand Down
Loading

0 comments on commit 76369d4

Please sign in to comment.