mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-30 13:35:18 +00:00
Merge pull request #1481 from bemusementpark/s1889
[SES-1889] Fix IndexOutOfBounds in MediaPreview
This commit is contained in:
commit
34baa9dc89
@ -21,6 +21,7 @@ import android.annotation.TargetApi;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
import android.database.CursorIndexOutOfBoundsException;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@ -145,6 +146,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
|||||||
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
|
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
private MediaItemAdapter adapter;
|
||||||
|
|
||||||
public static Intent getPreviewIntent(Context context, MediaPreviewArgs args) {
|
public static Intent getPreviewIntent(Context context, MediaPreviewArgs args) {
|
||||||
return getPreviewIntent(context, args.getSlide(), args.getMmsRecord(), args.getThread());
|
return getPreviewIntent(context, args.getSlide(), args.getMmsRecord(), args.getThread());
|
||||||
@ -217,13 +219,6 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
|||||||
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
|
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(VERSION_CODES.JELLY_BEAN)
|
|
||||||
private void setFullscreenIfPossible() {
|
|
||||||
if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
|
|
||||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onModified(Recipient recipient) {
|
public void onModified(Recipient recipient) {
|
||||||
Util.runOnMain(this::updateActionBar);
|
Util.runOnMain(this::updateActionBar);
|
||||||
@ -285,9 +280,6 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
|||||||
mediaPager = findViewById(R.id.media_pager);
|
mediaPager = findViewById(R.id.media_pager);
|
||||||
mediaPager.setOffscreenPageLimit(1);
|
mediaPager.setOffscreenPageLimit(1);
|
||||||
|
|
||||||
viewPagerListener = new ViewPagerListener();
|
|
||||||
mediaPager.addOnPageChangeListener(viewPagerListener);
|
|
||||||
|
|
||||||
albumRail = findViewById(R.id.media_preview_album_rail);
|
albumRail = findViewById(R.id.media_preview_album_rail);
|
||||||
albumRailAdapter = new MediaRailAdapter(GlideApp.with(this), this, false);
|
albumRailAdapter = new MediaRailAdapter(GlideApp.with(this), this, false);
|
||||||
|
|
||||||
@ -378,7 +370,8 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
|||||||
if (conversationRecipient != null) {
|
if (conversationRecipient != null) {
|
||||||
getSupportLoaderManager().restartLoader(0, null, this);
|
getSupportLoaderManager().restartLoader(0, null, this);
|
||||||
} else {
|
} else {
|
||||||
mediaPager.setAdapter(new SingleItemPagerAdapter(this, GlideApp.with(this), getWindow(), initialMediaUri, initialMediaType, initialMediaSize));
|
adapter = new SingleItemPagerAdapter(this, GlideApp.with(this), getWindow(), initialMediaUri, initialMediaType, initialMediaSize);
|
||||||
|
mediaPager.setAdapter(adapter);
|
||||||
|
|
||||||
if (initialCaption != null) {
|
if (initialCaption != null) {
|
||||||
detailsContainer.setVisibility(View.VISIBLE);
|
detailsContainer.setVisibility(View.VISIBLE);
|
||||||
@ -506,13 +499,8 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
|||||||
}
|
}
|
||||||
|
|
||||||
private @Nullable MediaItem getCurrentMediaItem() {
|
private @Nullable MediaItem getCurrentMediaItem() {
|
||||||
MediaItemAdapter adapter = (MediaItemAdapter)mediaPager.getAdapter();
|
if (adapter == null) return null;
|
||||||
|
return adapter.getMediaItemFor(mediaPager.getCurrentItem());
|
||||||
if (adapter != null) {
|
|
||||||
return adapter.getMediaItemFor(mediaPager.getCurrentItem());
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isContentTypeSupported(final String contentType) {
|
public static boolean isContentTypeSupported(final String contentType) {
|
||||||
@ -526,23 +514,28 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadFinished(@NonNull Loader<Pair<Cursor, Integer>> loader, @Nullable Pair<Cursor, Integer> data) {
|
public void onLoadFinished(@NonNull Loader<Pair<Cursor, Integer>> loader, @Nullable Pair<Cursor, Integer> data) {
|
||||||
if (data != null) {
|
if (data == null) return;
|
||||||
CursorPagerAdapter adapter = new CursorPagerAdapter(this, GlideApp.with(this), getWindow(), data.first, data.second, leftIsRecent);
|
|
||||||
mediaPager.setAdapter(adapter);
|
|
||||||
adapter.setActive(true);
|
|
||||||
|
|
||||||
viewModel.setCursor(this, data.first, leftIsRecent);
|
mediaPager.removeOnPageChangeListener(viewPagerListener);
|
||||||
|
|
||||||
if (restartItem >= 0 || data.second >= 0) {
|
adapter = new CursorPagerAdapter(this, GlideApp.with(this), getWindow(), data.first, data.second, leftIsRecent);
|
||||||
int item = restartItem >= 0 ? restartItem : data.second;
|
mediaPager.setAdapter(adapter);
|
||||||
mediaPager.setCurrentItem(item);
|
|
||||||
|
|
||||||
if (item == 0) {
|
viewModel.setCursor(this, data.first, leftIsRecent);
|
||||||
viewPagerListener.onPageSelected(0);
|
|
||||||
}
|
int item = restartItem >= 0 && restartItem < adapter.getCount() ? restartItem : Math.max(Math.min(data.second, adapter.getCount() - 1), 0);
|
||||||
} else {
|
|
||||||
Log.w(TAG, "one of restartItem "+restartItem+" and data.second "+data.second+" would cause OOB exception");
|
viewPagerListener = new ViewPagerListener();
|
||||||
}
|
mediaPager.addOnPageChangeListener(viewPagerListener);
|
||||||
|
|
||||||
|
try {
|
||||||
|
mediaPager.setCurrentItem(item);
|
||||||
|
} catch (CursorIndexOutOfBoundsException e) {
|
||||||
|
throw new RuntimeException("restartItem = " + restartItem + ", data.second = " + data.second + " leftIsRecent = " + leftIsRecent, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item == 0) {
|
||||||
|
viewPagerListener.onPageSelected(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -560,26 +553,26 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
|||||||
if (currentPage != -1 && currentPage != position) onPageUnselected(currentPage);
|
if (currentPage != -1 && currentPage != position) onPageUnselected(currentPage);
|
||||||
currentPage = position;
|
currentPage = position;
|
||||||
|
|
||||||
MediaItemAdapter adapter = (MediaItemAdapter)mediaPager.getAdapter();
|
if (adapter == null) return;
|
||||||
|
|
||||||
if (adapter != null) {
|
MediaItem item = adapter.getMediaItemFor(position);
|
||||||
MediaItem item = adapter.getMediaItemFor(position);
|
if (item.recipient != null) item.recipient.addListener(MediaPreviewActivity.this);
|
||||||
if (item.recipient != null) item.recipient.addListener(MediaPreviewActivity.this);
|
viewModel.setActiveAlbumRailItem(MediaPreviewActivity.this, position);
|
||||||
viewModel.setActiveAlbumRailItem(MediaPreviewActivity.this, position);
|
updateActionBar();
|
||||||
updateActionBar();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void onPageUnselected(int position) {
|
public void onPageUnselected(int position) {
|
||||||
MediaItemAdapter adapter = (MediaItemAdapter)mediaPager.getAdapter();
|
if (adapter == null) return;
|
||||||
|
|
||||||
if (adapter != null) {
|
try {
|
||||||
MediaItem item = adapter.getMediaItemFor(position);
|
MediaItem item = adapter.getMediaItemFor(position);
|
||||||
if (item.recipient != null) item.recipient.removeListener(MediaPreviewActivity.this);
|
if (item.recipient != null) item.recipient.removeListener(MediaPreviewActivity.this);
|
||||||
|
} catch (CursorIndexOutOfBoundsException e) {
|
||||||
adapter.pause(position);
|
throw new RuntimeException("position = " + position + " leftIsRecent = " + leftIsRecent, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adapter.pause(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -593,7 +586,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SingleItemPagerAdapter extends PagerAdapter implements MediaItemAdapter {
|
private static class SingleItemPagerAdapter extends MediaItemAdapter {
|
||||||
|
|
||||||
private final GlideRequests glideRequests;
|
private final GlideRequests glideRequests;
|
||||||
private final Window window;
|
private final Window window;
|
||||||
@ -665,7 +658,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CursorPagerAdapter extends PagerAdapter implements MediaItemAdapter {
|
private static class CursorPagerAdapter extends MediaItemAdapter {
|
||||||
|
|
||||||
private final WeakHashMap<Integer, MediaView> mediaViews = new WeakHashMap<>();
|
private final WeakHashMap<Integer, MediaView> mediaViews = new WeakHashMap<>();
|
||||||
|
|
||||||
@ -675,7 +668,6 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
|||||||
private final Cursor cursor;
|
private final Cursor cursor;
|
||||||
private final boolean leftIsRecent;
|
private final boolean leftIsRecent;
|
||||||
|
|
||||||
private boolean active;
|
|
||||||
private int autoPlayPosition;
|
private int autoPlayPosition;
|
||||||
|
|
||||||
CursorPagerAdapter(@NonNull Context context, @NonNull GlideRequests glideRequests,
|
CursorPagerAdapter(@NonNull Context context, @NonNull GlideRequests glideRequests,
|
||||||
@ -690,15 +682,9 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
|||||||
this.leftIsRecent = leftIsRecent;
|
this.leftIsRecent = leftIsRecent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setActive(boolean active) {
|
|
||||||
this.active = active;
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
if (!active) return 0;
|
return cursor.getCount();
|
||||||
else return cursor.getCount();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -771,8 +757,8 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getCursorPosition(int position) {
|
private int getCursorPosition(int position) {
|
||||||
if (leftIsRecent) return position;
|
int unclamped = leftIsRecent ? position : cursor.getCount() - 1 - position;
|
||||||
else return cursor.getCount() - 1 - position;
|
return Math.max(Math.min(unclamped, cursor.getCount() - 1), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -800,9 +786,9 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MediaItemAdapter {
|
abstract static class MediaItemAdapter extends PagerAdapter {
|
||||||
MediaItem getMediaItemFor(int position);
|
abstract MediaItem getMediaItemFor(int position);
|
||||||
void pause(int position);
|
abstract void pause(int position);
|
||||||
@Nullable View getPlaybackControls(int position);
|
@Nullable abstract View getPlaybackControls(int position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user