package me.piebridge.prevent.ui; import android.Manifest; import android.app.Activity; import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Process; import android.support.v13.app.ActivityCompat; import android.text.TextUtils; import android.util.TypedValue; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.WindowManager; import android.webkit.WebView; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import com.android.server.am.PreventRunning; import org.json.JSONException; import org.json.JSONObject; import java.io.File; import java.io.IOException; import java.util.Locale; import me.piebridge.prevent.BuildConfig; import me.piebridge.prevent.R; import me.piebridge.prevent.common.PreventIntent; import me.piebridge.prevent.ui.util.ColorUtils; import me.piebridge.prevent.ui.util.DeprecatedUtils; import me.piebridge.prevent.ui.util.EmailUtils; import me.piebridge.prevent.ui.util.FileUtils; import me.piebridge.prevent.ui.util.ThemeUtils; /** * Created by thom on 15/10/3. */ public class UserGuideActivity extends Activity implements View.OnClickListener { private ProgressDialog donateDialog; private BroadcastReceiver receiver; private static final int MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 0x1; private String name; private Integer version = null; private String method = null; private String colorBackground; private String colorText; private String colorLink; @Override public void onCreate(Bundle savedInstanceState) { ThemeUtils.setTheme(this); super.onCreate(savedInstanceState); setContentView(R.layout.about); ThemeUtils.fixSmartBar(this); if (getActionBar() != null) { getActionBar().setDisplayHomeAsUpEnabled(true); } WebView webView = (WebView) findViewById(R.id.webview); webView.setBackgroundColor(ColorUtils.resolveColor(this, android.R.attr.colorBackground)); webView.setVerticalScrollBarEnabled(false); webView.setHorizontalScrollBarEnabled(false); String path; if ("zh".equals(Locale.getDefault().getLanguage())) { path = "about.zh.html"; } else { path = "about.en.html"; } try { String template = FileUtils.readAsString(getAssets().open(path)); resolveColors(); String body = String.format(template, colorBackground, colorText, colorLink); webView.loadDataWithBaseURL(null, body, "text/html; charset=utf-8", "UTF-8", null); } catch (IOException e) { webView.loadUrl("file:///android_asset/" + path); UILog.d("cannot open " + path, e); } setView(R.id.alipay, "com.eg.android.AlipayGphone"); if (hasPermission()) { setView(R.id.wechat, "com.tencent.mm"); } else { findViewById(R.id.wechat).setVisibility(View.GONE); } if (!setView(R.id.paypal, "com.paypal.android.p2pmobile")) { TextView paypal = (TextView) findViewById(R.id.paypal); paypal.setClickable(true); paypal.setOnClickListener(this); paypal.setCompoundDrawablesWithIntrinsicBounds(null, cropDrawable(paypal.getCompoundDrawables()[1]), null, null); } retrieveInfo(); } @Override protected void onResume() { super.onResume(); hideDonateDialog(); } @Override protected void onDestroy() { deleteQrCodeIfNeeded(); super.onDestroy(); } private int getPixel(int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics()); } private Drawable cropDrawable(Drawable icon) { int width = getPixel(0x20); if (icon.getMinimumWidth() > width && icon instanceof BitmapDrawable) { Bitmap bitmap = Bitmap.createScaledBitmap(((BitmapDrawable) icon).getBitmap(), width, width, false); return new BitmapDrawable(getResources(), bitmap); } return icon; } private boolean setView(int id, String packageName) { TextView donate = (TextView) findViewById(id); PackageManager pm = getPackageManager(); try { ApplicationInfo info = pm.getApplicationInfo(packageName, 0); if (!info.enabled) { return false; } CharSequence label = getLabel(pm, info); donate.setContentDescription(label); donate.setCompoundDrawablesWithIntrinsicBounds(null, cropDrawable(pm.getApplicationIcon(info)), null, null); donate.setText(label); donate.setClickable(true); donate.setOnClickListener(this); donate.setVisibility(View.VISIBLE); return true; } catch (PackageManager.NameNotFoundException e) { UILog.d("cannot find package " + packageName, e); return false; } } private CharSequence getLabel(PackageManager pm, ApplicationInfo info) throws PackageManager.NameNotFoundException { CharSequence label = null; if ("com.android.vending".equals(info.packageName)) { Resources resources = pm.getResourcesForApplication(info); int appName = resources.getIdentifier("app_name", "string", info.packageName); if (appName > 0) { label = resources.getText(appName); } } if (TextUtils.isEmpty(label)) { label = pm.getApplicationLabel(info); } return label; } private File getQrCode() { File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); if (dir == null) { return null; } if (!checkPermission()) { return null; } File screenshots = new File(dir, "Screenshots"); if (!screenshots.exists()) { screenshots.mkdirs(); } return new File(screenshots, "pr_donate.png"); } public int checkPermission(String permission) { return checkPermission(permission, android.os.Process.myPid(), Process.myUid()); } private boolean hasPermission() { return checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED || !ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE); } private boolean checkPermission() { if (checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { return true; } if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE); } return false; } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { donateViaWeChat(); } else { findViewById(R.id.wechat).setVisibility(View.GONE); } } } private void refreshQrCode(File qrCode) { Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); mediaScanIntent.setData(Uri.fromFile(qrCode)); sendBroadcast(mediaScanIntent); } private void deleteQrCodeIfNeeded() { File qrCode = getQrCode(); if (qrCode != null && qrCode.exists()) { qrCode.delete(); refreshQrCode(qrCode); } } private boolean donateViaWeChat() { File qrCode = getQrCode(); if (qrCode == null) { return false; } try { FileUtils.dumpFile(getAssets().open("wechat.png"), qrCode); } catch (IOException e) { UILog.d("cannot dump wechat", e); return false; } refreshQrCode(qrCode); showDonateDialog(); Intent intent = new Intent("com.tencent.mm.action.BIZSHORTCUT"); intent.setPackage("com.tencent.mm"); intent.putExtra("LauncherUI.From.Scaner.Shortcut", true); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); try { startActivity(intent); for (int i = 0; i < 0x3; ++i) { Toast.makeText(this, R.string.select_qr_code, Toast.LENGTH_LONG).show(); } } catch (Throwable t) { // NOSONAR hideDonateDialog(); } return true; } private boolean donateViaAlipay() { showDonateDialog(); Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setData(Uri.parse(BuildConfig.DONATE_ALIPAY)); try { startActivity(intent); } catch (Throwable t) { // NOSONAR hideDonateDialog(); } return true; } private boolean donateViaPayPal() { showDonateDialog(); try { startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(BuildConfig.DONATE_PAYPAL))); } catch (Throwable t) { // NOSONAR // do nothing } return true; } @Override public void onClick(View v) { int id = v.getId(); if (id == R.id.wechat) { donateViaWeChat(); } else if (id == R.id.alipay) { donateViaAlipay(); } else if (id == R.id.paypal) { donateViaPayPal(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { menu.clear(); menu.add(Menu.NONE, R.string.version, Menu.NONE, R.string.version); if (BuildConfig.RELEASE) { menu.add(Menu.NONE, R.string.feedback, Menu.NONE, R.string.feedback); } menu.add(Menu.NONE, R.string.advanced_settings, Menu.NONE, R.string.advanced_settings); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == android.R.id.home) { finish(); } else if (id == R.string.feedback) { feedback(); } else if (id == R.string.version) { showVersionInfo(); } else if (id == R.string.advanced_settings) { startActivity(new Intent(this, AdvancedSettingsActivity.class)); } return true; } private void feedback() { EmailUtils.sendEmail(this, getString(R.string.feedback)); } private void showDonateDialog() { RelativeLayout layout = new RelativeLayout(this); int pixel = getPixel(0x30); RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(pixel, pixel); params.addRule(RelativeLayout.CENTER_IN_PARENT); layout.addView(new ProgressBar(this), params); donateDialog = ProgressDialog.show(this, null, null); donateDialog.setContentView(layout); if (donateDialog.getWindow() != null) { donateDialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, pixel * 0x4); } } private void hideDonateDialog() { if (donateDialog != null) { donateDialog.dismiss(); donateDialog = null; } } private void retrieveInfo() { Intent intent = new Intent(); intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); intent.setAction(PreventIntent.ACTION_GET_INFO); intent.setData(Uri.fromParts(PreventIntent.SCHEME, getPackageName(), null)); UILog.i("sending get info broadcast"); if (receiver == null) { receiver = new HookReceiver(); } sendOrderedBroadcast(intent, PreventIntent.PERMISSION_SYSTEM, receiver, null, 0, null, null); } private class HookReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (PreventIntent.ACTION_GET_INFO.equals(action)) { handleInfo(); } } private void handleInfo() { String info = getResultData(); if (TextUtils.isEmpty(info)) { return; } try { JSONObject json = new JSONObject(info); version = json.optInt("version"); method = json.optString("method"); name = json.optString("name"); } catch (JSONException e) { UILog.d("cannot get version from " + info, e); } } } private String getVersionInfo(boolean showAppVersion) { StringBuilder sb = new StringBuilder(); showVersion(sb); sb.append("Android: "); sb.append(Locale.getDefault()); sb.append("-"); sb.append(Build.VERSION.RELEASE); sb.append("\n"); if (showAppVersion) { sb.append(getString(R.string.app_name)); sb.append(": "); sb.append(BuildConfig.VERSION_NAME); sb.append("\n"); } sb.append(Build.FINGERPRINT); return sb.toString(); } private void showVersion(StringBuilder sb) { if (name != null && !BuildConfig.VERSION_NAME.equalsIgnoreCase(name)) { sb.append("Active: "); sb.append(name); sb.append("\n"); } if (version != null) { if (version == 0) { method = "native"; } sb.append("Bridge: "); sb.append(method); sb.append(" v"); sb.append(version); if ("native".equalsIgnoreCase(method) && version < PreventRunning.VERSION) { sb.append(" -> v"); sb.append(PreventRunning.VERSION); } sb.append("\n"); } } private void showVersionInfo() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(getString(R.string.app_name) + "(" + BuildConfig.VERSION_NAME + ")"); builder.setMessage(getVersionInfo(false)); builder.setIcon(R.drawable.ic_launcher); builder.setPositiveButton(getString(android.R.string.copy), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { DeprecatedUtils.setClipboard(getBaseContext(), getVersionInfo(true)); } }); builder.create().show(); } private void resolveColors() { colorBackground = ColorUtils.rgba(ColorUtils.resolveColor(this, android.R.attr.colorBackground)); colorLink = ColorUtils.rgba(ColorUtils.resolveColor(this, android.R.attr.textColorLink)); int textColorPrimary = ColorUtils.resolveColor(this, android.R.attr.textColorPrimary); colorText = ColorUtils.rgba(ColorUtils.fixOpacity(textColorPrimary)); } }