Code improvements
* Replace unchecked casts with checked casts * remove Utility.finViewById * Fix return activity checking * Create UserAction enum * Fix typos * Add instrumented test for error info * ErrorInfo make fields final * Log exception using logger * Add inherited annotations * Resolve deprecation warnings * Remove unused methods from utility * Reformat code * Remove unused methods from Utility and improve getFileExt * Create OnScrollBelowItemsListener
This commit is contained in:
parent
40213b2d6a
commit
b03723c3fb
40 changed files with 2077 additions and 1981 deletions
2
.github/CONTRIBUTING.md
vendored
2
.github/CONTRIBUTING.md
vendored
|
@ -5,7 +5,7 @@ READ THIS GUIDELINES CAREFULLY BEFORE CONTRIBUTING.
|
||||||
|
|
||||||
## Crash reporting
|
## Crash reporting
|
||||||
|
|
||||||
Do not report crashes in the GitHub issue tracker. NewPipe has an automated crash report system that will ask you to send a report if a crash occures.
|
Do not report crashes in the GitHub issue tracker. NewPipe has an automated crash report system that will ask you to send a report if a crash occurs.
|
||||||
|
|
||||||
## Issue reporting/feature request
|
## Issue reporting/feature request
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ android {
|
||||||
targetSdkVersion 25
|
targetSdkVersion 25
|
||||||
versionCode 35
|
versionCode 35
|
||||||
versionName "0.9.8"
|
versionName "0.9.8"
|
||||||
|
|
||||||
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
|
@ -31,6 +33,11 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2') {
|
||||||
|
exclude module: 'support-annotations'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
testCompile 'org.mockito:mockito-core:1.10.19'
|
testCompile 'org.mockito:mockito-core:1.10.19'
|
||||||
testCompile 'org.json:json:20160810'
|
testCompile 'org.json:json:20160810'
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package org.schabi.newpipe.report;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.support.test.filters.LargeTest;
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.schabi.newpipe.R;
|
||||||
|
import org.schabi.newpipe.report.ErrorActivity.ErrorInfo;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instrumented tests for {@link ErrorInfo}
|
||||||
|
*/
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
@LargeTest
|
||||||
|
public class ErrorInfoTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void errorInfo_testParcelable() {
|
||||||
|
ErrorInfo info = ErrorInfo.make(UserAction.USER_REPORT, "youtube", "request", R.string.general_error);
|
||||||
|
// Obtain a Parcel object and write the parcelable object to it:
|
||||||
|
Parcel parcel = Parcel.obtain();
|
||||||
|
info.writeToParcel(parcel, 0);
|
||||||
|
parcel.setDataPosition(0);
|
||||||
|
ErrorInfo infoFromParcel = ErrorInfo.CREATOR.createFromParcel(parcel);
|
||||||
|
|
||||||
|
assertEquals(UserAction.USER_REPORT, infoFromParcel.userAction);
|
||||||
|
assertEquals("youtube", infoFromParcel.serviceName);
|
||||||
|
assertEquals("request", infoFromParcel.request);
|
||||||
|
assertEquals(R.string.general_error, infoFromParcel.message);
|
||||||
|
|
||||||
|
parcel.recycle();
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ import org.acra.sender.ReportSenderFactory;
|
||||||
import org.schabi.newpipe.extractor.NewPipe;
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
import org.schabi.newpipe.report.AcraReportSenderFactory;
|
import org.schabi.newpipe.report.AcraReportSenderFactory;
|
||||||
import org.schabi.newpipe.report.ErrorActivity;
|
import org.schabi.newpipe.report.ErrorActivity;
|
||||||
|
import org.schabi.newpipe.report.UserAction;
|
||||||
import org.schabi.newpipe.settings.SettingsActivity;
|
import org.schabi.newpipe.settings.SettingsActivity;
|
||||||
import org.schabi.newpipe.util.ThemeHelper;
|
import org.schabi.newpipe.util.ThemeHelper;
|
||||||
|
|
||||||
|
@ -59,7 +60,7 @@ public class App extends Application {
|
||||||
} catch(ACRAConfigurationException ace) {
|
} catch(ACRAConfigurationException ace) {
|
||||||
ace.printStackTrace();
|
ace.printStackTrace();
|
||||||
ErrorActivity.reportError(this, ace, null, null,
|
ErrorActivity.reportError(this, ace, null, null,
|
||||||
ErrorActivity.ErrorInfo.make(ErrorActivity.SEARCHED,"none",
|
ErrorActivity.ErrorInfo.make(UserAction.SEARCHED,"none",
|
||||||
"Could not initialize ACRA crash report", R.string.app_ui_crash));
|
"Could not initialize ACRA crash report", R.string.app_ui_crash));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
||||||
|
|
||||||
import org.schabi.newpipe.extractor.NewPipe;
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
import org.schabi.newpipe.report.ErrorActivity;
|
import org.schabi.newpipe.report.ErrorActivity;
|
||||||
|
import org.schabi.newpipe.report.UserAction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Christian Schabesberger on 01.08.16.
|
* Created by Christian Schabesberger on 01.08.16.
|
||||||
|
@ -49,7 +50,7 @@ public class ImageErrorLoadingListener implements ImageLoadingListener {
|
||||||
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
||||||
ErrorActivity.reportError(context,
|
ErrorActivity.reportError(context,
|
||||||
failReason.getCause(), null, rootView,
|
failReason.getCause(), null, rootView,
|
||||||
ErrorActivity.ErrorInfo.make(ErrorActivity.LOAD_IMAGE,
|
ErrorActivity.ErrorInfo.make(UserAction.LOAD_IMAGE,
|
||||||
NewPipe.getNameOfService(serviceId), imageUri,
|
NewPipe.getNameOfService(serviceId), imageUri,
|
||||||
R.string.could_not_load_image));
|
R.string.could_not_load_image));
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,6 @@ import us.shandian.giga.service.DownloadManagerService;
|
||||||
import us.shandian.giga.ui.fragment.AllMissionsFragment;
|
import us.shandian.giga.ui.fragment.AllMissionsFragment;
|
||||||
import us.shandian.giga.ui.fragment.MissionsFragment;
|
import us.shandian.giga.ui.fragment.MissionsFragment;
|
||||||
import us.shandian.giga.util.CrashHandler;
|
import us.shandian.giga.util.CrashHandler;
|
||||||
import us.shandian.giga.util.Utility;
|
|
||||||
|
|
||||||
public class DownloadActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
|
public class DownloadActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
|
||||||
|
|
||||||
|
@ -125,11 +124,11 @@ public class DownloadActivity extends AppCompatActivity implements AdapterView.O
|
||||||
// Create the view
|
// Create the view
|
||||||
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
View v = inflater.inflate(R.layout.dialog_url, null);
|
View v = inflater.inflate(R.layout.dialog_url, null);
|
||||||
final EditText name = Utility.findViewById(v, R.id.file_name);
|
final EditText name = (EditText) v.findViewById(R.id.file_name);
|
||||||
final TextView tCount = Utility.findViewById(v, R.id.threads_count);
|
final TextView tCount = (TextView) v.findViewById(R.id.threads_count);
|
||||||
final SeekBar threads = Utility.findViewById(v, R.id.threads);
|
final SeekBar threads = (SeekBar) v.findViewById(R.id.threads);
|
||||||
final Toolbar toolbar = Utility.findViewById(v, R.id.toolbar);
|
final Toolbar toolbar = (Toolbar) v.findViewById(R.id.toolbar);
|
||||||
final RadioButton audioButton = (RadioButton) Utility.findViewById(v, R.id.audio_button);
|
final RadioButton audioButton = (RadioButton) v.findViewById(R.id.audio_button);
|
||||||
|
|
||||||
|
|
||||||
threads.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
threads.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||||
|
|
|
@ -253,7 +253,7 @@ public class DownloadDialog extends DialogFragment implements RadioGroup.OnCheck
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* #143 #44 #42 #22: make shure that the filename does not contain illegal chars.
|
* #143 #44 #42 #22: make sure that the filename does not contain illegal chars.
|
||||||
* This should fix some of the "cannot download" problems.
|
* This should fix some of the "cannot download" problems.
|
||||||
*/
|
*/
|
||||||
private String createFileName(String fileName) {
|
private String createFileName(String fileName) {
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.extractor.InfoItem;
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
import org.schabi.newpipe.extractor.channel.ChannelInfo;
|
import org.schabi.newpipe.extractor.channel.ChannelInfo;
|
||||||
import org.schabi.newpipe.fragments.BaseFragment;
|
import org.schabi.newpipe.fragments.BaseFragment;
|
||||||
|
import org.schabi.newpipe.fragments.search.OnScrollBelowItemsListener;
|
||||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||||
import org.schabi.newpipe.info_list.InfoListAdapter;
|
import org.schabi.newpipe.info_list.InfoListAdapter;
|
||||||
import org.schabi.newpipe.util.Constants;
|
import org.schabi.newpipe.util.Constants;
|
||||||
|
@ -245,25 +246,14 @@ public class ChannelFragment extends BaseFragment implements ChannelExtractorWor
|
||||||
});
|
});
|
||||||
|
|
||||||
channelVideosList.clearOnScrollListeners();
|
channelVideosList.clearOnScrollListeners();
|
||||||
channelVideosList.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
channelVideosList.addOnScrollListener(new OnScrollBelowItemsListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
public void onScrolledDown(RecyclerView recyclerView) {
|
||||||
int pastVisiblesItems, visibleItemCount, totalItemCount;
|
if ((currentChannelWorker == null || !currentChannelWorker.isRunning()) && hasNextPage && !isLoading.get()) {
|
||||||
super.onScrolled(recyclerView, dx, dy);
|
|
||||||
//check for scroll down
|
|
||||||
if (dy > 0) {
|
|
||||||
LinearLayoutManager layoutManager = (LinearLayoutManager) channelVideosList.getLayoutManager();
|
|
||||||
|
|
||||||
visibleItemCount = layoutManager.getChildCount();
|
|
||||||
totalItemCount = layoutManager.getItemCount();
|
|
||||||
pastVisiblesItems = layoutManager.findFirstVisibleItemPosition();
|
|
||||||
|
|
||||||
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount && (currentChannelWorker == null || !currentChannelWorker.isRunning()) && hasNextPage && !isLoading.get()) {
|
|
||||||
pageNumber++;
|
pageNumber++;
|
||||||
loadMoreVideos();
|
loadMoreVideos();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
headerRssButton.setOnClickListener(new View.OnClickListener() {
|
headerRssButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
|
@ -61,6 +61,7 @@ import org.schabi.newpipe.player.MainVideoPlayer;
|
||||||
import org.schabi.newpipe.player.PlayVideoActivity;
|
import org.schabi.newpipe.player.PlayVideoActivity;
|
||||||
import org.schabi.newpipe.player.PopupVideoPlayer;
|
import org.schabi.newpipe.player.PopupVideoPlayer;
|
||||||
import org.schabi.newpipe.report.ErrorActivity;
|
import org.schabi.newpipe.report.ErrorActivity;
|
||||||
|
import org.schabi.newpipe.report.UserAction;
|
||||||
import org.schabi.newpipe.util.Constants;
|
import org.schabi.newpipe.util.Constants;
|
||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
import org.schabi.newpipe.util.NavigationHelper;
|
import org.schabi.newpipe.util.NavigationHelper;
|
||||||
|
@ -578,7 +579,7 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
|
||||||
imageLoader.displayImage(info.thumbnail_url, thumbnailImageView, displayImageOptions, new SimpleImageLoadingListener() {
|
imageLoader.displayImage(info.thumbnail_url, thumbnailImageView, displayImageOptions, new SimpleImageLoadingListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
||||||
ErrorActivity.reportError(activity, failReason.getCause(), null, activity.findViewById(android.R.id.content), ErrorActivity.ErrorInfo.make(ErrorActivity.LOAD_IMAGE, NewPipe.getNameOfService(currentStreamInfo.service_id), imageUri, R.string.could_not_load_thumbnails));
|
ErrorActivity.reportError(activity, failReason.getCause(), null, activity.findViewById(android.R.id.content), ErrorActivity.ErrorInfo.make(UserAction.LOAD_IMAGE, NewPipe.getNameOfService(currentStreamInfo.service_id), imageUri, R.string.could_not_load_thumbnails));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else thumbnailImageView.setImageResource(R.drawable.dummy_thumbnail_dark);
|
} else thumbnailImageView.setImageResource(R.drawable.dummy_thumbnail_dark);
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package org.schabi.newpipe.fragments.search;
|
||||||
|
|
||||||
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recycler view scroll listener which calls the method {@link #onScrolledDown(RecyclerView)}
|
||||||
|
* if the view is scrolled below the last item.
|
||||||
|
*/
|
||||||
|
public abstract class OnScrollBelowItemsListener extends RecyclerView.OnScrollListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||||
|
super.onScrolled(recyclerView, dx, dy);
|
||||||
|
//check for scroll down
|
||||||
|
if (dy > 0) {
|
||||||
|
int pastVisibleItems, visibleItemCount, totalItemCount;
|
||||||
|
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
|
||||||
|
visibleItemCount = recyclerView.getLayoutManager().getChildCount();
|
||||||
|
totalItemCount = recyclerView.getLayoutManager().getItemCount();
|
||||||
|
pastVisibleItems = layoutManager.findFirstVisibleItemPosition();
|
||||||
|
if ((visibleItemCount + pastVisibleItems) >= totalItemCount) {
|
||||||
|
onScrolledDown(recyclerView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the recycler view is scrolled below the last item.
|
||||||
|
* @param recyclerView the recycler view
|
||||||
|
*/
|
||||||
|
public abstract void onScrolledDown(RecyclerView recyclerView);
|
||||||
|
}
|
|
@ -242,19 +242,10 @@ public class SearchFragment extends BaseFragment implements SuggestionWorker.OnS
|
||||||
protected void initListeners() {
|
protected void initListeners() {
|
||||||
super.initListeners();
|
super.initListeners();
|
||||||
resultRecyclerView.clearOnScrollListeners();
|
resultRecyclerView.clearOnScrollListeners();
|
||||||
resultRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
resultRecyclerView.addOnScrollListener(new OnScrollBelowItemsListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
public void onScrolledDown(RecyclerView recyclerView) {
|
||||||
int pastVisiblesItems, visibleItemCount, totalItemCount;
|
if(!isLoading.get()) {
|
||||||
super.onScrolled(recyclerView, dx, dy);
|
|
||||||
//check for scroll down
|
|
||||||
if (dy > 0) {
|
|
||||||
LinearLayoutManager layoutManager = (LinearLayoutManager) resultRecyclerView.getLayoutManager();
|
|
||||||
visibleItemCount = resultRecyclerView.getLayoutManager().getChildCount();
|
|
||||||
totalItemCount = resultRecyclerView.getLayoutManager().getItemCount();
|
|
||||||
pastVisiblesItems = layoutManager.findFirstVisibleItemPosition();
|
|
||||||
|
|
||||||
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount && !isLoading.get()) {
|
|
||||||
pageNumber++;
|
pageNumber++;
|
||||||
recyclerView.post(new Runnable() {
|
recyclerView.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -265,10 +256,10 @@ public class SearchFragment extends BaseFragment implements SuggestionWorker.OnS
|
||||||
search(searchQuery, pageNumber);
|
search(searchQuery, pageNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void reloadContent() {
|
protected void reloadContent() {
|
||||||
if (DEBUG) Log.d(TAG, "reloadContent() called");
|
if (DEBUG) Log.d(TAG, "reloadContent() called");
|
||||||
|
|
|
@ -155,7 +155,7 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(RecyclerView.ViewHolder holder, int i) {
|
public void onBindViewHolder(RecyclerView.ViewHolder holder, int i) {
|
||||||
//god damen f*** ANDROID SH**
|
//god damn f*** ANDROID SH**
|
||||||
if(holder instanceof InfoItemHolder) {
|
if(holder instanceof InfoItemHolder) {
|
||||||
if(header != null) {
|
if(header != null) {
|
||||||
i--;
|
i--;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.schabi.newpipe.report;
|
package org.schabi.newpipe.report;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
import org.acra.collector.CrashReportData;
|
import org.acra.collector.CrashReportData;
|
||||||
import org.acra.sender.ReportSender;
|
import org.acra.sender.ReportSender;
|
||||||
|
@ -30,9 +31,9 @@ import org.schabi.newpipe.R;
|
||||||
public class AcraReportSender implements ReportSender {
|
public class AcraReportSender implements ReportSender {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void send(Context context, CrashReportData report) throws ReportSenderException {
|
public void send(@NonNull Context context, @NonNull CrashReportData report) throws ReportSenderException {
|
||||||
ErrorActivity.reportError(context, report,
|
ErrorActivity.reportError(context, report,
|
||||||
ErrorActivity.ErrorInfo.make(ErrorActivity.UI_ERROR,"none",
|
ErrorActivity.ErrorInfo.make(UserAction.UI_ERROR,"none",
|
||||||
"App crash, UI failure", R.string.app_ui_crash));
|
"App crash, UI failure", R.string.app_ui_crash));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.schabi.newpipe.report;
|
package org.schabi.newpipe.report;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
import org.acra.config.ACRAConfiguration;
|
import org.acra.config.ACRAConfiguration;
|
||||||
import org.acra.sender.ReportSender;
|
import org.acra.sender.ReportSender;
|
||||||
|
@ -28,7 +29,8 @@ import org.schabi.newpipe.report.AcraReportSender;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class AcraReportSenderFactory implements ReportSenderFactory {
|
public class AcraReportSenderFactory implements ReportSenderFactory {
|
||||||
public ReportSender create(Context context, ACRAConfiguration config) {
|
@NonNull
|
||||||
|
public ReportSender create(@NonNull Context context, @NonNull ACRAConfiguration config) {
|
||||||
return new AcraReportSender();
|
return new AcraReportSender();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ import android.os.Handler;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.annotation.StringRes;
|
||||||
import android.support.design.widget.Snackbar;
|
import android.support.design.widget.Snackbar;
|
||||||
import android.support.v4.app.NavUtils;
|
import android.support.v4.app.NavUtils;
|
||||||
import android.support.v7.app.ActionBar;
|
import android.support.v7.app.ActionBar;
|
||||||
|
@ -71,24 +73,7 @@ public class ErrorActivity extends AppCompatActivity {
|
||||||
// BUNDLE TAGS
|
// BUNDLE TAGS
|
||||||
public static final String ERROR_INFO = "error_info";
|
public static final String ERROR_INFO = "error_info";
|
||||||
public static final String ERROR_LIST = "error_list";
|
public static final String ERROR_LIST = "error_list";
|
||||||
// MESSAGE ID
|
|
||||||
public static final int SEARCHED = 0;
|
|
||||||
public static final int REQUESTED_STREAM = 1;
|
|
||||||
public static final int GET_SUGGESTIONS = 2;
|
|
||||||
public static final int SOMETHING_ELSE = 3;
|
|
||||||
public static final int USER_REPORT = 4;
|
|
||||||
public static final int LOAD_IMAGE = 5;
|
|
||||||
public static final int UI_ERROR = 6;
|
|
||||||
public static final int REQUESTED_CHANNEL = 7;
|
|
||||||
// MESSAGE STRING
|
|
||||||
public static final String SEARCHED_STRING = "searched";
|
|
||||||
public static final String REQUESTED_STREAM_STRING = "requested stream";
|
|
||||||
public static final String GET_SUGGESTIONS_STRING = "get suggestions";
|
|
||||||
public static final String SOMETHING_ELSE_STRING = "something";
|
|
||||||
public static final String USER_REPORT_STRING = "user report";
|
|
||||||
public static final String LOAD_IMAGE_STRING = "load image";
|
|
||||||
public static final String UI_ERROR_STRING = "ui error";
|
|
||||||
public static final String REQUESTED_CHANNEL_STRING = "requested channel";
|
|
||||||
public static final String ERROR_EMAIL_ADDRESS = "crashreport@newpipe.schabi.org";
|
public static final String ERROR_EMAIL_ADDRESS = "crashreport@newpipe.schabi.org";
|
||||||
public static final String ERROR_EMAIL_SUBJECT = "Exception in NewPipe " + BuildConfig.VERSION_NAME;
|
public static final String ERROR_EMAIL_SUBJECT = "Exception in NewPipe " + BuildConfig.VERSION_NAME;
|
||||||
Thread globIpRangeThread;
|
Thread globIpRangeThread;
|
||||||
|
@ -105,11 +90,11 @@ public class ErrorActivity extends AppCompatActivity {
|
||||||
private TextView errorMessageView;
|
private TextView errorMessageView;
|
||||||
|
|
||||||
public static void reportUiError(final AppCompatActivity activity, final Throwable el) {
|
public static void reportUiError(final AppCompatActivity activity, final Throwable el) {
|
||||||
reportError(activity, el, activity.getClass(), null, ErrorInfo.make(UI_ERROR, "none", "", R.string.app_ui_crash));
|
reportError(activity, el, activity.getClass(), null, ErrorInfo.make(UserAction.UI_ERROR, "none", "", R.string.app_ui_crash));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void reportError(final Context context, final List<Throwable> el,
|
public static void reportError(final Context context, final List<Throwable> el,
|
||||||
final Class returnAcitivty, View rootView, final ErrorInfo errorInfo) {
|
final Class returnActivity, View rootView, final ErrorInfo errorInfo) {
|
||||||
|
|
||||||
if (rootView != null) {
|
if (rootView != null) {
|
||||||
Snackbar.make(rootView, R.string.error_snackbar_message, Snackbar.LENGTH_LONG)
|
Snackbar.make(rootView, R.string.error_snackbar_message, Snackbar.LENGTH_LONG)
|
||||||
|
@ -118,7 +103,7 @@ public class ErrorActivity extends AppCompatActivity {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
ActivityCommunicator ac = ActivityCommunicator.getCommunicator();
|
ActivityCommunicator ac = ActivityCommunicator.getCommunicator();
|
||||||
ac.returnActivity = returnAcitivty;
|
ac.returnActivity = returnActivity;
|
||||||
Intent intent = new Intent(context, ErrorActivity.class);
|
Intent intent = new Intent(context, ErrorActivity.class);
|
||||||
intent.putExtra(ERROR_INFO, errorInfo);
|
intent.putExtra(ERROR_INFO, errorInfo);
|
||||||
intent.putExtra(ERROR_LIST, elToSl(el));
|
intent.putExtra(ERROR_LIST, elToSl(el));
|
||||||
|
@ -128,7 +113,7 @@ public class ErrorActivity extends AppCompatActivity {
|
||||||
}).show();
|
}).show();
|
||||||
} else {
|
} else {
|
||||||
ActivityCommunicator ac = ActivityCommunicator.getCommunicator();
|
ActivityCommunicator ac = ActivityCommunicator.getCommunicator();
|
||||||
ac.returnActivity = returnAcitivty;
|
ac.returnActivity = returnActivity;
|
||||||
Intent intent = new Intent(context, ErrorActivity.class);
|
Intent intent = new Intent(context, ErrorActivity.class);
|
||||||
intent.putExtra(ERROR_INFO, errorInfo);
|
intent.putExtra(ERROR_INFO, errorInfo);
|
||||||
intent.putExtra(ERROR_LIST, elToSl(el));
|
intent.putExtra(ERROR_LIST, elToSl(el));
|
||||||
|
@ -138,34 +123,34 @@ public class ErrorActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void reportError(final Context context, final Throwable e,
|
public static void reportError(final Context context, final Throwable e,
|
||||||
final Class returnAcitivty, View rootView, final ErrorInfo errorInfo) {
|
final Class returnActivity, View rootView, final ErrorInfo errorInfo) {
|
||||||
List<Throwable> el = null;
|
List<Throwable> el = null;
|
||||||
if(e != null) {
|
if(e != null) {
|
||||||
el = new Vector<>();
|
el = new Vector<>();
|
||||||
el.add(e);
|
el.add(e);
|
||||||
}
|
}
|
||||||
reportError(context, el, returnAcitivty, rootView, errorInfo);
|
reportError(context, el, returnActivity, rootView, errorInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// async call
|
// async call
|
||||||
public static void reportError(Handler handler, final Context context, final Throwable e,
|
public static void reportError(Handler handler, final Context context, final Throwable e,
|
||||||
final Class returnAcitivty, final View rootView, final ErrorInfo errorInfo) {
|
final Class returnActivity, final View rootView, final ErrorInfo errorInfo) {
|
||||||
|
|
||||||
List<Throwable> el = null;
|
List<Throwable> el = null;
|
||||||
if(e != null) {
|
if(e != null) {
|
||||||
el = new Vector<>();
|
el = new Vector<>();
|
||||||
el.add(e);
|
el.add(e);
|
||||||
}
|
}
|
||||||
reportError(handler, context, el, returnAcitivty, rootView, errorInfo);
|
reportError(handler, context, el, returnActivity, rootView, errorInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// async call
|
// async call
|
||||||
public static void reportError(Handler handler, final Context context, final List<Throwable> el,
|
public static void reportError(Handler handler, final Context context, final List<Throwable> el,
|
||||||
final Class returnAcitivty, final View rootView, final ErrorInfo errorInfo) {
|
final Class returnActivity, final View rootView, final ErrorInfo errorInfo) {
|
||||||
handler.post(new Runnable() {
|
handler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
reportError(context, el, returnAcitivty, rootView, errorInfo);
|
reportError(context, el, returnActivity, rootView, errorInfo);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -232,7 +217,7 @@ public class ErrorActivity extends AppCompatActivity {
|
||||||
errorInfo = intent.getParcelableExtra(ERROR_INFO);
|
errorInfo = intent.getParcelableExtra(ERROR_INFO);
|
||||||
errorList = intent.getStringArrayExtra(ERROR_LIST);
|
errorList = intent.getStringArrayExtra(ERROR_LIST);
|
||||||
|
|
||||||
//importand add gurumeditaion
|
// important add guru meditation
|
||||||
addGuruMeditaion();
|
addGuruMeditaion();
|
||||||
currentTimeStamp = getCurrentTimeStamp();
|
currentTimeStamp = getCurrentTimeStamp();
|
||||||
|
|
||||||
|
@ -250,7 +235,7 @@ public class ErrorActivity extends AppCompatActivity {
|
||||||
});
|
});
|
||||||
reportButton.setEnabled(false);
|
reportButton.setEnabled(false);
|
||||||
|
|
||||||
globIpRangeThread = new Thread(new IpRagneRequester());
|
globIpRangeThread = new Thread(new IpRangeRequester());
|
||||||
globIpRangeThread.start();
|
globIpRangeThread.start();
|
||||||
|
|
||||||
// normal bugreport
|
// normal bugreport
|
||||||
|
@ -308,17 +293,30 @@ public class ErrorActivity extends AppCompatActivity {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the checked activity.
|
||||||
|
* @param returnActivity the activity to return to
|
||||||
|
* @return the casted return activity or null
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
static Class<? extends Activity> getReturnActivity(Class<?> returnActivity) {
|
||||||
|
Class<? extends Activity> checkedReturnActivity = null;
|
||||||
|
if (returnActivity != null){
|
||||||
|
if (Activity.class.isAssignableFrom(returnActivity)) {
|
||||||
|
checkedReturnActivity = returnActivity.asSubclass(Activity.class);
|
||||||
|
} else {
|
||||||
|
checkedReturnActivity = MainActivity.class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return checkedReturnActivity;
|
||||||
|
}
|
||||||
|
|
||||||
private void goToReturnActivity() {
|
private void goToReturnActivity() {
|
||||||
if (returnActivity == null) {
|
Class<? extends Activity> checkedReturnActivity = getReturnActivity(returnActivity);
|
||||||
|
if (checkedReturnActivity == null) {
|
||||||
super.onBackPressed();
|
super.onBackPressed();
|
||||||
} else {
|
} else {
|
||||||
Intent intent;
|
Intent intent = new Intent(this, checkedReturnActivity);
|
||||||
if (returnActivity != null &&
|
|
||||||
returnActivity.isAssignableFrom(Activity.class)) {
|
|
||||||
intent = new Intent(this, returnActivity);
|
|
||||||
} else {
|
|
||||||
intent = new Intent(this, MainActivity.class);
|
|
||||||
}
|
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
NavUtils.navigateUpTo(this, intent);
|
NavUtils.navigateUpTo(this, intent);
|
||||||
}
|
}
|
||||||
|
@ -376,26 +374,11 @@ public class ErrorActivity extends AppCompatActivity {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getUserActionString(int userAction) {
|
private String getUserActionString(UserAction userAction) {
|
||||||
switch (userAction) {
|
if(userAction == null) {
|
||||||
case REQUESTED_STREAM:
|
|
||||||
return REQUESTED_STREAM_STRING;
|
|
||||||
case SEARCHED:
|
|
||||||
return SEARCHED_STRING;
|
|
||||||
case GET_SUGGESTIONS:
|
|
||||||
return GET_SUGGESTIONS_STRING;
|
|
||||||
case SOMETHING_ELSE:
|
|
||||||
return SOMETHING_ELSE_STRING;
|
|
||||||
case USER_REPORT:
|
|
||||||
return USER_REPORT_STRING;
|
|
||||||
case LOAD_IMAGE:
|
|
||||||
return LOAD_IMAGE_STRING;
|
|
||||||
case UI_ERROR:
|
|
||||||
return UI_ERROR_STRING;
|
|
||||||
case REQUESTED_CHANNEL:
|
|
||||||
return REQUESTED_CHANNEL_STRING;
|
|
||||||
default:
|
|
||||||
return "Your description is in another castle.";
|
return "Your description is in another castle.";
|
||||||
|
} else {
|
||||||
|
return userAction.getMessage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,28 +427,28 @@ public class ErrorActivity extends AppCompatActivity {
|
||||||
return new ErrorInfo[size];
|
return new ErrorInfo[size];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
public int userAction;
|
final public UserAction userAction;
|
||||||
public String request;
|
final public String request;
|
||||||
public String serviceName;
|
final public String serviceName;
|
||||||
public int message;
|
@StringRes
|
||||||
|
final public int message;
|
||||||
|
|
||||||
public ErrorInfo() {
|
private ErrorInfo(UserAction userAction, String serviceName, String request, @StringRes int message) {
|
||||||
|
this.userAction = userAction;
|
||||||
|
this.serviceName = serviceName;
|
||||||
|
this.request = request;
|
||||||
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ErrorInfo(Parcel in) {
|
protected ErrorInfo(Parcel in) {
|
||||||
this.userAction = in.readInt();
|
this.userAction = UserAction.valueOf(in.readString());
|
||||||
this.request = in.readString();
|
this.request = in.readString();
|
||||||
this.serviceName = in.readString();
|
this.serviceName = in.readString();
|
||||||
this.message = in.readInt();
|
this.message = in.readInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ErrorInfo make(int userAction, String serviceName, String request, int message) {
|
public static ErrorInfo make(UserAction userAction, String serviceName, String request, @StringRes int message) {
|
||||||
ErrorInfo info = new ErrorInfo();
|
return new ErrorInfo(userAction, serviceName, request, message);
|
||||||
info.userAction = userAction;
|
|
||||||
info.serviceName = serviceName;
|
|
||||||
info.request = request;
|
|
||||||
info.message = message;
|
|
||||||
return info;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -475,14 +458,14 @@ public class ErrorActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToParcel(Parcel dest, int flags) {
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
dest.writeInt(this.userAction);
|
dest.writeString(this.userAction.name());
|
||||||
dest.writeString(this.request);
|
dest.writeString(this.request);
|
||||||
dest.writeString(this.serviceName);
|
dest.writeString(this.serviceName);
|
||||||
dest.writeInt(this.message);
|
dest.writeInt(this.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class IpRagneRequester implements Runnable {
|
private class IpRangeRequester implements Runnable {
|
||||||
Handler h = new Handler();
|
Handler h = new Handler();
|
||||||
public void run() {
|
public void run() {
|
||||||
String ipRange = "none";
|
String ipRange = "none";
|
||||||
|
@ -493,17 +476,16 @@ public class ErrorActivity extends AppCompatActivity {
|
||||||
ipRange = Parser.matchGroup1("([0-9]*\\.[0-9]*\\.)[0-9]*\\.[0-9]*", ip)
|
ipRange = Parser.matchGroup1("([0-9]*\\.[0-9]*\\.)[0-9]*\\.[0-9]*", ip)
|
||||||
+ "0.0";
|
+ "0.0";
|
||||||
} catch(Throwable e) {
|
} catch(Throwable e) {
|
||||||
Log.d(TAG, "Error while error: could not get iprange");
|
Log.w(TAG, "Error while error: could not get iprange", e);
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
} finally {
|
||||||
h.post(new IpRageReturnRunnable(ipRange));
|
h.post(new IpRangeReturnRunnable(ipRange));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class IpRageReturnRunnable implements Runnable {
|
private class IpRangeReturnRunnable implements Runnable {
|
||||||
String ipRange;
|
String ipRange;
|
||||||
public IpRageReturnRunnable(String ipRange) {
|
public IpRangeReturnRunnable(String ipRange) {
|
||||||
this.ipRange = ipRange;
|
this.ipRange = ipRange;
|
||||||
}
|
}
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
26
app/src/main/java/org/schabi/newpipe/report/UserAction.java
Normal file
26
app/src/main/java/org/schabi/newpipe/report/UserAction.java
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package org.schabi.newpipe.report;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user actions that can cause an error.
|
||||||
|
*/
|
||||||
|
public enum UserAction {
|
||||||
|
SEARCHED("searched"),
|
||||||
|
REQUESTED_STREAM("requested stream"),
|
||||||
|
GET_SUGGESTIONS("get suggestions"),
|
||||||
|
SOMETHING_ELSE("something"),
|
||||||
|
USER_REPORT("user report"),
|
||||||
|
LOAD_IMAGE("load image"),
|
||||||
|
UI_ERROR("ui error"),
|
||||||
|
REQUESTED_CHANNEL("requested channel");
|
||||||
|
|
||||||
|
|
||||||
|
private final String message;
|
||||||
|
|
||||||
|
UserAction(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
}
|
|
@ -72,9 +72,7 @@ public class NewPipeSettings {
|
||||||
public static String getVideoDownloadPath(Context context) {
|
public static String getVideoDownloadPath(Context context) {
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
final String key = context.getString(R.string.download_path_key);
|
final String key = context.getString(R.string.download_path_key);
|
||||||
String downloadPath = prefs.getString(key, Environment.DIRECTORY_MOVIES);
|
return prefs.getString(key, Environment.DIRECTORY_MOVIES);
|
||||||
|
|
||||||
return downloadPath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File getAudioDownloadFolder(Context context) {
|
public static File getAudioDownloadFolder(Context context) {
|
||||||
|
@ -84,9 +82,7 @@ public class NewPipeSettings {
|
||||||
public static String getAudioDownloadPath(Context context) {
|
public static String getAudioDownloadPath(Context context) {
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
final String key = context.getString(R.string.download_path_audio_key);
|
final String key = context.getString(R.string.download_path_audio_key);
|
||||||
String downloadPath = prefs.getString(key, Environment.DIRECTORY_MUSIC);
|
return prefs.getString(key, Environment.DIRECTORY_MUSIC);
|
||||||
|
|
||||||
return downloadPath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static File getFolder(Context context, int keyID, String defaultDirectoryName) {
|
private static File getFolder(Context context, int keyID, String defaultDirectoryName) {
|
||||||
|
|
|
@ -12,6 +12,8 @@ import org.schabi.newpipe.report.ErrorActivity;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.schabi.newpipe.report.UserAction.REQUESTED_CHANNEL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract {@link ChannelInfo} with {@link ChannelExtractor} from the given url of the given service
|
* Extract {@link ChannelInfo} with {@link ChannelExtractor} from the given url of the given service
|
||||||
*
|
*
|
||||||
|
@ -67,7 +69,7 @@ public class ChannelExtractorWorker extends ExtractorWorker {
|
||||||
ChannelExtractor extractor = getService().getChannelExtractorInstance(url, pageNumber);
|
ChannelExtractor extractor = getService().getChannelExtractorInstance(url, pageNumber);
|
||||||
channelInfo = ChannelInfo.getInfo(extractor);
|
channelInfo = ChannelInfo.getInfo(extractor);
|
||||||
|
|
||||||
if (!channelInfo.errors.isEmpty()) handleErrorsDuringExtraction(channelInfo.errors, ErrorActivity.REQUESTED_CHANNEL);
|
if (!channelInfo.errors.isEmpty()) handleErrorsDuringExtraction(channelInfo.errors, REQUESTED_CHANNEL);
|
||||||
|
|
||||||
if (callback != null && channelInfo != null && !isInterrupted()) getHandler().post(new Runnable() {
|
if (callback != null && channelInfo != null && !isInterrupted()) getHandler().post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -93,7 +95,7 @@ public class ChannelExtractorWorker extends ExtractorWorker {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (exception instanceof ParsingException || exception instanceof ExtractionException) {
|
} else if (exception instanceof ParsingException || exception instanceof ExtractionException) {
|
||||||
ErrorActivity.reportError(getHandler(), getContext(), exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_CHANNEL, getServiceName(), url, R.string.parsing_error));
|
ErrorActivity.reportError(getHandler(), getContext(), exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(REQUESTED_CHANNEL, getServiceName(), url, R.string.parsing_error));
|
||||||
getHandler().post(new Runnable() {
|
getHandler().post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -101,7 +103,7 @@ public class ChannelExtractorWorker extends ExtractorWorker {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
ErrorActivity.reportError(getHandler(), getContext(), exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_CHANNEL, getServiceName(), url, R.string.general_error));
|
ErrorActivity.reportError(getHandler(), getContext(), exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(REQUESTED_CHANNEL, getServiceName(), url, R.string.general_error));
|
||||||
getHandler().post(new Runnable() {
|
getHandler().post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import org.schabi.newpipe.report.ErrorActivity;
|
import org.schabi.newpipe.report.ErrorActivity;
|
||||||
|
import org.schabi.newpipe.report.UserAction;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -59,14 +60,14 @@ public abstract class ExtractorWorker extends AbstractWorker {
|
||||||
* @param errorUserAction what action was the user performing during the error.
|
* @param errorUserAction what action was the user performing during the error.
|
||||||
* (One of the {@link ErrorActivity}.REQUEST_* error (message) ids)
|
* (One of the {@link ErrorActivity}.REQUEST_* error (message) ids)
|
||||||
*/
|
*/
|
||||||
protected void handleErrorsDuringExtraction(List<Throwable> errorsList, int errorUserAction){
|
protected void handleErrorsDuringExtraction(List<Throwable> errorsList, UserAction errorUserAction){
|
||||||
String errorString = "<error id>";
|
String errorString = "<error id>";
|
||||||
switch (errorUserAction) {
|
switch (errorUserAction) {
|
||||||
case ErrorActivity.REQUESTED_STREAM:
|
case REQUESTED_STREAM:
|
||||||
errorString= ErrorActivity.REQUESTED_STREAM_STRING;
|
errorString= errorUserAction.getMessage();
|
||||||
break;
|
break;
|
||||||
case ErrorActivity.REQUESTED_CHANNEL:
|
case REQUESTED_CHANNEL:
|
||||||
errorString= ErrorActivity.REQUESTED_CHANNEL_STRING;
|
errorString= errorUserAction.getMessage();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,13 @@ import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
|
||||||
import org.schabi.newpipe.extractor.search.SearchEngine;
|
import org.schabi.newpipe.extractor.search.SearchEngine;
|
||||||
import org.schabi.newpipe.extractor.search.SearchResult;
|
import org.schabi.newpipe.extractor.search.SearchResult;
|
||||||
import org.schabi.newpipe.report.ErrorActivity;
|
import org.schabi.newpipe.report.ErrorActivity;
|
||||||
|
import org.schabi.newpipe.report.UserAction;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
|
||||||
|
import static org.schabi.newpipe.report.UserAction.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return list of results based on a query
|
* Return list of results based on a query
|
||||||
*
|
*
|
||||||
|
@ -106,7 +109,7 @@ public class SearchWorker extends AbstractWorker {
|
||||||
});
|
});
|
||||||
} else if (exception instanceof ExtractionException) {
|
} else if (exception instanceof ExtractionException) {
|
||||||
View rootView = getContext() instanceof Activity ? ((Activity) getContext()).findViewById(android.R.id.content) : null;
|
View rootView = getContext() instanceof Activity ? ((Activity) getContext()).findViewById(android.R.id.content) : null;
|
||||||
ErrorActivity.reportError(getHandler(), getContext(), exception, null, rootView, ErrorActivity.ErrorInfo.make(ErrorActivity.SEARCHED, getServiceName(), query, R.string.parsing_error));
|
ErrorActivity.reportError(getHandler(), getContext(), exception, null, rootView, ErrorActivity.ErrorInfo.make(SEARCHED, getServiceName(), query, R.string.parsing_error));
|
||||||
getHandler().post(new Runnable() {
|
getHandler().post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -115,7 +118,7 @@ public class SearchWorker extends AbstractWorker {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
View rootView = getContext() instanceof Activity ? ((Activity) getContext()).findViewById(android.R.id.content) : null;
|
View rootView = getContext() instanceof Activity ? ((Activity) getContext()).findViewById(android.R.id.content) : null;
|
||||||
ErrorActivity.reportError(getHandler(), getContext(), exception, null, rootView, ErrorActivity.ErrorInfo.make(ErrorActivity.SEARCHED, getServiceName(), query, R.string.general_error));
|
ErrorActivity.reportError(getHandler(), getContext(), exception, null, rootView, ErrorActivity.ErrorInfo.make(SEARCHED, getServiceName(), query, R.string.general_error));
|
||||||
getHandler().post(new Runnable() {
|
getHandler().post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
|
@ -10,9 +10,12 @@ import org.schabi.newpipe.extractor.services.youtube.YoutubeStreamExtractor;
|
||||||
import org.schabi.newpipe.extractor.stream_info.StreamExtractor;
|
import org.schabi.newpipe.extractor.stream_info.StreamExtractor;
|
||||||
import org.schabi.newpipe.extractor.stream_info.StreamInfo;
|
import org.schabi.newpipe.extractor.stream_info.StreamInfo;
|
||||||
import org.schabi.newpipe.report.ErrorActivity;
|
import org.schabi.newpipe.report.ErrorActivity;
|
||||||
|
import org.schabi.newpipe.report.UserAction;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.schabi.newpipe.report.UserAction.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract {@link StreamInfo} with {@link StreamExtractor} from the given url of the given service
|
* Extract {@link StreamInfo} with {@link StreamExtractor} from the given url of the given service
|
||||||
*
|
*
|
||||||
|
@ -66,7 +69,7 @@ public class StreamExtractorWorker extends ExtractorWorker {
|
||||||
StreamExtractor streamExtractor = getService().getExtractorInstance(url);
|
StreamExtractor streamExtractor = getService().getExtractorInstance(url);
|
||||||
streamInfo = StreamInfo.getVideoInfo(streamExtractor);
|
streamInfo = StreamInfo.getVideoInfo(streamExtractor);
|
||||||
|
|
||||||
if (streamInfo != null && !streamInfo.errors.isEmpty()) handleErrorsDuringExtraction(streamInfo.errors, ErrorActivity.REQUESTED_STREAM);
|
if (streamInfo != null && !streamInfo.errors.isEmpty()) handleErrorsDuringExtraction(streamInfo.errors, REQUESTED_STREAM);
|
||||||
|
|
||||||
if (callback != null && getHandler() != null && streamInfo != null && !isInterrupted()) getHandler().post(new Runnable() {
|
if (callback != null && getHandler() != null && streamInfo != null && !isInterrupted()) getHandler().post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -121,7 +124,7 @@ public class StreamExtractorWorker extends ExtractorWorker {
|
||||||
});
|
});
|
||||||
} else if (exception instanceof YoutubeStreamExtractor.DecryptException) {
|
} else if (exception instanceof YoutubeStreamExtractor.DecryptException) {
|
||||||
// custom service related exceptions
|
// custom service related exceptions
|
||||||
ErrorActivity.reportError(getHandler(), getContext(), exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM, getServiceName(), url, R.string.youtube_signature_decryption_error));
|
ErrorActivity.reportError(getHandler(), getContext(), exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(REQUESTED_STREAM, getServiceName(), url, R.string.youtube_signature_decryption_error));
|
||||||
getHandler().post(new Runnable() {
|
getHandler().post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -131,9 +134,9 @@ public class StreamExtractorWorker extends ExtractorWorker {
|
||||||
} else if (exception instanceof StreamInfo.StreamExctractException) {
|
} else if (exception instanceof StreamInfo.StreamExctractException) {
|
||||||
if (!streamInfo.errors.isEmpty()) {
|
if (!streamInfo.errors.isEmpty()) {
|
||||||
// !!! if this case ever kicks in someone gets kicked out !!!
|
// !!! if this case ever kicks in someone gets kicked out !!!
|
||||||
ErrorActivity.reportError(getHandler(), getContext(), exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM, getServiceName(), url, R.string.could_not_get_stream));
|
ErrorActivity.reportError(getHandler(), getContext(), exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(REQUESTED_STREAM, getServiceName(), url, R.string.could_not_get_stream));
|
||||||
} else {
|
} else {
|
||||||
ErrorActivity.reportError(getHandler(), getContext(), streamInfo.errors, MainActivity.class, null, ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM, getServiceName(), url, R.string.could_not_get_stream));
|
ErrorActivity.reportError(getHandler(), getContext(), streamInfo.errors, MainActivity.class, null, ErrorActivity.ErrorInfo.make(REQUESTED_STREAM, getServiceName(), url, R.string.could_not_get_stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
getHandler().post(new Runnable() {
|
getHandler().post(new Runnable() {
|
||||||
|
@ -143,7 +146,7 @@ public class StreamExtractorWorker extends ExtractorWorker {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (exception instanceof ParsingException) {
|
} else if (exception instanceof ParsingException) {
|
||||||
ErrorActivity.reportError(getHandler(), getContext(), exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM, getServiceName(), url, R.string.parsing_error));
|
ErrorActivity.reportError(getHandler(), getContext(), exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(REQUESTED_STREAM, getServiceName(), url, R.string.parsing_error));
|
||||||
getHandler().post(new Runnable() {
|
getHandler().post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -151,7 +154,7 @@ public class StreamExtractorWorker extends ExtractorWorker {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
ErrorActivity.reportError(getHandler(), getContext(), exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM, getServiceName(), url, R.string.general_error));
|
ErrorActivity.reportError(getHandler(), getContext(), exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(REQUESTED_STREAM, getServiceName(), url, R.string.general_error));
|
||||||
getHandler().post(new Runnable() {
|
getHandler().post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
|
@ -11,10 +11,13 @@ import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.extractor.SuggestionExtractor;
|
import org.schabi.newpipe.extractor.SuggestionExtractor;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
import org.schabi.newpipe.report.ErrorActivity;
|
import org.schabi.newpipe.report.ErrorActivity;
|
||||||
|
import org.schabi.newpipe.report.UserAction;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.schabi.newpipe.report.UserAction.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Worker that get suggestions based on the query
|
* Worker that get suggestions based on the query
|
||||||
*
|
*
|
||||||
|
@ -79,7 +82,7 @@ public class SuggestionWorker extends AbstractWorker {
|
||||||
|
|
||||||
if (exception instanceof ExtractionException) {
|
if (exception instanceof ExtractionException) {
|
||||||
View rootView = getContext() instanceof Activity ? ((Activity) getContext()).findViewById(android.R.id.content) : null;
|
View rootView = getContext() instanceof Activity ? ((Activity) getContext()).findViewById(android.R.id.content) : null;
|
||||||
ErrorActivity.reportError(getHandler(), getContext(), exception, null, rootView, ErrorActivity.ErrorInfo.make(ErrorActivity.GET_SUGGESTIONS, getServiceName(), query, R.string.parsing_error));
|
ErrorActivity.reportError(getHandler(), getContext(), exception, null, rootView, ErrorActivity.ErrorInfo.make(GET_SUGGESTIONS, getServiceName(), query, R.string.parsing_error));
|
||||||
getHandler().post(new Runnable() {
|
getHandler().post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -95,7 +98,7 @@ public class SuggestionWorker extends AbstractWorker {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
View rootView = getContext() instanceof Activity ? ((Activity) getContext()).findViewById(android.R.id.content) : null;
|
View rootView = getContext() instanceof Activity ? ((Activity) getContext()).findViewById(android.R.id.content) : null;
|
||||||
ErrorActivity.reportError(getHandler(), getContext(), exception, null, rootView, ErrorActivity.ErrorInfo.make(ErrorActivity.GET_SUGGESTIONS, getServiceName(), query, R.string.general_error));
|
ErrorActivity.reportError(getHandler(), getContext(), exception, null, rootView, ErrorActivity.ErrorInfo.make(GET_SUGGESTIONS, getServiceName(), query, R.string.general_error));
|
||||||
getHandler().post(new Runnable() {
|
getHandler().post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
|
@ -9,12 +9,14 @@ public interface DownloadDataSource {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load all missions
|
* Load all missions
|
||||||
|
*
|
||||||
* @return a list of download missions
|
* @return a list of download missions
|
||||||
*/
|
*/
|
||||||
List<DownloadMission> loadMissions();
|
List<DownloadMission> loadMissions();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a downlaod mission to the storage
|
* Add a download mission to the storage
|
||||||
|
*
|
||||||
* @param downloadMission the download mission to add
|
* @param downloadMission the download mission to add
|
||||||
* @return the identifier of the mission
|
* @return the identifier of the mission
|
||||||
*/
|
*/
|
||||||
|
@ -22,6 +24,7 @@ public interface DownloadDataSource {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a download mission which exists in the storage
|
* Update a download mission which exists in the storage
|
||||||
|
*
|
||||||
* @param downloadMission the download mission to update
|
* @param downloadMission the download mission to update
|
||||||
* @throws IllegalArgumentException if the mission was not added to storage
|
* @throws IllegalArgumentException if the mission was not added to storage
|
||||||
*/
|
*/
|
||||||
|
@ -30,6 +33,7 @@ public interface DownloadDataSource {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a download mission
|
* Delete a download mission
|
||||||
|
*
|
||||||
* @param downloadMission the mission to delete
|
* @param downloadMission the mission to delete
|
||||||
*/
|
*/
|
||||||
void deleteMission(DownloadMission downloadMission);
|
void deleteMission(DownloadMission downloadMission);
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package us.shandian.giga.get;
|
package us.shandian.giga.get;
|
||||||
|
|
||||||
public interface DownloadManager
|
public interface DownloadManager {
|
||||||
{
|
|
||||||
int BLOCK_SIZE = 512 * 1024;
|
int BLOCK_SIZE = 512 * 1024;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a new download mission
|
* Start a new download mission
|
||||||
|
*
|
||||||
* @param url the url to download
|
* @param url the url to download
|
||||||
* @param location the location
|
* @param location the location
|
||||||
* @param name the name of the file to create
|
* @param name the name of the file to create
|
||||||
|
@ -16,24 +16,28 @@ public interface DownloadManager
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resume the execution of a download mission.
|
* Resume the execution of a download mission.
|
||||||
|
*
|
||||||
* @param id the identifier of the mission to resume.
|
* @param id the identifier of the mission to resume.
|
||||||
*/
|
*/
|
||||||
void resumeMission(int id);
|
void resumeMission(int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pause the execution of a download mission.
|
* Pause the execution of a download mission.
|
||||||
|
*
|
||||||
* @param id the identifier of the mission to pause.
|
* @param id the identifier of the mission to pause.
|
||||||
*/
|
*/
|
||||||
void pauseMission(int id);
|
void pauseMission(int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes the mission from the downloaded list but keeps the downloaded file.
|
* Deletes the mission from the downloaded list but keeps the downloaded file.
|
||||||
|
*
|
||||||
* @param id The mission identifier
|
* @param id The mission identifier
|
||||||
*/
|
*/
|
||||||
void deleteMission(int id);
|
void deleteMission(int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the download mission by its identifier
|
* Get the download mission by its identifier
|
||||||
|
*
|
||||||
* @param id the identifier of the download mission
|
* @param id the identifier of the download mission
|
||||||
* @return the download mission or null if the mission doesn't exist
|
* @return the download mission or null if the mission doesn't exist
|
||||||
*/
|
*/
|
||||||
|
@ -41,6 +45,7 @@ public interface DownloadManager
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of download missions.
|
* Get the number of download missions.
|
||||||
|
*
|
||||||
* @return the number of download missions.
|
* @return the number of download missions.
|
||||||
*/
|
*/
|
||||||
int getCount();
|
int getCount();
|
||||||
|
|
|
@ -18,10 +18,10 @@ import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import us.shandian.giga.util.Utility;
|
import us.shandian.giga.util.Utility;
|
||||||
|
|
||||||
import static org.schabi.newpipe.BuildConfig.DEBUG;
|
import static org.schabi.newpipe.BuildConfig.DEBUG;
|
||||||
|
|
||||||
public class DownloadManagerImpl implements DownloadManager
|
public class DownloadManagerImpl implements DownloadManager {
|
||||||
{
|
|
||||||
private static final String TAG = DownloadManagerImpl.class.getSimpleName();
|
private static final String TAG = DownloadManagerImpl.class.getSimpleName();
|
||||||
private final DownloadDataSource mDownloadDataSource;
|
private final DownloadDataSource mDownloadDataSource;
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ public class DownloadManagerImpl implements DownloadManager
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance
|
* Create a new instance
|
||||||
|
*
|
||||||
* @param searchLocations the directories to search for unfinished downloads
|
* @param searchLocations the directories to search for unfinished downloads
|
||||||
* @param downloadDataSource the data source for finished downloads
|
* @param downloadDataSource the data source for finished downloads
|
||||||
*/
|
*/
|
||||||
|
@ -40,18 +41,18 @@ public class DownloadManagerImpl implements DownloadManager
|
||||||
@Override
|
@Override
|
||||||
public int startMission(String url, String location, String name, boolean isAudio, int threads) {
|
public int startMission(String url, String location, String name, boolean isAudio, int threads) {
|
||||||
DownloadMission existingMission = getMissionByLocation(location, name);
|
DownloadMission existingMission = getMissionByLocation(location, name);
|
||||||
if(existingMission != null) {
|
if (existingMission != null) {
|
||||||
// Already downloaded or downloading
|
// Already downloaded or downloading
|
||||||
if(existingMission.finished) {
|
if (existingMission.finished) {
|
||||||
// Overwrite mission
|
// Overwrite mission
|
||||||
deleteMission(mMissions.indexOf(existingMission));
|
deleteMission(mMissions.indexOf(existingMission));
|
||||||
} else {
|
} else {
|
||||||
// Rename file (?)
|
// Rename file (?)
|
||||||
try {
|
try {
|
||||||
name = generateUniqueName(location, name);
|
name = generateUniqueName(location, name);
|
||||||
}catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "Unable to generate unique name", e);
|
Log.e(TAG, "Unable to generate unique name", e);
|
||||||
name = System.currentTimeMillis() + name ;
|
name = System.currentTimeMillis() + name;
|
||||||
Log.i(TAG, "Using " + name);
|
Log.i(TAG, "Using " + name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,7 +85,7 @@ public class DownloadManagerImpl implements DownloadManager
|
||||||
@Override
|
@Override
|
||||||
public void deleteMission(int i) {
|
public void deleteMission(int i) {
|
||||||
DownloadMission mission = getMission(i);
|
DownloadMission mission = getMission(i);
|
||||||
if(mission.finished) {
|
if (mission.finished) {
|
||||||
mDownloadDataSource.deleteMission(mission);
|
mDownloadDataSource.deleteMission(mission);
|
||||||
}
|
}
|
||||||
mission.delete();
|
mission.delete();
|
||||||
|
@ -94,7 +95,7 @@ public class DownloadManagerImpl implements DownloadManager
|
||||||
private void loadMissions(Iterable<String> searchLocations) {
|
private void loadMissions(Iterable<String> searchLocations) {
|
||||||
mMissions.clear();
|
mMissions.clear();
|
||||||
loadFinishedMissions();
|
loadFinishedMissions();
|
||||||
for(String location: searchLocations) {
|
for (String location : searchLocations) {
|
||||||
loadMissions(location);
|
loadMissions(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +107,7 @@ public class DownloadManagerImpl implements DownloadManager
|
||||||
*/
|
*/
|
||||||
private void loadFinishedMissions() {
|
private void loadFinishedMissions() {
|
||||||
List<DownloadMission> finishedMissions = mDownloadDataSource.loadMissions();
|
List<DownloadMission> finishedMissions = mDownloadDataSource.loadMissions();
|
||||||
if(finishedMissions == null) {
|
if (finishedMissions == null) {
|
||||||
finishedMissions = new ArrayList<>();
|
finishedMissions = new ArrayList<>();
|
||||||
}
|
}
|
||||||
// Ensure its sorted
|
// Ensure its sorted
|
||||||
|
@ -117,10 +118,10 @@ public class DownloadManagerImpl implements DownloadManager
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mMissions.ensureCapacity(mMissions.size() + finishedMissions.size());
|
mMissions.ensureCapacity(mMissions.size() + finishedMissions.size());
|
||||||
for(DownloadMission mission: finishedMissions) {
|
for (DownloadMission mission : finishedMissions) {
|
||||||
File downloadedFile = mission.getDownloadedFile();
|
File downloadedFile = mission.getDownloadedFile();
|
||||||
if(!downloadedFile.isFile()) {
|
if (!downloadedFile.isFile()) {
|
||||||
if(DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "downloaded file removed: " + downloadedFile.getAbsolutePath());
|
Log.d(TAG, "downloaded file removed: " + downloadedFile.getAbsolutePath());
|
||||||
}
|
}
|
||||||
mDownloadDataSource.deleteMission(mission);
|
mDownloadDataSource.deleteMission(mission);
|
||||||
|
@ -140,7 +141,7 @@ public class DownloadManagerImpl implements DownloadManager
|
||||||
if (f.exists() && f.isDirectory()) {
|
if (f.exists() && f.isDirectory()) {
|
||||||
File[] subs = f.listFiles();
|
File[] subs = f.listFiles();
|
||||||
|
|
||||||
if(subs == null) {
|
if (subs == null) {
|
||||||
Log.e(TAG, "listFiles() returned null");
|
Log.e(TAG, "listFiles() returned null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -158,7 +159,7 @@ public class DownloadManagerImpl implements DownloadManager
|
||||||
DownloadMission mis = new Gson().fromJson(str, DownloadMission.class);
|
DownloadMission mis = new Gson().fromJson(str, DownloadMission.class);
|
||||||
|
|
||||||
if (mis.finished) {
|
if (mis.finished) {
|
||||||
if(!sub.delete()) {
|
if (!sub.delete()) {
|
||||||
Log.w(TAG, "Unable to delete .giga file: " + sub.getPath());
|
Log.w(TAG, "Unable to delete .giga file: " + sub.getPath());
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
@ -205,13 +206,16 @@ public class DownloadManagerImpl implements DownloadManager
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a mission by its location and name
|
* Get a mission by its location and name
|
||||||
|
*
|
||||||
* @param location the location
|
* @param location the location
|
||||||
* @param name the name
|
* @param name the name
|
||||||
* @return the mission or null if no such mission exists
|
* @return the mission or null if no such mission exists
|
||||||
*/
|
*/
|
||||||
private @Nullable DownloadMission getMissionByLocation(String location, String name) {
|
private
|
||||||
for(DownloadMission mission: mMissions) {
|
@Nullable
|
||||||
if(location.equals(mission.location) && name.equals(mission.name)) {
|
DownloadMission getMissionByLocation(String location, String name) {
|
||||||
|
for (DownloadMission mission : mMissions) {
|
||||||
|
if (location.equals(mission.location) && name.equals(mission.name)) {
|
||||||
return mission;
|
return mission;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,7 +224,7 @@ public class DownloadManagerImpl implements DownloadManager
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Splits the filename into name and extension
|
* Splits the filename into name and extension
|
||||||
*
|
* <p>
|
||||||
* Dots are ignored if they appear: not at all, at the beginning of the file,
|
* Dots are ignored if they appear: not at all, at the beginning of the file,
|
||||||
* at the end of the file
|
* at the end of the file
|
||||||
*
|
*
|
||||||
|
@ -229,7 +233,7 @@ public class DownloadManagerImpl implements DownloadManager
|
||||||
*/
|
*/
|
||||||
private static String[] splitName(String name) {
|
private static String[] splitName(String name) {
|
||||||
int dotIndex = name.lastIndexOf('.');
|
int dotIndex = name.lastIndexOf('.');
|
||||||
if(dotIndex <= 0 || (dotIndex == name.length() - 1)) {
|
if (dotIndex <= 0 || (dotIndex == name.length() - 1)) {
|
||||||
return new String[]{name, ""};
|
return new String[]{name, ""};
|
||||||
} else {
|
} else {
|
||||||
return new String[]{name.substring(0, dotIndex), name.substring(dotIndex + 1)};
|
return new String[]{name.substring(0, dotIndex), name.substring(dotIndex + 1)};
|
||||||
|
@ -238,8 +242,9 @@ public class DownloadManagerImpl implements DownloadManager
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a unique file name.
|
* Generates a unique file name.
|
||||||
*
|
* <p>
|
||||||
* e.g. "myname (1).txt" if the name "myname.txt" exists.
|
* e.g. "myname (1).txt" if the name "myname.txt" exists.
|
||||||
|
*
|
||||||
* @param location the location (to check for existing files)
|
* @param location the location (to check for existing files)
|
||||||
* @param name the name of the file
|
* @param name the name of the file
|
||||||
* @return the unique file name
|
* @return the unique file name
|
||||||
|
@ -247,10 +252,10 @@ public class DownloadManagerImpl implements DownloadManager
|
||||||
* @throws SecurityException if the location is not readable
|
* @throws SecurityException if the location is not readable
|
||||||
*/
|
*/
|
||||||
private static String generateUniqueName(String location, String name) {
|
private static String generateUniqueName(String location, String name) {
|
||||||
if(location == null) throw new NullPointerException("location is null");
|
if (location == null) throw new NullPointerException("location is null");
|
||||||
if(name == null) throw new NullPointerException("name is null");
|
if (name == null) throw new NullPointerException("name is null");
|
||||||
File destination = new File(location);
|
File destination = new File(location);
|
||||||
if(!destination.isDirectory()) {
|
if (!destination.isDirectory()) {
|
||||||
throw new IllegalArgumentException("location is not a directory: " + location);
|
throw new IllegalArgumentException("location is not a directory: " + location);
|
||||||
}
|
}
|
||||||
final String[] nameParts = splitName(name);
|
final String[] nameParts = splitName(name);
|
||||||
|
@ -266,7 +271,7 @@ public class DownloadManagerImpl implements DownloadManager
|
||||||
do {
|
do {
|
||||||
newName = nameParts[0] + " (" + downloadIndex + ")." + nameParts[1];
|
newName = nameParts[0] + " (" + downloadIndex + ")." + nameParts[1];
|
||||||
++downloadIndex;
|
++downloadIndex;
|
||||||
if(downloadIndex == 1000) { // Probably an error on our side
|
if (downloadIndex == 1000) { // Probably an error on our side
|
||||||
throw new RuntimeException("Too many existing files");
|
throw new RuntimeException("Too many existing files");
|
||||||
}
|
}
|
||||||
} while (Arrays.binarySearch(existingName, newName) >= 0);
|
} while (Arrays.binarySearch(existingName, newName) >= 0);
|
||||||
|
@ -346,7 +351,7 @@ public class DownloadManagerImpl implements DownloadManager
|
||||||
private final DownloadMission mMission;
|
private final DownloadMission mMission;
|
||||||
|
|
||||||
private MissionListener(DownloadMission mission) {
|
private MissionListener(DownloadMission mission) {
|
||||||
if(mission == null) throw new NullPointerException("mission is null");
|
if (mission == null) throw new NullPointerException("mission is null");
|
||||||
// Could the mission be passed in onFinish()?
|
// Could the mission be passed in onFinish()?
|
||||||
mMission = mission;
|
mMission = mission;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,15 +18,16 @@ import us.shandian.giga.util.Utility;
|
||||||
|
|
||||||
import static org.schabi.newpipe.BuildConfig.DEBUG;
|
import static org.schabi.newpipe.BuildConfig.DEBUG;
|
||||||
|
|
||||||
public class DownloadMission
|
public class DownloadMission {
|
||||||
{
|
|
||||||
private static final String TAG = DownloadMission.class.getSimpleName();
|
private static final String TAG = DownloadMission.class.getSimpleName();
|
||||||
|
|
||||||
public interface MissionListener {
|
public interface MissionListener {
|
||||||
HashMap<MissionListener, Handler> handlerStore = new HashMap<>();
|
HashMap<MissionListener, Handler> handlerStore = new HashMap<>();
|
||||||
|
|
||||||
void onProgressUpdate(DownloadMission downloadMission, long done, long total);
|
void onProgressUpdate(DownloadMission downloadMission, long done, long total);
|
||||||
|
|
||||||
void onFinish(DownloadMission downloadMission);
|
void onFinish(DownloadMission downloadMission);
|
||||||
|
|
||||||
void onError(DownloadMission downloadMission, int errCode);
|
void onError(DownloadMission downloadMission, int errCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,12 +85,12 @@ public class DownloadMission
|
||||||
}
|
}
|
||||||
|
|
||||||
public DownloadMission(String name, String url, String location) {
|
public DownloadMission(String name, String url, String location) {
|
||||||
if(name == null) throw new NullPointerException("name is null");
|
if (name == null) throw new NullPointerException("name is null");
|
||||||
if(name.isEmpty()) throw new IllegalArgumentException("name is empty");
|
if (name.isEmpty()) throw new IllegalArgumentException("name is empty");
|
||||||
if(url == null) throw new NullPointerException("url is null");
|
if (url == null) throw new NullPointerException("url is null");
|
||||||
if(url.isEmpty()) throw new IllegalArgumentException("url is empty");
|
if (url.isEmpty()) throw new IllegalArgumentException("url is empty");
|
||||||
if(location == null) throw new NullPointerException("location is null");
|
if (location == null) throw new NullPointerException("location is null");
|
||||||
if(location.isEmpty()) throw new IllegalArgumentException("location is empty");
|
if (location.isEmpty()) throw new IllegalArgumentException("location is empty");
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.location = location;
|
this.location = location;
|
||||||
|
@ -97,13 +98,14 @@ public class DownloadMission
|
||||||
|
|
||||||
|
|
||||||
private void checkBlock(long block) {
|
private void checkBlock(long block) {
|
||||||
if(block < 0 || block >= blocks) {
|
if (block < 0 || block >= blocks) {
|
||||||
throw new IllegalArgumentException("illegal block identifier");
|
throw new IllegalArgumentException("illegal block identifier");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a block is reserved
|
* Check if a block is reserved
|
||||||
|
*
|
||||||
* @param block the block identifier
|
* @param block the block identifier
|
||||||
* @return true if the block is reserved and false if otherwise
|
* @return true if the block is reserved and false if otherwise
|
||||||
*/
|
*/
|
||||||
|
@ -121,6 +123,7 @@ public class DownloadMission
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the download position of the file
|
* Set the download position of the file
|
||||||
|
*
|
||||||
* @param threadId the identifier of the thread
|
* @param threadId the identifier of the thread
|
||||||
* @param position the download position of the thread
|
* @param position the download position of the thread
|
||||||
*/
|
*/
|
||||||
|
@ -130,6 +133,7 @@ public class DownloadMission
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the position of a thread
|
* Get the position of a thread
|
||||||
|
*
|
||||||
* @param threadId the identifier of the thread
|
* @param threadId the identifier of the thread
|
||||||
* @return the position for the thread
|
* @return the position for the thread
|
||||||
*/
|
*/
|
||||||
|
@ -154,7 +158,7 @@ public class DownloadMission
|
||||||
writeThisToFile();
|
writeThisToFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (WeakReference<MissionListener> ref: mListeners) {
|
for (WeakReference<MissionListener> ref : mListeners) {
|
||||||
final MissionListener listener = ref.get();
|
final MissionListener listener = ref.get();
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
MissionListener.handlerStore.get(listener).post(new Runnable() {
|
MissionListener.handlerStore.get(listener).post(new Runnable() {
|
||||||
|
@ -234,8 +238,7 @@ public class DownloadMission
|
||||||
for (Iterator<WeakReference<MissionListener>> iterator = mListeners.iterator();
|
for (Iterator<WeakReference<MissionListener>> iterator = mListeners.iterator();
|
||||||
iterator.hasNext(); ) {
|
iterator.hasNext(); ) {
|
||||||
WeakReference<MissionListener> weakRef = iterator.next();
|
WeakReference<MissionListener> weakRef = iterator.next();
|
||||||
if (listener!=null && listener == weakRef.get())
|
if (listener != null && listener == weakRef.get()) {
|
||||||
{
|
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -315,6 +318,7 @@ public class DownloadMission
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the path of the meta file
|
* Get the path of the meta file
|
||||||
|
*
|
||||||
* @return the path to the meta file
|
* @return the path to the meta file
|
||||||
*/
|
*/
|
||||||
private String getMetaFilename() {
|
private String getMetaFilename() {
|
||||||
|
|
|
@ -13,15 +13,14 @@ import static org.schabi.newpipe.BuildConfig.DEBUG;
|
||||||
* Runnable to download blocks of a file until the file is completely downloaded,
|
* Runnable to download blocks of a file until the file is completely downloaded,
|
||||||
* an error occurs or the process is stopped.
|
* an error occurs or the process is stopped.
|
||||||
*/
|
*/
|
||||||
public class DownloadRunnable implements Runnable
|
public class DownloadRunnable implements Runnable {
|
||||||
{
|
|
||||||
private static final String TAG = DownloadRunnable.class.getSimpleName();
|
private static final String TAG = DownloadRunnable.class.getSimpleName();
|
||||||
|
|
||||||
private final DownloadMission mMission;
|
private final DownloadMission mMission;
|
||||||
private final int mId;
|
private final int mId;
|
||||||
|
|
||||||
public DownloadRunnable(DownloadMission mission, int id) {
|
public DownloadRunnable(DownloadMission mission, int id) {
|
||||||
if(mission == null) throw new NullPointerException("mission is null");
|
if (mission == null) throw new NullPointerException("mission is null");
|
||||||
mMission = mission;
|
mMission = mission;
|
||||||
mId = id;
|
mId = id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,12 @@ import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
// Single-threaded fallback mode
|
// Single-threaded fallback mode
|
||||||
public class DownloadRunnableFallback implements Runnable
|
public class DownloadRunnableFallback implements Runnable {
|
||||||
{
|
|
||||||
private final DownloadMission mMission;
|
private final DownloadMission mMission;
|
||||||
//private int mId;
|
//private int mId;
|
||||||
|
|
||||||
public DownloadRunnableFallback(DownloadMission mission) {
|
public DownloadRunnableFallback(DownloadMission mission) {
|
||||||
if(mission == null) throw new NullPointerException("mission is null");
|
if (mission == null) throw new NullPointerException("mission is null");
|
||||||
//mId = id;
|
//mId = id;
|
||||||
mMission = mission;
|
mMission = mission;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,7 @@ public class DownloadMissionSQLiteHelper extends SQLiteOpenHelper {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all values of the download mission as ContentValues.
|
* Returns all values of the download mission as ContentValues.
|
||||||
|
*
|
||||||
* @param downloadMission the download mission
|
* @param downloadMission the download mission
|
||||||
* @return the content values
|
* @return the content values
|
||||||
*/
|
*/
|
||||||
|
@ -88,7 +89,7 @@ public class DownloadMissionSQLiteHelper extends SQLiteOpenHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DownloadMission getMissionFromCursor(Cursor cursor) {
|
public static DownloadMission getMissionFromCursor(Cursor cursor) {
|
||||||
if(cursor == null) throw new NullPointerException("cursor is null");
|
if (cursor == null) throw new NullPointerException("cursor is null");
|
||||||
int pos;
|
int pos;
|
||||||
String name = cursor.getString(cursor.getColumnIndexOrThrow(KEY_NAME));
|
String name = cursor.getString(cursor.getColumnIndexOrThrow(KEY_NAME));
|
||||||
String location = cursor.getString(cursor.getColumnIndexOrThrow(KEY_LOCATION));
|
String location = cursor.getString(cursor.getColumnIndexOrThrow(KEY_LOCATION));
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class SQLiteDownloadDataSource implements DownloadDataSource {
|
||||||
null, null, null, DownloadMissionSQLiteHelper.KEY_TIMESTAMP);
|
null, null, null, DownloadMissionSQLiteHelper.KEY_TIMESTAMP);
|
||||||
|
|
||||||
int count = cursor.getCount();
|
int count = cursor.getCount();
|
||||||
if(count == 0) return new ArrayList<>();
|
if (count == 0) return new ArrayList<>();
|
||||||
result = new ArrayList<>(count);
|
result = new ArrayList<>(count);
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
result.add(DownloadMissionSQLiteHelper.getMissionFromCursor(cursor));
|
result.add(DownloadMissionSQLiteHelper.getMissionFromCursor(cursor));
|
||||||
|
@ -47,7 +47,7 @@ public class SQLiteDownloadDataSource implements DownloadDataSource {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addMission(DownloadMission downloadMission) {
|
public void addMission(DownloadMission downloadMission) {
|
||||||
if(downloadMission == null) throw new NullPointerException("downloadMission is null");
|
if (downloadMission == null) throw new NullPointerException("downloadMission is null");
|
||||||
SQLiteDatabase database = downloadMissionSQLiteHelper.getWritableDatabase();
|
SQLiteDatabase database = downloadMissionSQLiteHelper.getWritableDatabase();
|
||||||
ContentValues values = DownloadMissionSQLiteHelper.getValuesOfMission(downloadMission);
|
ContentValues values = DownloadMissionSQLiteHelper.getValuesOfMission(downloadMission);
|
||||||
database.insert(MISSIONS_TABLE_NAME, null, values);
|
database.insert(MISSIONS_TABLE_NAME, null, values);
|
||||||
|
@ -55,21 +55,21 @@ public class SQLiteDownloadDataSource implements DownloadDataSource {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateMission(DownloadMission downloadMission) {
|
public void updateMission(DownloadMission downloadMission) {
|
||||||
if(downloadMission == null) throw new NullPointerException("downloadMission is null");
|
if (downloadMission == null) throw new NullPointerException("downloadMission is null");
|
||||||
SQLiteDatabase database = downloadMissionSQLiteHelper.getWritableDatabase();
|
SQLiteDatabase database = downloadMissionSQLiteHelper.getWritableDatabase();
|
||||||
ContentValues values = DownloadMissionSQLiteHelper.getValuesOfMission(downloadMission);
|
ContentValues values = DownloadMissionSQLiteHelper.getValuesOfMission(downloadMission);
|
||||||
String whereClause = KEY_LOCATION+ " = ? AND " +
|
String whereClause = KEY_LOCATION + " = ? AND " +
|
||||||
KEY_NAME + " = ?";
|
KEY_NAME + " = ?";
|
||||||
int rowsAffected = database.update(MISSIONS_TABLE_NAME, values,
|
int rowsAffected = database.update(MISSIONS_TABLE_NAME, values,
|
||||||
whereClause, new String[]{downloadMission.location, downloadMission.name});
|
whereClause, new String[]{downloadMission.location, downloadMission.name});
|
||||||
if(rowsAffected != 1) {
|
if (rowsAffected != 1) {
|
||||||
Log.e(TAG, "Expected 1 row to be affected by update but got " + rowsAffected);
|
Log.e(TAG, "Expected 1 row to be affected by update but got " + rowsAffected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteMission(DownloadMission downloadMission) {
|
public void deleteMission(DownloadMission downloadMission) {
|
||||||
if(downloadMission == null) throw new NullPointerException("downloadMission is null");
|
if (downloadMission == null) throw new NullPointerException("downloadMission is null");
|
||||||
SQLiteDatabase database = downloadMissionSQLiteHelper.getWritableDatabase();
|
SQLiteDatabase database = downloadMissionSQLiteHelper.getWritableDatabase();
|
||||||
database.delete(MISSIONS_TABLE_NAME,
|
database.delete(MISSIONS_TABLE_NAME,
|
||||||
KEY_LOCATION + " = ? AND " +
|
KEY_LOCATION + " = ? AND " +
|
||||||
|
|
|
@ -6,7 +6,6 @@ import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
@ -16,6 +15,7 @@ import android.os.HandlerThread;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.support.v4.app.NotificationCompat.Builder;
|
import android.support.v4.app.NotificationCompat.Builder;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v4.content.PermissionChecker;
|
import android.support.v4.content.PermissionChecker;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
@ -34,8 +34,7 @@ import us.shandian.giga.get.sqlite.SQLiteDownloadDataSource;
|
||||||
|
|
||||||
import static org.schabi.newpipe.BuildConfig.DEBUG;
|
import static org.schabi.newpipe.BuildConfig.DEBUG;
|
||||||
|
|
||||||
public class DownloadManagerService extends Service
|
public class DownloadManagerService extends Service {
|
||||||
{
|
|
||||||
|
|
||||||
private static final String TAG = DownloadManagerService.class.getSimpleName();
|
private static final String TAG = DownloadManagerService.class.getSimpleName();
|
||||||
|
|
||||||
|
@ -58,7 +57,6 @@ public class DownloadManagerService extends Service
|
||||||
private DownloadDataSource mDataSource;
|
private DownloadDataSource mDataSource;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private MissionListener missionListener = new MissionListener();
|
private MissionListener missionListener = new MissionListener();
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,7 +75,7 @@ public class DownloadManagerService extends Service
|
||||||
}
|
}
|
||||||
|
|
||||||
mBinder = new DMBinder();
|
mBinder = new DMBinder();
|
||||||
if(mDataSource == null) {
|
if (mDataSource == null) {
|
||||||
mDataSource = new SQLiteDownloadDataSource(this);
|
mDataSource = new SQLiteDownloadDataSource(this);
|
||||||
}
|
}
|
||||||
if (mManager == null) {
|
if (mManager == null) {
|
||||||
|
@ -95,7 +93,7 @@ public class DownloadManagerService extends Service
|
||||||
i.setAction(Intent.ACTION_MAIN);
|
i.setAction(Intent.ACTION_MAIN);
|
||||||
i.setClass(this, DownloadActivity.class);
|
i.setClass(this, DownloadActivity.class);
|
||||||
|
|
||||||
Drawable icon = this.getResources().getDrawable(R.mipmap.ic_launcher);
|
Drawable icon = ContextCompat.getDrawable(this, R.mipmap.ic_launcher);
|
||||||
|
|
||||||
Builder builder = new Builder(this)
|
Builder builder = new Builder(this)
|
||||||
.setContentIntent(PendingIntent.getActivity(this, 0, i, 0))
|
.setContentIntent(PendingIntent.getActivity(this, 0, i, 0))
|
||||||
|
@ -159,7 +157,7 @@ public class DownloadManagerService extends Service
|
||||||
}
|
}
|
||||||
Log.i(TAG, "Got intent: " + intent);
|
Log.i(TAG, "Got intent: " + intent);
|
||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
if(action != null && action.equals(Intent.ACTION_RUN)) {
|
if (action != null && action.equals(Intent.ACTION_RUN)) {
|
||||||
String name = intent.getStringExtra(EXTRA_NAME);
|
String name = intent.getStringExtra(EXTRA_NAME);
|
||||||
String location = intent.getStringExtra(EXTRA_LOCATION);
|
String location = intent.getStringExtra(EXTRA_LOCATION);
|
||||||
int threads = intent.getIntExtra(EXTRA_THREADS, 1);
|
int threads = intent.getIntExtra(EXTRA_THREADS, 1);
|
||||||
|
@ -190,13 +188,13 @@ public class DownloadManagerService extends Service
|
||||||
int permissionCheck;
|
int permissionCheck;
|
||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
|
||||||
permissionCheck = PermissionChecker.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
|
permissionCheck = PermissionChecker.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
|
||||||
if(permissionCheck == PermissionChecker.PERMISSION_DENIED) {
|
if (permissionCheck == PermissionChecker.PERMISSION_DENIED) {
|
||||||
Toast.makeText(this, "Permission denied (read)", Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, "Permission denied (read)", Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
permissionCheck = PermissionChecker.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
permissionCheck = PermissionChecker.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||||
if(permissionCheck == PermissionChecker.PERMISSION_DENIED) {
|
if (permissionCheck == PermissionChecker.PERMISSION_DENIED) {
|
||||||
Toast.makeText(this, "Permission denied (write)", Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, "Permission denied (write)", Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +225,7 @@ public class DownloadManagerService extends Service
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class MissionListener implements DownloadMission.MissionListener {
|
private class MissionListener implements DownloadMission.MissionListener {
|
||||||
@Override
|
@Override
|
||||||
public void onProgressUpdate(DownloadMission downloadMission, long done, long total) {
|
public void onProgressUpdate(DownloadMission downloadMission, long done, long total) {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
|
|
|
@ -7,6 +7,8 @@ import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.support.v4.content.FileProvider;
|
import android.support.v4.content.FileProvider;
|
||||||
|
import android.support.v4.view.ViewCompat;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
|
@ -18,14 +20,13 @@ import android.widget.ImageView;
|
||||||
import android.widget.PopupMenu;
|
import android.widget.PopupMenu;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import android.support.v7.widget.RecyclerView;
|
import org.schabi.newpipe.R;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
|
||||||
import us.shandian.giga.get.DownloadManager;
|
import us.shandian.giga.get.DownloadManager;
|
||||||
import us.shandian.giga.get.DownloadMission;
|
import us.shandian.giga.get.DownloadMission;
|
||||||
import us.shandian.giga.service.DownloadManagerService;
|
import us.shandian.giga.service.DownloadManagerService;
|
||||||
|
@ -35,8 +36,7 @@ import us.shandian.giga.util.Utility;
|
||||||
import static android.content.Intent.FLAG_GRANT_PREFIX_URI_PERMISSION;
|
import static android.content.Intent.FLAG_GRANT_PREFIX_URI_PERMISSION;
|
||||||
import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
|
import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
|
||||||
|
|
||||||
public class MissionAdapter extends RecyclerView.Adapter<MissionAdapter.ViewHolder>
|
public class MissionAdapter extends RecyclerView.Adapter<MissionAdapter.ViewHolder> {
|
||||||
{
|
|
||||||
private static final Map<Integer, String> ALGORITHMS = new HashMap<>();
|
private static final Map<Integer, String> ALGORITHMS = new HashMap<>();
|
||||||
private static final String TAG = "MissionAdapter";
|
private static final String TAG = "MissionAdapter";
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ public class MissionAdapter extends RecyclerView.Adapter<MissionAdapter.ViewHold
|
||||||
h.size.setText(Utility.formatBytes(ms.length));
|
h.size.setText(Utility.formatBytes(ms.length));
|
||||||
|
|
||||||
h.progress = new ProgressDrawable(mContext, Utility.getBackgroundForFileType(type), Utility.getForegroundForFileType(type));
|
h.progress = new ProgressDrawable(mContext, Utility.getBackgroundForFileType(type), Utility.getForegroundForFileType(type));
|
||||||
h.bkg.setBackgroundDrawable(h.progress);
|
ViewCompat.setBackground(h.bkg, h.progress);
|
||||||
|
|
||||||
h.observer = new MissionObserver(this, h);
|
h.observer = new MissionObserver(this, h);
|
||||||
ms.addListener(h.observer);
|
ms.addListener(h.observer);
|
||||||
|
@ -285,33 +285,6 @@ public class MissionAdapter extends RecyclerView.Adapter<MissionAdapter.ViewHold
|
||||||
mContext.startActivity(intent);
|
mContext.startActivity(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ChecksumTask extends AsyncTask<String, Void, String> {
|
|
||||||
ProgressDialog prog;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPreExecute() {
|
|
||||||
super.onPreExecute();
|
|
||||||
|
|
||||||
// Create dialog
|
|
||||||
prog = new ProgressDialog(mContext);
|
|
||||||
prog.setCancelable(false);
|
|
||||||
prog.setMessage(mContext.getString(R.string.msg_wait));
|
|
||||||
prog.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String doInBackground(String... params) {
|
|
||||||
return Utility.checksum(params[0], params[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(String result) {
|
|
||||||
super.onPostExecute(result);
|
|
||||||
prog.dismiss();
|
|
||||||
Utility.copyToClipboard(mContext, result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
public DownloadMission mission;
|
public DownloadMission mission;
|
||||||
public int position;
|
public int position;
|
||||||
|
@ -332,12 +305,12 @@ public class MissionAdapter extends RecyclerView.Adapter<MissionAdapter.ViewHold
|
||||||
public ViewHolder(View v) {
|
public ViewHolder(View v) {
|
||||||
super(v);
|
super(v);
|
||||||
|
|
||||||
status = Utility.findViewById(v, R.id.item_status);
|
status = (TextView) v.findViewById(R.id.item_status);
|
||||||
icon = Utility.findViewById(v, R.id.item_icon);
|
icon = (ImageView) v.findViewById(R.id.item_icon);
|
||||||
name = Utility.findViewById(v, R.id.item_name);
|
name = (TextView) v.findViewById(R.id.item_name);
|
||||||
size = Utility.findViewById(v, R.id.item_size);
|
size = (TextView) v.findViewById(R.id.item_size);
|
||||||
bkg = Utility.findViewById(v, R.id.item_bkg);
|
bkg = v.findViewById(R.id.item_bkg);
|
||||||
menu = Utility.findViewById(v, R.id.item_more);
|
menu = (ImageView) v.findViewById(R.id.item_more);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,4 +345,31 @@ public class MissionAdapter extends RecyclerView.Adapter<MissionAdapter.ViewHold
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ChecksumTask extends AsyncTask<String, Void, String> {
|
||||||
|
ProgressDialog prog;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPreExecute() {
|
||||||
|
super.onPreExecute();
|
||||||
|
|
||||||
|
// Create dialog
|
||||||
|
prog = new ProgressDialog(mContext);
|
||||||
|
prog.setCancelable(false);
|
||||||
|
prog.setMessage(mContext.getString(R.string.msg_wait));
|
||||||
|
prog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String doInBackground(String... params) {
|
||||||
|
return Utility.checksum(params[0], params[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(String result) {
|
||||||
|
super.onPostExecute(result);
|
||||||
|
prog.dismiss();
|
||||||
|
Utility.copyToClipboard(mContext, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,14 +6,16 @@ import android.graphics.ColorFilter;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.PixelFormat;
|
import android.graphics.PixelFormat;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.support.annotation.ColorRes;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
|
|
||||||
public class ProgressDrawable extends Drawable
|
public class ProgressDrawable extends Drawable {
|
||||||
{
|
|
||||||
private float mProgress;
|
private float mProgress;
|
||||||
private int mBackgroundColor, mForegroundColor;
|
private int mBackgroundColor, mForegroundColor;
|
||||||
|
|
||||||
public ProgressDrawable(Context context, int background, int foreground) {
|
public ProgressDrawable(Context context, @ColorRes int background, @ColorRes int foreground) {
|
||||||
this(context.getResources().getColor(background), context.getResources().getColor(foreground));
|
this(ContextCompat.getColor(context, background), ContextCompat.getColor(context, foreground));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProgressDrawable(int background, int foreground) {
|
public ProgressDrawable(int background, int foreground) {
|
||||||
|
@ -27,7 +29,7 @@ public class ProgressDrawable extends Drawable
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Canvas canvas) {
|
public void draw(@NonNull Canvas canvas) {
|
||||||
int width = canvas.getWidth();
|
int width = canvas.getWidth();
|
||||||
int height = canvas.getHeight();
|
int height = canvas.getHeight();
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
package us.shandian.giga.ui.common;
|
package us.shandian.giga.ui.common;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import android.support.v7.app.ActionBarActivity;
|
import android.support.v7.app.ActionBarActivity;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import us.shandian.giga.util.Utility;
|
|
||||||
|
|
||||||
public abstract class ToolbarActivity extends ActionBarActivity
|
public abstract class ToolbarActivity extends ActionBarActivity {
|
||||||
{
|
|
||||||
protected Toolbar mToolbar;
|
protected Toolbar mToolbar;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -17,7 +14,7 @@ public abstract class ToolbarActivity extends ActionBarActivity
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(getLayoutResource());
|
setContentView(getLayoutResource());
|
||||||
|
|
||||||
mToolbar = Utility.findViewById(this, R.id.toolbar);
|
mToolbar = (Toolbar) this.findViewById(R.id.toolbar);
|
||||||
|
|
||||||
setSupportActionBar(mToolbar);
|
setSupportActionBar(mToolbar);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,7 @@ package us.shandian.giga.ui.fragment;
|
||||||
import us.shandian.giga.get.DownloadManager;
|
import us.shandian.giga.get.DownloadManager;
|
||||||
import us.shandian.giga.service.DownloadManagerService;
|
import us.shandian.giga.service.DownloadManagerService;
|
||||||
|
|
||||||
public class AllMissionsFragment extends MissionsFragment
|
public class AllMissionsFragment extends MissionsFragment {
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DownloadManager setupDownloadManager(DownloadManagerService.DMBinder binder) {
|
protected DownloadManager setupDownloadManager(DownloadManagerService.DMBinder binder) {
|
||||||
|
|
|
@ -23,10 +23,8 @@ import org.schabi.newpipe.R;
|
||||||
import us.shandian.giga.get.DownloadManager;
|
import us.shandian.giga.get.DownloadManager;
|
||||||
import us.shandian.giga.service.DownloadManagerService;
|
import us.shandian.giga.service.DownloadManagerService;
|
||||||
import us.shandian.giga.ui.adapter.MissionAdapter;
|
import us.shandian.giga.ui.adapter.MissionAdapter;
|
||||||
import us.shandian.giga.util.Utility;
|
|
||||||
|
|
||||||
public abstract class MissionsFragment extends Fragment
|
public abstract class MissionsFragment extends Fragment {
|
||||||
{
|
|
||||||
private DownloadManager mManager;
|
private DownloadManager mManager;
|
||||||
private DownloadManagerService.DMBinder mBinder;
|
private DownloadManagerService.DMBinder mBinder;
|
||||||
|
|
||||||
|
@ -70,7 +68,7 @@ public abstract class MissionsFragment extends Fragment
|
||||||
getActivity().bindService(i, mConnection, Context.BIND_AUTO_CREATE);
|
getActivity().bindService(i, mConnection, Context.BIND_AUTO_CREATE);
|
||||||
|
|
||||||
// Views
|
// Views
|
||||||
mList = Utility.findViewById(v, R.id.mission_recycler);
|
mList = (RecyclerView) v.findViewById(R.id.mission_recycler);
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
mGridManager = new GridLayoutManager(getActivity(), 2);
|
mGridManager = new GridLayoutManager(getActivity(), 2);
|
||||||
|
@ -82,7 +80,9 @@ public abstract class MissionsFragment extends Fragment
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Added in API level 23. */
|
/**
|
||||||
|
* Added in API level 23.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Context activity) {
|
public void onAttach(Context activity) {
|
||||||
super.onAttach(activity);
|
super.onAttach(activity);
|
||||||
|
@ -93,8 +93,10 @@ public abstract class MissionsFragment extends Fragment
|
||||||
mActivity = activity;
|
mActivity = activity;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** deprecated in API level 23,
|
/**
|
||||||
* but must remain to allow compatibility with api<23 */
|
* deprecated in API level 23,
|
||||||
|
* but must remain to allow compatibility with api<23
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Activity activity) {
|
public void onAttach(Activity activity) {
|
||||||
super.onAttach(activity);
|
super.onAttach(activity);
|
||||||
|
|
|
@ -9,8 +9,7 @@ import java.io.File;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
//todo: replace this by using the internal crash handler of newpipe
|
//todo: replace this by using the internal crash handler of newpipe
|
||||||
public class CrashHandler implements Thread.UncaughtExceptionHandler
|
public class CrashHandler implements Thread.UncaughtExceptionHandler {
|
||||||
{
|
|
||||||
public static final String CRASH_DIR = Environment.getExternalStorageDirectory().getPath() + "/GigaCrash/";
|
public static final String CRASH_DIR = Environment.getExternalStorageDirectory().getPath() + "/GigaCrash/";
|
||||||
public static final String CRASH_LOG = CRASH_DIR + "last_crash.log";
|
public static final String CRASH_LOG = CRASH_DIR + "last_crash.log";
|
||||||
public static final String CRASH_TAG = CRASH_DIR + ".crashed";
|
public static final String CRASH_TAG = CRASH_DIR + ".crashed";
|
||||||
|
|
|
@ -1,32 +1,27 @@
|
||||||
package us.shandian.giga.util;
|
package us.shandian.giga.util;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.ClipboardManager;
|
|
||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
|
import android.content.ClipboardManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.support.annotation.ColorRes;
|
||||||
import android.view.View;
|
import android.support.annotation.DrawableRes;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.R;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
import org.schabi.newpipe.settings.NewPipeSettings;
|
public class Utility {
|
||||||
import org.schabi.newpipe.R;
|
|
||||||
|
|
||||||
import com.nononsenseapps.filepicker.FilePickerActivity;
|
public enum FileType {
|
||||||
import com.nononsenseapps.filepicker.AbstractFilePickerFragment;
|
|
||||||
|
|
||||||
public class Utility
|
|
||||||
{
|
|
||||||
|
|
||||||
public static enum FileType {
|
|
||||||
VIDEO,
|
VIDEO,
|
||||||
MUSIC,
|
MUSIC,
|
||||||
UNKNOWN
|
UNKNOWN
|
||||||
|
@ -109,30 +104,25 @@ public class Utility
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> T findViewById(View v, int id) {
|
@Nullable
|
||||||
return (T) v.findViewById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T findViewById(Activity activity, int id) {
|
|
||||||
return (T) activity.findViewById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getFileExt(String url) {
|
public static String getFileExt(String url) {
|
||||||
if (url.indexOf("?")>-1) {
|
int index;
|
||||||
url = url.substring(0,url.indexOf("?"));
|
if ((index = url.indexOf("?")) > -1) {
|
||||||
|
url = url.substring(0, index);
|
||||||
}
|
}
|
||||||
if (url.lastIndexOf(".") == -1) {
|
|
||||||
|
index = url.lastIndexOf(".");
|
||||||
|
if (index == -1) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
String ext = url.substring(url.lastIndexOf(".") );
|
String ext = url.substring(index);
|
||||||
if (ext.indexOf("%")>-1) {
|
if ((index = ext.indexOf("%")) > -1) {
|
||||||
ext = ext.substring(0,ext.indexOf("%"));
|
ext = ext.substring(0, index);
|
||||||
}
|
}
|
||||||
if (ext.indexOf("/")>-1) {
|
if ((index = ext.indexOf("/")) > -1) {
|
||||||
ext = ext.substring(0,ext.indexOf("/"));
|
ext = ext.substring(0, index);
|
||||||
}
|
}
|
||||||
return ext.toLowerCase();
|
return ext.toLowerCase();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,16 +137,7 @@ public class Utility
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean isMusicFile(String file)
|
@ColorRes
|
||||||
{
|
|
||||||
return Utility.getFileType(file) == FileType.MUSIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean isVideoFile(String file)
|
|
||||||
{
|
|
||||||
return Utility.getFileType(file) == FileType.VIDEO;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getBackgroundForFileType(FileType type) {
|
public static int getBackgroundForFileType(FileType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case MUSIC:
|
case MUSIC:
|
||||||
|
@ -168,6 +149,7 @@ public class Utility
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ColorRes
|
||||||
public static int getForegroundForFileType(FileType type) {
|
public static int getForegroundForFileType(FileType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case MUSIC:
|
case MUSIC:
|
||||||
|
@ -179,8 +161,9 @@ public class Utility
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DrawableRes
|
||||||
public static int getIconForFileType(FileType type) {
|
public static int getIconForFileType(FileType type) {
|
||||||
switch(type) {
|
switch (type) {
|
||||||
case MUSIC:
|
case MUSIC:
|
||||||
return R.drawable.music;
|
return R.drawable.music;
|
||||||
case VIDEO:
|
case VIDEO:
|
||||||
|
@ -190,24 +173,6 @@ public class Utility
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isDirectoryAvailble(String path) {
|
|
||||||
File dir = new File(path);
|
|
||||||
return dir.exists() && dir.isDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isDownloadDirectoryAvailble(Context context) {
|
|
||||||
return isDirectoryAvailble(NewPipeSettings.getVideoDownloadPath(context));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void showDirectoryChooser(Activity activity) {
|
|
||||||
Intent i = new Intent(activity, FilePickerActivity.class);
|
|
||||||
i.setAction(Intent.ACTION_GET_CONTENT);
|
|
||||||
i.putExtra(FilePickerActivity.EXTRA_ALLOW_MULTIPLE, false);
|
|
||||||
i.putExtra(FilePickerActivity.EXTRA_ALLOW_CREATE_DIR, true);
|
|
||||||
i.putExtra(FilePickerActivity.EXTRA_MODE, AbstractFilePickerFragment.MODE_DIR);
|
|
||||||
activity.startActivityForResult(i, 233);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void copyToClipboard(Context context, String str) {
|
public static void copyToClipboard(Context context, String str) {
|
||||||
ClipboardManager cm = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
ClipboardManager cm = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||||
cm.setPrimaryClip(ClipData.newPlainText("text", str));
|
cm.setPrimaryClip(ClipData.newPlainText("text", str));
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package org.schabi.newpipe.report;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.schabi.newpipe.MainActivity;
|
||||||
|
import org.schabi.newpipe.RouterActivity;
|
||||||
|
import org.schabi.newpipe.fragments.detail.VideoDetailFragment;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for {@link ErrorActivity}
|
||||||
|
*/
|
||||||
|
public class ErrorActivityTest {
|
||||||
|
@Test
|
||||||
|
public void getReturnActivity() throws Exception {
|
||||||
|
Class<? extends Activity> returnActivity;
|
||||||
|
returnActivity = ErrorActivity.getReturnActivity(MainActivity.class);
|
||||||
|
assertEquals(MainActivity.class, returnActivity);
|
||||||
|
|
||||||
|
returnActivity = ErrorActivity.getReturnActivity(RouterActivity.class);
|
||||||
|
assertEquals(RouterActivity.class, returnActivity);
|
||||||
|
|
||||||
|
returnActivity = ErrorActivity.getReturnActivity(null);
|
||||||
|
assertNull(returnActivity);
|
||||||
|
|
||||||
|
returnActivity = ErrorActivity.getReturnActivity(Integer.class);
|
||||||
|
assertEquals(MainActivity.class, returnActivity);
|
||||||
|
|
||||||
|
returnActivity = ErrorActivity.getReturnActivity(VideoDetailFragment.class);
|
||||||
|
assertEquals(MainActivity.class, returnActivity);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -31,18 +31,18 @@ import static org.mockito.Mockito.when;
|
||||||
public class DownloadManagerImplTest {
|
public class DownloadManagerImplTest {
|
||||||
|
|
||||||
private DownloadManagerImpl downloadManager;
|
private DownloadManagerImpl downloadManager;
|
||||||
private DownloadDataSource dowloadDataSource;
|
private DownloadDataSource downloadDataSource;
|
||||||
private ArrayList<DownloadMission> missions;
|
private ArrayList<DownloadMission> missions;
|
||||||
|
|
||||||
@org.junit.Before
|
@org.junit.Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
dowloadDataSource = mock(DownloadDataSource.class);
|
downloadDataSource = mock(DownloadDataSource.class);
|
||||||
missions = new ArrayList<>();
|
missions = new ArrayList<>();
|
||||||
for(int i = 0; i < 50; ++i){
|
for(int i = 0; i < 50; ++i){
|
||||||
missions.add(generateFinishedDownloadMission());
|
missions.add(generateFinishedDownloadMission());
|
||||||
}
|
}
|
||||||
when(dowloadDataSource.loadMissions()).thenReturn(new ArrayList<>(missions));
|
when(downloadDataSource.loadMissions()).thenReturn(new ArrayList<>(missions));
|
||||||
downloadManager = new DownloadManagerImpl(new ArrayList<String>(), dowloadDataSource);
|
downloadManager = new DownloadManagerImpl(new ArrayList<String>(), downloadDataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = NullPointerException.class)
|
@Test(expected = NullPointerException.class)
|
||||||
|
@ -82,10 +82,10 @@ public class DownloadManagerImplTest {
|
||||||
missions.add(mission);
|
missions.add(mission);
|
||||||
}
|
}
|
||||||
|
|
||||||
dowloadDataSource = mock(DownloadDataSource.class);
|
downloadDataSource = mock(DownloadDataSource.class);
|
||||||
when(dowloadDataSource.loadMissions()).thenReturn(new ArrayList<>(missions));
|
when(downloadDataSource.loadMissions()).thenReturn(new ArrayList<>(missions));
|
||||||
downloadManager = new DownloadManagerImpl(new ArrayList<String>(), dowloadDataSource);
|
downloadManager = new DownloadManagerImpl(new ArrayList<String>(), downloadDataSource);
|
||||||
verify(dowloadDataSource, times(1)).loadMissions();
|
verify(downloadDataSource, times(1)).loadMissions();
|
||||||
|
|
||||||
assertEquals(50, downloadManager.getCount());
|
assertEquals(50, downloadManager.getCount());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue