Draft crowd sourced settings fetching
|
@ -62,11 +62,21 @@ import android.widget.TextView;
|
|||
|
||||
import com.squareup.picasso.Picasso;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
public class AdapterRule extends RecyclerView.Adapter<AdapterRule.ViewHolder> implements Filterable {
|
||||
private static final String TAG = "NetGuard.Adapter";
|
||||
|
||||
|
@ -83,6 +93,9 @@ public class AdapterRule extends RecyclerView.Adapter<AdapterRule.ViewHolder> im
|
|||
private List<Rule> listAll = new ArrayList<>();
|
||||
private List<Rule> listFiltered = new ArrayList<>();
|
||||
|
||||
private static final String cUrl = "https://crowd.netguard.me/";
|
||||
private static final int cTimeOutMs = 15000;
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
public View view;
|
||||
|
||||
|
@ -112,6 +125,7 @@ public class AdapterRule extends RecyclerView.Adapter<AdapterRule.ViewHolder> im
|
|||
public CheckBox cbApply;
|
||||
|
||||
public Button btnRelated;
|
||||
public ImageButton ibFetch;
|
||||
public ImageButton ibSettings;
|
||||
public ImageButton ibLaunch;
|
||||
|
||||
|
@ -162,6 +176,7 @@ public class AdapterRule extends RecyclerView.Adapter<AdapterRule.ViewHolder> im
|
|||
cbApply = (CheckBox) itemView.findViewById(R.id.cbApply);
|
||||
|
||||
btnRelated = (Button) itemView.findViewById(R.id.btnRelated);
|
||||
ibFetch = (ImageButton) itemView.findViewById(R.id.ibFetch);
|
||||
ibSettings = (ImageButton) itemView.findViewById(R.id.ibSettings);
|
||||
ibLaunch = (ImageButton) itemView.findViewById(R.id.ibLaunch);
|
||||
|
||||
|
@ -429,6 +444,72 @@ public class AdapterRule extends RecyclerView.Adapter<AdapterRule.ViewHolder> im
|
|||
}
|
||||
});
|
||||
|
||||
// Fetch settings
|
||||
holder.ibFetch.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
new AsyncTask<Rule, Object, Object>() {
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
holder.ibFetch.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object doInBackground(Rule... rules) {
|
||||
HttpsURLConnection urlConnection = null;
|
||||
try {
|
||||
JSONObject json = new JSONObject();
|
||||
|
||||
json.put("type", "fetch");
|
||||
json.put("netguard", Util.getSelfVersionCode(context));
|
||||
json.put("fingerprint", Util.getFingerprint(context));
|
||||
|
||||
JSONArray pkgs = new JSONArray();
|
||||
pkgs.put(rules[0].info.packageName);
|
||||
json.put("package", pkgs);
|
||||
|
||||
urlConnection = (HttpsURLConnection) new URL(cUrl).openConnection();
|
||||
urlConnection.setConnectTimeout(cTimeOutMs);
|
||||
urlConnection.setReadTimeout(cTimeOutMs);
|
||||
urlConnection.setRequestProperty("Accept", "application/json");
|
||||
urlConnection.setRequestProperty("Content-type", "application/json");
|
||||
urlConnection.setRequestMethod("POST");
|
||||
urlConnection.setDoInput(true);
|
||||
urlConnection.setDoOutput(true);
|
||||
|
||||
Log.i(TAG, "Request=" + json.toString());
|
||||
OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
|
||||
out.write(json.toString().getBytes()); // UTF-8
|
||||
out.flush();
|
||||
|
||||
int code = urlConnection.getResponseCode();
|
||||
if (code != HttpsURLConnection.HTTP_OK)
|
||||
throw new IOException("HTTP " + code);
|
||||
|
||||
InputStreamReader isr = new InputStreamReader(urlConnection.getInputStream());
|
||||
Log.i(TAG, "Response=" + Util.readString(isr).toString());
|
||||
|
||||
} catch (Throwable ex) {
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
return ex;
|
||||
|
||||
} finally {
|
||||
if (urlConnection != null)
|
||||
urlConnection.disconnect();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Object result) {
|
||||
holder.ibFetch.setEnabled(true);
|
||||
}
|
||||
|
||||
}.execute(rule);
|
||||
}
|
||||
});
|
||||
|
||||
// Launch application settings
|
||||
final Intent settings = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
settings.setData(Uri.parse("package:" + rule.info.packageName));
|
||||
|
|
|
@ -105,8 +105,7 @@ public class ServiceJob extends JobService {
|
|||
throw new IOException("HTTP " + code);
|
||||
|
||||
InputStreamReader isr = new InputStreamReader(urlConnection.getInputStream());
|
||||
String response = read(isr);
|
||||
Log.i(TAG, "Response=" + response);
|
||||
Log.i(TAG, "Response=" + Util.readString(isr).toString());
|
||||
|
||||
jobFinished(params[0], false);
|
||||
|
||||
|
@ -142,17 +141,6 @@ public class ServiceJob extends JobService {
|
|||
return true;
|
||||
}
|
||||
|
||||
private String read(InputStreamReader reader) {
|
||||
StringBuilder sb = new StringBuilder(2048);
|
||||
char[] read = new char[128];
|
||||
try {
|
||||
for (int i; (i = reader.read(read)) >= 0; sb.append(read, 0, i)) ;
|
||||
} catch (Throwable ex) {
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static void submit(Rule rule, Context context) {
|
||||
PersistableBundle bundle = new PersistableBundle();
|
||||
bundle.putString("type", "rule");
|
||||
|
|
|
@ -386,7 +386,7 @@ public class Util {
|
|||
return "com.android.vending".equals(context.getPackageManager().getInstallerPackageName(context.getPackageName()));
|
||||
}
|
||||
|
||||
public static boolean hasValidFingerprint(Context context) {
|
||||
public static String getFingerprint(Context context) {
|
||||
try {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
String pkg = context.getPackageName();
|
||||
|
@ -397,15 +397,19 @@ public class Util {
|
|||
StringBuilder sb = new StringBuilder();
|
||||
for (byte b : bytes)
|
||||
sb.append(Integer.toString(b & 0xff, 16).toLowerCase());
|
||||
String calculated = sb.toString();
|
||||
String expected = context.getString(R.string.fingerprint);
|
||||
return calculated.equals(expected);
|
||||
return sb.toString();
|
||||
} catch (Throwable ex) {
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasValidFingerprint(Context context) {
|
||||
String calculated = getFingerprint(context);
|
||||
String expected = context.getString(R.string.fingerprint);
|
||||
return (calculated != null && calculated.equals(expected));
|
||||
}
|
||||
|
||||
public static void setTheme(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
boolean dark = prefs.getBoolean("dark_theme", false);
|
||||
|
@ -549,6 +553,17 @@ public class Util {
|
|||
}
|
||||
}
|
||||
|
||||
public static StringBuilder readString(InputStreamReader reader) {
|
||||
StringBuilder sb = new StringBuilder(2048);
|
||||
char[] read = new char[128];
|
||||
try {
|
||||
for (int i; (i = reader.read(read)) >= 0; sb.append(read, 0, i)) ;
|
||||
} catch (Throwable ex) {
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
public static void sendCrashReport(Throwable ex, final Context context) {
|
||||
if (!isPlayStoreInstall(context))
|
||||
return;
|
||||
|
|
After Width: | Height: | Size: 344 B |
After Width: | Height: | Size: 353 B |
After Width: | Height: | Size: 235 B |
After Width: | Height: | Size: 242 B |
After Width: | Height: | Size: 404 B |
After Width: | Height: | Size: 417 B |
After Width: | Height: | Size: 592 B |
After Width: | Height: | Size: 610 B |
After Width: | Height: | Size: 764 B |
After Width: | Height: | Size: 789 B |
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/fetch_disabled_black" android:state_enabled="false" />
|
||||
<item android:drawable="@drawable/ic_cloud_download_black_24dp" />
|
||||
</selector>
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:src="@drawable/ic_cloud_download_black_24dp"
|
||||
android:tint="@color/colorGrayed" />
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:src="@drawable/ic_cloud_download_white_24dp"
|
||||
android:tint="@color/colorGrayed" />
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/fetch_disabled_white" android:state_enabled="false" />
|
||||
<item android:drawable="@drawable/ic_cloud_download_white_24dp" />
|
||||
</selector>
|
|
@ -233,11 +233,20 @@
|
|||
android:layout_marginRight="8dp"
|
||||
android:text="@string/title_related" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/ibFetch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:src="?attr/iconFetch" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/ibSettings"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:src="?attr/iconSettings" />
|
||||
|
||||
<ImageButton
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
<attr name="expander" format="reference" />
|
||||
<attr name="iconQueue" format="reference" />
|
||||
<attr name="iconMetered" format="reference" />
|
||||
<attr name="iconFetch" format="reference" />
|
||||
<attr name="iconSettings" format="reference" />
|
||||
<attr name="iconDelete" format="reference" />
|
||||
<attr name="iconLaunch" format="reference" />
|
||||
|
@ -17,6 +18,7 @@
|
|||
<item name="expander">@drawable/expander_black</item>
|
||||
<item name="iconQueue">@drawable/ic_hourglass_empty_black_24dp</item>
|
||||
<item name="iconMetered">@drawable/ic_attach_money_black_24dp</item>
|
||||
<item name="iconFetch">@drawable/fetch_black</item>
|
||||
<item name="iconSettings">@drawable/ic_settings_black_24dp</item>
|
||||
<item name="iconDelete">@drawable/ic_delete_black_24dp</item>
|
||||
<item name="iconLaunch">@drawable/ic_launch_black_24dp</item>
|
||||
|
@ -27,6 +29,7 @@
|
|||
<item name="expander">@drawable/expander_white</item>
|
||||
<item name="iconQueue">@drawable/ic_hourglass_empty_white_24dp</item>
|
||||
<item name="iconMetered">@drawable/ic_attach_money_white_24dp</item>
|
||||
<item name="iconFetch">@drawable/fetch_white</item>
|
||||
<item name="iconSettings">@drawable/ic_settings_white_24dp</item>
|
||||
<item name="iconDelete">@drawable/ic_delete_white_24dp</item>
|
||||
<item name="iconLaunch">@drawable/ic_launch_white_24dp</item>
|
||||
|
|