Skip to content

Commit 6cc3153

Browse files
author
dfokin
committed
add proxy settings
1 parent 965eea2 commit 6cc3153

13 files changed

Lines changed: 233 additions & 16 deletions

File tree

app/src/debug/java/org/schabi/newpipe/DebugApp.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ class DebugApp : App() {
2626
override fun getDownloader(): Downloader {
2727
val downloader = DownloaderImpl.init(
2828
OkHttpClient.Builder()
29-
.addNetworkInterceptor(StethoInterceptor())
29+
.addNetworkInterceptor(StethoInterceptor()),
30+
this
3031
)
3132
setCookiesToDownloader(downloader)
3233
return downloader

app/src/main/java/org/schabi/newpipe/App.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public void onTerminate() {
131131
}
132132

133133
protected Downloader getDownloader() {
134-
final DownloaderImpl downloader = DownloaderImpl.init(null);
134+
final DownloaderImpl downloader = DownloaderImpl.init(null, this);
135135
setCookiesToDownloader(downloader);
136136
return downloader;
137137
}

app/src/main/java/org/schabi/newpipe/DownloaderImpl.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.schabi.newpipe.extractor.downloader.Request;
1212
import org.schabi.newpipe.extractor.downloader.Response;
1313
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
14+
import org.schabi.newpipe.settings.ProxyManager;
1415
import org.schabi.newpipe.util.InfoCache;
1516

1617
import java.io.IOException;
@@ -52,11 +53,18 @@ private DownloaderImpl(final OkHttpClient.Builder builder) {
5253
* It's recommended to call exactly once in the entire lifetime of the application.
5354
*
5455
* @param builder if null, default builder will be used
56+
* @param context the context to use
5557
* @return a new instance of {@link DownloaderImpl}
5658
*/
57-
public static DownloaderImpl init(@Nullable final OkHttpClient.Builder builder) {
58-
instance = new DownloaderImpl(
59-
builder != null ? builder : new OkHttpClient.Builder());
59+
public static DownloaderImpl init(@Nullable final OkHttpClient.Builder builder,
60+
final Context context) {
61+
final OkHttpClient.Builder builderToUse = builder != null ? builder
62+
: new OkHttpClient.Builder();
63+
final ProxyManager proxyManager = new ProxyManager(context);
64+
if (proxyManager.isProxyEnabled()) {
65+
builderToUse.proxy(proxyManager.getProxy());
66+
}
67+
instance = new DownloaderImpl(builderToUse);
6068
return instance;
6169
}
6270

app/src/main/java/org/schabi/newpipe/player/datasource/YoutubeHttpDataSource.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isWebEmbeddedPlayerStreamingUrl;
2323
import static java.lang.Math.min;
2424

25+
import android.content.Context;
2526
import android.net.Uri;
2627

2728
import androidx.annotation.NonNull;
@@ -47,6 +48,7 @@
4748
import com.google.common.net.HttpHeaders;
4849

4950
import org.schabi.newpipe.DownloaderImpl;
51+
import org.schabi.newpipe.settings.ProxyManager;
5052

5153
import java.io.IOException;
5254
import java.io.InputStream;
@@ -56,6 +58,7 @@
5658
import java.net.HttpURLConnection;
5759
import java.net.MalformedURLException;
5860
import java.net.NoRouteToHostException;
61+
import java.net.Proxy;
5962
import java.net.URL;
6063
import java.util.HashMap;
6164
import java.util.List;
@@ -86,6 +89,7 @@ public final class YoutubeHttpDataSource extends BaseDataSource implements HttpD
8689
*/
8790
public static final class Factory implements HttpDataSource.Factory {
8891

92+
private final Context context;
8993
private final RequestProperties defaultRequestProperties;
9094

9195
@Nullable
@@ -102,8 +106,10 @@ public static final class Factory implements HttpDataSource.Factory {
102106

103107
/**
104108
* Creates an instance.
109+
* @param context the context to use
105110
*/
106-
public Factory() {
111+
public Factory(final Context context) {
112+
this.context = context;
107113
defaultRequestProperties = new RequestProperties();
108114
connectTimeoutMs = DEFAULT_CONNECT_TIMEOUT_MILLIS;
109115
readTimeoutMs = DEFAULT_READ_TIMEOUT_MILLIS;
@@ -222,7 +228,6 @@ public Factory setContentTypePredicate(
222228
* <p>The default is {@code null}.
223229
*
224230
* <p>See {@link DataSource#addTransferListener(TransferListener)}.
225-
*
226231
* @param transferListenerToUse The listener that will be used.
227232
* @return This factory.
228233
*/
@@ -249,6 +254,7 @@ public Factory setKeepPostFor302Redirects(final boolean keepPostFor302RedirectsV
249254
@Override
250255
public YoutubeHttpDataSource createDataSource() {
251256
final YoutubeHttpDataSource dataSource = new YoutubeHttpDataSource(
257+
context,
252258
connectTimeoutMs,
253259
readTimeoutMs,
254260
allowCrossProtocolRedirects,
@@ -274,6 +280,7 @@ public YoutubeHttpDataSource createDataSource() {
274280
private static final String YOUTUBE_BASE_URL = "https://www.youtube.com";
275281
private static final byte[] POST_BODY = new byte[] {0x78, 0};
276282

283+
private final Context context;
277284
private final boolean allowCrossProtocolRedirects;
278285
private final boolean rangeParameterEnabled;
279286
private final boolean rnParameterEnabled;
@@ -301,7 +308,8 @@ public YoutubeHttpDataSource createDataSource() {
301308
private long requestNumber;
302309

303310
@SuppressWarnings("checkstyle:ParameterNumber")
304-
private YoutubeHttpDataSource(final int connectTimeoutMillis,
311+
private YoutubeHttpDataSource(final Context context,
312+
final int connectTimeoutMillis,
305313
final int readTimeoutMillis,
306314
final boolean allowCrossProtocolRedirects,
307315
final boolean rangeParameterEnabled,
@@ -310,6 +318,7 @@ private YoutubeHttpDataSource(final int connectTimeoutMillis,
310318
@Nullable final Predicate<String> contentTypePredicate,
311319
final boolean keepPostFor302Redirects) {
312320
super(true);
321+
this.context = context;
313322
this.connectTimeoutMillis = connectTimeoutMillis;
314323
this.readTimeoutMillis = readTimeoutMillis;
315324
this.allowCrossProtocolRedirects = allowCrossProtocolRedirects;
@@ -716,6 +725,11 @@ private HttpURLConnection makeConnection(
716725
* @return an {@link HttpURLConnection} created with the {@code url}
717726
*/
718727
private HttpURLConnection openConnection(@NonNull final URL url) throws IOException {
728+
final ProxyManager proxyManager = new ProxyManager(context);
729+
final Proxy proxy = proxyManager.getProxy();
730+
if (proxy != null) {
731+
return (HttpURLConnection) url.openConnection(proxy);
732+
}
719733
return (HttpURLConnection) url.openConnection();
720734
}
721735

@@ -1014,4 +1028,3 @@ public int hashCode() {
10141028
}
10151029
}
10161030
}
1017-

app/src/main/java/org/schabi/newpipe/player/helper/PlayerDataSource.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,11 @@ public PlayerDataSource(final Context context,
9595

9696
// YouTube-specific data source factories use getYoutubeHttpDataSourceFactory()
9797
ytHlsCacheDataSourceFactory = new CacheFactory(context, transferListener, cache,
98-
getYoutubeHttpDataSourceFactory(false, false));
98+
getYoutubeHttpDataSourceFactory(context, false, false));
9999
ytDashCacheDataSourceFactory = new CacheFactory(context, transferListener, cache,
100-
getYoutubeHttpDataSourceFactory(true, true));
100+
getYoutubeHttpDataSourceFactory(context, true, true));
101101
ytProgressiveDashCacheDataSourceFactory = new CacheFactory(context, transferListener, cache,
102-
getYoutubeHttpDataSourceFactory(false, true));
102+
getYoutubeHttpDataSourceFactory(context, false, true));
103103

104104
// set the maximum size to manifest creators
105105
YoutubeProgressiveDashManifestCreator.getCache().setMaximumSize(MAX_MANIFEST_CACHE_SIZE);
@@ -191,9 +191,10 @@ private static DefaultDashChunkSource.Factory getDefaultDashChunkSourceFactory(
191191
}
192192

193193
private static YoutubeHttpDataSource.Factory getYoutubeHttpDataSourceFactory(
194+
final Context context,
194195
final boolean rangeParameterEnabled,
195196
final boolean rnParameterEnabled) {
196-
return new YoutubeHttpDataSource.Factory()
197+
return new YoutubeHttpDataSource.Factory(context)
197198
.setRangeParameterEnabled(rangeParameterEnabled)
198199
.setRnParameterEnabled(rnParameterEnabled);
199200
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package org.schabi.newpipe.settings;
2+
3+
import android.content.Context;
4+
import android.content.SharedPreferences;
5+
6+
import androidx.preference.PreferenceManager;
7+
8+
import java.net.InetSocketAddress;
9+
import java.net.Proxy;
10+
11+
/**
12+
* A class to manage proxy settings.
13+
*/
14+
public class ProxyManager {
15+
16+
private final SharedPreferences sharedPreferences;
17+
18+
/**
19+
* Creates a new ProxyManager.
20+
* @param context the context to use
21+
*/
22+
public ProxyManager(final Context context) {
23+
this.sharedPreferences =
24+
PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
25+
}
26+
27+
/**
28+
* Checks if the proxy is enabled.
29+
* @return true if the proxy is enabled, false otherwise
30+
*/
31+
public boolean isProxyEnabled() {
32+
return sharedPreferences.getBoolean("use_proxy", false);
33+
}
34+
35+
/**
36+
* Gets the proxy host.
37+
* @return the proxy host
38+
*/
39+
public String getProxyHost() {
40+
return sharedPreferences.getString("proxy_host", "127.0.0.1");
41+
}
42+
43+
/**
44+
* Gets the proxy port.
45+
* @return the proxy port
46+
*/
47+
public int getProxyPort() {
48+
final String portString = sharedPreferences.getString("proxy_port", "1080");
49+
try {
50+
return Integer.parseInt(portString);
51+
} catch (final NumberFormatException e) {
52+
return 1080;
53+
}
54+
}
55+
56+
/**
57+
* Gets the proxy type.
58+
* @return the proxy type
59+
*/
60+
public Proxy.Type getProxyType() {
61+
final String type = sharedPreferences.getString("proxy_type", "SOCKS");
62+
if ("SOCKS".equals(type)) {
63+
return Proxy.Type.SOCKS;
64+
} else {
65+
return Proxy.Type.HTTP;
66+
}
67+
}
68+
69+
/**
70+
* Gets the proxy.
71+
* @return the proxy, or null if the proxy is not enabled
72+
*/
73+
public Proxy getProxy() {
74+
if (!isProxyEnabled()) {
75+
return null;
76+
}
77+
return new Proxy(getProxyType(), new InetSocketAddress(getProxyHost(), getProxyPort()));
78+
}
79+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.schabi.newpipe.settings;
2+
3+
import android.os.Bundle;
4+
5+
import androidx.annotation.Nullable;
6+
import androidx.preference.ListPreference;
7+
8+
import org.schabi.newpipe.R;
9+
10+
/**
11+
* A fragment that displays proxy settings.
12+
*/
13+
public class ProxySettingsFragment extends BasePreferenceFragment {
14+
15+
@Override
16+
public void onCreatePreferences(@Nullable final Bundle savedInstanceState,
17+
@Nullable final String rootKey) {
18+
addPreferencesFromResource(R.xml.proxy_settings);
19+
20+
final ListPreference proxyTypePreference = findPreference("proxy_type");
21+
if (proxyTypePreference != null) {
22+
proxyTypePreference.setSummaryProvider(
23+
ListPreference.SimpleSummaryProvider.getInstance());
24+
}
25+
}
26+
}

app/src/main/java/org/schabi/newpipe/util/image/PicassoHelper.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import org.schabi.newpipe.R;
2525
import org.schabi.newpipe.extractor.Image;
26+
import org.schabi.newpipe.settings.ProxyManager;
2627

2728
import java.io.File;
2829
import java.io.IOException;
@@ -49,12 +50,17 @@ private PicassoHelper() {
4950

5051
public static void init(final Context context) {
5152
picassoCache = new LruCache(10 * 1024 * 1024);
52-
picassoDownloaderClient = new OkHttpClient.Builder()
53+
final ProxyManager proxyManager = new ProxyManager(context);
54+
final OkHttpClient.Builder builder = new OkHttpClient.Builder()
5355
.cache(new okhttp3.Cache(new File(context.getExternalCacheDir(), "picasso"),
5456
50L * 1024L * 1024L))
5557
// this should already be the default timeout in OkHttp3, but just to be sure...
56-
.callTimeout(15, TimeUnit.SECONDS)
57-
.build();
58+
.callTimeout(15, TimeUnit.SECONDS);
59+
60+
if (proxyManager.isProxyEnabled()) {
61+
builder.proxy(proxyManager.getProxy());
62+
}
63+
picassoDownloaderClient = builder.build();
5864

5965
picassoInstance = new Picasso.Builder(context)
6066
.memoryCache(picassoCache) // memory cache
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<menu xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto">
4+
<item
5+
android:id="@+id/action_search"
6+
android:icon="@drawable/ic_search"
7+
android:title="@string/search"
8+
app:showAsAction="ifRoom" />
9+
</menu>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<string name="proxy_settings_title">Настройки прокси</string>
4+
<string name="use_proxy">Использовать прокси</string>
5+
<string name="use_proxy_summary">Перенаправлять трафик через прокси</string>
6+
<string name="proxy_host">Хост прокси</string>
7+
<string name="proxy_host_summary">Имя хоста или IP-адрес прокси</string>
8+
<string name="proxy_port">Порт прокси</string>
9+
<string name="proxy_port_summary">Номер порта прокси</string>
10+
<string name="proxy_port_dialog_message">Введите номер порта прокси</string>
11+
</resources>

0 commit comments

Comments
 (0)