Merge pull request #1043 from eighthave/proxy
add support for a proxy and use more HTTPS
This commit is contained in:
commit
0c523a5226
14 changed files with 145 additions and 18 deletions
|
@ -67,7 +67,7 @@ public abstract class Entity {
|
|||
}
|
||||
|
||||
public String getOsmUrl() {
|
||||
final String browseUrl = "http://www.openstreetmap.org/browse/";
|
||||
final String browseUrl = "https://www.openstreetmap.org/browse/";
|
||||
if (type == EntityType.NODE)
|
||||
return browseUrl + "node/" + id;
|
||||
if (type == EntityType.WAY)
|
||||
|
|
|
@ -9,6 +9,9 @@ import java.io.InputStream;
|
|||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Map;
|
||||
|
@ -21,12 +24,15 @@ import org.apache.commons.logging.Log;
|
|||
|
||||
public class NetworkUtils {
|
||||
private static final Log log = PlatformUtil.getLog(NetworkUtils.class);
|
||||
|
||||
private static Proxy proxy = null;
|
||||
|
||||
public static String sendGetRequest(String urlText, String userNamePassword){
|
||||
URL url;
|
||||
try {
|
||||
log.info("GET : " + urlText);
|
||||
url = new URL(urlText);
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
HttpURLConnection conn = getHttpURLConnection(urlText);
|
||||
conn.setDoInput(true);
|
||||
conn.setDoOutput(false);
|
||||
conn.setRequestMethod("GET");
|
||||
|
@ -151,4 +157,24 @@ public class NetworkUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static void setProxy(String host, int port) {
|
||||
if(host != null && port > 0) {
|
||||
InetSocketAddress isa = new InetSocketAddress(host, port);
|
||||
proxy = new Proxy(Proxy.Type.HTTP, isa);
|
||||
} else {
|
||||
proxy = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static HttpURLConnection getHttpURLConnection(String urlString) throws MalformedURLException, IOException {
|
||||
return getHttpURLConnection(new URL(urlString));
|
||||
}
|
||||
|
||||
public static HttpURLConnection getHttpURLConnection(URL url) throws IOException {
|
||||
if (proxy != null) {
|
||||
return (HttpURLConnection) url.openConnection(proxy);
|
||||
} else {
|
||||
return (HttpURLConnection) url.openConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -155,6 +155,13 @@
|
|||
<string name="save_track_interval_descr">Choose logging interval for track recording during navigation</string>
|
||||
<string name="voice_provider_descr">Select voice guidance for navigation</string>
|
||||
<string name="voice_provider">Voice guidance</string>
|
||||
<string name="proxy_pref_title">Proxy</string>
|
||||
<string name="enable_proxy_title">Enable HTTP Proxy</string>
|
||||
<string name="enable_proxy_descr">Configure HTTP Proxy for all network requests</string>
|
||||
<string name="proxy_host_title">Proxy Host</string>
|
||||
<string name="proxy_host_descr">Configure your proxy\'s hostname (e.g. 127.0.0.1)</string>
|
||||
<string name="proxy_port_title">Proxy Port</string>
|
||||
<string name="proxy_port_descr">Configure your proxy\'s port number (e.g. 8118)</string>
|
||||
<string name="tips_and_tricks">Help</string>
|
||||
<string name="tip_initial">Help</string>
|
||||
<string name="tip_initial_t">OsmAnd is a navigation application with many features.
|
||||
|
|
|
@ -13,6 +13,16 @@
|
|||
<PreferenceCategory android:title="@string/voice_pref_title" android:key="voice">
|
||||
<ListPreference android:title="@string/voice_provider" android:key="voice_provider" android:summary="@string/voice_provider_descr"></ListPreference>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/proxy_pref_title" android:key="proxy">
|
||||
<CheckBoxPreference
|
||||
android:key="enable_proxy" android:title="@string/enable_proxy_title" android:summary="@string/enable_proxy_descr" android:defaultValue="false" />
|
||||
<EditTextPreference
|
||||
android:key="proxy_host" android:title="@string/proxy_host_title" android:summary="@string/proxy_host_descr" android:dependency="enable_proxy"
|
||||
android:defaultValue="127.0.0.1" />
|
||||
<EditTextPreference
|
||||
android:key="proxy_port" android:title="@string/proxy_port_title" android:summary="@string/proxy_port_descr" android:dependency="enable_proxy"
|
||||
android:defaultValue="8118" />
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/misc_pref_title" android:key="misc">
|
||||
<ListPreference android:key="osmand_theme" android:title="@string/choose_osmand_theme" android:summary="@string/choose_osmand_theme_descr"></ListPreference>
|
||||
</PreferenceCategory>
|
||||
|
|
|
@ -796,6 +796,9 @@ public class OsmandSettings {
|
|||
|
||||
public final CommonPreference<Boolean> INTERRUPT_MUSIC = new BooleanPreference("interrupt_music", false).makeGlobal();
|
||||
|
||||
public final CommonPreference<Boolean> ENABLE_PROXY = new BooleanPreference("enable_proxy", false).makeGlobal();
|
||||
public final CommonPreference<String> PROXY_HOST = new StringPreference("proxy_host", "127.0.0.1").makeGlobal();
|
||||
public final CommonPreference<Integer> PROXY_PORT = new IntPreference("proxy_port", 8118).makeGlobal();
|
||||
|
||||
// this value string is synchronized with settings_pref.xml preference name
|
||||
public static final String SAVE_CURRENT_TRACK = "save_current_track"; //$NON-NLS-1$
|
||||
|
|
|
@ -14,6 +14,7 @@ import net.osmand.CallbackWithObject;
|
|||
import net.osmand.IProgress;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.access.AccessibleToast;
|
||||
import net.osmand.osm.io.NetworkUtils;
|
||||
import net.osmand.plus.ApplicationMode;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
|
@ -43,6 +44,7 @@ import android.media.AudioManager;
|
|||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.preference.ListPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.Preference.OnPreferenceChangeListener;
|
||||
|
@ -94,6 +96,7 @@ public class SettingsGeneralActivity extends SettingsBaseActivity {
|
|||
|
||||
addLocalPrefs((PreferenceGroup) screen.findPreference("localization"));
|
||||
addVoicePrefs((PreferenceGroup) screen.findPreference("voice"));
|
||||
addProxyPrefs((PreferenceGroup) screen.findPreference("proxy"));
|
||||
addMiscPreferences((PreferenceGroup) screen.findPreference("misc"));
|
||||
|
||||
|
||||
|
@ -264,6 +267,54 @@ public class SettingsGeneralActivity extends SettingsBaseActivity {
|
|||
|
||||
|
||||
|
||||
|
||||
private void addProxyPrefs(PreferenceGroup proxy) {
|
||||
CheckBoxPreference enableProxyPref = (CheckBoxPreference) proxy.findPreference(settings.ENABLE_PROXY.getId());
|
||||
enableProxyPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if ((Boolean) newValue)
|
||||
NetworkUtils.setProxy(settings.PROXY_HOST.get(), settings.PROXY_PORT.get());
|
||||
else
|
||||
NetworkUtils.setProxy(null, 0);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
EditTextPreference hostPref = (EditTextPreference) proxy.findPreference(settings.PROXY_HOST.getId());
|
||||
hostPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
System.out.println("PROXY newValue: " + newValue);
|
||||
settings.PROXY_HOST.set((String) newValue);
|
||||
NetworkUtils.setProxy((String) newValue, settings.PROXY_PORT.get());
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
EditTextPreference portPref = (EditTextPreference) proxy.findPreference(settings.PROXY_PORT.getId());
|
||||
portPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
System.out.println("PROXY newValue: " + newValue);
|
||||
int port = -1;
|
||||
String portString = (String) newValue;
|
||||
try {
|
||||
port = Integer.valueOf(portString.replaceAll("[^0-9]", ""));
|
||||
} catch (NumberFormatException e1) {
|
||||
}
|
||||
settings.PROXY_PORT.set(port);
|
||||
NetworkUtils.setProxy(settings.PROXY_HOST.get(), port);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void addMiscPreferences(PreferenceGroup misc) {
|
||||
if (!Version.isBlackberry(getMyApplication())) {
|
||||
applicationDir = new Preference(this);
|
||||
|
|
|
@ -14,6 +14,7 @@ import java.util.zip.ZipInputStream;
|
|||
import net.osmand.IProgress;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.osm.io.NetworkUtils;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.Version;
|
||||
|
@ -66,7 +67,7 @@ public class DownloadFileHelper {
|
|||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
HttpURLConnection conn = NetworkUtils.getHttpURLConnection(url);
|
||||
conn.setRequestProperty("User-Agent", Version.getFullVersion(ctx)); //$NON-NLS-1$
|
||||
conn.setReadTimeout(30000);
|
||||
if (fileread > 0) {
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -12,6 +13,7 @@ import java.util.zip.GZIPInputStream;
|
|||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.osm.io.NetworkUtils;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
|
||||
|
@ -104,9 +106,11 @@ public class DownloadOsmandIndexesHelper {
|
|||
String strUrl = ctx.getAppCustomization().getIndexesUrl();
|
||||
|
||||
log.info(strUrl);
|
||||
URL url = new URL(strUrl );
|
||||
XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
|
||||
parser.setInput(new GZIPInputStream(url.openStream()), "UTF-8"); //$NON-NLS-1$
|
||||
URLConnection connection = NetworkUtils.getHttpURLConnection(strUrl);
|
||||
InputStream in = connection.getInputStream();
|
||||
GZIPInputStream gzin = new GZIPInputStream(in);
|
||||
parser.setInput(gzin, "UTF-8"); //$NON-NLS-1$
|
||||
int next;
|
||||
while((next = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||
if (next == XmlPullParser.START_TAG) {
|
||||
|
@ -123,6 +127,8 @@ public class DownloadOsmandIndexesHelper {
|
|||
}
|
||||
}
|
||||
result.sort();
|
||||
gzin.close();
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
log.error("Error while loading indexes from repository", e); //$NON-NLS-1$
|
||||
return null;
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.Map.Entry;
|
|||
import java.util.Random;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.osm.io.NetworkUtils;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.Version;
|
||||
|
||||
|
@ -40,7 +41,6 @@ public class DownloadTracker {
|
|||
return (new Random(System.currentTimeMillis()).nextInt(100000000) + 100000000) + "";
|
||||
}
|
||||
|
||||
static final String beaconUrl = "http://www.google-analytics.com/__utm.gif";
|
||||
static final String analyticsVersion = "4.3"; // Analytics version - AnalyticsVersion
|
||||
|
||||
public void trackEvent(OsmandApplication a,
|
||||
|
@ -86,6 +86,12 @@ public class DownloadTracker {
|
|||
parameters.put("utme", MessageFormat.format("5({0}*{1}*{2})({3})", category, action, label == null ? "" : label, value)
|
||||
+ customVars);
|
||||
|
||||
String scheme = "";
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD)
|
||||
scheme = "https";
|
||||
else
|
||||
scheme = "http";
|
||||
String beaconUrl = scheme + "://www.google-analytics.com/__utm.gif";
|
||||
StringBuilder urlString = new StringBuilder(beaconUrl + "?");
|
||||
Iterator<Entry<String, String>> it = parameters.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
|
@ -97,8 +103,7 @@ public class DownloadTracker {
|
|||
}
|
||||
|
||||
log.debug(urlString);
|
||||
URL url = new URL(urlString.toString());
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
HttpURLConnection conn = NetworkUtils.getHttpURLConnection(urlString.toString());
|
||||
conn.setConnectTimeout(5000);
|
||||
conn.setDoInput(false);
|
||||
conn.setDoOutput(false);
|
||||
|
|
|
@ -103,7 +103,7 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil {
|
|||
private String sendRequest(String url, String requestMethod, String requestBody, String userOperation, boolean doAuthenticate) {
|
||||
log.info("Sending request " + url); //$NON-NLS-1$
|
||||
try {
|
||||
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
|
||||
HttpURLConnection connection = NetworkUtils.getHttpURLConnection(url);
|
||||
|
||||
connection.setConnectTimeout(15000);
|
||||
connection.setRequestMethod(requestMethod);
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.net.URLEncoder;
|
|||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.osm.io.Base64;
|
||||
import net.osmand.osm.io.NetworkUtils;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
|
@ -76,7 +77,7 @@ public class OsmBugsRemoteUtil implements OsmBugsUtil {
|
|||
|
||||
private String editingPOI(String url, String requestMethod, String userOperation) {
|
||||
try {
|
||||
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
|
||||
HttpURLConnection connection = NetworkUtils.getHttpURLConnection(url);
|
||||
log.info("Editing poi " + url);
|
||||
connection.setConnectTimeout(15000);
|
||||
connection.setRequestMethod(requestMethod);
|
||||
|
|
|
@ -3,6 +3,7 @@ package net.osmand.plus.poi;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -11,6 +12,7 @@ import net.osmand.PlatformUtil;
|
|||
import net.osmand.ResultMatcher;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.AmenityType;
|
||||
import net.osmand.osm.io.NetworkUtils;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.R.string;
|
||||
|
@ -76,8 +78,8 @@ public class NameFinderPoiFilter extends PoiLegacyFilter {
|
|||
lastError = "";
|
||||
String urlq = NOMINATIM_API + URLEncoder.encode(query)+ "?format=xml&addressdetails=1&limit="+LIMIT+"&bounded=1&"+viewbox;
|
||||
log.info(urlq);
|
||||
URL url = new URL(urlq); //$NON-NLS-1$
|
||||
InputStream stream = url.openStream();
|
||||
URLConnection connection = NetworkUtils.getHttpURLConnection(urlq); //$NON-NLS-1$
|
||||
InputStream stream = connection.getInputStream();
|
||||
XmlPullParser parser = PlatformUtil.newXMLPullParser();
|
||||
parser.setInput(stream, "UTF-8"); //$NON-NLS-1$
|
||||
int eventType;
|
||||
|
|
|
@ -27,6 +27,7 @@ import net.osmand.PlatformUtil;
|
|||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.LocationPoint;
|
||||
import net.osmand.osm.io.NetworkUtils;
|
||||
import net.osmand.plus.ApplicationMode;
|
||||
import net.osmand.plus.GPXUtilities;
|
||||
import net.osmand.plus.GPXUtilities.GPXFile;
|
||||
|
@ -67,6 +68,7 @@ import org.xml.sax.InputSource;
|
|||
import org.xml.sax.SAXException;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import btools.routingapp.IBRouterService;
|
||||
|
||||
|
@ -1079,12 +1081,17 @@ public class RouteProvider {
|
|||
}
|
||||
protected RouteCalculationResult findOSRMRoute(RouteCalculationParams params)
|
||||
throws MalformedURLException, IOException, JSONException {
|
||||
// http://router.project-osrm.org/viaroute?loc=52.28,4.83&loc=52.35,4.95&alt=false&output=gpx
|
||||
// https://router.project-osrm.org/viaroute?loc=52.28,4.83&loc=52.35,4.95&alt=false&output=gpx
|
||||
List<Location> res = new ArrayList<Location>();
|
||||
StringBuilder uri = new StringBuilder();
|
||||
// possibly hide that API key because it is privacy of osmand
|
||||
// A6421860EBB04234AB5EF2D049F2CD8F key is compromised
|
||||
uri.append("http://router.project-osrm.org/viaroute?alt=false"); //$NON-NLS-1$
|
||||
String scheme = "";
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD)
|
||||
scheme = "https";
|
||||
else
|
||||
scheme = "http";
|
||||
uri.append(scheme + "://router.project-osrm.org/viaroute?alt=false"); //$NON-NLS-1$
|
||||
uri.append("&loc=").append(String.valueOf(params.start.getLatitude()));
|
||||
uri.append(",").append(String.valueOf(params.start.getLongitude()));
|
||||
if(params.intermediates != null && params.intermediates.size() > 0) {
|
||||
|
@ -1097,8 +1104,7 @@ public class RouteProvider {
|
|||
|
||||
log.info("URL route " + uri);
|
||||
|
||||
URL url = new URL(uri.toString());
|
||||
URLConnection connection = url.openConnection();
|
||||
URLConnection connection = NetworkUtils.getHttpURLConnection(uri.toString());
|
||||
connection.setRequestProperty("User-Agent", Version.getFullVersion(params.ctx));
|
||||
// StringBuilder content = new StringBuilder();
|
||||
// BufferedReader rs = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
|
|
|
@ -6,10 +6,12 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.data.RotatedTileBox;
|
||||
import net.osmand.osm.io.NetworkUtils;
|
||||
import net.osmand.map.TileSourceManager.TileSourceTemplate;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
|
@ -17,6 +19,7 @@ import org.apache.commons.logging.Log;
|
|||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Build;
|
||||
|
||||
public class YandexTrafficAdapter extends MapTileAdapter {
|
||||
|
||||
|
@ -56,10 +59,16 @@ public class YandexTrafficAdapter extends MapTileAdapter {
|
|||
}
|
||||
|
||||
protected void updateTimeStampImpl() {
|
||||
String YANDEX_BASE_URL;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD)
|
||||
YANDEX_BASE_URL = "https://jgo.maps.yandex.net";
|
||||
else
|
||||
YANDEX_BASE_URL = "http://jgo.maps.yandex.net";
|
||||
if (mTimestamp == null || (System.currentTimeMillis() - lastTimestampUpdated) > DELTA) {
|
||||
log.info("Updating timestamp"); //$NON-NLS-1$
|
||||
try {
|
||||
BufferedInputStream in = new BufferedInputStream(new URL("http://jgo.maps.yandex.net/trf/stat.js").openStream(), 1024); //$NON-NLS-1$
|
||||
URLConnection connection = NetworkUtils.getHttpURLConnection(YANDEX_BASE_URL + "/trf/stat.js");
|
||||
BufferedInputStream in = new BufferedInputStream(connection.getInputStream(), 1024); //$NON-NLS-1$
|
||||
ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
|
||||
BufferedOutputStream out = new BufferedOutputStream(dataStream, 1024);
|
||||
Algorithms.streamCopy(in, out);
|
||||
|
@ -82,7 +91,7 @@ public class YandexTrafficAdapter extends MapTileAdapter {
|
|||
if (!newTimestamp.equals(mTimestamp)) {
|
||||
mTimestamp = newTimestamp;
|
||||
TileSourceTemplate template = new TileSourceTemplate(YANDEX_PREFFIX + mTimestamp,
|
||||
"http://jgo.maps.yandex.net/1.1/tiles?l=trf,trfe&x={1}&y={2}&z={0}&tm=" + mTimestamp, ".png", 17, 7, 256, 8, 18000);
|
||||
YANDEX_BASE_URL + "/1.1/tiles?l=trf,trfe&x={1}&y={2}&z={0}&tm=" + mTimestamp, ".png", 17, 7, 256, 8, 18000);
|
||||
template.setEllipticYTile(true);
|
||||
template.setExpirationTimeMinutes(20);
|
||||
clearCache();
|
||||
|
|
Loading…
Reference in a new issue